简体   繁体   English

HTML5和画布绘制饼图

[英]HTML5 and canvas to plot Pie Chart

I'm trying to plot a pie chart using HTML5 and Canvas. 我正在尝试使用HTML5和Canvas绘制饼图。

Here below is my working example in jsfiddle. 以下是我在jsfiddle中的工作示例。 http://jsfiddle.net/2mf8gt2c/ http://jsfiddle.net/2mf8gt2c/

I need to show the values inside of the pie chart. 我需要在饼图中显示值。 ie

    var myColor = ["Green","Red","Blue"];
    var myData = [30,60,10];    

The value should be displayed inside the pie chart. 该值应显示在饼图中。 How can I achieve that? 我该如何实现?

The full code is available below. 完整的代码如下。

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<title>My Title</title>
</head>
<body>
<section>
  <div>
    <table width="80%" cellpadding=1 cellspacing=1 border=0>
      <tr>
        <td width=50%><canvas id="canvas" align="center" width="400" height="250"> This text is displayed if your browser does not support HTML5 Canvas. </canvas>
        </td>
      </tr>
    </table>
  </div>
  <script type="text/javascript">
var myColor = ["Green","Red","Blue"];
var myData = [30,60,10];
function degreesToRadians(degrees) {
return (degrees * Math.PI)/180;
}
function sumTo(a, i) {
var sum = 0;
for (var j = 0; j < i; j++) {
sum += a[j];
}
return sum;
}
function getTotal(){
var myTotal = 0;
for (var j = 0; j < myData.length; j++) {
myTotal += (typeof myData[j] == 'number') ? myData[j] : 0;
}
return myTotal;
}
var drawSegmentLabel = function(canvas, context, i) 
{
context.save();
var x = Math.floor(250 / 2);
var y = Math.floor(100 / 2);
var angle;
var angleD = sumTo(myData, i);
var flip = (angleD < 90 || angleD > 270) ? false : true;
context.translate(x, y);
if (flip) {
angleD = angleD-180;
context.textAlign = "left";
angle = degreesToRadians(angleD);
context.rotate(angle);
context.translate(-(x + (canvas.width * 0.5))+15, -(canvas.height * 0.05)-10);
}
else {
context.textAlign = "right";
angle = degreesToRadians(angleD);
context.rotate(angle);
}
var fontSize = Math.floor(canvas.height / 25);
context.font = fontSize + "pt Helvetica";
context.fillStyle = "black";
var dx = Math.floor(250 * 0.5) - 10;
var dy = Math.floor(100 * 0.05);
context.fillText(myData[i], dx, dy);
context.restore();
}
function plotData() 
{
var canvas;
var ctx;
var lastend = 0;
var myTotal = getTotal();
var pRadius = 100;
var xPie=250;
canvas = document.getElementById("canvas");
ctx = canvas.getContext("2d");
ctx.imageSmoothingEnabled = true;
ctx.clearRect(0, 0, canvas.width, canvas.height);
for (var i = 0; i < myData.length; i++)
{
ctx.fillStyle = myColor[i];
ctx.beginPath();
ctx.moveTo(xPie,pRadius+10);
ctx.arc(xPie,pRadius+10,pRadius,lastend,lastend +
(Math.PI*2*(myData[i]/myTotal)),false);
ctx.lineTo(xPie,pRadius+10);        
ctx.fill();     
lastend += Math.PI*2*(myData[i]/myTotal);
ctx.lineWidth = 2;
ctx.strokeStyle = '#000000';
ctx.stroke();
}
}
plotData();
</script>
</section>
</body>
</html>

Can someone help me to get this done? 有人可以帮我完成这项工作吗?

Thanks, Kimz 谢谢,金兹

在此处输入图片说明

Here's an alternate way to draw a wedge with a specified starting & ending angle: 这是一种以指定的开始和结束角度绘制楔形的替代方法:

ctx.beginPath();
ctx.moveTo(cx,cy);
ctx.arc(cx,cy,radius,startAngle,endAngle,false);
ctx.closePath();
ctx.fillStyle=fill;
ctx.strokeStyle='black';
ctx.fill();
ctx.stroke();

I suggest this alternate method because you can easily calculate the angle exactly between the starting & ending angle like this: 我建议使用这种替代方法,因为您可以像这样轻松地精确计算起始角度和终止角度之间的角度:

var midAngle=startAngle+(endAngle-startAngle)/2;

And given the midAngle, you can use some trigonometry to calculate where to draw your values inside the wedge: 给定了midAngle,您可以使用一些三角函数来计算在楔形内绘制值的位置:

// draw the value labels 75% of the way from centerpoint to 
// the outside of the wedge
var labelRadius=radius*.75;

// calculate the x,y at midAngle
var x=cx+(labelRadius)*Math.cos(midAngle);
var y=cy+(labelRadius)*Math.sin(midAngle);

Here's example code and a Demo: 这是示例代码和演示:

 var canvas = document.getElementById("canvas"); var ctx = canvas.getContext("2d"); var cw = canvas.width; var ch = canvas.height; ctx.lineWidth = 2; ctx.font = '12px verdana'; var PI2 = Math.PI * 2; var myColor = ["Green", "Red", "Blue"]; var myData = [30, 60, 10]; var cx = 150; var cy = 150; var radius = 100; pieChart(myData, myColor); function pieChart(data, colors) { var total = 0; for (var i = 0; i < data.length; i++) { total += data[i]; } var sweeps = [] for (var i = 0; i < data.length; i++) { sweeps.push(data[i] / total * PI2); } var accumAngle = 0; for (var i = 0; i < sweeps.length; i++) { drawWedge(accumAngle, accumAngle + sweeps[i], colors[i], data[i]); accumAngle += sweeps[i]; } } function drawWedge(startAngle, endAngle, fill, label) { // draw the wedge ctx.beginPath(); ctx.moveTo(cx, cy); ctx.arc(cx, cy, radius, startAngle, endAngle, false); ctx.closePath(); ctx.fillStyle = fill; ctx.strokeStyle = 'black'; ctx.fill(); ctx.stroke(); // draw the label var midAngle = startAngle + (endAngle - startAngle) / 2; var labelRadius = radius * .75; var x = cx + (labelRadius) * Math.cos(midAngle); var y = cy + (labelRadius) * Math.sin(midAngle); ctx.fillStyle = 'white'; ctx.fillText(label, x, y); } 
 body { background-color: ivory; padding: 10px; } #canvas { border: 1px solid red; } 
 <canvas id="canvas" width=400 height=300></canvas> 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM