用于绘制饼图的HTML5和画布

时间:2015-01-21 12:22:22

标签: javascript html html5 html5-canvas

我正在尝试使用HTML5和Canvas绘制饼图。

以下是我在jsfiddle中的工作示例。     http://jsfiddle.net/2mf8gt2c/

我需要显示饼图内的值。 即

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

该值应显示在饼图内。我怎样才能做到这一点?

完整代码可在下面找到。

<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>

有人可以帮助我完成这项工作吗?

谢谢, Kimz

1 个答案:

答案 0 :(得分:0)

enter image description here

这是另一种绘制具有指定起始位置的楔形的方法。结束角度:

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();

我建议使用这种替代方法,因为你可以很容易地计算起始和开始之间的角度。结束角度如下:

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

考虑到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);

以下是示例代码和演示:

&#13;
&#13;
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);

}
&#13;
body {
  background-color: ivory;
  padding: 10px;
}
#canvas {
  border: 1px solid red;
}
&#13;
<canvas id="canvas" width=400 height=300></canvas>
&#13;
&#13;
&#13;