Skip to content

Commit 019786f

Browse files
authored
Merge pull request #630 from vizzuhq/axis_refactor_v13b
Axis refactor v13b - Multiple origo
2 parents 742bd52 + cd36ede commit 019786f

File tree

21 files changed

+459
-252
lines changed

21 files changed

+459
-252
lines changed

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,12 @@
1212
### Changed
1313

1414
- Channels 'set' rewrite doesn't clear AxisChannel properties.
15+
- Split charts
16+
- axis line multiplication.
17+
- axis labels multiplication.
18+
- axis range interpretation differently for all split part.
19+
- negative values are handled correctly.
20+
- align center / stretch fix.
1521

1622
### Added
1723

src/base/math/range.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,8 @@ template <std::floating_point T = double> struct Range
4242

4343
[[nodiscard]] bool includes(const T &value) const
4444
{
45-
return !less(value, min) && !less(max, value);
45+
return !is_lt(std::weak_order(value, min))
46+
&& !is_lt(std::weak_order(max, value));
4647
}
4748

4849
[[nodiscard]] T rescale(const T &value, T def = 0.5) const

src/chart/generator/axis.cpp

Lines changed: 106 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -348,7 +348,8 @@ interpolate(const SplitAxis &op0, const SplitAxis &op1, double factor)
348348
interpolate(static_cast<const Axis &>(op0),
349349
static_cast<const Axis &>(op1),
350350
factor);
351-
if (!op0.parts.empty() && !op1.parts.empty()) {
351+
if (!op0.parts.empty() && !op1.parts.empty()
352+
&& op0.seriesName() == op1.seriesName()) {
352353
using PartPair = const decltype(res.parts)::value_type;
353354
Alg::union_foreach(
354355
op0.parts,
@@ -360,69 +361,128 @@ interpolate(const SplitAxis &op0, const SplitAxis &op1, double factor)
360361
switch (type) {
361362
case Alg::union_call_t::only_left: {
362363
auto from = lhs->second.range.min;
363-
res.parts[lhs->first] = {
364-
.weight = interpolate(lhs->second.weight,
365-
0.0,
366-
factor),
367-
.range = interpolate(lhs->second.range,
368-
Math::Range<>{from, from},
369-
factor)};
364+
res.parts.insert({lhs->first,
365+
{.weight = interpolate(lhs->second.weight,
366+
0.0,
367+
factor),
368+
.range = interpolate(lhs->second.range,
369+
Math::Range<>{from, from},
370+
factor),
371+
.measureRange =
372+
interpolate(lhs->second.measureRange,
373+
Math::Range<>{0, 1},
374+
factor)}});
370375
break;
371376
}
372377
case Alg::union_call_t::only_right: {
373378
auto from = rhs->second.range.min;
374-
res.parts[rhs->first] = {
375-
.weight = interpolate(0.0,
376-
rhs->second.weight,
377-
factor),
378-
.range =
379-
interpolate(Math::Range<>{from, from},
380-
rhs->second.range,
381-
factor)};
379+
res.parts.insert({rhs->first,
380+
{.weight = interpolate(0.0,
381+
rhs->second.weight,
382+
factor),
383+
.range =
384+
interpolate(Math::Range<>{from, from},
385+
rhs->second.range,
386+
factor),
387+
.measureRange =
388+
interpolate(Math::Range<>{0, 1},
389+
rhs->second.measureRange,
390+
factor)}});
382391
break;
383392
}
384393
default:
385394
case Alg::union_call_t::both: {
386-
res.parts[lhs->first] =
387-
interpolate(lhs->second, rhs->second, factor);
395+
res.parts.insert({lhs->first,
396+
interpolate(lhs->second,
397+
rhs->second,
398+
factor)});
388399
break;
389400
}
390401
}
391402
},
392403
res.parts.value_comp());
404+
405+
return res;
393406
}
394-
else if (!op0.parts.empty()) {
395-
auto begin = op0.parts.begin();
396-
res.parts[begin->first] = {
397-
.weight = interpolate(begin->second.weight, 1.0, factor),
398-
.range = interpolate(begin->second.range,
399-
Math::Range<>{0, 1},
400-
factor)};
401-
while (++begin != op0.parts.end()) {
402-
res.parts[begin->first] = {
403-
.weight =
404-
interpolate(begin->second.weight, 0.0, factor),
405-
.range = interpolate(begin->second.range,
406-
Math::Range<>{0, 1},
407-
factor)};
407+
408+
if (!op0.parts.empty()) {
409+
if (op0.seriesName() != op1.seriesName()) {
410+
for (auto &&[index, part] : op0.parts)
411+
res.parts.insert({index,
412+
{.weight = part.weight * (1 - factor),
413+
.range = part.range,
414+
.measureRange = part.measureRange}});
415+
}
416+
else {
417+
auto begin = op0.parts.begin();
418+
res.parts.insert({begin->first,
419+
{.weight = interpolate(begin->second.weight,
420+
1.0,
421+
factor),
422+
.range = interpolate(begin->second.range,
423+
Math::Range<>{0, 1},
424+
factor),
425+
.measureRange =
426+
interpolate(begin->second.measureRange,
427+
Math::Range<>{0, 1},
428+
factor)}});
429+
while (++begin != op0.parts.end()) {
430+
res.parts.insert({begin->first,
431+
{.weight = interpolate(begin->second.weight,
432+
0.0,
433+
factor),
434+
.range = interpolate(begin->second.range,
435+
Math::Range<>{0, 1},
436+
factor),
437+
.measureRange =
438+
interpolate(begin->second.measureRange,
439+
Math::Range<>{0, 1},
440+
factor)}});
441+
}
408442
}
409443
}
410-
else if (!op1.parts.empty()) {
411-
auto begin = op1.parts.begin();
412-
res.parts[begin->first] = {
413-
.weight = interpolate(1.0, begin->second.weight, factor),
414-
.range = interpolate(Math::Range<>{0, 1},
415-
begin->second.range,
416-
factor)};
417-
while (++begin != op1.parts.end()) {
418-
res.parts[begin->first] = {
419-
.weight =
420-
interpolate(0.0, begin->second.weight, factor),
421-
.range = interpolate(Math::Range<>{0, 1},
422-
begin->second.range,
423-
factor)};
444+
else if (!op1.parts.empty()
445+
&& op0.seriesName() != op1.seriesName())
446+
res.parts.insert({std::nullopt, {.weight = 1 - factor}});
447+
448+
if (!op1.parts.empty()) {
449+
if (op0.seriesName() != op1.seriesName()) {
450+
for (auto &&[index, part] : op1.parts)
451+
res.parts.insert({index,
452+
{.weight = part.weight * factor,
453+
.range = part.range,
454+
.measureRange = part.measureRange}});
455+
}
456+
else {
457+
auto begin = op1.parts.begin();
458+
res.parts.insert({begin->first,
459+
{.weight = interpolate(1.0,
460+
begin->second.weight,
461+
factor),
462+
.range = interpolate(Math::Range<>{0, 1},
463+
begin->second.range,
464+
factor),
465+
.measureRange = interpolate(Math::Range<>{0, 1},
466+
begin->second.measureRange,
467+
factor)}});
468+
while (++begin != op1.parts.end()) {
469+
res.parts.insert({begin->first,
470+
{.weight = interpolate(0.0,
471+
begin->second.weight,
472+
factor),
473+
.range = interpolate(Math::Range<>{0, 1},
474+
begin->second.range,
475+
factor),
476+
.measureRange =
477+
interpolate(Math::Range<>{0, 1},
478+
begin->second.measureRange,
479+
factor)}});
480+
}
424481
}
425482
}
483+
else if (!op0.parts.empty()
484+
&& op0.seriesName() != op1.seriesName())
485+
res.parts.insert({std::nullopt, {.weight = factor}});
426486

427487
return res;
428488
}

src/chart/generator/axis.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -202,12 +202,14 @@ struct SplitAxis : Axis
202202
{
203203
double weight{1.0};
204204
Math::Range<> range{0, 1};
205+
Math::Range<> measureRange{0, 1};
205206

206207
[[nodiscard]] bool operator==(
207208
const Part &other) const = default;
208209
};
209210

210-
using Parts = std::map<std::size_t, Part>;
211+
using Parts =
212+
std::multimap<std::optional<Data::SliceIndex>, Part>;
211213
Parts parts;
212214

213215
[[nodiscard]] bool operator==(

0 commit comments

Comments
 (0)