Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Axis refactor v11d - Refactor DrawAxes #615

Merged
merged 9 commits into from
Nov 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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