- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta http-equiv="X-UA-Compatible" content="ie=edge">
- <title>Document</title>
- <style>
- #canvas {
- border: 1px solid #000;
- }
- </style>
- </head>
- <body>
- <canvas id="canvas" width="800" height="600"></canvas>
- </body>
- <script>
- ; (function () {
- /**
- * 绘制饼图
- * 1. 把数据转换成弧度
- * 2. 根据弧度绘制圆弧扇形
- * 3. 绘制备注文本
- */
- function CookieChart(options) {
- this.canvas = document.getElementById(options.id)
- this.ctx = this.canvas.getContext('2d')
- this.data = options.data
- this.radius = 200
- this.outline = 40
- // 圆心坐标
- this.circleCenter = {
- x: this.canvas.width / 2,
- y: this.canvas.height / 2
- }
- this.startAngle = Math.PI / 180 * options.startAngle
- this.init()
- }
- var methods = CookieChart.prototype
- // 初始化
- methods.init = function () {
- this.drawChart()
- }
- // 绘制饼图
- methods.drawChart = function () {
- this.translateDataToRadians()//data 里面加了 radian
- var ctx = this.ctx
- var circleCenter = this.circleCenter
- var startAngle = this.startAngle
- this.data.forEach(function (item) {
- ctx.beginPath()
- ctx.moveTo(circleCenter.x, circleCenter.y)
- var color = 'rgb(' + Math.floor(Math.random() * 256) + ',' + Math.floor(Math.random() * 256) + ',' + Math.floor(Math.random() * 256) + ')'
- ctx.fillStyle = color
- ctx.arc(circleCenter.x, circleCenter.y, this.radius, startAngle, startAngle + item.radian)
- ctx.fill()
- startAngle += item.radian
- // 绘制线条
- ctx.beginPath()
- ctx.moveTo(circleCenter.x, circleCenter.y)
- ctx.strokeStyle = color
- // 线条的 x
- var c = this.radius + this.outline
- var lineX = circleCenter.x + c * Math.cos(startAngle - item.radian / 2)
- var lineY = circleCenter.y + c * Math.sin(startAngle - item.radian / 2)
- ctx.lineTo(lineX, lineY)
- // ctx.stroke()
- // 绘制文字
- // ctx.beginPath()
- // ctx.moveTo(lineX,lineY)
- var textWidth = ctx.measureText(item.title).width
- ctx.font = '24px serif'
- ctx.textBaseline = 'bottom'
- if (lineX> circleCenter.x) {
- ctx.lineTo(textWidth + lineX, lineY)
- ctx.textAlign = 'left'
- } else {
- ctx.lineTo(lineX - textWidth, lineY)
- ctx.textAlign = 'right'
- }
- ctx.fillText(item.title, lineX, lineY)
- ctx.stroke()
- }.bind(this))
- }
- // 将业务数据转换弧度
- methods.translateDataToRadians = function () {
- var sum = this.data.reduce(function (prev, curr) {
- return prev + curr.count
- }, 0)
- // 100 分 每一份占多少弧度
- var perRadian = 2 * Math.PI / 100
- // 计算弧度百分比
- this.data.forEach(function (item) {
- item.radian = item.count / sum * 100 * perRadian
- })
- }
- window.CookieChart = CookieChart
- })()
- </script>
- <script>
- new CookieChart({
- id: 'canvas',
- data: [
- {
- title: '苹果',
- count: 5000
- },
- {
- title: '橘子',
- count: 4000
- },
- {
- title: '火龙果',
- count: 2000
- },
- {
- title: '葡萄',
- count: 8000
- },
- {
- title: '榴莲',
- count: 6000
- }
- ],
- startAngle: 0
- })
- </script>
- </html>
来源: http://www.qdfuns.com/article/50506/29d23d7df46e670591a347c81d79b092.html