Skip to content

Commit

Permalink
Merge pull request #590 from vizzuhq/axis_refactor_v2
Browse files Browse the repository at this point in the history
Axis refactor v2 - Do not interpolate hiding/showing legend
  • Loading branch information
simzer authored Nov 4, 2024
2 parents e658231 + 0ca3981 commit d3a985c
Show file tree
Hide file tree
Showing 13 changed files with 99 additions and 84 deletions.
6 changes: 5 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,22 @@

## [Unreleased]

### Fixed

- Do not interpolate hiding/showing legend

## [0.15.0] - 2024-10-28

### Fixed

- Removed 'min' align property from the API which equivalent with the 'none'.
- Markers are the same even if new record added.
- Flying out marker label fixed.
- Axis line hide/show at same time with axis labels/ticks/title.
- Do not draw invisible axis line.

### Changed

- Removed 'min' align property from the API which equivalent with the 'none'.
- Changed MarkerId to be a string instead of a number.

### Added
Expand Down
11 changes: 7 additions & 4 deletions src/base/refl/auto_enum.h
Original file line number Diff line number Diff line change
Expand Up @@ -196,28 +196,31 @@ template <class E> constexpr E get_enum(const std::string_view &data)
template <class E, class V>
struct EnumArray : std::array<V, std::size(enum_names<E>)>
{
constexpr static auto first = Detail::from_to<E>().first;
using base_array = std::array<V, std::size(enum_names<E>)>;
[[nodiscard]] constexpr V &operator[](E value) noexcept
{
return base_array::operator[](
static_cast<std::size_t>(value));
static_cast<std::size_t>(value) - first);
}

[[nodiscard]] constexpr const V &operator[](
E value) const noexcept
{
return base_array::operator[](
static_cast<std::size_t>(value));
static_cast<std::size_t>(value) - first);
}

[[nodiscard]] constexpr V &at(E value)
{
return base_array::at(static_cast<std::size_t>(value));
return base_array::at(
static_cast<std::size_t>(value) - first);
}

[[nodiscard]] constexpr const V &at(E value) const
{
return base_array::at(static_cast<std::size_t>(value));
return base_array::at(
static_cast<std::size_t>(value) - first);
}

bool operator==(const EnumArray &) const = default;
Expand Down
13 changes: 8 additions & 5 deletions src/base/refl/auto_struct.h
Original file line number Diff line number Diff line change
Expand Up @@ -593,6 +593,13 @@ template <class T, class Visitor> struct Applier
[[maybe_unused]] Visitor &v) noexcept
{
if constexpr (!std::is_empty_v<U>) {
constexpr auto members =
Members::get_member_functors<U>(nullptr);

static_assert(
std::tuple_size_v<bases_t<U>> > 0
|| std::tuple_size_v<decltype(members)> > 0,
"Unable to run reflection");
if constexpr (std::tuple_size_v<bases_t<U>> > 0) {
std::invoke(
[&v]<class... Bases>(std::tuple<Bases...> *)
Expand All @@ -604,11 +611,7 @@ template <class T, class Visitor> struct Applier
},
std::add_pointer_t<bases_t<U>>{});
}

if constexpr (constexpr auto members =
Members::get_member_functors<U>(
nullptr);
std::tuple_size_v<decltype(members)> > 0) {
if constexpr (std::tuple_size_v<decltype(members)> > 0) {
std::apply(
[&v]<class... MF>(MF...)
{
Expand Down
22 changes: 6 additions & 16 deletions src/chart/animator/planner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -351,12 +351,10 @@ bool Planner::positionMorphNeeded() const

bool Planner::needColor() const
{
return (isAnyLegend(Gen::ChannelId::color)
&& source->axises.at(Gen::ChannelId::color)
!= target->axises.at(Gen::ChannelId::color))
|| (isAnyLegend(Gen::ChannelId::lightness)
&& source->axises.at(Gen::ChannelId::lightness)
!= target->axises.at(Gen::ChannelId::lightness))
return source->axises.at(Gen::ChannelId::color)
!= target->axises.at(Gen::ChannelId::color)
|| source->axises.at(Gen::ChannelId::lightness)
!= target->axises.at(Gen::ChannelId::lightness)
|| anyMarker(+[](const Gen::Marker &source,
const Gen::Marker &target) -> bool
{
Expand Down Expand Up @@ -406,9 +404,8 @@ bool Planner::needVertical() const
!= target->axises.at(Gen::AxisId::y)
|| source->guides.at(Gen::AxisId::y)
!= target->guides.at(Gen::AxisId::y)
|| (isAnyLegend(Gen::ChannelId::size)
&& source->axises.at(Gen::ChannelId::size)
!= target->axises.at(Gen::ChannelId::size))
|| source->axises.at(Gen::ChannelId::size)
!= target->axises.at(Gen::ChannelId::size)
|| (source->markerConnectionOrientation
!= target->markerConnectionOrientation
&& (source->markerConnectionOrientation.value_or(
Expand Down Expand Up @@ -461,13 +458,6 @@ bool Planner::needHorizontal() const
});
}

bool Planner::isAnyLegend(Gen::ChannelId type) const
{
const auto &src = source->getOptions()->legend.get();
const auto &trg = target->getOptions()->legend.get();
return (src && *src == type) || (trg && *trg == type);
}

void Planner::addMorph(SectionId sectionId,
::Anim::Duration duration,
::Anim::Duration delay,
Expand Down
2 changes: 0 additions & 2 deletions src/chart/animator/planner.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,6 @@ class Planner : public ::Anim::Group
static size_t dimensionCount(const Gen::Plot *plot,
Gen::AxisId type);

[[nodiscard]] bool isAnyLegend(Gen::ChannelId type) const;

::Anim::Options getOptions(SectionId sectionId,
::Anim::Duration duration,
::Anim::Duration delay = ::Anim::Duration(0),
Expand Down
53 changes: 36 additions & 17 deletions src/chart/generator/plotbuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -357,9 +357,12 @@ void PlotBuilder::normalizeXY()

void PlotBuilder::calcMeasureAxises(const Data::DataTable &dataTable)
{
for (const Channel &ch :
plot->getOptions()->getChannels().getChannels())
calcMeasureAxis(dataTable, ch.type);
for (const ChannelId &ch :
{ChannelId::x, ChannelId::y, ChannelId::label})
calcMeasureAxis(dataTable, ch);

if (auto &&legend = plot->options->legend.get())
calcMeasureAxis(dataTable, asChannel(*legend));
}

void PlotBuilder::calcMeasureAxis(const Data::DataTable &dataTable,
Expand Down Expand Up @@ -395,9 +398,11 @@ void PlotBuilder::calcMeasureAxis(const Data::DataTable &dataTable,

void PlotBuilder::calcDimensionAxises()
{
for (const Channel &ch :
plot->getOptions()->getChannels().getChannels())
calcDimensionAxis(ch.type);
for (const ChannelId &ch : {ChannelId::x, ChannelId::y})
calcDimensionAxis(ch);

if (auto &&legend = plot->options->legend.get())
calcDimensionAxis(asChannel(*legend));
}

void PlotBuilder::calcDimensionAxis(ChannelId type)
Expand Down Expand Up @@ -590,17 +595,31 @@ void PlotBuilder::normalizeColors()
cbase.setPos(color.rescale(cbase.getPos()));
}

plot->axises.at(ChannelId::color).measure.range = color;
plot->axises.at(ChannelId::lightness).measure.range = lightness;

for (auto &value : plot->axises.at(ChannelId::color).dimension)
value.second.colorBase =
ColorBase(static_cast<uint32_t>(value.second.value), 0.5);

for (auto &value :
plot->axises.at(ChannelId::lightness).dimension) {
value.second.value = lightness.rescale(value.second.value);
value.second.colorBase = ColorBase(0U, value.second.value);
if (auto &&legend = plot->options->legend.get()) {
switch (*legend) {
case Options::LegendId::color:
plot->axises.at(ChannelId::color).measure.range = color;

for (auto &value :
plot->axises.at(ChannelId::color).dimension)
value.second.colorBase = ColorBase(
static_cast<uint32_t>(value.second.value),
0.5);
break;
case Options::LegendId::lightness:
plot->axises.at(ChannelId::lightness).measure.range =
lightness;

for (auto &value :
plot->axises.at(ChannelId::lightness).dimension) {
value.second.value =
lightness.rescale(value.second.value);
value.second.colorBase =
ColorBase(0U, value.second.value);
}
break;
default:;
}
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/chart/main/events.h
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ class Events

struct LegendProperties
{
Gen::ChannelId channel;
Gen::Options::LegendId channel;
double scrollTop{};
double scrollHeight{};
};
Expand Down
17 changes: 3 additions & 14 deletions src/chart/options/options.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,6 @@ ChannelExtrema operator"" _perc(long double percent)
}
}

[[nodiscard]] bool operator==(const Options::LegendId &l,
const ChannelId &c)
{
return Options::toChannel(l) == c;
}

void Options::reset()
{
channels.reset();
Expand Down Expand Up @@ -283,14 +277,14 @@ std::optional<Options::LegendId> Options::getAutoLegend() const
series.erase(*id);

for (auto channelId : {LegendId::color, LegendId::lightness})
if (channels.at(toChannel(channelId))
if (channels.at(asChannel(channelId))
.dimensions()
.contains_any(series.begin(), series.end()))
return channelId;

for (auto channelId :
{LegendId::color, LegendId::lightness, LegendId::size})
if (auto &&mid = channels.at(toChannel(channelId)).measureId)
if (auto &&mid = channels.at(asChannel(channelId)).measureId)
if (series.contains(*mid)) return channelId;

return std::nullopt;
Expand Down Expand Up @@ -341,7 +335,7 @@ bool Options::labelsShownFor(const Data::SeriesIndex &series) const
return channels.at(AxisId::x).labelSeries() == series
|| channels.at(AxisId::y).labelSeries() == series
|| (legend.get()
&& channels.at(toChannel(*legend.get())).labelSeries()
&& channels.at(asChannel(*legend.get())).labelSeries()
== series);
}

Expand All @@ -365,9 +359,4 @@ void Options::showTooltip(std::optional<MarkerIndex> marker)
}
}

[[nodiscard]] ChannelId Options::toChannel(const LegendId &l)
{
return static_cast<ChannelId>(l);
}

}
16 changes: 12 additions & 4 deletions src/chart/options/options.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,6 @@ class Options
using Orientation = ::Anim::Interpolated<OrientationType>;
using MarkersInfoMap = std::map<MarkerInfoId, MarkerIndex>;

friend bool operator==(const LegendId &, const ChannelId &);

[[nodiscard]] static ChannelId toChannel(const LegendId &);

Options() = default;

[[nodiscard]] const Channels &getChannels() const
Expand Down Expand Up @@ -193,6 +189,18 @@ class Options
ChannelExtrema max);
};

[[nodiscard]] constexpr ChannelId asChannel(
const Options::LegendId &l)
{
return static_cast<ChannelId>(l);
}

[[nodiscard]] constexpr bool operator==(const Options::LegendId &l,
const ChannelId &c)
{
return asChannel(l) == c;
}

using PlotOptionsPtr = std::shared_ptr<Options>;

}
Expand Down
2 changes: 1 addition & 1 deletion src/chart/rendering/drawchart.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ void DrawChart::drawLegend(Gfx::ICanvas &canvas,
if (legend.value)
legendObj.draw(canvas,
bounds,
Gen::Options::toChannel(*legend.value),
*legend.value,
legend.weight);
});
}
Expand Down
13 changes: 7 additions & 6 deletions src/chart/rendering/drawlegend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
#include "base/text/smartstring.h"
#include "chart/generator/plot.h" // NOLINT(misc-include-cleaner)
#include "chart/main/events.h"
#include "chart/options/channel.h"
#include "chart/options/options.h"
#include "chart/rendering/colorbuilder.h"
#include "chart/rendering/drawbackground.h"
#include "chart/rendering/drawlabel.h"
Expand All @@ -31,7 +31,7 @@ namespace Vizzu::Draw

void DrawLegend::draw(Gfx::ICanvas &canvas,
const Geom::Rect &legendLayout,
Gen::ChannelId channelType,
Gen::Options::LegendId channelType,
double weight) const
{
auto markerWindowRect =
Expand All @@ -58,8 +58,9 @@ void DrawLegend::draw(Gfx::ICanvas &canvas,
.weight = weight,
.itemHeight = itemHeight,
.markerSize = markerSize,
.measure = plot->axises.at(channelType).measure,
.dimension = plot->axises.at(channelType).dimension,
.measure = plot->axises.at(asChannel(channelType)).measure,
.dimension =
plot->axises.at(asChannel(channelType)).dimension,
.properties = {.channel = channelType},
.fadeBarGradient = {markerWindowRect.leftSide(),
{.line = {},
Expand Down Expand Up @@ -120,7 +121,7 @@ const Gfx::LinearGradient &DrawLegend::FadeBarGradient::operator()(

void DrawLegend::drawTitle(const Info &info) const
{
plot->axises.at(info.properties.channel)
plot->axises.at(asChannel(info.properties.channel))
.title.visit(
[this,
&info,
Expand Down Expand Up @@ -286,7 +287,7 @@ void DrawLegend::drawMeasure(const Info &info) const

auto bar = getBarRect(info);

using ST = Gen::ChannelId;
using ST = Gen::Options::LegendId;
switch (info.properties.channel) {
case ST::color: colorBar(info, bar); break;
case ST::lightness: lightnessBar(info, bar); break;
Expand Down
2 changes: 1 addition & 1 deletion src/chart/rendering/drawlegend.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ class DrawLegend : public DrawingContext
public:
void draw(Gfx::ICanvas &canvas,
const Geom::Rect &legendLayout,
Gen::ChannelId channelType,
Gen::Options::LegendId channelType,
double weight) const;

const Events::DrawEvents::Legend &events = rootEvents.draw.legend;
Expand Down
Loading

0 comments on commit d3a985c

Please sign in to comment.