findRadarPoint static method

ChartInteractionResult? findRadarPoint(
  1. Offset tapPosition,
  2. List<RadarDataSet> dataSets,
  3. Size size,
  4. double maxValue,
  5. double animationProgress,
)

Find radar point at tap location Find radar chart point at tap location.

Searches through all radar data sets to find the point closest to the tap position within the specified tap radius. Radar charts have points arranged in a circle.

Parameters:

  • tapPosition - The position where the user tapped
  • dataSets - List of radar data sets to search through
  • size - Size of the chart area
  • maxValue - Maximum value for scaling radar points
  • animationProgress - Animation progress value (0.0 to 1.0)

Returns a ChartInteractionResult if a point is found, null otherwise.

Implementation

static ChartInteractionResult? findRadarPoint(
  Offset tapPosition,
  List<RadarDataSet> dataSets,
  Size size,
  double maxValue,
  double animationProgress,
) {
  if (dataSets.isEmpty) return null;
  if (!size.width.isFinite ||
      !size.height.isFinite ||
      size.width <= 0 ||
      size.height <= 0) {
    return null;
  }
  if (!tapPosition.dx.isFinite || !tapPosition.dy.isFinite) {
    return null;
  }

  final firstDataSet = dataSets.first;
  final numAxes = firstDataSet.dataPoints.length;
  if (numAxes < 3) return null;

  final center = Offset(size.width / 2, size.height / 2);
  final radius = math.min(size.width, size.height) / 2 - 60;
  if (radius <= 0 || !radius.isFinite) return null;

  final tapRadiusSquared = (ChartInteractionConstants.tapRadius *
      ChartInteractionConstants.tapRadius);
  double minDistanceSquared = double.infinity;
  ChartInteractionResult? nearestResult;

  for (int dsIndex = 0; dsIndex < dataSets.length; dsIndex++) {
    final dataSet = dataSets[dsIndex];
    if (dataSet.dataPoints.length != numAxes) continue;

    for (int ptIndex = 0; ptIndex < numAxes; ptIndex++) {
      final radarPoint = dataSet.dataPoints[ptIndex];
      if (!radarPoint.value.isFinite) continue;

      final angle = (2 * math.pi * ptIndex / numAxes) - (math.pi / 2);
      final value = radarPoint.value.clamp(0.0, maxValue);
      final normalizedValue = (value / maxValue) * animationProgress;
      final pointRadius = radius * normalizedValue;

      final point = Offset(
        center.dx + pointRadius * math.cos(angle),
        center.dy + pointRadius * math.sin(angle),
      );

      final dx = tapPosition.dx - point.dx;
      final dy = tapPosition.dy - point.dy;

      if (!dx.isFinite || !dy.isFinite) continue;
      if (dx.abs() > ChartInteractionConstants.tapRadius ||
          dy.abs() > ChartInteractionConstants.tapRadius) {
        continue;
      }

      final distanceSquared = dx * dx + dy * dy;
      if (!distanceSquared.isFinite) continue;

      if (distanceSquared < tapRadiusSquared &&
          distanceSquared < minDistanceSquared) {
        minDistanceSquared = distanceSquared;
        // Convert RadarDataPoint to ChartDataPoint for compatibility
        final chartPoint = ChartDataPoint(
          x: ptIndex.toDouble(),
          y: radarPoint.value,
          label: radarPoint.label,
        );
        nearestResult = ChartInteractionResult(
          point: chartPoint,
          datasetIndex: dsIndex,
          elementIndex: ptIndex,
          isHit: true,
        );
      }
    }
  }

  return nearestResult;
}