前几天处理一个需求,需要根据四项数值来绘制一个折线图,具体样子比较简单,为此实在没有必要引入第三方的图表库,干脆还是自己写一个吧。
首先,从结构上,四个图标使用页面来做,画布只负责上部分的折线图,四个坐标将图标和图表对齐即可。然后是逻辑上,先初始化canvas画布。
1 | var |
这里假设四个数值是通过ajax请求的,在回调中调用绘制折线和圆点的方法即可。
1 | ... |
然后是四个纵坐标的值,一开始感觉是间隔完全相等的,但最后一个圆点总是显示不全,可能跟图表太小,半个像素的显示问题有关,所以还是直接将四个坐标定死。然后是定位的xy值的问题,由于效果图是750宽度,canvas在实际像素定义的时候应该加一个缩放比,不然在各个宽度下,显示会不同,而且实际坐标值也很难计算。
1 | var |
之后就是绘制折线图,先依次使用lineTo
方法链接四个点,在画出右边、右下圆角、下边,左下圆角就可以了。填充的颜色这里是用的是createLinearGradient
方法创建的渐变色。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24var
...
...
linear = ctx.createLinearGradient(0, 60, 208, 60);
linear.addColorStop(0,'#2b80ff');
linear.addColorStop(1,'#41d4ff');
...
...
function drawTheRectangle(chartpoints){
ctx.save();
ctx.beginPath();
for(var i in chartpoints){
var j = chartpoints[i];
ctx.lineTo(cirX[i], 120 - (bottomspace + chartpoints[i] * 8));
}
ctx.lineTo(cirX[3], 120 - bottomspace);
ctx.arc(cirX[3] - bottomspace, 120 - bottomspace, bottomspace, 0, Math.PI * 1 / 2);
ctx.lineTo(cirX[0] + bottomspace, 120);
ctx.arc(cirX[0] + bottomspace, 120 - bottomspace, bottomspace, Math.PI * 1 / 2, Math.PI);
ctx.closePath();
ctx.fillStyle = linear;
ctx.fill();
ctx.restore();
}
最后绘制四个圆点,就可以了1
2
3
4
5
6
7
8
9
10
11function drawTheCircle(chartpoints){
ctx.save();
ctx.fillStyle = "white";
for(var i in chartpoints){
var j = chartpoints[i];
ctx.beginPath();
ctx.arc(cirX[i], 120 - (bottomspace + chartpoints[i] * 8), 5.5, 0, Math.PI * 2, true);
ctx.fill();
}
ctx.restore();
}