How to display pie chart data values ​​for each fragment in chart.js

I am using Chart.js to draw a pie chart on my php page. I found a tooltip as showing all slice values.
enter image description here

But I want to show these values ​​as shown below. enter image description here

I do not know how to do this with chart.js.

Please help me.

My javascript code is:

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

php code:

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

enter image description here

+20
javascript jquery php charts
Oct 27 '15 at 8:48
source share
7 answers

From what I know, I do not believe that Chart.JS has any functionality that helps draw text on a pie chart. But this does not mean that you cannot do it yourself in native JavaScript. I will give you an example of how to do this, below is the code for drawing text for each segment in a pie chart:

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

A Pie Chart has an array of segments stored in PieChart.segments , we can look at the startAngle and endAngle these segments to determine the angle between where the text will be middleAngle . Then we move in that direction on Radius/2 to be at the midpoint of the chart in radians.

The above example performs some other cleaning operations, because the position of the text shown in fillText() is the upper right corner, we need to get some offset values ​​to fix this. And finally, textSize is determined based on the size of the chart itself, the larger the chart, the larger the text.

Script example




With minor changes, you can change the values ​​of the discrete numbers for the data set into percentile numbers on the graph. To do this, get the total number of value elements in your data set, call it totalValue . Then on each segment you can find the percentage:

 Math.round(myPieChart.segments[i].value/totalValue*100)+'%'; 

Here, the myPieChart.segments[i].value/totalValue calculates the percentage that the segment occupies in the chart. For example, if the current segment was 50 , and totalValue was 200 . Then the percentage that the segment occupied will be as follows: 50/200 => 0.25 . The rest is to do it well. 0.25*100 => 25 , then we will add a % to the end. For an integer percent of tiles, I rounded to the nearest integer, although it could lead to problems with accuracy. If we need higher precision, you can use .toFixed(n) to store decimals. For example, we could do this to save one decimal place if necessary:

 var value = myPieChart.segments[i].value/totalValue*100; if(Math.round(value) !== value) value = (myPieChart.segments[i].value/totalValue*100).toFixed(1); value = value + '%'; 

Script Example percentile with decimal places

Script Example percent with integers

+16
Oct 27 '15 at 18:53
source share

For Chart.js 2.0 and above, the Chart object data has changed. For those using Chart.js 2.0+, the following is an example of using the HTML5 Canvas fillText() method to display the data value in the circular part. The code also works for a donut chart, with the only difference being that type: 'pie' and " type: 'doughnut' are used when creating the diagram.

Script writer:

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> 

jsFiddle

+54
Aug 05 '16 at 20:51 on
source share

I found a great Chart.js plugin that does exactly what you want: https://github.com/emn178/Chart.PieceLabel.js

+21
Mar 21 '17 at 16:33
source share

You can use the PieceLabel plugin for Chart.js.

{itemLabel: {mode: 'percent', precision: 2}}

Demo | Documentation

+11
Jun 12 '17 at 9:20
source share

@ Reply to Hung Tran works great. As an improvement, I would suggest not showing values ​​equal to 0. Let's say you have 5 elements, and 2 of them are 0, and the rest of them have values, in the above solution 0 and 0% will be displayed. It’s better to filter this out with a non-0 check!

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

Updated code below:

 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 }); 
+1
Dec 27 '16 at 6:32
source share

You can also take a look at: https://chartjs-plugin-datalabels.netlify.com for chart.js 2.7.0 or later.

0
May 21 '19 at 23:08
source share

The easiest way to do this with Chartjs. Just add the bottom line in the settings:

 pieceLabel: { fontColor: '#000' } 

Good luck

-2
Jul 24 '18 at 5:55
source share



All Articles