update method

  1. @override
void update(
  1. List<ImmutableSeries<D>> seriesList,
  2. bool isAnimatingThisDraw
)
override

Generates rendering data needed to paint the data on the chart.

This is called during the post layout phase of the chart draw cycle.

Implementation

@override
void update(List<ImmutableSeries<D>> seriesList, bool isAnimatingThisDraw) {
  _currentKeys.clear();

  // Build a list of sorted series IDs as we iterate through the list, used
  // later for sorting.
  final sortedSeriesIds = <String>[];

  for (final series in seriesList) {
    sortedSeriesIds.add(series.id);

    final domainAxis = series.getAttr(domainAxisKey)! as ImmutableAxis<D>;
    final domainFn = series.domainFn;
    final domainLowerBoundFn = series.domainLowerBoundFn;
    final domainUpperBoundFn = series.domainUpperBoundFn;
    final measureAxis = series.getAttr(measureAxisKey)! as ImmutableAxis<num>;
    final measureFn = series.measureFn;
    final measureLowerBoundFn = series.measureLowerBoundFn;
    final measureUpperBoundFn = series.measureUpperBoundFn;
    final measureOffsetFn = series.measureOffsetFn;
    final seriesKey = series.id;
    final keyFn = series.keyFn!;

    final pointList = seriesPointMap.putIfAbsent(seriesKey, () => []);

    final elementsList = series.getAttr(pointElementsKey);

    for (var index = 0; index < series.data.length; index++) {
      final Object? datum = series.data[index];
      final details = elementsList![index];

      final domainValue = domainFn(index);
      final domainLowerBoundValue = domainLowerBoundFn?.call(index);
      final domainUpperBoundValue = domainUpperBoundFn?.call(index);

      final measureValue = measureFn(index);
      final measureLowerBoundValue = measureLowerBoundFn?.call(index);
      final measureUpperBoundValue = measureUpperBoundFn?.call(index);
      final measureOffsetValue = measureOffsetFn!(index);

      // Create a new point using the final location.
      final point = getPoint(
        datum,
        domainValue,
        domainLowerBoundValue,
        domainUpperBoundValue,
        series,
        domainAxis,
        measureValue,
        measureLowerBoundValue,
        measureUpperBoundValue,
        measureOffsetValue,
        measureAxis,
      );

      final pointKey = keyFn(index);

      // If we already have an AnimatingPoint for that index, use it.
      var animatingPoint =
          pointList.firstWhereOrNull((point) => point.key == pointKey);

      // If we don't have any existing arc element, create a new arc and
      // have it animate in from the position of the previous arc's end
      // angle. If there were no previous arcs, then animate everything in
      // from 0.
      if (animatingPoint == null) {
        // Create a new point and have it animate in from axis.
        final point = getPoint(
          datum,
          domainValue,
          domainLowerBoundValue,
          domainUpperBoundValue,
          series,
          domainAxis,
          0.0,
          0.0,
          0.0,
          0.0,
          measureAxis,
        );

        animatingPoint = AnimatedPoint<D>(
          key: pointKey,
          overlaySeries: series.overlaySeries,
        )..setNewTarget(
            PointRendererElement<D>(
              index: details.index,
              color: details.color,
              fillColor: details.fillColor,
              measureAxisPosition: measureAxis.getLocation(0.0),
              point: point,
              radiusPx: details.radiusPx,
              boundsLineRadiusPx: details.boundsLineRadiusPx,
              strokeWidthPx: details.strokeWidthPx,
              symbolRendererId: details.symbolRendererId,
            ),
          );

        pointList.add(animatingPoint);
      }

      // Update the set of arcs that still exist in the series data.
      _currentKeys.add(pointKey);

      // Get the pointElement we are going to setup.
      final pointElement = PointRendererElement<D>(
        index: index,
        color: details.color,
        fillColor: details.fillColor,
        measureAxisPosition: measureAxis.getLocation(0.0),
        point: point,
        radiusPx: details.radiusPx,
        boundsLineRadiusPx: details.boundsLineRadiusPx,
        strokeWidthPx: details.strokeWidthPx,
        symbolRendererId: details.symbolRendererId,
      );

      animatingPoint.setNewTarget(pointElement);
    }
  }

  // Sort the renderer elements to be in the same order as the series list.
  // They may get disordered between chart draw cycles if a behavior adds or
  // removes series from the list (e.g. click to hide on legends).
  seriesPointMap = LinkedHashMap<String, List<AnimatedPoint<D>>>.fromIterable(
    sortedSeriesIds,
    key: (k) => k as String,
    value: (k) => seriesPointMap[k]!,
  );

  // Animate out points that don't exist anymore.
  seriesPointMap.forEach((key, points) {
    for (final point in points) {
      if (!_currentKeys.contains(point.key)) {
        point.animateOut();
      }
    }
  });
}