2011-08-09 3 views
19

Je tente de créer un simple diagramme circulaire comme le montre le graphique ci-dessous:HTML5 graphique en toile

enter image description here

Le graphique montre les résultats pour un quiz où un utilisateur peut choisir soit un, b ou c. Ils sont 10 questions et l'utilisateur ne peut choisir qu'une option par question. Ce que je veux faire est montrer le camembert avec chaque segment étant un pourcentage de 100% en passant dans les valeurs pour a, b, ou c.

Je donne les résultats suivants jusqu'à présent:

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>

Les couleurs sont spécifiques à la taille du segment, si un vert est utilisé pour le plus grand et vert trois pour les plus petits.

Merci

+0

Un peu plus d'effort pourrait aller un long chemin. Quel est votre problème exactement? – TJHeuvel

+2

Je ne sais pas par où commencer avec les données et dessiner le graphique – Cameron

Répondre

28

Même après la recherche Google et triple vérifier mes radians valeurs, etc. J'étais encore avoir du mal avec cela, j'ai donc créé un jsFiddle pour les gens à jouer avec comme un exemple direct et en différé afficher le code ci-dessous.

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

J'aime ça, c'est super simple, très léger, ne nécessite pas de scripts externes comme jQuery, etc. C'est bon pour moi parce que je prévois d'utiliser des centaines de ces chargés dans via une demande partielle lol – RedactedProfile

+0

C'est génial! Puis-je ajouter que si vous voulez que les segments commencent à partir de la position de minuit, initialisez 'var lastend = -1.57'. 1,57 est le quart du nombre de radians dans un cercle. Merci. –

3

J'aime la réponse précédente, mais je sentais qu'il manquait de clarté du code et il ne couvre pas vraiment comment utiliser les étiquettes. J'ai déplacé les valeurs dans un tableau d'objets de données pour une déclaration facile. D'autres valeurs, comme le pourcentage, I explicitement déclarées comme une propriété sur l'objet de données, ou comme une variable distincte. Cela, je pense, le rend plus facile à lire.

Le refactoring a également rendu plus facile de lier les valeurs à des boîtes d'entrée si c'est quelque chose que vous êtes intéressé par

Pour voir ce que je veux dire et jouer avec les valeurs vérifier cette 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

J'ai eu le même problème avant, mais j'ai pu résoudre ce problème plus tard. Ce qui me manquait, c'était que je dessinais une arche en contexte et que j'essayais de la remplir, à cause de la couleur qui s'étendait sur tout le cercle parce que le contexte était maintenant lié seulement entre une ligne de rayon du centre au point de départ point d'arche et l'arc pour délimiter le contexte.

Mais il n'y avait pas d'autre limite de la ligne à l'extrémité de l'arc au centre, dès que je dessine cette ligne en utilisant les éléments suivants:

ctx.lineTo(center coordinates of circle); 

J'ai une frontière complète d'une tarte, maintenant si je remplis la couleur dans son contexte, elle ne se répandra pas dans tout le cercle mais se limitera à cette tarte.