示例代码托管在:http://www.github.com/dashnowords/blogs
博客园地址:《大史住在大前端》原创博文目录
华为云社区地址:【你要的前端打怪升级指南】
[TOC]
一. 任务说明
使用原生 canvasAPI
绘制 K 线图。(截图以及数据来自于百度 Echarts 官方示例库【查看示例链接】)。
二. 重点提示
K 线图最常见的是在金融市场,尤其是股市中,它的绘制算法和表达的意思是直接相关的:
- 一般一个数据点包含
开盘价
,收盘价
,当日最高价
,当日最低价
4 个数据点。 - 当
开盘价
低于收盘价
时,当天为涨价,则图形为红色,反之则为绿色。 - 图形中间的细线是
当日最高价
和当日最低价
之间的连线。 - 图形中的矩形是在
开盘价
和收盘价
之间的范围。
了解了上述基本知识,K 线图的绘制和折线图其实并没有太大区别,按部就班去绘制就好了。如果仔细观察 Echarts
官方提供的示例会发现图例中还有 MA5
,MA10
这样的图例标记,这里其实指的是 N 天的移动平均值 Moving Average N,是减小数据波动性展示其宏观规律的常用方法之一,示例中的MA5
就是指依次将源数据中每 5 个点的值求平均值作为当前点的数据(至于 5 个点是从当前点开始算,还是从当前点结束都是可以的)。
三. 示例代码
实现难度较低,本文不再赘述。
/* 数据点来自于百度 Echarts 官方示例库
* 每个数据点意义:[日期,开盘(open),收盘(close),最低(lowest),最高(highest)]
* 例如:['2013/2/7', 2430.69,2418.53,2394.22,2433.89],
*/
/**
* 绘制数据
*/
function drawData(options) {
let data = options.data;
let xLength = options.chartZone[2] - options.chartZone[0];
let c;// 记录当前绘制点的颜色
let gap = xLength / options.xAxisLabel.length;
let activeX = 0;// 记录绘制过程中当前点的坐标
let activeY = 0;// 记录绘制过程中当前点的 y 坐标
context.strokeWidth = 2;
context.beginPath();
context.moveTo(options.chartZone[0],options.chartZone[3]);// 先将起点移动至 0,0 坐标
for(let i = 0; i < data.length; i++){
// 获取绘图颜色
c = getColor(data[i]);
context.strokeWidth = 1;
context.strokeStyle = context.fillStyle = c;
// 计算绘制中心点 x 坐标
activeX = options.chartZone[0] + (i + 1) * gap;
// 绘制最高最低线;
context.beginPath();
context.moveTo(activeX,transCoord(data[i][3]));
context.lineTo(activeX,transCoord(data[i][4]));
context.closePath();
context.stroke();
// 绘制开盘收盘矩形
if (data[i][0] >= data[i][5]) {context.fillRect(activeX - 5 , transCoord(data[i][0]) , 10, transCoord(data[i][6]) - transCoord(data[i][0]));
} else{context.fillRect(activeX - 5 , transCoord(data[i][7]) , 10, transCoord(data[i][0]) - transCoord(data[i][8]));
}
}
}
// 根据 K 线图的数据中开盘价和收盘价计算绘图颜色
function getColor(data) {return data[0] >= data[1] ? '#1abc9c' : '#DA5961';
}
// 从可视坐标系坐标转换为 canvas 坐标系坐标
function transCoord(coord) {return options.chartZone[3] - (options.chartZone[3] - options.chartZone[1])*(coord - options.yMin) / (options.yMax - options.yMin);
}
浏览器中可查看效果: