返回
Flutter股票分时线,K线,WEB,移动端支持
见解分享
2024-02-18 23:08:22
公司项目中有涉及到股票类K线及分时线,原先使用flutter_k_chart,但是由于样式及数据方面的问题,决定自己从头开始画一个。 移动端、WEB端都支持。 废话不多说。先上图
[图片]
点击K线图,VOL窗口进行切换指标。
分时线需要提前在/lib/hb_chart_config.dart中配置好指标。
[图片]
实现原理
一般K线和分时线的数据接口都是带时序的,所以使用flutter中的CustomPaint来画图时需要注意将时序数据与屏幕坐标系对应起来。
-
将K线,分时线数据转化为Rect,这样就可以使用canvas.drawRect()来画矩形。
-
将最高点,最低点,开盘价,收盘价转化为屏幕坐标系中的y坐标。这样就可以使用canvas.drawLine()来画线。
-
将成交量数据转化为Rect,这样就可以使用canvas.drawRect()来画矩形。
-
将时间数据转化为屏幕坐标系中的x坐标。这样就可以使用canvas.drawText()来画文字。
注意:
-
K线和分时线的数据需要按照时间顺序排列。
-
K线和分时线的数据需要包含最高点,最低点,开盘价,收盘价,成交量等信息。
代码实现
1. 定义数据模型
class KLineData {
DateTime time;
double open;
double high;
double low;
double close;
double volume;
KLineData(this.time, this.open, this.high, this.low, this.close, this.volume);
}
2. 定义画笔
class KLinePainter extends CustomPainter {
List<KLineData> data;
KLinePainter(this.data);
@override
void paint(Canvas canvas, Size size) {
// 将K线数据转化为Rect
List<Rect> rects = [];
for (var i = 0; i < data.length; i++) {
var kLineData = data[i];
var rect = Rect.fromLTWH(
i * size.width / data.length,
size.height - (kLineData.high - kLineData.low) / (kLineData.high - kLineData.low) * size.height,
size.width / data.length,
(kLineData.high - kLineData.low) / (kLineData.high - kLineData.low) * size.height);
rects.add(rect);
}
// 使用canvas.drawRect()来画矩形
for (var i = 0; i < rects.length; i++) {
var rect = rects[i];
if (data[i].close > data[i].open) {
canvas.drawRect(rect, Paint()..color = Colors.red);
} else {
canvas.drawRect(rect, Paint()..color = Colors.green);
}
}
// 将最高点,最低点,开盘价,收盘价转化为屏幕坐标系中的y坐标
List<double> yAxis = [];
for (var i = 0; i < data.length; i++) {
var kLineData = data[i];
yAxis.add(size.height - (kLineData.high - kLineData.low) / (kLineData.high - kLineData.low) * size.height);
}
// 使用canvas.drawLine()来画线
for (var i = 0; i < yAxis.length - 1; i++) {
canvas.drawLine(Offset(i * size.width / data.length, yAxis[i]),
Offset((i + 1) * size.width / data.length, yAxis[i + 1]),
Paint()..color = Colors.black);
}
// 将成交量数据转化为Rect
List<Rect> volumeRects = [];
for (var i = 0; i < data.length; i++) {
var kLineData = data[i];
var rect = Rect.fromLTWH(
i * size.width / data.length,
size.height - kLineData.volume / kLineData.volume * size.height,
size.width / data.length,
kLineData.volume / kLineData.volume * size.height);
volumeRects.add(rect);
}
// 使用canvas.drawRect()来画矩形
for (var i = 0; i < volumeRects.length; i++) {
var rect = volumeRects[i];
canvas.drawRect(rect, Paint()..color = Colors.blue);
}
// 将时间数据转化为屏幕坐标系中的x坐标
List<double> xAxis = [];
for (var i = 0; i < data.length; i++) {
var kLineData = data[i];
xAxis.add(i * size.width / data.length);
}
// 使用canvas.drawText()来画文字
for (var i = 0; i < xAxis.length; i++) {
var x = xAxis[i];
var y = size.height - 20;
var text = data[i].time.toString();
canvas.drawText(text, Offset(x, y), Paint()..color = Colors.black);
}
}
@override
bool shouldRepaint(CustomPainter oldDelegate) {
return true;
}
}
3. 使用CustomPaint来画图
class KLineChart extends StatelessWidget {
List<KLineData> data;
KLineChart(this.data);
@override
Widget build(BuildContext context) {
return CustomPaint(
painter: KLinePainter(data),
);
}
}
总结
本文详细介绍了如何在Flutter中实现股票分时线和K线图,支持移动端和WEB端。本文提供了详细的步骤和示例代码,帮助您快速入门。