我来解释一下!!!!
Topic source详细解读了仁兄的思路,自己实现了一遍。仁兄的是最符合K线图的。我在仁兄的基础上封装了划线和画盒子的函数。增加了文字信息,背景我是使用第二个图层实现的。
function drawline(data,width_start,width_half_k,k_blank,height_start,scale,high) { for(var i=0;i<data.length;i++) { var line_X=width_start+width_half_k+i*(1+2*width_half_k+k_blank); var line_y=Math.round(height_start+Math.abs(data[i].high-high)*scale); var line_width=1; var line_high=(data[i].high-data[i].low)*scale; if (data[i].open >= data[i].close) { ctx.fillStyle = "#dc0000"; } else { ctx.fillStyle = "#1caa3d"; } ctx.fillRect(line_X,line_y,line_width,line_high); } } function drawbox(data,width_start,width_half_k,k_blank,height_start,scale,high) { for(var i=0;i<data.length;i++) { var box_x=width_start+i*(2*width_half_k+1+k_blank); var y_open=Math.round(height_start+Math.abs(data[i].open-high)*scale); var y_close=Math.round(height_start+Math.abs(data[i].close-high)*scale); var box_y=y_open<y_close ? y_open:y_close; var box_width=2*width_half_k+1; var box_high=Math.abs(data[i].open-data[i].close)*scale; if (data[i].open >= data[i].close) { ctx.fillStyle = "#dc0000"; } else { ctx.fillStyle = "#1caa3d"; } ctx.fillRect(box_x,box_y,box_width,box_high); } } function drawStock(data) { var canvas=document.getElementById('stock-canvas'); var width=canvas.width; var height=canvas.height;
//创建背景图层2,创建图层2的原因是为了避免文字,背景用一种fillStyle
var layer2=document.createElement('canvas');
layer2.style.position='absolute';
layer2.style.left='0';
layer2.style.opacity='0.2';
var ctx2=layer2.getContext('2d');
ctx2.fillStyle='#00000';
ctx2.fillRect(0,0,width,height);
document.getElementsByTagName('body')[0].appendChild(layer2);
ctx=canvas.getContext('2d');
ctx.clearRect(0,0,width,height);
ctx.font='20px Verdana';
// 创建渐变,产生文字
var gradient=ctx.createLinearGradient(0,0,width,height);
gradient.addColorStop("0","magenta");
gradient.addColorStop("0.5","blue");
gradient.addColorStop("1.0","red");
ctx.fillStyle=gradient;
ctx.fillText('Test canvas',75,20);
var low=data[0].low;
var high=data[0].high;
for(var i=0;i<data.length;i++)
{
low=data[i].low<low ? data[i].low:low;
high=data[i].high>high ? data[i].high:high;
}
var height_start=height*0.05;
var scale=height*0.9/(high-low);
var width_half_k=Math.round((width*0.3)/data.length);
var k_blank=Math.round((width*0.2)/(data.length-1));
var width_start=width*0.05;
//调用上面封装好的划线和画盒子的函数
drawline(data,width_start,width_half_k,k_blank,height_start,scale,high);
drawbox(data,width_start,width_half_k,k_blank,height_start,scale,high);
}
function loadStockData(r) {
var NUM=30;
var data=r.data;
if(data.length>NUM){
data=data.slice(data.length-NUM);
}
data=data.map(function (x) {
return {
data: x[0],
open: x[1],
close:x[2],
high: x[3],
low: x[4],
vol: x[5],
change:x[6]
};
});
drawStock(data);
}
var js=document.createElement('script');
js.src = 'http://img1.money.126.net/data/hs/kline/day/history/2015/0000001.json?callback=loadStockData&t='+Date.now();
document.getElementsByTagName('head')[0].appendChild(js);
- 1
你若成风丶丶
已知函数传进来的data是一个数组,数组的每个元素是一个对象,格式如下 {"date":"20150602","open":4844.7,"close":4910.53,"high":4911.57,"low":4797.55,"vol":62374809900,"change":1.69} 其中我们能用到的是 open , close, high, low 解释一下四个参数的含义,我们知道K线图的形状 类似于汉字 中 其中 high表示的是中字中间一竖的最上边一点的Y坐标, low 是中字中间一竖的最下边一点的Y坐标, 如果open大于close,则表示股票交易结束的时候比开始的时候低了,则要用绿色表示 open是中字中间的口的上边一横的Y坐标, close是下边一横的Y坐标 如果open小于close,则表示股票交易结束的时候比开始的时候高了,则要用红色表示 open是中字中间的口的下边一横的Y坐标 close是上边一横的Y坐标 这样就可以清楚的表示出 在时间上(横坐标,单位:天)股票点数(Y坐标)的变化
下面来看我写的代码