@@ -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
7484Geom::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
91103Geom::Line Marker::getLine () const { return {points[3 ], points[2 ]}; }
0 commit comments