Skip to content

Commit

Permalink
Add error indicator functionality in the Scatter Chart
Browse files Browse the repository at this point in the history
  • Loading branch information
imaNNeo committed Jan 11, 2025
1 parent f652121 commit 66b5800
Show file tree
Hide file tree
Showing 2 changed files with 92 additions and 0 deletions.
31 changes: 31 additions & 0 deletions lib/src/chart/scatter_chart/scatter_chart_data.dart
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ class ScatterChartData extends AxisChartData with EquatableMixin {
super.backgroundColor,
ScatterLabelSettings? scatterLabelSettings,
super.rotationQuarterTurns,
this.errorIndicatorData =
const FlErrorIndicatorData<ScatterChartSpotErrorRangeCallbackInput>(),
}) : scatterSpots = scatterSpots ?? const [],
scatterTouchData = scatterTouchData ?? ScatterTouchData(),
showingTooltipIndicators = showingTooltipIndicators ?? const [],
Expand Down Expand Up @@ -89,6 +91,10 @@ class ScatterChartData extends AxisChartData with EquatableMixin {

final ScatterLabelSettings scatterLabelSettings;

/// Holds data for showing error indicators on the spots in this line.
final FlErrorIndicatorData<ScatterChartSpotErrorRangeCallbackInput>
errorIndicatorData;

/// Lerps a [ScatterChartData] based on [t] value, check [Tween.lerp].
@override
ScatterChartData lerp(BaseChartData a, BaseChartData b, double t) {
Expand Down Expand Up @@ -118,6 +124,11 @@ class ScatterChartData extends AxisChartData with EquatableMixin {
t,
),
rotationQuarterTurns: b.rotationQuarterTurns,
errorIndicatorData: FlErrorIndicatorData.lerp(
a.errorIndicatorData,
b.errorIndicatorData,
t,
),
);
} else {
throw Exception('Illegal State');
Expand All @@ -143,6 +154,7 @@ class ScatterChartData extends AxisChartData with EquatableMixin {
Color? backgroundColor,
ScatterLabelSettings? scatterLabelSettings,
int? rotationQuarterTurns,
FlErrorIndicatorData<ScatterChartSpotErrorRangeCallbackInput>? errorIndicatorData,
}) =>
ScatterChartData(
scatterSpots: scatterSpots ?? this.scatterSpots,
Expand All @@ -162,6 +174,7 @@ class ScatterChartData extends AxisChartData with EquatableMixin {
backgroundColor: backgroundColor ?? this.backgroundColor,
scatterLabelSettings: scatterLabelSettings ?? this.scatterLabelSettings,
rotationQuarterTurns: rotationQuarterTurns ?? this.rotationQuarterTurns,
errorIndicatorData: errorIndicatorData ?? this.errorIndicatorData,
);

/// Used for equality check, see [EquatableMixin].
Expand All @@ -186,6 +199,7 @@ class ScatterChartData extends AxisChartData with EquatableMixin {
borderData,
touchData,
rotationQuarterTurns,
errorIndicatorData,
];
}

Expand Down Expand Up @@ -746,3 +760,20 @@ class ScatterLabelSettings with EquatableMixin {
textDirection,
];
}

class ScatterChartSpotErrorRangeCallbackInput
extends FlSpotErrorRangeCallbackInput {
ScatterChartSpotErrorRangeCallbackInput({
required this.spot,
required this.spotIndex,
});

final ScatterSpot spot;
final int spotIndex;

@override
List<Object?> get props => [
spot,
spotIndex,
];
}
61 changes: 61 additions & 0 deletions lib/src/chart/scatter_chart/scatter_chart_painter.dart
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,8 @@ class ScatterChartPainter extends AxisChartPainter<ScatterChartData> {
);
}

drawScatterErrorBars(canvasWrapper, holder);

if (data.scatterLabelSettings.showLabel) {
for (var i = 0; i < data.scatterSpots.length; i++) {
final scatterSpot = data.scatterSpots[i];
Expand Down Expand Up @@ -191,6 +193,65 @@ class ScatterChartPainter extends AxisChartPainter<ScatterChartData> {
}
}

@visibleForTesting
void drawScatterErrorBars(
CanvasWrapper canvasWrapper,
PaintHolder<ScatterChartData> holder,
) {
final data = holder.data;
final viewSize = canvasWrapper.size;

final errorIndicatorData = data.errorIndicatorData;
if (!errorIndicatorData.show) {
return;
}
for (var i = 0; i < data.scatterSpots.length; i++) {
final spot = data.scatterSpots[i];
if (!spot.show || spot.isNull()) {
continue;
}
final x = getPixelX(spot.x, viewSize, holder);
final y = getPixelY(spot.y, viewSize, holder);
if (spot.xError == null && spot.yError == null) {
continue;
}

var left = 0.0;
var right = 0.0;
if (spot.xError != null) {
left = getPixelX(spot.x - spot.xError!.lowerBy, viewSize, holder) - x;
right = getPixelX(spot.x + spot.xError!.upperBy, viewSize, holder) - x;

Check warning on line 223 in lib/src/chart/scatter_chart/scatter_chart_painter.dart

View check run for this annotation

Codecov / codecov/patch

lib/src/chart/scatter_chart/scatter_chart_painter.dart#L221-L223

Added lines #L221 - L223 were not covered by tests
}

var top = 0.0;
var bottom = 0.0;
if (spot.yError != null) {
top = getPixelY(spot.y + spot.yError!.lowerBy, viewSize, holder) - y;
bottom = getPixelY(spot.y - spot.yError!.upperBy, viewSize, holder) - y;

Check warning on line 230 in lib/src/chart/scatter_chart/scatter_chart_painter.dart

View check run for this annotation

Codecov / codecov/patch

lib/src/chart/scatter_chart/scatter_chart_painter.dart#L228-L230

Added lines #L228 - L230 were not covered by tests
}
final relativeErrorPixelsRect = Rect.fromLTRB(

Check warning on line 232 in lib/src/chart/scatter_chart/scatter_chart_painter.dart

View check run for this annotation

Codecov / codecov/patch

lib/src/chart/scatter_chart/scatter_chart_painter.dart#L232

Added line #L232 was not covered by tests
left,
top,
right,
bottom,
);

final painter = errorIndicatorData.painter(
ScatterChartSpotErrorRangeCallbackInput(

Check warning on line 240 in lib/src/chart/scatter_chart/scatter_chart_painter.dart

View check run for this annotation

Codecov / codecov/patch

lib/src/chart/scatter_chart/scatter_chart_painter.dart#L239-L240

Added lines #L239 - L240 were not covered by tests
spot: spot,
spotIndex: i,
),
);
canvasWrapper.drawErrorIndicator(

Check warning on line 245 in lib/src/chart/scatter_chart/scatter_chart_painter.dart

View check run for this annotation

Codecov / codecov/patch

lib/src/chart/scatter_chart/scatter_chart_painter.dart#L245

Added line #L245 was not covered by tests
painter,
spot,
Offset(x, y),

Check warning on line 248 in lib/src/chart/scatter_chart/scatter_chart_painter.dart

View check run for this annotation

Codecov / codecov/patch

lib/src/chart/scatter_chart/scatter_chart_painter.dart#L248

Added line #L248 was not covered by tests
relativeErrorPixelsRect,
holder.data,

Check warning on line 250 in lib/src/chart/scatter_chart/scatter_chart_painter.dart

View check run for this annotation

Codecov / codecov/patch

lib/src/chart/scatter_chart/scatter_chart_painter.dart#L250

Added line #L250 was not covered by tests
);
}
}

@visibleForTesting
void drawTouchTooltips(
BuildContext context,
Expand Down

0 comments on commit 66b5800

Please sign in to comment.