https://codesandbox.io/s/twil...首先是画饼图var data = [150, 70]; var radius = 100; var total = data.reduce((a, b) => a+b, 0); var cx = 250; var cy = 250; var startAngle = -Math.PI/2; for (var i = 0; i < data.length; i++) { ctx.fillStyle = i > 0 ? 'skyblue' : 'hotpink'; ctx.beginPath(); ctx.moveTo(cx, cy); ctx.arc(cx, cy, radius, startAngle,startAngle + (Math.PI * 2 * (data[i] / total)), false); ctx.lineTo(cx, cy); ctx.fill(); startAngle += Math.PI * 2 * (data[i] / total); }然后外边的弧线同样可以视为一个更大半径圆的一部分,定义一下这条线对应的角度,根据饼图数据,那么这个圆上的3个点的坐标都有了,代码不解释了,都是初中几何const getPoint = (angle, radius) => { angle -= Math.PI/2; var x = radius * Math.cos(angle); var y = radius * Math.sin(angle) return {x:x+cx, y:y+cy} } var totalAngle = Math.PI/2; var percent = data[0]/total; var r2 = radius+30; var points = [ getPoint(- totalAngle/2,r2), getPoint( totalAngle/2, r2), getPoint(-totalAngle/2 + totalAngle*percent, r2) ] ctx.beginPath(); ctx.arc(cx, cy, r2, -totalAngle/2-Math.PI/2, totalAngle/2-Math.PI/2, false); ctx.stroke(); points.forEach(({x, y})=> { ctx.fillStyle = '#f60'; ctx.beginPath(x, y); ctx.arc(x, y, 6, 0, Math.PI * 2, false); ctx.fill(); })
https://codesandbox.io/s/twil...
首先是画饼图
然后外边的弧线同样可以视为一个更大半径圆的一部分,定义一下这条线对应的角度,根据饼图数据,那么这个圆上的3个点的坐标都有了,代码不解释了,都是初中几何