2011-08-09 24 views
19

私は下図に示すように、単純な円グラフを作成しようとしています:HTML5のCanvas円グラフ

enter image description here

チャートは、ユーザーがいずれかを選択することができクイズの結果が表示されます、 bまたはc。彼らは10の質問であり、ユーザーは質問ごとに1つのオプションしか選択できません。

私がしたいのは、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>

色がそう緑の最大と最小のための3つの緑のために使用されるセグメントのサイズ、に特異的です。

おかげで

+0

もう少し努力すれば、長く進むことができます。あなたの問題は何ですか? – TJHeuvel

+2

データをどこから始めてグラフを描画するのかはわかりません – Cameron

答えて

28

さえなど、Googleの検索と私のラジアン値をトリプルチェックした後、私はまだはこれでトラブルを抱えていたので、私は実際の例として、一緒にプレイする人のための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); 

私は今パイの完全な境界を持っているので、文脈の中で色を塗りつぶすと、円全体に広がることはありませんが、その円に限定されます。