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>[];

  seriesList.forEach((ImmutableSeries<D> series) {
    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!;

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

    var 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: (dynamic k) => k as String,
      value: (dynamic k) => seriesPointMap[k]!);

  // Animate out points that don't exist anymore.
  seriesPointMap.forEach((String key, List<AnimatedPoint<D>> points) {
    for (var point in points) {
      if (_currentKeys.contains(point.key) != true) {
        point.animateOut();
      }
    }
  });
}