Skip to content

Commit

Permalink
Merge pull request #615 from vizzuhq/axis_refactor_v11d
Browse files Browse the repository at this point in the history
Axis refactor v11d - Refactor DrawAxes
  • Loading branch information
schaumb authored Nov 25, 2024
2 parents cf45663 + 46f1cb3 commit 5ff6c82
Show file tree
Hide file tree
Showing 22 changed files with 501 additions and 374 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@
- Fix chaotic axis labels on sorted chart with multiple dimension.
- Fix Mekko charts: The main axis handled as dimension.
- LabelLevel can be used to handle measure axis as dimension axis.
- Enable dimension axis ticks and interlacing.
- Enable measure axis guides.
- Fix dimension axis guides on sorted chart.

## [0.15.0] - 2024-10-28

Expand Down
3 changes: 2 additions & 1 deletion src/base/math/interpolation.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ template <class T> struct interpolatable_t
return requires(const T &a, const T &b, double factor) {
{
interpolate(a, b, factor)
} -> std::same_as<T>;
} -> std::same_as<
std::conditional_t<std::is_integral_v<T>, double, T>>;
};
}
};
Expand Down
20 changes: 6 additions & 14 deletions src/chart/generator/axis.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,7 @@ MeasureAxis interpolate(const MeasureAxis &op0,
}
bool DimensionAxis::add(const Data::SliceIndex &index,
const Math::Range<> &range,
const std::optional<std::uint32_t> &position,
std::uint32_t position,
const std::optional<ColorBase> &color,
bool label,
bool merge)
Expand Down Expand Up @@ -286,15 +286,7 @@ bool DimensionAxis::setLabels(double step)
step = std::max(step, 1.0, Math::Floating::less);
auto currStep = 0.0;

using SortedItems =
std::multiset<std::reference_wrapper<Item>, decltype(
[] (Item& lhs, Item &rhs)
{
return Math::Floating::less(lhs.range.getMin(), rhs.range.getMin());
})>;

for (auto curr = int{};
auto &&item : SortedItems{begin(), end()}) {
for (auto curr = int{}; auto &&item : sortedItems()) {
if (++curr <= currStep) continue;
currStep += step;
item.get().label = true;
Expand Down Expand Up @@ -346,15 +338,15 @@ DimensionAxis interpolate(const DimensionAxis &op0,
res.values
.emplace(key,
interpolate(first1->second, latest, factor))
->second.end = false;
->second.endPos.makeAuto();

for (const auto &latest = std::prev(to1)->second;
first2 != to2;
++first2)
res.values
.emplace(key,
interpolate(latest, first2->second, factor))
->second.start = false;
->second.startPos.makeAuto();
}

return res;
Expand All @@ -366,11 +358,11 @@ DimensionAxis::Item interpolate(const DimensionAxis::Item &op0,
{
using Math::Niebloid::interpolate;
DimensionAxis::Item res;
res.start = res.end = true;
res.startPos = op0.startPos;
res.endPos = op1.endPos;
res.range = interpolate(op0.range, op1.range, factor);
res.colorBase = interpolate(op0.colorBase, op1.colorBase, factor);
res.label = interpolate(op0.label, op1.label, factor);
res.position = interpolate(op0.position, op1.position, factor);
return res;
}

Expand Down
57 changes: 28 additions & 29 deletions src/chart/generator/axis.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,50 +83,43 @@ struct DimensionAxis
explicit Item() = default;

public:
bool start{};
bool end{};
using PosType = Base::AutoParam<std::uint32_t>;
PosType startPos{};
PosType endPos{};
Math::Range<> range;
::Anim::Interpolated<std::uint32_t> position;
::Anim::Interpolated<ColorBase> colorBase;
::Anim::Interpolated<bool> label;

Item(Math::Range<> range,
const std::optional<std::uint32_t> &position,
std::uint32_t position,
const std::optional<ColorBase> &color,
bool setCategoryAsLabel) :
start(true),
end(true),
startPos(position),
endPos(position),
range(range),
label(setCategoryAsLabel)
{
if (position) this->position = *position;
if (color) colorBase = *color;
}

Item(const Item &item, bool starter) :
start(starter),
end(!starter),
startPos(starter ? item.startPos : PosType{}),
endPos(starter ? PosType{} : item.endPos),
range(item.range),
position(item.position),
colorBase(item.colorBase),
label(item.label)
{}

bool operator==(const Item &other) const
{
return range == other.range && position == other.position;
}

[[nodiscard]] bool presentAt(
::Anim::InterpolateIndex index) const
{
return (index == ::Anim::first && start)
|| (index == ::Anim::second && end);
return range == other.range && startPos == other.startPos;
}

[[nodiscard]] double weight(double atEnd) const
{
return Math::Niebloid::interpolate(start, end, atEnd);
return Math::Niebloid::interpolate(!startPos.isAuto(),
!endPos.isAuto(),
atEnd);
}

friend Item
Expand All @@ -139,7 +132,7 @@ struct DimensionAxis
DimensionAxis() = default;
bool add(const Data::SliceIndex &index,
const Math::Range<> &range,
const std::optional<std::uint32_t> &position,
std::uint32_t position,
const std::optional<ColorBase> &color,
bool label,
bool merge);
Expand Down Expand Up @@ -167,6 +160,21 @@ struct DimensionAxis

[[nodiscard]] const Values &getValues() const { return values; }

[[nodiscard]] auto sortedItems()
{
struct ItemSorterByRangeStart
{
[[nodiscard]] bool operator()(const Item &lhs,
const Item &rhs) const
{
return Math::Floating::less(lhs.range.getMin(),
rhs.range.getMin());
}
};
return std::multiset<std::reference_wrapper<Item>,
ItemSorterByRangeStart>{begin(), end()};
}

private:
Values values;
};
Expand Down Expand Up @@ -237,15 +245,6 @@ struct Axises
return axises[axisType];
}

[[nodiscard]] const Axis &other(AxisId axisType) const
{
switch (axisType) {
default:
case AxisId::x: return at(AxisId::y);
case AxisId::y: return at(AxisId::x);
}
}

[[nodiscard]] Geom::Point origo() const;

private:
Expand Down
4 changes: 4 additions & 0 deletions src/chart/generator/plotbuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -452,6 +452,10 @@ void PlotBuilder::calcAxis(const Data::DataTable &dataTable,
!axis.dimension.setLabels(scale.step.getValue(1.0))
&& series && isAutoTitle)
axis.title = series.value().getColIndex();
for (std::uint32_t pos{};
DimensionAxis::Item & i : axis.dimension.sortedItems())
i.endPos = i.startPos =
DimensionAxis::Item::PosType{pos++};
}
}

Expand Down
9 changes: 7 additions & 2 deletions src/chart/options/autoparam.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ template <typename Type, bool nullable = false> struct AutoParam
return Conv::toString(*value);
}

explicit operator bool() const
[[nodiscard]] explicit operator bool() const
{
return static_cast<bool>(value);
}
Expand Down Expand Up @@ -76,7 +76,12 @@ template <typename Type, bool nullable = false> struct AutoParam

bool operator==(const AutoParam &other) const = default;

const std::optional<Type> &getValueOrAuto() { return value; }
[[nodiscard]] const std::optional<Type> &getValueOrAuto() const
{
return value;
}

void makeAuto() { autoSet = true; }

private:
bool autoSet{};
Expand Down
Loading

0 comments on commit 5ff6c82

Please sign in to comment.