Skip to content

Commit fe4dd93

Browse files
committed
Closest marker
1 parent 29d13cf commit fe4dd93

File tree

2 files changed

+32
-20
lines changed

2 files changed

+32
-20
lines changed

src/chart/rendering/renderedchart.cpp

Lines changed: 31 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@ const Util::EventTarget *RenderedChart::find(
1212
{
1313
auto original = coordinateSystem.getOriginal(point);
1414

15+
const Util::EventTarget *closestMarker{};
16+
double closestMarkerDistance = std::numeric_limits<double>::max();
17+
1518
for (const auto &element : std::ranges::reverse_view(elements)) {
1619
if (const auto *rect = std::get_if<Geom::TransformedRect>(
1720
&element.geometry)) {
@@ -31,61 +34,70 @@ const Util::EventTarget *RenderedChart::find(
3134
}
3235
else if (const auto *marker =
3336
std::get_if<Marker>(&element.geometry)) {
34-
if (marker->bounds(coordinateSystem, original))
35-
return element.target.get();
37+
constexpr double MARKER_DISTANCE_THRESHOLD = 0.01;
38+
if (const auto dist =
39+
marker->distance(coordinateSystem, original);
40+
dist < MARKER_DISTANCE_THRESHOLD
41+
&& dist < closestMarkerDistance) {
42+
closestMarker = element.target.get();
43+
if (Math::Floating::is_zero(dist)) break;
44+
closestMarkerDistance = dist;
45+
}
3646
}
3747
}
38-
return nullptr;
48+
return closestMarker;
3949
}
4050

41-
bool Marker::bounds(const CoordinateSystem &coordSys,
51+
double Marker::distance(const CoordinateSystem &coordSys,
4252
const Geom::Point &point) const
4353
{
44-
if (!enabled) return false;
54+
if (!enabled) return std::numeric_limits<double>::max();
4555

4656
/** Approximated solution */
47-
auto isInside = shapeType.combine<Math::FuzzyBool>(
57+
return shapeType.combine(
4858
[this, &point, &coordSys](const Gen::ShapeType &shapeType)
4959
{
5060
switch (shapeType) {
5161
using enum Gen::ShapeType;
62+
default:
5263
case rectangle:
5364
case area:
54-
return Geom::ConvexQuad{points}.distance(point)
55-
< 0.01;
65+
return Geom::ConvexQuad{points}.distance(point);
5666
case circle: {
5767
auto &&rect = Geom::Rect::Boundary(points);
5868
return Geom::Circle(rect.pos + rect.size / 2.0,
59-
rect.size.x / 2.0)
60-
.distance(point)
61-
< 0.01;
69+
rect.size.x / 2.0)
70+
.distance(point);
6271
}
63-
case line:
72+
case line: {
73+
auto rel_to_px = coordSys.getRect().size.minSize();
6474
return lineToQuad(coordSys).distance(
6575
coordSys.convert(point))
66-
< 0.01;
76+
/ (Math::Floating::is_zero(rel_to_px)
77+
? 1.0
78+
: rel_to_px);
79+
}
6780
}
68-
return false;
6981
});
70-
71-
return isInside != false;
7282
}
7383

7484
Geom::ConvexQuad Marker::lineToQuad(
7585
const CoordinateSystem &coordSys) const
7686
{
77-
using Math::Floating::less;
87+
constexpr double MIN_WIDTH_PX = 10.0;
7888
auto line = getLine();
7989

8090
auto pBeg = coordSys.convert(line.begin);
8191
auto pEnd = coordSys.convert(line.end);
8292

8393
auto wBeg = lineWidth[0] * coordSys.getRect().size.minSize();
8494
auto wEnd = lineWidth[1] * coordSys.getRect().size.minSize();
95+
96+
using Math::Floating::less;
8597
return Geom::ConvexQuad::Isosceles(pBeg,
8698
pEnd,
87-
wBeg * 2,
88-
wEnd * 2);
99+
std::max(MIN_WIDTH_PX, wBeg * 2, less),
100+
std::max(MIN_WIDTH_PX, wEnd * 2, less));
89101
}
90102

91103
Geom::Line Marker::getLine() const { return {points[3], points[2]}; }

src/chart/rendering/renderedchart.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ class Marker
4040
std::array<Geom::Point, 4> points;
4141
std::array<double, 2> lineWidth;
4242

43-
[[nodiscard]] bool bounds(const CoordinateSystem &coordSys,
43+
[[nodiscard]] double distance(const CoordinateSystem &coordSys,
4444
const Geom::Point &point) const;
4545

4646
private:

0 commit comments

Comments
 (0)