Unlimited Plugins, WordPress themes, videos & courses! Unlimited asset downloads! From $16.50/m
Advertisement
  1. Code
  2. JavaScript
Code

怎样用JavaScript和HTML5 Canvas绘制图表

by
Difficulty:BeginnerLength:LongLanguages:

Chinese (Simplified) (中文(简体)) translation by Stypstive (you can also view the original English article)

Final product image
What You'll Be Creating

在这篇教程中,我将展示用JavaScript和canvas作为手段,在饼状图和圆环图上显示数字信息。

与从零到一创建图表相比,其实有更简便的方式,例如用CodeCanyon上的这个图表库

Infographic charts and graphics HTML tags library
CodeCanyon上的图表库

但是如果你想知道库背后的原理,往下读。

什么是饼状图?

图表是用来图形化展示数据的工具。 饼状图将数据用切割成份的圆来展示。 每份的大小代表了数据值所代表的比例大小。

什么是圆环图?

简而言之,圆环图是饼状图的一个变种。 不同的是每份切向饼图的中心,这样只有轮缘是可见。 就这样,图表就如其名一个圆环。

开始用Canvas画

绘制饼图之前, 我们先看看它的组成部分。 我们先看看如何用canvas组件和JavaScript来画:

  • 一条线
  • 一个弧度(一个圆的部分)
  • 一个颜色填充的图形

要想用HTML canvas画它,我们需要先创建几样东西:

  • 创建一个项目文件夹,把它命名为piechart-tutorial
  • piechart-tutorial文件夹中创建一个HTML文件index.html 这个文件中将是HTML代码。
  • 一个JS文件scritp.jspiechart-tutorial文件夹中 这个文件中将是JavaScript代码。

我们将能简就简,然后添加一下代码到index.html中:

我们有一个ID为myCanvas<canvas>元素。 然后我们通过<script>标签载入JS代码。

script.js中,JS代码首先获取一个canvas的索引,然后设置canvas的宽和高。 要想在canvas上画,我们只需要一个2D上下文,哪里包含着所有的绘图方法。

现在我们已经设置了canvas的宽和高,同时也获取了canvas的索引,接下来我们定义一些画饼状图时,需要用到的可重用的函数。 我们将函数添加在script.js文件中。

函数drawLine接受5个参数:

  1. ctx: 指向绘图上下文的索引
  2. startX:线段起始点的X坐标
  3. startY:线段起始点的Y坐标
  4. endX:线段结束点的X坐标
  5. endY:线段结束点的Y坐标

我们通过调用beginPath()来开始划线。 它通知绘图上下文,我们要在canvas上画一些东西了。 我们用moveTo()来设置起始点,调用lineTo()来表示结束点,然后调用stoke()来进行真正的绘图。

现在看看我们如何画圆的一部分,也叫做弧度。

函数drawArc接受6个参数:

  1. ctx:指向绘图上下文的索引
  2. centerX:圆心的X坐标
  3. centerY:圆心的Y坐标
  4. radius: 圆的半径
  5. startAngle:部分圆的扇形的开始角度
  6. endAngle: 部分圆的扇形的结束角度

我们已经知道怎样画线和弧度了,现在让我看看如何画带颜色的形状。 由于我们的目标是画一份份组成的饼状图,所以我们创建一个画饼形图的份的函数。

函数drawPieSlice接受7个参数:

  1. ctx:指向绘图上下文的索引
  2. centerX:圆心的X坐标
  3. centerY:圆心的Y坐标
  4. radius:圆的半径
  5. startAngle:部分圆的扇形的起始角度
  6. endAngle:部分圆的扇形的结束角度
  7. color:填充的颜色

以下是调用这三个函数的例子:

它将产生如下结果:

Canvas line arc and pie slice

现在,我们有了画一个饼形图的所有必要的工具,让我们看看如何一起使用它们。

画饼形图

在概念上,任意图表都有两部分:

  • 包含要展示的数据的数据模型。 这由特定类型的图表进行结构化。
  • 图形化展示是指按照数学公式的规则,将数据模型中的数据通过视觉元素来进行展示。

饼状图数据模型

结构化饼状图数据的方式中,最常用的就是用一系列的类别和对应的值,每个类别的值与饼图的份相关联。

例如,饼图的数据模型展示按照流派进行分组,看起来就是下面这样:

  • 古典音乐:10
  • 另类摇滚:14
  • 流行:2
  • 爵士:12

我们可以在script.js文件中添加一个JS对象来存储数据模型,如下:

饼状图的图形化展示

饼状图用圆来显示数据模型中的信息,通过将圆切分成一份份。 每份和数据模型中的类别对应,每份的大小与对应类别的值成正比。

我的音乐集有四个类别。 每个类别在饼形图中的份数大小,与它的类别对应的值成正比。

但是我们怎样度量份数的大小? 简单--我们通过每份的角度。 我们所需要知道的就是它占360度或者2PI的份数。 那么半圆就是180deg或者PI,1/4圆90度PI/2,以此类推。

为了决定每个类别的份的角度,我们用以下公式:

份角度= 2 * PI * 类别值 / 总值

按照这个公式,古典音乐的那份近似得到如下角度。 0.526 * PI 或者 94度

让我开始画吧。 这次我们将用JavaScript类,将其命名为 PieChart 构造函数接受options做为参数,options包含以下:

  • canvas:指向我们想要画饼状图的索引
  • data:盛放数据模型的对象的索引
  • colors:一个数组,数组中是每份的颜色。

PieChart类同时也包含一个draw()方法,它来对图表进行实际的绘制。

类中首先将传入的options参数进行存储。 它保存了canvas的索引,同时也创建一个绘画上下文作为类成员变量。 然后它存储了options中的colors数组。

接下来的部分是最根本的,函数draw()。 它会从数据模型中提取数据。 首先,它计算数据模型中所有数据值的和。 然后对其中每个类别应用上面提到的计算角度的函数。 最后我们调用drawPieSlice()函数,用canvas的中心作为饼状图的中心。 至于半径,我们用canvas宽度的一半与canvas高度的一半的较小值,因为我们不想让饼状图超出canvas。

同样,每次画一个类别时,要偏移每份的起始角度和结束角度,否则会发生重叠。

要想使用类,我们必须先创建一个实例对象,然后在创建的对象上调用draw()方法。

结果看起来如下这样

Drawing a pie chart using HTML5 canvas

绘制圆环图

我们已经看到如何创建饼状图。 同样我们看到,圆环图与饼状图不同之处仅在于中间多了一个洞。 怎样画洞呢? 我们可以画一个白色的圆在饼状图上。

让我们通过修改PieChart类来做它。

添加的代码在options参数中,通过一个doughnutHoleSize成员变量。 如果这个参数在options中没有传,代码就按照之前的进行绘制,如果传了,就在饼状图中心画一个白色的圆形。

圆的半径由饼形图的半径和doughnutHoleSize参数的乘积来决定。 它应该是0到1之间的数字,0代表饼形图,大于0时,值越大饼形图中间的洞越大,当值为1时会使图表不可见。

要想画一个图表一半大小的圆环图,我们可以将doughnutHoleSize设置为0.5,然后像下面这样调用:

以下是结果:

drawing a doughnut chart with HTML5 canvas

添加标签和图表图例

我们的饼状图表和圆环图表看起来挺棒了,但是它会变得更棒,通过添加两样东西:

  • 值标签:显示每份对应的百分比
  • 图表图例:显示图表中每个类别和颜色的对应关系

通常,每份的值用百分比来表示,通过100 * 每份值 / 总的值来计算,整个圆代表100%

例如,在我们的例子数据中,古典音乐可以近似地用26%来表示。 如果能将这个值刚好显示在对应的份上面就太好了。 要想这样,我们可以用绘图上下文的fillText(text, x, y)函数。 这个函数接受三个参数:文本和xy坐标。

怎样计算放置文本的xy坐标呢? 我们必须动用一些几何知识了,一个叫做极坐标的东西。 一般地,极坐标用半径和角度来定义一个点的位置。 我们将要用到的两个公式是:

x = R * cos(angle)

y = R * sin(angle)

我们将要应用这个公式,将文本放在饼状图的半径的一半位置与每份角度的一半位置处。 要想做它,我们需要修改我们的PieChart类,增加如下代码在if(this.options.doughnutHoleSize){...}代码块中。

上面代码遍历每份,计算百分比和位置,然后调用fillText()方法将之绘制到图表上。 我们用了fillStyle属性来设置文本颜色为白色,font属性来设置标签文本的字体、样式和大小。 同样重要,需要注意的是圆环图的doughnutHoleSize设置后,标签会被往边沿推,以使文本能处于圆环图每份的中央。

以下就是带值标签的图表看起来的样子:

Pie chart and doughnut chart with value labels

要想完成图表,最后一件事就是为图表添加图例。 我们的图表图例将会显示数据模型中数据的类别和对应每份的颜色。 首先,我们需要对index.html文件做些修改,添加一个<div>标签用来存储我们的图例元素。

然后在script.js中,我们添加创建图例元素的代码。 我们将代码添加在PieChart类中draw()函数的末尾。

代码通过传入options参数来寻找legend元素。 如果找到,就在其中填上带颜色的块和数据模型类别的名字。

同时,我们也需要将调用绘值图表的代码改成如下形式:

这就是结果的图表和图表图例:

Pie chart with value labels and chart legend

恭喜

我们看到用HTML5 canvas绘制图表,其实也并不是那么困难。 它仅仅需要一点数学和JavaScript知识。 你现在有了要画一个你自己的饼形图和圆环图的全部。

如果你想要一个简便快捷的解决方案,用来创建饼形图和圆环图,同时还有其他类型的图表。你可以下载信息图表和HTML图表标签库或者WordPress插件对应的Charts and Graphs WordPress Visual Designer.

关注我们的公众号
Advertisement
Advertisement
Advertisement
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.