Skip to content

Commit 808c5a8

Browse files
committed
feat: Add extraLinesData support to CandlestickChart
1 parent 32e75f5 commit 808c5a8

File tree

5 files changed

+92
-0
lines changed

5 files changed

+92
-0
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
## newVersion
2+
* **FEATURE** Add `extraLinesData` support to [CandlestickChart](https://github.com/imaNNeo/fl_chart/blob/main/repo_files/documentations/candlestick_chart.md). You can now draw horizontal and vertical lines on candlestick charts, similar to LineChart. Useful for showing support/resistance levels, moving averages, or other reference lines.
23
* **BUGFIX** (by @imaNNeo) Consider the `enabled` property in [LineTouchData](https://github.com/imaNNeo/fl_chart/blob/main/repo_files/documentations/line_chart.md#linetouchdata-read-about-touch-handling), [BarTouchData](https://github.com/imaNNeo/fl_chart/blob/main/repo_files/documentations/bar_chart.md#bartouchdata-read-about-touch-handling), [PieTouchData](https://github.com/imaNNeo/fl_chart/blob/main/repo_files/documentations/pie_chart.md#pietouchdata-read-about-touch-handling), [ScatterTouchData](https://github.com/imaNNeo/fl_chart/blob/main/repo_files/documentations/scatter_chart.md#scattertouchdata-read-about-touch-handling), [RadarTouchData](https://github.com/imaNNeo/fl_chart/blob/main/repo_files/documentations/radar_chart.md#radartouchdata-read-about-touch-handling) and [CandlestickTouchData](https://github.com/imaNNeo/fl_chart/blob/main/repo_files/documentations/candlestick_chart.md#candlesticktouchdata-read-about-touch-handling), #1676
34

45
## 1.1.1

example/lib/presentation/samples/candlestick/candlestick_chart_sample1.dart

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,29 @@ class CandlestickChartSample1State extends State<CandlestickChartSample1> {
166166
getDrawingHorizontalLine: (_) => _gridLine,
167167
getDrawingVerticalLine: (_) => _gridLine,
168168
),
169+
extraLinesData: ExtraLinesData(
170+
horizontalLines: [
171+
HorizontalLine(
172+
y: _monthMedian,
173+
color: AppColors.contentColorYellow,
174+
strokeWidth: 2,
175+
dashArray: [10, 5],
176+
label: HorizontalLineLabel(
177+
show: true,
178+
alignment: Alignment.topRight,
179+
padding:
180+
const EdgeInsets.only(bottom: 8, right: 8),
181+
style: const TextStyle(
182+
color: AppColors.contentColorYellow,
183+
fontSize: 12,
184+
fontWeight: FontWeight.bold,
185+
),
186+
labelResolver: (line) =>
187+
'Median: \$${line.y.toStringAsFixed(0)}',
188+
),
189+
),
190+
],
191+
),
169192
titlesData: FlTitlesData(
170193
show: true,
171194
rightTitles: const AxisTitles(
@@ -258,6 +281,22 @@ class CandlestickChartSample1State extends State<CandlestickChartSample1> {
258281

259282
bool get _canGoPrevious => _currentMonthIndex > 0;
260283

284+
double get _monthMedian {
285+
if (_btcMonthlyData == null) return 0;
286+
final monthData = _btcMonthlyData![_currentMonthIndex];
287+
if (monthData.isEmpty) return 0;
288+
289+
// Calculate median of closing prices
290+
final closingPrices = monthData.map((e) => e.close).toList()..sort();
291+
final middle = closingPrices.length ~/ 2;
292+
293+
if (closingPrices.length % 2 == 0) {
294+
return (closingPrices[middle - 1] + closingPrices[middle]) / 2;
295+
} else {
296+
return closingPrices[middle];
297+
}
298+
}
299+
261300
void _previousMonth() {
262301
if (!_canGoPrevious) {
263302
return;

lib/src/chart/candlestick_chart/candlestick_chart_data.dart

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,16 @@ class CandlestickChartData extends AxisChartData with EquatableMixin {
3030
/// on top of each [CandlestickChartData.candleSpots] using [showingTooltipIndicators],
3131
/// just put spot indices you want to show it on top of them.
3232
///
33+
/// [CandlestickChart] draws some horizontal or vertical lines on above or below of everything,
34+
/// they are useful in some scenarios, for example you can show average line, you can fill
35+
/// [extraLinesData] property to have your extra lines.
36+
///
3337
/// [clipData] forces the [CandlestickChart] to draw lines inside the chart bounding box.
3438
CandlestickChartData({
3539
List<CandlestickSpot>? candlestickSpots,
3640
FlCandlestickPainter? candlestickPainter,
3741
FlTitlesData? titlesData,
42+
ExtraLinesData? extraLinesData,
3843
CandlestickTouchData? candlestickTouchData,
3944
List<int>? showingTooltipIndicators,
4045
FlGridData? gridData,
@@ -57,6 +62,7 @@ class CandlestickChartData extends AxisChartData with EquatableMixin {
5762
super(
5863
gridData: gridData ?? const FlGridData(),
5964
titlesData: titlesData ?? const FlTitlesData(),
65+
extraLinesData: extraLinesData ?? const ExtraLinesData(),
6066
clipData: clipData ?? const FlClipData.none(),
6167
minX: minX ??
6268
CandlestickChartHelper.calculateMaxAxisValues(
@@ -121,6 +127,8 @@ class CandlestickChartData extends AxisChartData with EquatableMixin {
121127
t,
122128
),
123129
titlesData: FlTitlesData.lerp(a.titlesData, b.titlesData, t),
130+
extraLinesData:
131+
ExtraLinesData.lerp(a.extraLinesData, b.extraLinesData, t),
124132
candlestickTouchData: b.candlestickTouchData,
125133
showingTooltipIndicators: lerpIntList(
126134
a.showingTooltipIndicators,
@@ -156,6 +164,7 @@ class CandlestickChartData extends AxisChartData with EquatableMixin {
156164
List<CandlestickSpot>? candlestickSpots,
157165
FlCandlestickPainter? candlestickPainter,
158166
FlTitlesData? titlesData,
167+
ExtraLinesData? extraLinesData,
159168
CandlestickTouchData? candlestickTouchData,
160169
List<int>? showingTooltipIndicators,
161170
FlGridData? gridData,
@@ -176,6 +185,7 @@ class CandlestickChartData extends AxisChartData with EquatableMixin {
176185
candlestickSpots: candlestickSpots ?? this.candlestickSpots,
177186
candlestickPainter: candlestickPainter ?? this.candlestickPainter,
178187
titlesData: titlesData ?? this.titlesData,
188+
extraLinesData: extraLinesData ?? this.extraLinesData,
179189
candlestickTouchData: candlestickTouchData ?? this.candlestickTouchData,
180190
showingTooltipIndicators:
181191
showingTooltipIndicators ?? this.showingTooltipIndicators,
@@ -204,6 +214,7 @@ class CandlestickChartData extends AxisChartData with EquatableMixin {
204214
showingTooltipIndicators,
205215
gridData,
206216
titlesData,
217+
extraLinesData,
207218
minX,
208219
maxX,
209220
baselineX,

lib/src/chart/candlestick_chart/candlestick_chart_painter.dart

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,18 @@ class CandlestickChartPainter extends AxisChartPainter<CandlestickChartData> {
4141
..clipRect(Offset.zero & canvasWrapper.size);
4242
}
4343
super.paint(context, canvasWrapper, holder);
44+
45+
if (!holder.data.extraLinesData.extraLinesOnTop) {
46+
super.drawExtraLines(context, canvasWrapper, holder);
47+
}
48+
4449
drawAxisSpotIndicator(context, canvasWrapper, holder);
4550
drawCandlesticks(context, canvasWrapper, holder);
4651

52+
if (holder.data.extraLinesData.extraLinesOnTop) {
53+
super.drawExtraLines(context, canvasWrapper, holder);
54+
}
55+
4756
if (holder.chartVirtualRect != null) {
4857
canvasWrapper.restore();
4958
}

test/chart/candlestick_chart/candlestick_chart_data_test.dart

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,38 @@ void main() {
273273
),
274274
false,
275275
);
276+
277+
expect(
278+
candleStickChartData1 ==
279+
candleStickChartData1Clone.copyWith(
280+
extraLinesData: ExtraLinesData(
281+
horizontalLines: [
282+
HorizontalLine(y: 10),
283+
],
284+
),
285+
),
286+
false,
287+
);
288+
289+
expect(
290+
candleStickChartData1 ==
291+
candleStickChartData1Clone.copyWith(
292+
extraLinesData: ExtraLinesData(
293+
verticalLines: [
294+
VerticalLine(x: 5),
295+
],
296+
),
297+
),
298+
false,
299+
);
300+
301+
expect(
302+
candleStickChartData1 ==
303+
candleStickChartData1Clone.copyWith(
304+
extraLinesData: const ExtraLinesData(),
305+
),
306+
true,
307+
);
276308
});
277309

278310
test('CandlestickSpot equality test', () {

0 commit comments

Comments
 (0)