Skip to content

Commit 5b9bc88

Browse files
authored
Merge pull request #561 from vizzuhq/fix_areachart_zerostart_marker_tooltip
Fix tooltip on area charts with data series started with zero
2 parents 6ad5fed + fe4dd93 commit 5b9bc88

File tree

18 files changed

+219
-218
lines changed

18 files changed

+219
-218
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22

33
## [Unreleased]
44

5+
### Fixed
6+
7+
- Area charts with data series started with zero: tooltip fixed.
8+
59
## [0.12.0] - 2024-07-29
610

711
### Fixed

src/base/geom/circle.cpp

Lines changed: 9 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -7,18 +7,6 @@
77
namespace Geom
88
{
99

10-
Circle::Circle(const Rect &rect, FromRect fromRect)
11-
{
12-
radius = fromRect == FromRect::inscribed
13-
? rect.size.minSize() / 2.0
14-
: fromRect == FromRect::sameWidth ? rect.size.x / 2.0
15-
: fromRect == FromRect::sameHeight ? rect.size.y / 2.0
16-
: fromRect == FromRect::outscribed
17-
? rect.size.diagonal() / 2.0
18-
: throw std::logic_error("invalid circle parameter");
19-
center = rect.pos + rect.size / 2.0;
20-
}
21-
2210
Circle::Circle(const Circle &c0,
2311
const Circle &c1,
2412
double radius,
@@ -40,27 +28,13 @@ bool Circle::concentric(const Circle &c) const
4028
return center == c.center;
4129
}
4230

43-
bool Circle::colateral(const Circle &c, double tolerance) const
44-
{
45-
return Math::AddTolerance(centerDistance(c), tolerance)
46-
== (radius + c.radius);
47-
}
48-
4931
double Circle::area() const { return M_PI * radius * radius; }
5032

51-
bool Circle::overlaps(const Circle &c, double tolerance) const
33+
bool Circle::overlaps(const Circle &c) const
5234
{
5335
auto d = c.center - center;
5436
auto sumRadius = radius + c.radius;
55-
return Math::AddTolerance(d.sqrAbs(), tolerance)
56-
< sumRadius * sumRadius;
57-
}
58-
59-
double Circle::overlapFactor(const Circle &c) const
60-
{
61-
auto d = centerDistance(c);
62-
auto r = radius + c.radius;
63-
return d == 0 ? 0 : r / d;
37+
return Math::AddTolerance(d.sqrAbs()) < sumRadius * sumRadius;
6438
}
6539

6640
Rect Circle::boundary() const
@@ -74,6 +48,13 @@ bool Circle::contains(const Point &point) const
7448
return (point - center).sqrAbs() <= radius * radius;
7549
}
7650

51+
double Circle::distance(const Point &point) const
52+
{
53+
return std::max(0.0,
54+
(point - center).abs() - radius,
55+
Math::Floating::less);
56+
}
57+
7758
double Circle::centerDistance(const Circle &c) const
7859
{
7960
return (center - c.center).abs();

src/base/geom/circle.h

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,6 @@ namespace Geom
1313
class Circle
1414
{
1515
public:
16-
enum class FromRect {
17-
inscribed,
18-
sameWidth,
19-
sameHeight,
20-
outscribed
21-
};
22-
2316
Point center;
2417
double radius;
2518

@@ -30,8 +23,6 @@ class Circle
3023
radius(radius)
3124
{}
3225

33-
Circle(const Rect &rect, FromRect fromRect);
34-
3526
Circle(const Circle &c0,
3627
const Circle &c1,
3728
double radius,
@@ -48,13 +39,10 @@ class Circle
4839
}
4940

5041
[[nodiscard]] double area() const;
51-
[[nodiscard]] bool overlaps(const Circle &c,
52-
double tolerance) const;
53-
[[nodiscard]] double overlapFactor(const Circle &c) const;
54-
[[nodiscard]] bool colateral(const Circle &c,
55-
double tolerance) const;
42+
[[nodiscard]] bool overlaps(const Circle &c) const;
5643
[[nodiscard]] Rect boundary() const;
5744
[[nodiscard]] bool contains(const Point &point) const;
45+
[[nodiscard]] double distance(const Point &point) const;
5846
[[nodiscard]] double distance(const Circle &c) const;
5947
[[nodiscard]] Solutions<Point, 2> intersection(
6048
const Circle &c) const;

src/base/geom/line.h

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ struct Line
1919

2020
[[nodiscard]] bool isPoint() const { return begin == end; }
2121

22-
[[nodiscard]] Geom::Line extend(double length) const
22+
[[nodiscard]] Line extend(double length) const
2323
{
2424
auto p = end - begin;
2525
auto d = p.abs();
@@ -28,28 +28,28 @@ struct Line
2828
return {begin, begin + (p * m)};
2929
}
3030

31-
Geom::Line operator*(double value) const
31+
Line operator*(double value) const
3232
{
3333
return {begin * value, end * value};
3434
}
3535

36-
Geom::Line operator+(const Geom::Line &other) const
36+
Line operator+(const Line &other) const
3737
{
3838
return {begin + other.begin, end + other.end};
3939
}
4040

41-
void shift(const Geom::Point &offset)
41+
void shift(const Point &offset)
4242
{
4343
begin = begin + offset;
4444
end = end + offset;
4545
}
4646

47-
[[nodiscard]] Geom::Point at(double t) const
47+
[[nodiscard]] Point at(double t) const
4848
{
4949
return begin + (end - begin) * t;
5050
}
5151

52-
[[nodiscard]] Geom::Line segment(double t0, double t1) const
52+
[[nodiscard]] Line segment(double t0, double t1) const
5353
{
5454
return {at(t0), at(t1)};
5555
}
@@ -61,7 +61,9 @@ struct Line
6161

6262
[[nodiscard]] double distance(const Point &point) const
6363
{
64-
auto projection = ((point - begin).dot(getDirection()))
64+
if (isPoint()) return (point - begin).abs();
65+
66+
auto projection = (point - begin).dot(getDirection())
6567
/ (length() * length());
6668

6769
projection =

src/base/geom/point.h

Lines changed: 62 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -18,56 +18,56 @@ struct Point
1818
double x{0.0};
1919
double y{0.0};
2020

21-
static Point Invalid() { return {NAN, NAN}; }
21+
[[nodiscard]] static Point Invalid() { return {NAN, NAN}; }
2222

23-
static Point Max()
23+
[[nodiscard]] static Point Max()
2424
{
2525
return {std::numeric_limits<double>::max(),
2626
std::numeric_limits<double>::max()};
2727
}
2828

29-
static Point Min()
29+
[[nodiscard]] static Point Min()
3030
{
3131
return {std::numeric_limits<double>::lowest(),
3232
std::numeric_limits<double>::lowest()};
3333
}
3434

35-
static Point Ident(bool horizontal)
35+
[[nodiscard]] static Point Ident(bool horizontal)
3636
{
3737
return {horizontal ? 1.0 : 0.0, horizontal ? 0.0 : 1.0};
3838
}
3939

40-
static Point Polar(double radius, double angle)
40+
[[nodiscard]] static Point Polar(double radius, double angle)
4141
{
4242
return {radius * cos(angle), radius * sin(angle)};
4343
}
4444

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

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

49-
Point operator*(double factor) const
49+
[[nodiscard]] Point operator*(double factor) const
5050
{
5151
return {x * factor, y * factor};
5252
}
5353

54-
Point operator/(double divisor) const
54+
[[nodiscard]] Point operator/(double divisor) const
5555
{
5656
if (Math::Floating::is_zero(divisor)) return Invalid();
5757
return {x / divisor, y / divisor};
5858
}
5959

60-
Point operator+(const Point &other) const
60+
[[nodiscard]] Point operator+(const Point &other) const
6161
{
6262
return {x + other.x, y + other.y};
6363
}
6464

65-
Point operator-(const Point &other) const
65+
[[nodiscard]] Point operator-(const Point &other) const
6666
{
6767
return {x - other.x, y - other.y};
6868
}
6969

70-
Point operator*(const Point &other) const
70+
[[nodiscard]] Point operator*(const Point &other) const
7171
{
7272
return {x * other.x, y * other.y};
7373
}
@@ -77,18 +77,65 @@ struct Point
7777
return x * other.x + y * other.y;
7878
}
7979

80-
Point operator/(const Point &other) const
80+
[[nodiscard]] Point operator/(const Point &other) const
8181
{
8282
using Math::Floating::is_zero;
8383
if (is_zero(other.x) || is_zero(other.y)) return Invalid();
8484
return {x / other.x, y / other.y};
8585
}
8686

87-
double operator^(const Point &p) const
87+
[[nodiscard]] double operator^(const Point &p) const
8888
{
8989
return x * p.y - y * p.x;
9090
}
9191

92+
Point &operator+=(const Point &other)
93+
{
94+
x += other.x;
95+
y += other.y;
96+
return *this;
97+
}
98+
99+
Point &operator-=(const Point &other)
100+
{
101+
x -= other.x;
102+
y -= other.y;
103+
return *this;
104+
}
105+
106+
Point &operator*=(double factor)
107+
{
108+
x *= factor;
109+
y *= factor;
110+
return *this;
111+
}
112+
113+
Point &operator/=(double divisor)
114+
{
115+
if (Math::Floating::is_zero(divisor))
116+
return *this = Invalid();
117+
x /= divisor;
118+
y /= divisor;
119+
return *this;
120+
}
121+
122+
Point &operator*=(const Point &other)
123+
{
124+
x *= other.x;
125+
y *= other.y;
126+
return *this;
127+
}
128+
129+
Point &operator/=(const Point &other)
130+
{
131+
using Math::Floating::is_zero;
132+
if (is_zero(other.x) || is_zero(other.y))
133+
return *this = Invalid();
134+
x /= other.x;
135+
y /= other.y;
136+
return *this;
137+
}
138+
92139
[[nodiscard]] Point flip() const { return {y, x}; }
93140

94141
[[nodiscard]] Point flipX() const { return {-x, y}; }
@@ -214,7 +261,7 @@ struct Size : Point
214261
std::min(s1.y, s2.y, less)};
215262
}
216263

217-
[[nodiscard]] bool isSquare(double toleranceFactor = 0.0) const
264+
[[nodiscard]] bool isSquare(double toleranceFactor) const
218265
{
219266
using Math::Floating::is_zero;
220267
if (is_zero(y)) return false;

src/base/geom/quadrilateral.cpp

Lines changed: 6 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -7,33 +7,12 @@
77
namespace Geom
88
{
99

10-
ConvexQuad::ConvexQuad(const Rect &rect)
11-
{
12-
points[0] = rect.pos;
13-
points[1] = rect.pos + Point{rect.size.x, 0.0};
14-
points[2] = rect.pos + rect.size;
15-
points[3] = rect.pos + Point{0.0, rect.size.y};
16-
}
17-
18-
Rect ConvexQuad::boundary() const { return Rect::Boundary(points); }
19-
20-
ConvexQuad ConvexQuad::Square(Point p0, Point p2)
21-
{
22-
auto center = (p0 + p2) / 2;
23-
auto halfDiagonal = (p2 - p0) / 2;
24-
auto p1 = center + halfDiagonal.normal(false);
25-
auto p3 = center + halfDiagonal.normal(true);
26-
return ConvexQuad({p0, p1, p2, p3});
27-
}
28-
2910
ConvexQuad ConvexQuad::Isosceles(Point base0Middle,
3011
Point base1Middle,
3112
double base0Length,
3213
double base1Length)
3314
{
34-
auto dir = base1Middle == base0Middle
35-
? Point{0, 1}
36-
: (base1Middle - base0Middle).normalized();
15+
auto dir = (base1Middle - base0Middle).normalized();
3716

3817
return ConvexQuad(
3918
{base0Middle + dir.normal(false) * (base0Length / 2),
@@ -42,20 +21,12 @@ ConvexQuad ConvexQuad::Isosceles(Point base0Middle,
4221
base1Middle + dir.normal(false) * (base1Length / 2)});
4322
}
4423

45-
bool ConvexQuad::contains(const Point &p, double tolerance) const
46-
{
47-
auto boundaryArea = Triangle{{points[0], points[1], p}}.area()
48-
+ Triangle{{points[1], points[2], p}}.area()
49-
+ Triangle{{points[2], points[3], p}}.area()
50-
+ Triangle{{points[3], points[0], p}}.area();
51-
52-
return Math::AddTolerance(boundaryArea, tolerance) <= area();
53-
}
54-
55-
double ConvexQuad::area() const
24+
double ConvexQuad::distance(const Point &point) const
5625
{
57-
return Triangle{{points[0], points[1], points[2]}}.area()
58-
+ Triangle{{points[2], points[3], points[0]}}.area();
26+
return std::min(
27+
Triangle{{points[0], points[1], points[2]}}.distance(point),
28+
Triangle{{points[2], points[3], points[0]}}.distance(point),
29+
Math::Floating::less);
5930
}
6031

6132
}

src/base/geom/quadrilateral.h

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,16 +17,12 @@ class ConvexQuad
1717

1818
ConvexQuad() = default;
1919
explicit ConvexQuad(const Points &points) : points(points) {}
20-
explicit ConvexQuad(const Rect &rect);
21-
[[nodiscard]] static ConvexQuad Square(Point p0, Point p2);
2220
[[nodiscard]] static ConvexQuad Isosceles(Point base0Middle,
2321
Point base1Middle,
2422
double base0Length,
2523
double base1Length);
26-
[[nodiscard]] bool contains(const Point &p,
27-
double tolerance = 0.0) const;
28-
[[nodiscard]] double area() const;
29-
[[nodiscard]] Rect boundary() const;
24+
25+
[[nodiscard]] double distance(const Point &point) const;
3026
};
3127

3228
}

0 commit comments

Comments
 (0)