Skip to content

Commit

Permalink
Merge pull request #573 from vizzuhq/Translate_legend
Browse files Browse the repository at this point in the history
Axis fixes
  • Loading branch information
schaumb authored Sep 9, 2024
2 parents 507f39a + adeab10 commit d4e27e2
Show file tree
Hide file tree
Showing 15 changed files with 636 additions and 564 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@
- Axis: line, title, labels, guides, interlacing, ticks
- Legend: title, dimension markers, measure extrema labels
- Marker: line with connections
- Fix negative ranges on x, y, color (measure) and lightness.
- Fix axis step parameter if not match with the range sign (neg/pos).
- Fix axis interpolation. From now the axis and axis labels are following the markers.
- Fix measure axis labels when the range started after the 2000th step value from origo.

### Added

Expand Down
2 changes: 1 addition & 1 deletion src/base/anim/interpolated.h
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,7 @@ template <typename Type> class Interpolated
return false;
}

template <class T, class U>
template <class T = double, class U>
[[nodiscard]] T factor(const U &value) const
{
double res{};
Expand Down
5 changes: 0 additions & 5 deletions src/base/math/range.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,11 +74,6 @@ template <std::floating_point T> struct Range
return is_zero(s) ? 0.5 : (value - min) / s;
}

[[nodiscard]] Range<T> rescale(const Range<T> &range) const
{
return Range<T>(rescale(range.min), rescale(range.max));
}

[[nodiscard]] T scale(const T &value) const
{
return value * size() + min;
Expand Down
72 changes: 69 additions & 3 deletions src/chart/generator/axis.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
#include "axis.h"

#include <algorithm>
#include <cmath>
#include <limits>
#include <map>
#include <optional>
#include <string>
Expand Down Expand Up @@ -42,7 +44,13 @@ MeasureAxis::MeasureAxis(Math::Range<double> interval,
unit(std::string{unit}),
origMeasureName(std::string{measName}),
step(step ? *step : Math::Renard::R5().ceil(range.size() / 5.0))
{}
{
if (Math::Floating::is_zero(range.size()))
this->step->value = 0;
else if (std::signbit(this->step->value)
!= std::signbit(range.size()))
this->step->value *= -1;
}

bool MeasureAxis::operator==(const MeasureAxis &other) const
{
Expand All @@ -68,8 +76,66 @@ MeasureAxis interpolate(const MeasureAxis &op0,
interpolate(op0.origMeasureName, op1.origMeasureName, factor);

if (op0.enabled.get() && op1.enabled.get()) {
res.range = Math::interpolate(op0.range, op1.range, factor);
res.step = interpolate(op0.step, op1.step, factor);
constexpr auto MAX = std::numeric_limits<double>::max() / 2;
using Math::Floating::is_zero;

const auto s0 = op0.range.size();
const auto s1 = op1.range.size();

if (auto s0Zero = is_zero(s0); s0Zero || is_zero(s1)) {
res.range = Math::Range<double>::Raw(
Math::interpolate(op0.range.getMin(),
op1.range.getMin(),
factor),
Math::interpolate(op0.range.getMax(),
op1.range.getMax(),
factor));
res.step = s0Zero ? op1.step : op0.step;
}
else {
auto s0Inv = 1 / s0;
auto s1Inv = 1 / s1;

const auto interp =
Math::interpolate(s0Inv, s1Inv, factor);

const auto s = is_zero(interp) ? MAX : 1 / interp;

res.range = Math::Range<double>::Raw(
Math::interpolate(op0.range.getMin() * s0Inv,
op1.range.getMin() * s1Inv,
factor)
* s,
Math::interpolate(op0.range.getMax() * s0Inv,
op1.range.getMax() * s1Inv,
factor)
* s);

auto step = Math::interpolate(op0.step.get() * s0Inv,
op1.step.get() * s1Inv,
factor)
* s;

if (auto op0sign = std::signbit(op0.step.get());
op0sign == std::signbit(op1.step.get()))
res.step = interpolate(op0.step,
op1.step,
Math::Range<double>::Raw(op0.step.get(),
op1.step.get())
.rescale(step));
else if (auto max = std::copysign(MAX, step);
op0sign == std::signbit(step))
res.step = interpolate(op0.step,
Anim::Interpolated{max},
Math::Range<double>::Raw(op0.step.get(), max)
.rescale(step));
else
res.step = interpolate(op1.step,
Anim::Interpolated{max},
Math::Range<double>::Raw(op1.step.get(), max)
.rescale(step));
}

res.unit = interpolate(op0.unit, op1.unit, factor);
}
else if (op0.enabled.get()) {
Expand Down
18 changes: 12 additions & 6 deletions src/chart/generator/plotbuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -355,23 +355,26 @@ void PlotBuilder::normalizeXY()
}

plot->getOptions()->setAutoRange(
!std::signbit(boundRect.positive().hSize().getMin()),
!std::signbit(boundRect.positive().vSize().getMin()));
!std::signbit(boundRect.hSize().getMin()),
!std::signbit(boundRect.vSize().getMin()));

boundRect.setHSize(xrange.getRange(boundRect.hSize()));
boundRect.setVSize(yrange.getRange(boundRect.vSize()));

for (auto &marker : plot->markers) {
if (!boundRect.intersects(marker.toRectangle().positive()))
if (!boundRect.positive().intersects(
marker.toRectangle().positive()))
marker.enabled = false;

auto rect = marker.toRectangle();
auto newRect = boundRect.normalize(rect);
marker.fromRectangle(newRect);
}

getMeasTrackRange(ChannelId::x) = boundRect.hSize();
getMeasTrackRange(ChannelId::y) = boundRect.vSize();
getMeasTrackRange(ChannelId::x) =
Math::Range<double>::Raw(boundRect.left(), boundRect.right());
getMeasTrackRange(ChannelId::y) =
Math::Range<double>::Raw(boundRect.bottom(), boundRect.top());
}

void PlotBuilder::calcMeasureAxises(const Data::DataTable &dataTable)
Expand Down Expand Up @@ -478,7 +481,10 @@ void PlotBuilder::addAlignment(const Buckets &subBuckets) const

if (std::signbit(
plot->axises.at(plot->getOptions()->subAxisType())
.measure.range.getMin()))
.measure.range.getMin())
|| std::signbit(
plot->axises.at(plot->getOptions()->subAxisType())
.measure.range.getMax()))
return;

if (plot->getOptions()->align == Base::Align::Type::none) return;
Expand Down
5 changes: 3 additions & 2 deletions src/chart/options/channelrange.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,9 @@ ChannelExtrema::operator std::string() const
Math::Range<double> ChannelRange::getRange(
const Math::Range<double> &original) const
{
return {getExtrema(min, original.getMin(), original),
getExtrema(max, original.getMax(), original)};
return Math::Range<double>::Raw(
getExtrema(min, original.getMin(), original),
getExtrema(max, original.getMax(), original));
}

double ChannelRange::getExtrema(const OptionalChannelExtrema &extrema,
Expand Down
4 changes: 2 additions & 2 deletions src/chart/rendering/drawaxes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,7 @@ void DrawAxes::drawTitle(Gen::ChannelId axisIndex) const
? titleStyle.orientation->get_or_first(index)
.value
== Styles::AxisTitle::Orientation::vertical
: titleStyle.orientation->factor<double>(
: titleStyle.orientation->factor(
Styles::AxisTitle::Orientation::vertical));

auto orientedSize =
Expand Down Expand Up @@ -336,7 +336,7 @@ void DrawAxes::drawDimensionLabel(bool horizontal,
labelStyle.position->interpolates()
? labelStyle.side->get_or_first(index).value
== Styles::AxisLabel::Side::negative
: labelStyle.side->factor<double>(
: labelStyle.side->factor(
Styles::AxisLabel::Side::negative);

auto sign = 1 - 2 * under;
Expand Down
3 changes: 1 addition & 2 deletions src/chart/rendering/drawguides.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,7 @@ void DrawGuides::draw(bool horizontal)
const auto &axis = axises.at(axisId).dimension;

if (axis.enabled && *guideStyle.lineWidth > 0
&& (static_cast<double>(plot->guides.at(axisId).axisGuides)
> 0)) {
&& plot->guides.at(axisId).axisGuides != false) {
canvas.setLineWidth(*guideStyle.lineWidth);

for (auto it = axis.begin(); it != axis.end(); ++it) {
Expand Down
22 changes: 13 additions & 9 deletions src/chart/rendering/drawinterlacing.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include "base/geom/rect.h"
#include "base/gfx/colortransform.h"
#include "base/gfx/font.h"
#include "base/math/floating.h"
#include "base/math/range.h"
#include "base/math/renard.h"
#include "base/text/smartstring.h"
Expand Down Expand Up @@ -79,7 +80,7 @@ void DrawInterlacing::draw(bool horizontal, bool text) const
}
else {
auto highWeight =
Math::Range(stepLow, stepHigh).rescale(step);
Math::Range<double>::Raw(stepLow, stepHigh).rescale(step);

auto lowWeight = (1.0 - highWeight) * enabled;
highWeight *= enabled;
Expand Down Expand Up @@ -119,9 +120,8 @@ void DrawInterlacing::draw(

const auto origo = plot->axises.origo();

if (static_cast<double>(enabled.interlacings || enabled.axisSticks
|| enabled.labels)
> 0) {
if ((enabled.interlacings || enabled.axisSticks || enabled.labels)
!= false) {
auto interlaceIntensity = Math::FuzzyBool::And<double>(weight,
enabled.interlacings);
auto interlaceColor =
Expand All @@ -133,15 +133,19 @@ void DrawInterlacing::draw(
auto textAlpha =
Math::FuzzyBool::And<double>(weight, enabled.labels);

if (rangeSize <= 0) return;
if (std::signbit(rangeSize) != std::signbit(stepSize)
|| Math::Floating::is_zero(rangeSize))
return;

auto stripWidth = stepSize / rangeSize;

auto axisBottom = axis.origo() + stripWidth;

auto iMin = axisBottom > 0 ? static_cast<int>(
std::floor(-axis.origo() / (2 * stripWidth)))
: 0;
auto iMin =
axisBottom > 0 ? static_cast<int>(
std::floor(-axis.origo() / (2 * stripWidth)))
: static_cast<int>(
(axis.range.getMin() - stepSize) / 2);

if (stripWidth <= 0) return;
auto interlaceCount = 0U;
Expand Down Expand Up @@ -270,7 +274,7 @@ void DrawInterlacing::drawDataLabel(
auto under = labelStyle.position->interpolates()
? labelStyle.side->get_or_first(index).value
== Styles::AxisLabel::Side::negative
: labelStyle.side->factor<double>(
: labelStyle.side->factor(
Styles::AxisLabel::Side::negative);

auto &&posDir =
Expand Down
2 changes: 1 addition & 1 deletion src/chart/rendering/drawlegend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,7 @@ void DrawLegend::drawMarker(Info &info,
info.canvas.setLineColor(color);
info.canvas.setLineWidth(0);

auto radius = rootStyle.legend.marker.type->factor<double>(
auto radius = rootStyle.legend.marker.type->factor(
Styles::Legend::Marker::Type::circle)
* rect.size.minSize() / 2.0;

Expand Down
9 changes: 4 additions & 5 deletions src/chart/rendering/markerrenderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ void MarkerRenderer::drawLines(Gfx::ICanvas &canvas,
auto center = Geom::Point{blended.center};
center.x = Math::interpolate(center.x,
1.0,
getOptions().coordSystem.factor<double>(
getOptions().coordSystem.factor(
Gen::CoordSystem::polar));
canvas.setLineColor(yLineColor);
auto axisPoint = center.yComp() + origo.xComp();
Expand Down Expand Up @@ -142,9 +142,8 @@ void MarkerRenderer::drawMarkers(Gfx::ICanvas &canvas,
const auto &blended0 =
index == ::Anim::second ? *other : blended;

auto lineFactor =
getOptions().geometry.factor<double>(
Gen::ShapeType::line);
auto lineFactor = getOptions().geometry.factor(
Gen::ShapeType::line);

draw(canvas,
painter,
Expand Down Expand Up @@ -335,7 +334,7 @@ void MarkerRenderer::drawLabel(Gfx::ICanvas &canvas,
return abstractMarker.getLabelPos(position, coordSys);
});

auto centered = labelStyle.position->factor<double>(
auto centered = labelStyle.position->factor(
Styles::MarkerLabel::Position::center);

OrientedLabel{{ctx()}}.draw(canvas,
Expand Down
4 changes: 1 addition & 3 deletions src/chart/rendering/markers/rectanglemarker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,7 @@ RectangleMarker::RectangleMarker(const Gen::Marker &marker,
const Styles::Chart &style) :
SingleDrawMarker(marker, options, Gen::ShapeType::rectangle)
{
linear =
options.coordSystem.factor<double>(Gen::CoordSystem::polar)
== 0;
linear = options.coordSystem.factor(Gen::CoordSystem::polar) == 0;
border = Math::FuzzyBool(true);

auto spacing = Geom::Size{
Expand Down
2 changes: 1 addition & 1 deletion src/chart/rendering/painter/coordinatesystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ namespace Vizzu::Draw
PolarDescartesTransform::PolarDescartesTransform(
const Anim::Interpolated<Gen::CoordSystem> &coordSystem) :
zoomOut{true},
polar(coordSystem.factor<double>(Gen::CoordSystem::polar))
polar(coordSystem.factor(Gen::CoordSystem::polar))
{}

Geom::Point PolarDescartesTransform::convert(
Expand Down
Loading

0 comments on commit d4e27e2

Please sign in to comment.