J'utilise Chart.js pour dessiner un graphique en secteurs dans ma page php.J'ai trouvé info-bulle montrant chaque valeur de la tranche.
Mais je souhaite afficher ces valeurs comme ci-dessous image.
Je ne sais pas comment faire cela avec chart.js.
Aidez-moi, s'il vous plaît.
Mon code Javascript:
function drawPie(canvasId,data,legend){
var ctx = $("#pie-canvas-" + canvasId).get(0).getContext("2d");
var piedata = [];
$.each(data,function(i,val){
piedata.Push({value:val.count,color:val.color,label:val.status});
});
var options =
{
tooltipTemplate: "<%= Math.round(circumference / 6.283 * 100) %>%",
}
var pie = new Chart(ctx).Pie(piedata,options);
if(legend)document.getElementById("legend").innerHTML = pie.generateLegend();
}
code php:
printf('<table><tr>');
echo '<td style="text-align: right;"><canvas id="pie-canvas-'
. $canvasId
. '" width="256" height="256" ></canvas></td><td style="text-align: left;width:360px;height:auto" id="legend" class="chart-legend"></td></tr></table>';
echo '<script type="text/javascript">drawPie('
. $canvasId
. ', '
. $data3
.', '
. $legend
. ');</script>';
D'après ce que je sais, je ne pense pas que Chart.JS dispose d'une fonctionnalité permettant de dessiner du texte sur un graphique à secteurs. Mais cela ne signifie pas que vous ne pouvez pas le faire vous-même en JavaScript natif. Je vais vous donner un exemple sur la façon de procéder. Le code permettant de dessiner du texte pour chaque segment du graphique à secteurs est présenté ci-dessous:
function drawSegmentValues()
{
for(var i=0; i<myPieChart.segments.length; i++)
{
// Default properties for text (size is scaled)
ctx.fillStyle="white";
var textSize = canvas.width/10;
ctx.font= textSize+"px Verdana";
// Get needed variables
var value = myPieChart.segments[i].value;
var startAngle = myPieChart.segments[i].startAngle;
var endAngle = myPieChart.segments[i].endAngle;
var middleAngle = startAngle + ((endAngle - startAngle)/2);
// Compute text location
var posX = (radius/2) * Math.cos(middleAngle) + midX;
var posY = (radius/2) * Math.sin(middleAngle) + midY;
// Text offside to middle of text
var w_offset = ctx.measureText(value).width/2;
var h_offset = textSize/4;
ctx.fillText(value, posX - w_offset, posY + h_offset);
}
}
Un graphique à secteurs comporte un tableau de segments stockés dans PieChart.segments
. Nous pouvons examiner les startAngle
et endAngle
de ces segments pour déterminer l'angle entre le texte middleAngle
. Ensuite, nous avancerions dans cette direction de Radius/2
Pour être au centre de la carte en radians.
Dans l'exemple ci-dessus, d'autres opérations de nettoyage sont effectuées. En raison de la position du texte dessiné dans fillText()
étant le coin supérieur droit, nous devons obtenir des valeurs de décalage pour corriger cela. Et finalement textSize
est déterminé en fonction de la taille du graphique lui-même, plus le graphique est grand, plus le texte est volumineux.
Avec de légères modifications, vous pouvez modifier les valeurs de nombres discrets d'un jeu de données en nombres de centiles dans un graphique. Pour ce faire, obtenez le total value
des éléments de votre jeu de données, appelez ceci totalValue
. Ensuite, sur chaque segment, vous pouvez trouver le pourcentage en faisant:
Math.round(myPieChart.segments[i].value/totalValue*100)+'%';
La section ici myPieChart.segments[i].value/totalValue
Est ce qui calcule le pourcentage que prend le segment dans le graphique. Par exemple, si le segment en cours avait une valeur de 50
Et que la valeur totale était de 200
. Ensuite, le pourcentage pris par le segment serait: 50/200 => 0.25
. Le reste est de faire ce look Nice. 0.25*100 => 25
, Nous ajoutons un %
À la fin. Pour les nombres entiers de pourcentages, j'ai arrondi à l'entier le plus proche, mais cela peut entraîner des problèmes de précision. Si nous avons besoin de plus de précision, vous pouvez utiliser .toFixed(n)
pour enregistrer les décimales. Par exemple, nous pourrions le faire pour enregistrer une décimale unique au besoin:
var value = myPieChart.segments[i].value/totalValue*100;
if(Math.round(value) !== value)
value = (myPieChart.segments[i].value/totalValue*100).toFixed(1);
value = value + '%';
Pour Chart.js 2.0 et les versions ultérieures, les données de l'objet Graphique ont été modifiées. Pour ceux qui utilisent Chart.js 2.0+, voici un exemple d'utilisation de la méthode HTML5 Canvas fillText()
pour afficher la valeur des données à l'intérieur de la tranche de camembert. Le code fonctionne également pour le graphique en anneau, la seule différence étant que type: 'pie'
contre type: 'doughnut'
lors de la création du graphique.
Script:
Javascript
var data = {
datasets: [{
data: [
11,
16,
7,
3,
14
],
backgroundColor: [
"#FF6384",
"#4BC0C0",
"#FFCE56",
"#E7E9ED",
"#36A2EB"
],
label: 'My dataset' // for legend
}],
labels: [
"Red",
"Green",
"Yellow",
"Grey",
"Blue"
]
};
var pieOptions = {
events: false,
animation: {
duration: 500,
easing: "easeOutQuart",
onComplete: function () {
var ctx = this.chart.ctx;
ctx.font = Chart.helpers.fontString(Chart.defaults.global.defaultFontFamily, 'normal', Chart.defaults.global.defaultFontFamily);
ctx.textAlign = 'center';
ctx.textBaseline = 'bottom';
this.data.datasets.forEach(function (dataset) {
for (var i = 0; i < dataset.data.length; i++) {
var model = dataset._meta[Object.keys(dataset._meta)[0]].data[i]._model,
total = dataset._meta[Object.keys(dataset._meta)[0]].total,
mid_radius = model.innerRadius + (model.outerRadius - model.innerRadius)/2,
start_angle = model.startAngle,
end_angle = model.endAngle,
mid_angle = start_angle + (end_angle - start_angle)/2;
var x = mid_radius * Math.cos(mid_angle);
var y = mid_radius * Math.sin(mid_angle);
ctx.fillStyle = '#fff';
if (i == 3){ // Darker text color for lighter background
ctx.fillStyle = '#444';
}
var percent = String(Math.round(dataset.data[i]/total*100)) + "%";
//Don't Display If Legend is hide or value is 0
if(dataset.data[i] != 0 && dataset._meta[0].data[i].hidden != true) {
ctx.fillText(dataset.data[i], model.x + x, model.y + y);
// Display percent in another line, line break doesn't work for fillText
ctx.fillText(percent, model.x + x, model.y + y + 15);
}
}
});
}
}
};
var pieChartCanvas = $("#pieChart");
var pieChart = new Chart(pieChartCanvas, {
type: 'pie', // or doughnut
data: data,
options: pieOptions
});
HTML
<canvas id="pieChart" width=200 height=200></canvas>
J'ai trouvé un excellent Chart.js
plugin qui fait exactement ce que vous voulez: https://github.com/emn178/Chart.PieceLabel.js
La réponse de @Hung Tran fonctionne parfaitement. En guise d’amélioration, je suggérerais de ne pas afficher les valeurs égales à 0. Supposons que vous avez 5 éléments et que 2 d’entre eux sont 0 et que le reste d’entre eux ont des valeurs, la solution ci-dessus indique 0 et 0%. Il vaut mieux filtrer cela avec une vérification différente de 0!
var val = dataset.data[i]; var percent = String(Math.round(val/total*100)) + "%"; if(val != 0) { ctx.fillText(dataset.data[i], model.x + x, model.y + y); // Display percent in another line, line break doesn't work for fillText ctx.fillText(percent, model.x + x, model.y + y + 15); }
Code mis à jour ci-dessous:
var data = {
datasets: [{
data: [
11,
16,
7,
3,
14
],
backgroundColor: [
"#FF6384",
"#4BC0C0",
"#FFCE56",
"#E7E9ED",
"#36A2EB"
],
label: 'My dataset' // for legend
}],
labels: [
"Red",
"Green",
"Yellow",
"Grey",
"Blue"
]
};
var pieOptions = {
events: false,
animation: {
duration: 500,
easing: "easeOutQuart",
onComplete: function () {
var ctx = this.chart.ctx;
ctx.font = Chart.helpers.fontString(Chart.defaults.global.defaultFontFamily, 'normal', Chart.defaults.global.defaultFontFamily);
ctx.textAlign = 'center';
ctx.textBaseline = 'bottom';
this.data.datasets.forEach(function (dataset) {
for (var i = 0; i < dataset.data.length; i++) {
var model = dataset._meta[Object.keys(dataset._meta)[0]].data[i]._model,
total = dataset._meta[Object.keys(dataset._meta)[0]].total,
mid_radius = model.innerRadius + (model.outerRadius - model.innerRadius)/2,
start_angle = model.startAngle,
end_angle = model.endAngle,
mid_angle = start_angle + (end_angle - start_angle)/2;
var x = mid_radius * Math.cos(mid_angle);
var y = mid_radius * Math.sin(mid_angle);
ctx.fillStyle = '#fff';
if (i == 3){ // Darker text color for lighter background
ctx.fillStyle = '#444';
}
var val = dataset.data[i];
var percent = String(Math.round(val/total*100)) + "%";
if(val != 0) {
ctx.fillText(dataset.data[i], model.x + x, model.y + y);
// Display percent in another line, line break doesn't work for fillText
ctx.fillText(percent, model.x + x, model.y + y + 15);
}
}
});
}
}
};
var pieChartCanvas = $("#pieChart");
var pieChart = new Chart(pieChartCanvas, {
type: 'pie', // or doughnut
data: data,
options: pieOptions
});