@@ -5,15 +5,27 @@ import 'package:flutter/widgets.dart';
55import 'candle_data.dart' ;
66import 'painter_params.dart' ;
77
8+ typedef TimeLabelGetter = String Function (int timestamp, int visibleDataCount);
9+ typedef PriceLabelGetter = String Function (double price);
10+ typedef OverlayInfoGetter = Map <String , String > Function (CandleData candle);
11+
812class ChartPainter extends CustomPainter {
913 final PainterParams params;
14+ final TimeLabelGetter getTimeLabel;
15+ final PriceLabelGetter getPriceLabel;
16+ final OverlayInfoGetter getOverlayInfo;
1017
11- ChartPainter (this .params);
18+ ChartPainter ({
19+ required this .params,
20+ required this .getTimeLabel,
21+ required this .getPriceLabel,
22+ required this .getOverlayInfo,
23+ });
1224
1325 @override
1426 void paint (Canvas canvas, Size size) {
15- // Draw date labels & price labels
16- _drawDateLabels (canvas, params);
27+ // Draw time labels (dates) & price labels
28+ _drawTimeLabels (canvas, params);
1729 _drawPriceGridAndLabels (canvas, params);
1830
1931 // Draw prices, volumes & trend line
@@ -38,8 +50,8 @@ class ChartPainter extends CustomPainter {
3850 }
3951 }
4052
41- void _drawDateLabels (canvas, PainterParams params) {
42- // We draw one date label per 90 pixels of screen width
53+ void _drawTimeLabels (canvas, PainterParams params) {
54+ // We draw one time label per 90 pixels of screen width
4355 final lineCount = params.chartWidth ~ / 90 ;
4456 final gap = 1 / (lineCount + 1 );
4557 for (int i = 1 ; i <= lineCount; i++ ) {
@@ -48,15 +60,15 @@ class ChartPainter extends CustomPainter {
4860 if (index < params.candles.length) {
4961 final candle = params.candles[index];
5062 final visibleDataCount = params.candles.length;
51- final dateTp = TextPainter (
63+ final timeTp = TextPainter (
5264 text: TextSpan (
53- text: params. getDateLabel (candle.timestamp, visibleDataCount),
54- style: params.style.dateLabelStyle ,
65+ text: getTimeLabel (candle.timestamp, visibleDataCount),
66+ style: params.style.timeLabelStyle ,
5567 ),
5668 )
5769 ..textDirection = TextDirection .ltr
5870 ..layout ();
59- dateTp .paint (canvas, Offset (x - dateTp .width / 2 , params.chartHeight));
71+ timeTp .paint (canvas, Offset (x - timeTp .width / 2 , params.chartHeight));
6072 }
6173 }
6274 }
@@ -74,7 +86,7 @@ class ChartPainter extends CustomPainter {
7486 );
7587 final priceTp = TextPainter (
7688 text: TextSpan (
77- text: params. getPriceLabel (y),
89+ text: getPriceLabel (y),
7890 style: params.style.priceLabelStyle,
7991 ),
8092 )
@@ -200,16 +212,20 @@ class ChartPainter extends CustomPainter {
200212 ..textDirection = TextDirection .ltr
201213 ..layout ();
202214
203- final info = params. getOverlayInfo (candle);
215+ final info = getOverlayInfo (candle);
204216 final labels = info.keys.map ((text) => makeTP (text)).toList ();
205217 final values = info.values.map ((text) => makeTP (text)).toList ();
206218
207219 final labelsMaxWidth = labels.map ((tp) => tp.width).reduce (max);
208220 final valuesMaxWidth = values.map ((tp) => tp.width).reduce (max);
209221 final panelWidth = labelsMaxWidth + valuesMaxWidth + xGap * 3 ;
210- final panelHeight =
211- values.first.height * values.length + yGap * (values.length + 1 );
222+ final panelHeight = max (
223+ labels.map ((tp) => tp.height).reduce ((a, b) => a + b),
224+ values.map ((tp) => tp.height).reduce ((a, b) => a + b),
225+ ) +
226+ yGap * (values.length + 1 );
212227
228+ // Shift the canvas, so the overlay panel can appear near touch position.
213229 canvas.save ();
214230 final pos = params.tapPosition! ;
215231 final fingerSize = 32.0 ; // leave some margin around user's finger
@@ -226,27 +242,33 @@ class ChartPainter extends CustomPainter {
226242 if (dy < 0 ) dy = 0.0 ;
227243 canvas.translate (dx, dy);
228244
229- // Paint overlay panel and texts
245+ // Draw the background for overlay panel
230246 canvas.drawRRect (
231247 RRect .fromRectAndRadius (
232248 Offset .zero & Size (panelWidth, panelHeight),
233249 Radius .circular (8 ),
234250 ),
235251 Paint ()..color = params.style.overlayBackgroundColor);
252+
253+ // Draw texts
254+ var y = 0.0 ;
236255 for (int i = 0 ; i < labels.length; i++ ) {
237- labels[i].paint (
238- canvas,
239- Offset (xGap, (yGap + values.first.height) * i + yGap),
240- );
241- }
242- for (int i = 0 ; i < values.length; i++ ) {
243- final leading = valuesMaxWidth - values[i].width;
256+ y += yGap;
257+ final rowHeight = max (labels[i].height, values[i].height);
258+ // Draw labels (left align, vertical center)
259+ final labelY = y + (rowHeight - labels[i].height) / 2 ; // vertical center
260+ labels[i].paint (canvas, Offset (xGap, labelY));
261+
262+ // Draw values (right align, vertical center)
263+ final leading = valuesMaxWidth - values[i].width; // right align
264+ final valueY = y + (rowHeight - values[i].height) / 2 ; // vertical center
244265 values[i].paint (
245266 canvas,
246- Offset (labelsMaxWidth + xGap * 2 + leading,
247- (yGap + values.first.height) * i + yGap),
267+ Offset (labelsMaxWidth + xGap * 2 + leading, valueY),
248268 );
269+ y += rowHeight;
249270 }
271+
250272 canvas.restore ();
251273 }
252274
0 commit comments