preprocessSeries method
Pre-calculates some details for the series that will be needed later during the drawing phase.
Implementation
@override
void preprocessSeries(List<MutableSeries<D>> seriesList) {
seriesList.forEach((MutableSeries<D> series) {
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!.toDouble();
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 ??=
(int? 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);
});
}