HTML5 canvas 最流行的应用之一是绘制图表。我们将用一个很简单的例子,讲述如何在画布上绘制图表。明白这些基本概念后再进一步深化,就可以使我们的图形功能更灵活。
步骤
下面是我们简单绘制图表的步骤:
- 创建 2D 画布
context
对象 - 绘制
X
轴 - 绘制
Y
轴 - 基于数据绘制路径
我们需要理解如何在画布上元素绘制多个点。在 X
轴从左边 0
开始,向右移值增加,y
轴从 0
开始的顶部,向向下移值增加。如下图:
代码实现
让我们将画布放置在页面上。
<canvas id="canvas" width="180" height="105">
Your browser does not support the canvas element.
</canvas>
要在画布上绘图,我们需要使用 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
像素,这样才有足够的空间。
参考示例
访问 codepen 查看示例代码及效果。
评论 (0)