示例代碼托管在: "http://www.github.com/dashnowords/blogs" 博客園地址: "《大史住在大前端》原創博文目錄" 華為雲社區地址: "【你要的前端打怪升級指南】" [TOC] 一. 任務說明 使用原生 繪製K線圖。(截圖以及數據來自於百度Echarts官方示例庫 ...
目錄
示例代碼托管在:http://www.github.com/dashnowords/blogs
博客園地址:《大史住在大前端》原創博文目錄
華為雲社區地址:【你要的前端打怪升級指南】
一. 任務說明
使用原生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][2]));
context.lineTo(activeX,transCoord(data[i][3]));
context.closePath();
context.stroke();
//繪製開盤收盤矩形
if (data[i][0] >= data[i][1]) {
context.fillRect(activeX - 5 , transCoord(data[i][0]) , 10, transCoord(data[i][1]) - transCoord(data[i][0]));
} else{
context.fillRect(activeX - 5 , transCoord(data[i][1]) , 10, transCoord(data[i][0]) - transCoord(data[i][1]));
}
}
}
//根據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);
}
瀏覽器中可查看效果: