Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions example/lib/presentation/samples/line/line_chart_sample2.dart
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,8 @@ class _LineChartSample2State extends State<LineChartSample2> {
maxY: 6,
lineBarsData: [
LineChartBarData(
strokeColor: Colors.red,
strokeWidth: 3,
spots: const [
FlSpot(0, 3),
FlSpot(2.6, 2),
Expand Down
18 changes: 18 additions & 0 deletions lib/src/chart/line_chart/line_chart_data.dart
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,8 @@ class LineChartBarData with EquatableMixin {
this.isStrokeJoinRound = false,
BarAreaData? belowBarData,
BarAreaData? aboveBarData,
this.strokeColor,
this.strokeWidth = 0,
this.dotData = const FlDotData(),
this.errorIndicatorData =
const FlErrorIndicatorData<LineChartSpotErrorRangeCallbackInput>(),
Expand Down Expand Up @@ -346,6 +348,14 @@ class LineChartBarData with EquatableMixin {
/// otherwise it draws line with hard edges.
final bool isCurved;

/// Optional border color for the line.
/// Useful for improving visibility when lines overlap.
final Color? strokeColor;
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we use the BorderSide class instead of defining strokeColor and strokeWidth here?
Because all other chart types in fl_chart use BorderSide for borders (e.g., BarChartRodData.borderSide, PieChartSectionData.borderSide).

Let's keep the API consistent:

final BorderSide borderSide; // default: BorderSide.none


/// Width of the border around the line.
/// Default is 0 (no border).
final double strokeWidth;

/// If [isCurved] is true, it determines smoothness of the curved edges.
final double curveSmoothness;

Expand Down Expand Up @@ -427,6 +437,8 @@ class LineChartBarData with EquatableMixin {
isStepLineChart: b.isStepLineChart,
lineChartStepData:
LineChartStepData.lerp(a.lineChartStepData, b.lineChartStepData, t),
strokeColor: Color.lerp(a.strokeColor, b.strokeColor, t),
strokeWidth: lerpDouble(a.strokeWidth, b.strokeWidth, t)!,
);

/// Copies current [LineChartBarData] to a new [LineChartBarData],
Expand Down Expand Up @@ -454,6 +466,8 @@ class LineChartBarData with EquatableMixin {
Shadow? shadow,
bool? isStepLineChart,
LineChartStepData? lineChartStepData,
Color? strokeColor,
double? strokeWidth,
}) =>
LineChartBarData(
spots: spots ?? this.spots,
Expand All @@ -479,6 +493,8 @@ class LineChartBarData with EquatableMixin {
shadow: shadow ?? this.shadow,
isStepLineChart: isStepLineChart ?? this.isStepLineChart,
lineChartStepData: lineChartStepData ?? this.lineChartStepData,
strokeColor: strokeColor ?? this.strokeColor,
strokeWidth: strokeWidth ?? this.strokeWidth,
);

/// Used for equality check, see [EquatableMixin].
Expand All @@ -505,6 +521,8 @@ class LineChartBarData with EquatableMixin {
shadow,
isStepLineChart,
lineChartStepData,
strokeColor,
strokeWidth,
];
}

Expand Down
12 changes: 12 additions & 0 deletions lib/src/chart/line_chart/line_chart_painter.dart
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,18 @@ class LineChartPainter extends AxisChartPainter<LineChartData> {
barData,
);
drawBarShadow(canvasWrapper, barPath, barData);
if (barData.strokeColor != null && barData.strokeWidth > 0) {
final borderPaint = Paint()
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's a performance issue with creating the Paint() object in every frame.
Please create the Paint instance once (in the constructor, just like other Paint() objects) and reuse it here.

..color = barData.strokeColor!
..strokeWidth = barData.barWidth + (barData.strokeWidth * 2)
..style = PaintingStyle.stroke
..strokeCap =
barData.isStrokeCapRound ? StrokeCap.round : StrokeCap.butt
..strokeJoin =
barData.isStrokeJoinRound ? StrokeJoin.round : StrokeJoin.miter;

canvasWrapper.canvas.drawPath(barPath, borderPaint);
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This line bypasses the canvas wrapper. All drawing must go through canvasWrapper.drawPath(...)

So please use .drawPath() directly on the canvasWrapper

}
drawBar(canvasWrapper, barPath, barData, holder);
}
}
Expand Down
Loading