preprocessSeries method

  1. @override
void preprocessSeries(
  1. List<MutableSeries<D>> seriesList
)

Pre-calculates some details for the series that will be needed later during the drawing phase.

Implementation

@override
void preprocessSeries(List<MutableSeries<D>> seriesList) {
  for (final series in seriesList) {
    final elements = <PointRendererElement<D>>[];

    // Default to the configured radius if none was defined by the series.
    series.radiusPxFn ??= (_) => config.radiusPx;

    // Create an accessor function for the bounds line radius, if needed. If
    // the series doesn't define an accessor function, then each datum's
    // boundsLineRadiusPx value will be filled in by using the following
    // values, in order of what is defined:
    //
    // 1) boundsLineRadiusPx defined on the series.
    // 2) boundsLineRadiusPx defined on the renderer config.
    // 3) Final fallback is to use the point radiusPx for this datum.
    var boundsLineRadiusPxFn = series.getAttr(boundsLineRadiusPxFnKey);

    if (boundsLineRadiusPxFn == null) {
      var boundsLineRadiusPx = series.getAttr(boundsLineRadiusPxKey);
      boundsLineRadiusPx ??= config.boundsLineRadiusPx;
      if (boundsLineRadiusPx != null) {
        boundsLineRadiusPxFn = (_) => boundsLineRadiusPx!;
        series.setAttr(boundsLineRadiusPxFnKey, boundsLineRadiusPxFn);
      }
    }

    final symbolRendererFn = series.getAttr(pointSymbolRendererFnKey);

    // Add a key function to help animate points moved in position in the
    // series data between chart draw cycles. Ideally we should require the
    // user to provide a key function, but this at least provides some
    // smoothing when adding/removing data.
    series.keyFn ??= (index) => '${series.id}__${series.domainFn(index)}__'
        '${series.measureFn(index)}';

    for (var index = 0; index < series.data.length; index++) {
      // Default to the configured radius if none was returned by the
      // accessor function.
      var radiusPx = series.radiusPxFn!(index);
      radiusPx ??= config.radiusPx;

      num? boundsLineRadiusPx;
      if (boundsLineRadiusPxFn != null) {
        boundsLineRadiusPx = (boundsLineRadiusPxFn is TypedAccessorFn)
            ? (boundsLineRadiusPxFn as TypedAccessorFn<dynamic, int>)(
                series.data[index],
                index,
              )
            : boundsLineRadiusPxFn(index);
      }
      boundsLineRadiusPx ??= config.boundsLineRadiusPx;
      boundsLineRadiusPx ??= radiusPx;

      // Default to the configured stroke width if none was returned by the
      // accessor function.
      var strokeWidthPx = series.strokeWidthPxFn != null
          ? series.strokeWidthPxFn!(index)
          : null;
      strokeWidthPx ??= config.strokeWidthPx;

      // Get the ID of the [SymbolRenderer] for this point. An ID may be
      // specified on the datum, or on the series. If neither is specified,
      // fall back to the default.
      String? symbolRendererId;
      if (symbolRendererFn != null) {
        symbolRendererId = symbolRendererFn(index);
      }
      symbolRendererId ??= series.getAttr(pointSymbolRendererIdKey);
      symbolRendererId ??= defaultSymbolRendererId;

      // Get the colors. If no fill color is provided, default it to the
      // primary data color.
      final colorFn = series.colorFn;
      final fillColorFn = series.fillColorFn ?? colorFn;

      final color = colorFn!(index);

      // Fill color is an optional override for color. Make sure we get a
      // value if the series doesn't define anything specific.
      var fillColor = fillColorFn!(index);
      fillColor ??= color;

      final details = PointRendererElement<D>(
        index: index,
        color: color,
        fillColor: fillColor,
        radiusPx: radiusPx.toDouble(),
        boundsLineRadiusPx: boundsLineRadiusPx.toDouble(),
        strokeWidthPx: strokeWidthPx.toDouble(),
        symbolRendererId: symbolRendererId,
      );

      elements.add(details);
    }

    series.setAttr(pointElementsKey, elements);
  }
}