使用H5的canvas绘制饼状图
2020-06-04 05:52
148 查看
前言:在我们写网站,我们往往都想要向用户展示一些数据,比如访问数,文章的点击数等等。如果我们只是用数字来向用户展示的,用户很可能会感觉到枯燥,因为数据的显示实在使太单一的。所以今天我来教大家来用H5的画布api来绘制饼状图,让你的网站更加高大上。
直接进入正题,先展示成果和源码。
最终结果:
代码:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <style> canvas { border: 1px solid black; } </style> </head> <body> <canvas width="600" height="600"></canvas> </body> <script> let data = [ { size: 2, title: '0-5岁' }, { size: 3, title: '5-10岁' }, { size: 4, title: '10-15岁' }, { size: 1, title: '15-20岁' }, { size: 6, title: '20-25岁' }, { size: 4, title: '25-30岁' }, { size: 1, title: '20-35岁' } ] class Chart { constructor(data) { this.myCanvas = document.querySelector('canvas') this.ctx = this.myCanvas.getContext('2d') // 绘制饼状图所需的数据 this.data = data // 取画布的中心作为饼状图的圆心 this.x0 = this.myCanvas.width / 2 this.y0 = this.myCanvas.height / 2 // 用来存储每一个数据对应的弧度 this.angles = [] // 半径 this.radius = 150 // 延申线的长度 this.outline = 15 // 初始化功能 this.init() } init() { // 获取对应的角度 this.getAngles() // 画饼状图 this.drawCircle() } // 获取每个数据对应的角度 getAngles() { let sum = 0 this.data.forEach(item => { sum += item.size }) this.data.forEach((item) => { this.angles.push((item.size / sum) * Math.PI * 2) }) } drawCircle() { let startAngle = 0 let endAngle = 0 // 循环绘制扇形,最后组成圆 for (let i = 0; i < this.data.length; i++) { endAngle = startAngle + this.angles[i] this.ctx.beginPath() // 每次都要把起点移回圆心,不然就会就弄不成扇形 this.ctx.moveTo(this.x0, this.y0) this.ctx.fillStyle = this.getRandomColor() this.ctx.arc(this.x0, this.y0, this.radius, startAngle, endAngle) this.ctx.closePath() this.ctx.fill() // 绘制延迟线 this.drawDetails(startAngle, this.angles[i], this.ctx.fillStyle, i) startAngle = endAngle } } // 获取随机颜色 getRandomColor() { let r = Math.floor(Math.random() * 255) let g = Math.floor(Math.random() * 255) let b = Math.floor(Math.random() * 255) return `rgb(${r},${g},${b})` } drawDetails(startAngle, angle, color, i) { // 绘制延申线 let edge = this.radius + this.outline let edgeX = Math.cos(startAngle + angle / 2) * edge let edgeY = Math.sin(startAngle + angle / 2) * edge this.ctx.moveTo(this.x0, this.y0) this.ctx.lineTo(edgeX + this.x0, edgeY + this.y0) this.ctx.strokeStyle = color this.ctx.stroke() // 绘制文字下划线 this.drawTextDecoration(edgeX + this.x0, edgeY + this.y0, i, color) // 画布左上方的描述 this.drawDataDecoration(this.data[i].title, color, i) } drawTextDecoration(x, y, i, color) { this.ctx.font = '20px 宋体' this.ctx.beginPath() this.ctx.moveTo(x, y) this.ctx.strokeStyle = color let textWidth = this.ctx.measureText(this.data[i].title).width if (x > this.x0) { // x坐标大于原点,下划线向右延申不会与圆重叠 this.ctx.lineTo(x + textWidth, y) // 添加文字,y-3使文字和下划线不用紧贴 this.ctx.fillText(this.data[i].title, x, y - 3) } else { // x坐标小于原点,下划线向左延申不会与圆重叠 this.ctx.lineTo(x - textWidth, y) // 添加文字 this.ctx.fillText(this.data[i].title, x - textWidth, y - 3) } this.ctx.stroke() } // 在画布的左上方添加描述 drawDataDecoration(title, color, i) { this.ctx.font = '15px 宋体' this.ctx.fillStyle = color this.ctx.beginPath() this.ctx.fillRect(10, (18 * i) + 10, 30, 10) this.ctx.fillStyle = 'black' this.ctx.fillText(title, 50, (18 * i) + 20) } } const chart = new Chart(data) </script> </html>
难点:
1.绘制圆形:
计算每个数据占总数的百分比,拿去乘以整个圆的弧度2π,就可以得到每个数据对应的弧度了。利用这个弧度去绘制扇形,这个扇形组合起来就是一个圆了。如果不想设置颜色,可以像我一样写一个获取随机颜色的函数。
2.绘制延长线
由于将延长线的颜色和对应的区域的颜色是一样的,我们就只看到饼状图区域外的线。
先说一下延长线的特点:会平分对应扇形的角,经过中点。
.
我们要已知延长线的长度,角度。我们就可以根据三角函数来求延长线的坐标。
我们假设原点是x0和y0,半径的radius,对应扇形的角度是30°。那么我们可以做一个辅助线。如下图:
斜边就是代码中的半径+outline
a边的长度:斜边×cos(当前扇形的一半)
b边的长度:斜边×sin(当前扇形的一半)
因为垂直嘛,所以:
x坐标就是:圆心的x坐标+a
y坐标就是:圆心的y坐标+b
有些人可能会疑问如果角度大于180度的话,会不会异常,假如扇形的角度是大于180°的,获取到的三角函数值是负数的,就会自动的往那个方向延申了。
3.绘制下滑线
根据对应的延长线的终点坐标,和计算文字所需要的宽度来画线。如果延长线的终点x坐标是在右边的话,就x+文字所需要的宽度,y不变。在左边就x-文字所需要的宽度,y不变
其他的都是基本操作了。
结语
最近学的h5的画布功能,发现画布能实现的功能还是挺多的,实现的功能的可以增添自己网站的丰富度。让网站感觉没那么单调。加油!!
相关文章推荐
- H5使用canvas绘制饼状图
- h5中使用canvas绘制线段、多边形、圆、圆弧
- 用原型的方式使用canvas来绘制饼状图
- 使用h5 canvas绘制圆形进度条
- Android:使用canvas绘制饼状统计图(自动适应条目数量/大小)
- 使用canvas绘制见缝插针小游戏Hello_yihao的博客
- android中Canvas使用drawBitmap绘制图片
- H5使用canvas实现星星闪烁效果
- 使用canvas来绘制图形
- html5之canvas绘制图形的简单使用
- 第一讲:使用html5——canvas绘制奥运五环
- HTML5 Canvas 绘图――使用 Canvas 绘制图形图文教程 使用html5 canvas 绘制精美的图
- 【坑】html5中使用canvas绘制两个strokeRect之间忘了用beginPath()
- HTML5——Canvas_03之【使用bezierCurveTo绘制贝塞尔曲线】
- H5 canvas无法绘制图像的原因
- 使用canvas绘制股票图【envision.js】
- HTML5吃豆豆游戏开发实战(一)使用Canvas绘制游戏主角
- Canvas使用 -- 在canvas上绘制圆角矩形并添加文字
- 使用canvas绘制环形进度条