2011-08-09 146 views
19

我試圖創建一個簡單的餅圖像下圖所示:HTML5畫布餅圖

enter image description here

圖表將顯示測驗結果,其中,用戶可以選擇一個, b或c。他們有10個問題,用戶每個問題只能選擇一個選項。

我想要做的是通過傳遞a,b或c的值來顯示餅圖,每個段的百分比均爲100%。

我見到目前爲止以下內容:

var greenOne = "#95B524"; 
 
var greenTwo = "#AFCC4C"; 
 
var greenThree = "#C1DD54"; 
 

 
function CreatePieChart() { 
 
    var chart = document.getElementById('piechart'); 
 
    var canvas = chart.getContext('2d'); 
 
    canvas.clearRect(0, 0, chart.width, chart.height); 
 

 
    var total = 100; 
 

 
    var a = 3; 
 
    var b = 4; 
 
    var c = 3; 
 

 
    for (var i = 0; i < 3; i++) { 
 
    canvas.fillStyle = "#95B524"; 
 
    canvas.beginPath(); 
 
    canvas.strokeStyle = "#fff"; 
 
    canvas.lineWidth = 3; 
 
    canvas.arc(100, 100, 100, 0, Math.PI * 2, true); 
 
    canvas.closePath(); 
 
    canvas.stroke(); 
 
    canvas.fill(); 
 
    } 
 
} 
 
CreatePieChart();
<canvas id="piechart" width="200" height="200"></canvas>

的顏色是具體到段的大小,所以綠色的用於最大,綠三種爲最小。

感謝

+0

多一點努力可以走很長的路。你確切的問題是什麼? – TJHeuvel

+2

我不知道從哪裏開始數據和繪製圖表 – Cameron

回答

28

即使谷歌搜索和三重檢查我的弧度值,等以後我有這個麻煩仍然,所以我創建了一個jsFiddle人玩一個活生生的例子和意志發佈下面的代碼。

var canvas = document.getElementById("can"); 
 
var ctx = canvas.getContext("2d"); 
 
var lastend = 0; 
 
var data = [200, 60, 15]; // If you add more data values make sure you add more colors 
 
var myTotal = 0; // Automatically calculated so don't touch 
 
var myColor = ['red', 'green', 'blue']; // Colors of each slice 
 

 
for (var e = 0; e < data.length; e++) { 
 
    myTotal += data[e]; 
 
} 
 

 
for (var i = 0; i < data.length; i++) { 
 
    ctx.fillStyle = myColor[i]; 
 
    ctx.beginPath(); 
 
    ctx.moveTo(canvas.width/2, canvas.height/2); 
 
    // Arc Parameters: x, y, radius, startingAngle (radians), endingAngle (radians), antiClockwise (boolean) 
 
    ctx.arc(canvas.width/2, canvas.height/2, canvas.height/2, lastend, lastend + (Math.PI * 2 * (data[i]/myTotal)), false); 
 
    ctx.lineTo(canvas.width/2, canvas.height/2); 
 
    ctx.fill(); 
 
    lastend += Math.PI * 2 * (data[i]/myTotal); 
 
}
<canvas id="can" width="200" height="200" />

+1

我喜歡這個,它非常簡單,非常輕便,不需要任何外部腳本,比如jQuery等。這對我來說很好,因爲我打算使用數百這些通過部分請求加載大聲笑 – RedactedProfile

+0

這太棒了!我可以添加,如果你想段從午夜的位置開始,初始化'var lastend = -1.57'。 1.57是一圈圓弧數的四分之一。謝謝。 –

3

我喜歡以前的答案,但我覺得這是缺乏清晰的代碼,並沒有真正涵蓋如何利用標籤。

我將值移入數據對象數組中以便於聲明。其他值,如百分比,我明確聲明爲數據對象上的屬性,或作爲單獨的變量。我認爲這使得它更易於閱讀。

的重構也使得它更容易的價值觀聯繫到輸入框,如果這是你感興趣的東西

要明白我的意思,並與價值觀玩看看這個CodePen:http://codepen.io/zfrisch/pen/pRbZeb

var data = [{ 
 
    label: "one", 
 
    value: 100, 
 
    color: 'white' 
 
    }, { 
 
    label: "two", 
 
    value: 100, 
 
    color: 'skyBlue' 
 
    }, { 
 
    label: "three", 
 
    value: 100, 
 
    color: 'yellow' 
 
    }]; 
 

 
    var total = 0; 
 
    for (obj of data) { 
 
    total += obj.value; 
 
    } 
 

 
    var canvas = document.getElementById('myCanvas'); 
 
    var ctx = canvas.getContext('2d'); 
 
    var previousRadian; 
 
    var middle = { 
 
    x: canvas.width/2, 
 
    y: canvas.height/2, 
 
    radius: canvas.height/2, 
 
    }; 
 
    
 
    //background 
 
    ctx.beginPath(); 
 
    ctx.arc(middle.x, middle.y, middle.radius, 0, 2 * Math.PI); 
 
    ctx.closePath(); 
 
    ctx.stroke(); 
 
    ctx.fillStyle = "black"; 
 
    ctx.fill(); 
 
    //end of background 
 

 
    for (obj of data) { 
 
    previousRadian = previousRadian || 0; 
 
    obj.percentage = parseInt((obj.value/total) * 100) 
 
    
 
    ctx.beginPath(); 
 
    ctx.fillStyle = obj.color; 
 
    obj.radian = (Math.PI * 2) * (obj.value/total); 
 
    ctx.moveTo(middle.x, middle.y); 
 
    //middle.radius - 2 is to add border between the background and the pie chart 
 
    ctx.arc(middle.x, middle.y, middle.radius - 2, previousRadian, previousRadian + obj.radian, false); 
 
    ctx.closePath(); 
 
    ctx.fill(); 
 
    ctx.save(); 
 
    ctx.translate(middle.x, middle.y); 
 
    ctx.fillStyle = "black"; 
 
    ctx.font = middle.radius/10 + "px Arial"; 
 
    ctx.rotate(previousRadian + obj.radian); 
 
    var labelText = "'" + obj.label + "' " + obj.percentage + "%"; 
 
    ctx.fillText(labelText, ctx.measureText(labelText).width/2, 0); 
 
    ctx.restore(); 
 

 
    previousRadian += obj.radian; 
 
    }
<canvas id="myCanvas" width="500" height="500" ></canvas>

0

我有同樣的問題之前,但我以後能夠解決這個問題。

我錯過的是我在上下文中畫了一道拱門,並試圖填充它,因爲顏色遍佈整個圓圈,因爲現在上下文僅限於從中心到起點的半徑線之間拱的點和拱界限於上下文。

但是沒有其他的邊界從拱端中心的線,只要我使用繪製行:

ctx.lineTo(center coordinates of circle); 

我有一個餡餅的一個完整的邊界,所以現在如果我在上下文中填充顏色,它不會在整個圓圈內傳播,但會被限制在該餡餅中。