2015-01-21 123 views
0

我想绘制使用HTML5和画布的饼图。HTML5和画布绘制饼图

下面是我在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

+0

请格式化您的代码。没有人会像现在这样再看一眼它。 – ElGavilan 2015-01-21 12:24:02

+0

完成!帮我出 – user3350885 2015-01-21 12:28:40

+0

把这一行添加到你的plotdata()中。 “ctx.fillText(myColor [i],x,y);”其中x和y是您想要放置文本的位置 – 2015-01-21 13:07:03

回答

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

这里的示例代码和演示:

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>