Skip to content

Commit 683a2c5

Browse files
authored
fix: Swap inverted lowerBy/upperBy in error range pixel calculation (#2060)
1 parent 76161d6 commit 683a2c5

File tree

4 files changed

+90
-4
lines changed

4 files changed

+90
-4
lines changed

lib/src/chart/line_chart/line_chart_painter.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -406,9 +406,9 @@ class LineChartPainter extends AxisChartPainter<LineChartData> {
406406
var top = 0.0;
407407
var bottom = 0.0;
408408
if (spot.yError != null) {
409-
top = getPixelY(spot.y + spot.yError!.lowerBy, viewSize, holder) - y;
409+
top = getPixelY(spot.y + spot.yError!.upperBy, viewSize, holder) - y;
410410
bottom =
411-
getPixelY(spot.y - spot.yError!.upperBy, viewSize, holder) - y;
411+
getPixelY(spot.y - spot.yError!.lowerBy, viewSize, holder) - y;
412412
}
413413
final relativeErrorPixelsRect = Rect.fromLTRB(
414414
left,

lib/src/chart/scatter_chart/scatter_chart_painter.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -226,8 +226,8 @@ class ScatterChartPainter extends AxisChartPainter<ScatterChartData> {
226226
var top = 0.0;
227227
var bottom = 0.0;
228228
if (spot.yError != null) {
229-
top = getPixelY(spot.y + spot.yError!.lowerBy, viewSize, holder) - y;
230-
bottom = getPixelY(spot.y - spot.yError!.upperBy, viewSize, holder) - y;
229+
top = getPixelY(spot.y + spot.yError!.upperBy, viewSize, holder) - y;
230+
bottom = getPixelY(spot.y - spot.yError!.lowerBy, viewSize, holder) - y;
231231
}
232232
final relativeErrorPixelsRect = Rect.fromLTRB(
233233
left,

test/chart/line_chart/line_chart_painter_test.dart

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -931,6 +931,51 @@ void main() {
931931
}
932932
verifyNever(mockCanvasWrapper.drawText(any, any, any));
933933
});
934+
935+
test('test 4 - asymmetric yError maps lowerBy downward and upperBy upward',
936+
() {
937+
const viewSize = Size(400, 400);
938+
939+
final barData = LineChartBarData(
940+
spots: [
941+
const FlSpot(
942+
5,
943+
5,
944+
yError: FlErrorRange(lowerBy: 1, upperBy: 3),
945+
),
946+
],
947+
);
948+
949+
final data = LineChartData(
950+
minY: 0,
951+
maxY: 10,
952+
lineBarsData: [barData],
953+
);
954+
955+
final lineChartPainter = LineChartPainter();
956+
final holder =
957+
PaintHolder<LineChartData>(data, data, TextScaler.noScaling);
958+
final mockCanvasWrapper = MockCanvasWrapper();
959+
when(mockCanvasWrapper.size).thenAnswer((realInvocation) => viewSize);
960+
when(mockCanvasWrapper.canvas).thenReturn(MockCanvas());
961+
962+
lineChartPainter.drawErrorIndicatorData(
963+
mockCanvasWrapper,
964+
barData,
965+
holder,
966+
);
967+
968+
final result = verify(
969+
mockCanvasWrapper.drawErrorIndicator(any, any, any, captureAny, any),
970+
)..called(1);
971+
final rect = result.captured[0] as Rect;
972+
// getPixelY(y) = 400 - (y/10)*400
973+
// spot y=5 -> pixel 200
974+
// upper bound y=8 -> pixel 80, relative top = 80 - 200 = -120
975+
// lower bound y=4 -> pixel 240, relative bottom = 240 - 200 = 40
976+
expect(rect.top, -120);
977+
expect(rect.bottom, 40);
978+
});
934979
});
935980

936981
group('drawTouchedSpotsIndicator()', () {

test/chart/scatter_chart/scatter_chart_painter_test.dart

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -877,4 +877,45 @@ void main() {
877877
expect(touchedSpot6, null);
878878
});
879879
});
880+
881+
group('drawScatterErrorBars()', () {
882+
test('asymmetric yError maps lowerBy downward and upperBy upward', () {
883+
const viewSize = Size(400, 400);
884+
885+
final data = ScatterChartData(
886+
minY: 0,
887+
maxY: 10,
888+
scatterSpots: [
889+
ScatterSpot(
890+
5,
891+
5,
892+
yError: const FlErrorRange(lowerBy: 1, upperBy: 3),
893+
),
894+
],
895+
);
896+
897+
final scatterChartPainter = ScatterChartPainter();
898+
final holder =
899+
PaintHolder<ScatterChartData>(data, data, TextScaler.noScaling);
900+
final mockCanvasWrapper = MockCanvasWrapper();
901+
when(mockCanvasWrapper.size).thenAnswer((realInvocation) => viewSize);
902+
when(mockCanvasWrapper.canvas).thenReturn(MockCanvas());
903+
904+
scatterChartPainter.drawScatterErrorBars(
905+
mockCanvasWrapper,
906+
holder,
907+
);
908+
909+
final result = verify(
910+
mockCanvasWrapper.drawErrorIndicator(any, any, any, captureAny, any),
911+
)..called(1);
912+
final rect = result.captured[0] as Rect;
913+
// getPixelY(y) = 400 - (y/10)*400
914+
// spot y=5 -> pixel 200
915+
// upper bound y=8 -> pixel 80, relative top = 80 - 200 = -120
916+
// lower bound y=4 -> pixel 240, relative bottom = 240 - 200 = 40
917+
expect(rect.top, -120);
918+
expect(rect.bottom, 40);
919+
});
920+
});
880921
}

0 commit comments

Comments
 (0)