HTML5 canvas最流行的应用之一是绘制图表。我们将用一个很简单的例子,讲述如何在画布上绘制图表。明白这些基本概念后再进一步深化,就可以使我们的图形功能更灵活。
下面是我们简单绘制图表的步骤:
创建2D画布context对象
绘制X轴
绘制Y轴
基于数据绘制路径
我们需要理解如何在画布上元素绘制多个点。在X轴从左边0开始,向右移值增加,y轴从0开始的顶部,向向下移值增加。如下图:
让我们将画布放置在页面上。
Your browser does not support the canvas element.
要在画布上绘图,我们需要使用JavaScript引用canvas元素。我们用init()函数实现这一功能并在初始化时调用它。
function init() {
canvas = document.getElementById("canvas");
if(canvas.getContext)
{
ctx = canvas.getContext("2d");
draw();
}
}
首先,我们通过canvas的id搜索DOM元素得到画布元素,然后新建了一个画布context对象,该对象可以在JavaScript内部完成绘制工作。 context对象包含在画布上绘图的基本方法,比如arc(), lineto() 和stroke()。
然后调用draw()函数来绘制图表。
function draw() {
clear();
drawaxes();
plotdata();
}
我们调用clear()函数,该函数使用clearRect()方法来清除一个与画布同样大小矩形。清除的矩形的两个对角设置为(0,0)和(宽,高)。宽度和高度与画布上的宽度高度相同。你可以很容易部分清除画布,但我们想要的是清空画布。
function clear() {
ctx.clearRect(0, 0, WIDTH, HEIGHT);
}
接下来,使用drawaxes()函数在画布左侧和底部绘制X轴和Y轴。
function drawaxes(){
ctx.strokeStyle = "black";
ctx.beginPath();
/* y axis along the left edge of the canvas*/
ctx.moveTo(0,0);
ctx.lineTo(0,105);
ctx.stroke();
/* x axis along the bottom edge of the canvas*/
ctx.moveTo(0,105);
ctx.lineTo(180,105);
ctx.stroke();
}
context对象的strokestyle属性设置成想要的笔触颜色,在使用stroke()方法绘制路径时会用到它。
ctx.strokeStyle = “black”;
然后我们从新建的路径开始绘制。
ctx.beginPath();
现在,我们利用创建的新路径,使用stroke方法绘制Y轴。
/* y axis along the left edge of the canvas*/
ctx.moveTo(0,0);
ctx.lineTo(0,105);
ctx.stroke();
同样的方法绘制X轴。
/* x axis along the bottom edge of the canvas*/
ctx.moveTo(0,105);
ctx.lineTo(180,105);
ctx.stroke();
下一步,在draw()方法中调用plotdata()方法。
function plotdata() {
ctx.strokeStyle = "rgb(0,0,165)";
ctx.lineWidth = 1;
ctx.beginPath();
ctx.lineJoin = "miter";
ctx.moveTo(0, HEIGHT - (temps[0]));
j = 1;
for (var i in temps) {
ctx.lineTo(j * 30, HEIGHT - (temps[j]));
ctx.stroke();
j++;
}
}
同样,设置context对象的strokestyle属性,从新建路径开始绘制。
ctx.strokeStyle = "black";
ctx.beginPath();
移至坐标原点。从顶部至底部Y轴值下降,但打算我们顶端表示数据的最小值,底端表示数据的最大值,因此我们使用如下公式:
ctx.moveTo(0,HEIGHT-(temps[0]));
这个公式有效地反转温度值,因此距离底部80像素,而不是距离顶部80像素。现在,我们遍历其它的温度值并在每个相邻值之间画一条线。
j = 1;
for (var i in temps) {
ctx.lineTo(j * 30, HEIGHT - (temps[j]));
ctx.stroke();
j++;
}
我们使用j * 30,每个数据点间距为30像素,而不是7像素,这样才有足够的空间。
点击此处查看本实例的效果。