Canvas繪制股票K線圖
阿新 • • 發佈:2018-01-18
mat restore screen 位置 mar toc rect() store water 最近想在小程序做股票K線圖,於是嘗試用Canvas實現股票K線圖。
K線圖用到Canvas的API其實只有劃線和畫矩形,即moveTo(),lineTo(),fillRect()等函數。
K線圖用到Canvas的API其實只有劃線和畫矩形,即moveTo(),lineTo(),fillRect()等函數。
第一步,我們先定義K線類:
function Bar(open,high,low,close,width){
this.open = open;
this.high = high;
this.low = low;
this.close = close;
this.width = width | 5;
}
輸入參數分別表示開盤價,最高價,最低價,收盤價,K線寬度。
K線類定義一個繪制函數:
Bar.prototype.draw = function(pen,x,base,frag,screen){ //根據base,frag計算坐標 var _open = screen - (this.open - base)*frag - 10; var _high = screen - (this.high - base)*frag - 10; var _low = screen - (this.low - base)*frag - 10; var _close = screen - (this.close - base)*frag - 10; //根據base,frag畫K線 pen.save(); if(this.close >= this.open){ pen.fillStyle = "#FF0000"; pen.strokeStyle = "#FF0000"; }else{ pen.fillStyle = "#00FF00"; pen.strokeStyle = "#00FF00"; } pen.beginPath(); pen.moveTo(30 + x * this.width*2 + this.width,_high); pen.lineTo(30 + x * this.width*2 + this.width,_low); pen.stroke(); var y = ((_open > _close)?_open:_close); if(Math.abs(_open - _close) == 0 ){ pen.moveTo(35 + x * this.width*2,y); pen.lineTo(30 + (x+1) * this.width*2,y); pen.stroke(); }else{ pen.fillRect(35 + x * this.width*2,((_open < _close)?_open:_close),2*(this.width-5),Math.abs(_open - _close)); } pen.restore(); }
pen為畫布的上下文,x為該K線的X位置,base為整個數據中最小坐標對應的價格,frag是單位價格對應的高度,screen為畫布的整體高度,由於Canvas是左上角為坐標點(0,0),所以需要screen做坐標轉換。
繪制流程大致為:
1、將價格轉換為畫布上相應的坐標
2、根據收盤價和開盤價確定陰柱與陽柱,設置相應的顏色
3、根據最高價與最低價畫線,根據開盤價與收盤價畫矩形
至此,K線已經繪制代碼已經結束。
第二步,實現坐標系
首先先創建一個圖表類
function chart(dom){ var width = parseFloat(dom.style.width.replace("px","")); var height = parseFloat(dom.style.height.replace("px","")); var canvas = document.createElement("canvas"); canvas.style.width = width + "px"; canvas.style.height = height + "px"; canvas.width = width; canvas.height = height; dom.appendChild(canvas); var context = canvas.getContext("2d"); this.width = width; this.height = height; this.pen = context; }
根據傳入的div節點,創建Canvas,這裏需要註意
canvas.width = width;
canvas.height = height;
兩行代碼的必要性,這兩行保證了繪制內容與實際設置的大小相符,這裏不能帶“px”,否則無效。
坐標軸的實質就是兩個相交的直線,對於刻度,需要根據數據進行設置,實現代碼如下:
chart.prototype.drawBar = function(date,data){
//計算價格最大值與最小值
var maxPrice = -1,minPrice = 999999;
for(var i = 0;i < data.length;i++){
if(data[i][1] > maxPrice){
maxPrice = data[i][1];
}
if(data[i][2] < minPrice){
minPrice = data[i][2];
}
}
var frag = (this.height-20)/(maxPrice - minPrice);
var kwidth = Math.round((this.width-30)/(date.length+2));
//清屏
this.pen.save();
this.pen.fillStyle = "#FFFFFF";
this.pen.fillRect(0,0,this.width,this.height);
this.pen.restore();
//畫坐標軸
this.pen.save();
this.pen.beginPath();
this.pen.lineWidth = 1;
this.pen.strokeStyle = "#888888";
this.pen.moveTo(30,this.height - 10);
this.pen.lineTo(this.width-30,this.height - 10);
this.pen.stroke();
this.pen.moveTo(30,this.height - 10);
this.pen.lineTo(30,10);
this.pen.stroke();
for(var i = 0;i < 5;i++){
this.pen.moveTo(30,(this.height - (10 + i*(this.height-20)/5)));
this.pen.lineTo(35,(this.height - (10 + i*(this.height-20)/5)));
this.pen.stroke();
this.pen.fillText((i*(this.height-20)/5/frag + minPrice).toFixed(2),0,(this.height - (10 + i*(this.height-20)/5)));
}
for(var i = 0;i < data.length;i++){
var bar = new Bar(data[i][0],data[i][1],data[i][2],data[i][3],kwidth/2);
bar.draw(this.pen,i,minPrice,frag,this.height);
//繪制日期
//this.pen.save();
//this.pen.restore();
}
for(var i = 0;i < date.length;i++){
this.pen.moveTo(30 + (i+1) * kwidth,this.height - 10);
this.pen.lineTo(30 + (i+1) * kwidth,this.height - 15);
this.pen.stroke();
this.pen.fillText(date[i],30 + (i + 1/2) * kwidth,this.height);
}
}
以上,K線繪制組件已經實現,接下來查看應用:
<script src = "http://data.gtimg.cn/flashdata/hushen/daily/18/sz002578.js"></script>
<script src = "stock.js"></script>
<div id = "canvas" style = "width:600px;height:400px;"></div>
<script>
var ev_data = daily_data_18.split("\n");
var date = [],data = [];
for(var i = 1;i < ev_data.length - 1;i++){
var es = ev_data[i].split(" ");
date.push(es[0]);
data.push([parseFloat(es[1]),parseFloat(es[3]),parseFloat(es[4]),parseFloat(es[2])]);
}
var canvas = document.getElementById("canvas");
var chart = new chart(canvas);
chart.drawBar(date,data);
</script>
效果如圖:
Canvas繪制股票K線圖