fitToContent method
Automatically adjusts the view (scale and origin) to fit all items within the viewport.
Implementation
@override
void fitToContent() {
if (!mounted) return;
final canvasSize = context.size;
if (canvasSize == null) return;
final boundaryPoints = <Offset>[];
for (final item in widget.items) {
if (item is SeriesItem) {
for (final p in item.points) {
boundaryPoints.add(Offset(p.x, p.y));
}
} else if (item is PointItem) {
boundaryPoints.add(Offset(item.x, item.y));
} else if (item is PolygonItem) {
for (final v in item.vertices) {
boundaryPoints.add(Offset(v.$1, v.$2));
}
}
}
for (final widgetItem in widget.widgetItems) {
boundaryPoints.add(Offset(widgetItem.x, widgetItem.y));
}
if (boundaryPoints.isEmpty) {
resetView();
return;
}
final xValues = boundaryPoints.map((p) => p.dx);
final yValues = boundaryPoints.map((p) => p.dy);
final minimumX = xValues.reduce(min);
final maximumX = xValues.reduce(max);
final minimumY = yValues.reduce(min);
final maximumY = yValues.reduce(max);
final rangeX = maximumX - minimumX;
final rangeY = maximumY - minimumY;
const marginRatio = 0.18;
final computedScaleX = rangeX > 1e-10
? (canvasSize.width * (1 - 2 * marginRatio)) / rangeX
: double.infinity;
final computedScaleY = rangeY > 1e-10
? (canvasSize.height * (1 - 2 * marginRatio)) / rangeY
: double.infinity;
final calculatedNewScale = min(
computedScaleX,
computedScaleY,
).clamp(0.00001, 5000000.0);
final centerX = (minimumX + maximumX) / 2;
final centerY = (minimumY + maximumY) / 2;
setState(() {
currentScale = calculatedNewScale;
currentOrigin = Offset(
canvasSize.width / 2 - centerX * calculatedNewScale,
canvasSize.height / 2 + centerY * calculatedNewScale,
);
});
}