Skip to content

Commit

Permalink
Fix area tooltip
Browse files Browse the repository at this point in the history
  • Loading branch information
schaumb committed Jul 30, 2024
1 parent 9cb3b5b commit 83c7070
Show file tree
Hide file tree
Showing 6 changed files with 101 additions and 27 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

## [Unreleased]

### Fixed

- Area charts with data series started with zero: tooltip fixed.

## [0.12.0] - 2024-07-29

### Fixed
Expand Down
75 changes: 61 additions & 14 deletions src/base/geom/point.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,56 +18,56 @@ struct Point
double x{0.0};
double y{0.0};

static Point Invalid() { return {NAN, NAN}; }
[[nodiscard]] static Point Invalid() { return {NAN, NAN}; }

static Point Max()
[[nodiscard]] static Point Max()
{
return {std::numeric_limits<double>::max(),
std::numeric_limits<double>::max()};
}

static Point Min()
[[nodiscard]] static Point Min()
{
return {std::numeric_limits<double>::lowest(),
std::numeric_limits<double>::lowest()};
}

static Point Ident(bool horizontal)
[[nodiscard]] static Point Ident(bool horizontal)
{
return {horizontal ? 1.0 : 0.0, horizontal ? 0.0 : 1.0};
}

static Point Polar(double radius, double angle)
[[nodiscard]] static Point Polar(double radius, double angle)
{
return {radius * cos(angle), radius * sin(angle)};
}

static Point X(double x) { return {x, 0}; }
[[nodiscard]] static Point X(double x) { return {x, 0}; }

static Point Y(double y) { return {0, y}; }
[[nodiscard]] static Point Y(double y) { return {0, y}; }

Point operator*(double factor) const
[[nodiscard]] Point operator*(double factor) const
{
return {x * factor, y * factor};
}

Point operator/(double divisor) const
[[nodiscard]] Point operator/(double divisor) const
{
if (Math::Floating::is_zero(divisor)) return Invalid();
return {x / divisor, y / divisor};
}

Point operator+(const Point &other) const
[[nodiscard]] Point operator+(const Point &other) const
{
return {x + other.x, y + other.y};
}

Point operator-(const Point &other) const
[[nodiscard]] Point operator-(const Point &other) const
{
return {x - other.x, y - other.y};
}

Point operator*(const Point &other) const
[[nodiscard]] Point operator*(const Point &other) const
{
return {x * other.x, y * other.y};
}
Expand All @@ -77,18 +77,65 @@ struct Point
return x * other.x + y * other.y;
}

Point operator/(const Point &other) const
[[nodiscard]] Point operator/(const Point &other) const
{
using Math::Floating::is_zero;
if (is_zero(other.x) || is_zero(other.y)) return Invalid();
return {x / other.x, y / other.y};
}

double operator^(const Point &p) const
[[nodiscard]] double operator^(const Point &p) const
{
return x * p.y - y * p.x;
}

Point &operator+=(const Point &other)
{
x += other.x;
y += other.y;
return *this;
}

Point &operator-=(const Point &other)
{
x -= other.x;
y -= other.y;
return *this;
}

Point &operator*=(double factor)
{
x *= factor;
y *= factor;
return *this;
}

Point &operator/=(double divisor)
{
if (Math::Floating::is_zero(divisor))
return *this = Invalid();
x /= divisor;
y /= divisor;
return *this;
}

Point &operator*=(const Point &other)
{
x *= other.x;
y *= other.y;
return *this;
}

Point &operator/=(const Point &other)
{
using Math::Floating::is_zero;
if (is_zero(other.x) || is_zero(other.y))
return *this = Invalid();
x /= other.x;
y /= other.y;
return *this;
}

[[nodiscard]] Point flip() const { return {y, x}; }

[[nodiscard]] Point flipX() const { return {-x, y}; }
Expand Down
10 changes: 0 additions & 10 deletions src/base/geom/quadrilateral.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,6 @@
namespace Geom
{

ConvexQuad::ConvexQuad(const Rect &rect)
{
points[0] = rect.pos;
points[1] = rect.pos + Point{rect.size.x, 0.0};
points[2] = rect.pos + rect.size;
points[3] = rect.pos + Point{0.0, rect.size.y};
}

Rect ConvexQuad::boundary() const { return Rect::Boundary(points); }

ConvexQuad ConvexQuad::Square(Point p0, Point p2)
{
auto center = (p0 + p2) / 2;
Expand Down
2 changes: 0 additions & 2 deletions src/base/geom/quadrilateral.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ class ConvexQuad

ConvexQuad() = default;
explicit ConvexQuad(const Points &points) : points(points) {}
explicit ConvexQuad(const Rect &rect);
[[nodiscard]] static ConvexQuad Square(Point p0, Point p2);
[[nodiscard]] static ConvexQuad Isosceles(Point base0Middle,
Point base1Middle,
Expand All @@ -26,7 +25,6 @@ class ConvexQuad
[[nodiscard]] bool contains(const Point &p,
double tolerance = 0.0) const;
[[nodiscard]] double area() const;
[[nodiscard]] Rect boundary() const;
};

}
Expand Down
33 changes: 32 additions & 1 deletion src/chart/rendering/renderedchart.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,8 @@ bool Marker::bounds(const CoordinateSystem &coordSys,
switch (shapeType) {
case Gen::ShapeType::rectangle:
case Gen::ShapeType::area:
return Geom::ConvexQuad(points).contains(point, 0.01);
return pointsToQuad(points, 0.1)
.contains(point, 0.01);
case Gen::ShapeType::circle:
return Geom::Circle(Geom::Rect::Boundary(points),
Geom::Circle::FromRect::sameWidth)
Expand All @@ -65,6 +66,36 @@ bool Marker::bounds(const CoordinateSystem &coordSys,
return isInside != false;
}

Geom::ConvexQuad Marker::pointsToQuad(
const std::array<Geom::Point, 4> &points,
double atLeastWidth) const
{
if (const auto &[p0, p1, p2, p3] = points;
p0 == p1 && p0 == p2 && p0 == p3) {
const Geom::Point half{atLeastWidth / 2, atLeastWidth / 2};
return Geom::ConvexQuad::Square(p0 - half, p0 + half);
}
Geom::ConvexQuad res{points};

for (std::size_t ix{}; ix < 4; ++ix) {
const auto nextIx = (ix + 1) % 4;
auto &&vector = points[nextIx] - points[ix];
if (auto &&diff = vector.abs(); diff < atLeastWidth) {
if (Math::Floating::is_zero(diff)) {
const auto nextNextIx = (nextIx + 1) % 4;
vector = (points[nextNextIx] - points[nextIx])
.normal(false);
}
auto &&move =
vector.normalized() * ((atLeastWidth - diff) / 2);
res.points[ix] -= move;
res.points[nextIx] += move;
}
}

return res;
}

Geom::ConvexQuad Marker::lineToQuad(const CoordinateSystem &coordSys,
double atLeastWidth) const
{
Expand Down
4 changes: 4 additions & 0 deletions src/chart/rendering/renderedchart.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,10 @@ class Marker
const Geom::Point &point) const;

private:
[[nodiscard]] Geom::ConvexQuad pointsToQuad(
const std::array<Geom::Point, 4> &points,
double atLeastWidthIfDot) const;

[[nodiscard]] Geom::ConvexQuad lineToQuad(
const CoordinateSystem &coordSys,
double atLeastWidth) const;
Expand Down

0 comments on commit 83c7070

Please sign in to comment.