<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> </head> <body> <canvas id="c"></canvas> <script> var cv = document.getElementById("c"); var ctx = cv.getContext("2d"); cv.width = 600; cv.height = 400; cv.style.border = "1px solid #000"; // 角度转弧度方法 function toRadian(angle) { return angle / 180 * Math.PI; } function toAngle(radain) { return radian / Math.PI * 180; } // 数据中的value值的和 为: 1 /*var data = [{ "value": .1, "color": "orange", "title": "社会招生" },{ "value": .1, "color": "pink", "title": "公务员" },{ "value": .1, "color": "gray", "title": "公开课" },{ "value": .1, "color": "#909090", "title": "前端" },{ "value": .2, "color": "red", "title": "应届生" },{ "value": .3, "color": "blue", "title": "程序员" },{ "value": .1, "color": "#abc", "title": "老司机" }];*/ var data = [{ "value": .9, "color": "orange", "title": "社会招生" },{ "value": .1, "color": "pink", "title": "公务员" }]; var startAngle = -90, // 起始角度 x0 = cv.width / 2, y0 = cv.height / 2, // 圆心点坐标 radius = 100, // 半径 curAngle = 0, // 结束角度 textX = 0, textY = 0, // 文字的坐标 textOffset = 20, // 文字到饼型图的距离 textWidth = 0, // 文字的宽度 text2Line = 0; // 文字的起始位置到结束位置的长度 data.forEach(function(value, index) { ctx.beginPath(); // 1 先绘制饼型图 curAngle = value.value * 360; ctx.fillStyle = value.color; ctx.moveTo(x0, y0); ctx.arc(x0, y0, radius, toRadian(startAngle), toRadian( startAngle+curAngle)); ctx.fill(); // 2 绘制指向文字的线, 不要忘了将角度转化为弧度!!! textX = x0 + (radius + textOffset) * Math.cos( toRadian(startAngle + curAngle / 2) ); textY = y0 + (radius + textOffset) * Math.sin( toRadian(startAngle + curAngle / 2) ); ctx.strokeStyle = value.color; ctx.moveTo(x0, y0); ctx.lineTo(textX, textY); ctx.stroke(); // 3 绘制文字 和 文字的底线 // 获取文字的宽度 textWidth = ctx.measureText(value.title).width; if(textX <= x0) { // 设置文字的对齐方式 右对齐 ctx.textAlign = "right"; textOffset = -textOffset; textWidth = -textWidth; } // 3.1 绘制文字 ctx.fillText(value.title, textX + textOffset, textY - 10); // 3.2 绘制文字的底线 // 文字底线的长度 = 文字的x坐标 + 文字到线的偏移 + 文字的宽度 text2Line = textX + textOffset + textWidth; ctx.moveTo(textX, textY); ctx.lineTo(text2Line, textY); ctx.stroke(); // 赋值 startAngle += curAngle; // 每次执行完,需要重新初始化偏移值 // (因为上一次有可能改变了偏移值的符号) textOffset = 20; }); </script> </body> </html>