getNearestDatumDetailPerSeries method
- Point<
double> chartPoint, - bool byDomain,
- Rectangle<
int> ? boundsOverride, { - bool selectOverlappingPoints = false,
- bool selectExactEventLocation = false,
Gets a list of the data from each series that is closest to a given point.
chartPoint represents a point in the chart, such as a point that was
clicked/tapped on by a user.
selectOverlappingPoints specifies whether to include all points that
overlap the tapped position in the result. If specified, the method will
return either the closest point or all the overlapping points with the
tapped position.
byDomain specifies whether the nearest data should be defined by domain
distance, or relative Cartesian distance.
boundsOverride optionally specifies a bounding box for the selection
event. If specified, then no data should be returned if chartPoint lies
outside the box. If not specified, then each series renderer on the chart
will use its own component bounds for filtering out selection events
(usually the chart draw area).
Implementation
@override
List<DatumDetails<D>> getNearestDatumDetailPerSeries(
Point<double> chartPoint,
bool byDomain,
Rectangle<int>? boundsOverride, {
bool selectOverlappingPoints = false,
bool selectExactEventLocation = false,
}) {
var nearest = <DatumDetails<D>>[];
// Was it even in the component bounds?
if (!isPointWithinBounds(chartPoint, boundsOverride)) {
return nearest;
}
if (_prevDomainAxis is OrdinalAxis) {
final domainValue = _prevDomainAxis!
.getDomain(renderingVertically ? chartPoint.x : chartPoint.y);
// If we have a domainValue for the event point, then find all segments
// that match it.
if (domainValue != null) {
if (renderingVertically) {
nearest = _getVerticalDetailsForDomainValue(domainValue, chartPoint);
} else {
nearest =
_getHorizontalDetailsForDomainValue(domainValue, chartPoint);
}
}
} else {
if (renderingVertically) {
nearest = _getVerticalDetailsForDomainValue(null, chartPoint);
} else {
nearest = _getHorizontalDetailsForDomainValue(null, chartPoint);
}
// Find the closest domain and only keep values that match the domain.
var minRelativeDistance = double.maxFinite;
var minDomainDistance = double.maxFinite;
var minMeasureDistance = double.maxFinite;
D? nearestDomain;
// TODO: Optimize this with a binary search based on chartX.
for (final detail in nearest) {
if (byDomain) {
if (detail.domainDistance! < minDomainDistance ||
(detail.domainDistance! == minDomainDistance &&
detail.measureDistance! < minMeasureDistance)) {
minDomainDistance = detail.domainDistance!;
minMeasureDistance = detail.measureDistance!;
nearestDomain = detail.domain;
}
} else {
if (detail.relativeDistance! < minRelativeDistance) {
minRelativeDistance = detail.relativeDistance!;
nearestDomain = detail.domain;
}
}
}
nearest.retainWhere((d) => d.domain == nearestDomain);
}
// Note: the details are already sorted by domain & measure distance in
// base chart.
return nearest;
}