How to Display Pie Chart Data Values of Each Slice in Chart.Js

How to display pie chart data values of each slice in chart.js

From what I know I don't believe that Chart.JS has any functionality to help for drawing text on a pie chart. But that doesn't mean you can't do it yourself in native JavaScript. I will give you an example on how to do that, below is the code for drawing text for each segment in the 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 of these segments to determine the angle in between where the text would be middleAngle. Then we would move in that direction by Radius/2 to be in the middle point of the chart in radians.

In the example above some other clean-up operations are done, due to the position of text drawn in fillText() being the top right corner, we need to get some offset values to correct for that. And finally textSize is determined based on the size of the chart itself, the larger the chart the larger the text.

Fiddle Example


With some slight modification you can change the discrete number values for a dataset into the percentile numbers in a graph. To do this get the total value of the items in your dataset, call this totalValue. Then on each segment you can find the percent by doing:

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

The section here myPieChart.segments[i].value/totalValue is what calculates the percent that the segment takes up in the chart. For example if the current segment had a value of 50 and the totalValue was 200. Then the percent that the segment took up would be: 50/200 => 0.25. The rest is to make this look nice. 0.25*100 => 25, then we add a % at the end. For whole number percent tiles I rounded to the nearest integer, although can can lead to problems with accuracy. If we need more accuracy you can use .toFixed(n) to save decimal places. For example we could do this to save a single decimal place when needed:

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

Fiddle Example of percentile with decimals

Fiddle Example of percentile with integers

How to show slice value inside of slice in pie chart using chart.js

This answers the issue contained in the question's title:

How to show slice value inside of slice in pie chart using chart.js

The code snippet below show how to display the values inside the slices with the use of chartjs-plugin-labels. The code of the samples was extracted from the chartjs-plugin-labels demo page.

var canvas = document.getElementById('myChart');new Chart(canvas, {    type: 'pie',        data: {      labels: ['January', 'February', 'March'],      datasets: [{        data: [50445, 33655, 15900],        backgroundColor: ['#FF6384', '#36A2EB','#FFCE56']      }]    },    options: {      responsive: true,      maintainAspectRatio: true,      plugins: {        labels: {          render: 'value',          fontColor: ['green', 'white', 'red']        }      }    }});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.min.js"></script><script src="https://cdn.jsdelivr.net/gh/emn178/chartjs-plugin-labels/src/chartjs-plugin-labels.js"></script><canvas id="myChart"></canvas>

How add the sizes of the slices in the pie chart (at the top) in Chart.js?

I found the answer. My project is written in CoffeeScript, but I think it would be more useful for the StackOverflow community to post the code in JS.

options: {
legend: {
labels: {
generateLabels: function(chart) {
var data = chart.data;
if (data.labels.length && data.datasets.length) {
return data.labels.map(function(label, i) {
var meta = chart.getDatasetMeta(0);
var ds = data.datasets[0];
var arc = meta.data[i];
var custom = arc && arc.custom || {};
var getValueAtIndexOrDefault = Chart.helpers.getValueAtIndexOrDefault;
var arcOpts = chart.options.elements.arc;
var fill = custom.backgroundColor ? custom.backgroundColor : getValueAtIndexOrDefault(ds.backgroundColor, i, arcOpts.backgroundColor);
var stroke = custom.borderColor ? custom.borderColor : getValueAtIndexOrDefault(ds.borderColor, i, arcOpts.borderColor);
var bw = custom.borderWidth ? custom.borderWidth : getValueAtIndexOrDefault(ds.borderWidth, i, arcOpts.borderWidth);
var value = chart.config.data.datasets[arc._datasetIndex].data[arc._index];

return {
text: label + ": " + value,
fillStyle: fill,
strokeStyle: stroke,
lineWidth: bw,
hidden: isNaN(ds.data[i]) || meta.data[i].hidden,
index: i
};
});
} else {
return [];
}
}
}
}
}

Show values in Chart.js Pie chart parts

Yes, this is possible. You can achieve that using a Chart.js plugin called - Chart.PieceLabel.js.

Here is a basic example :

var chart = new Chart(ctx, {   type: 'pie',   data: {      labels: ['Jan', 'Feb', 'Mar'],      datasets: [{         data: [30, 40, 25],         backgroundColor: 'rgba(0,119, 220, 0.2)'      }]   },   options: {      pieceLabel: {         render: 'value' //show values      }   }});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.0/Chart.min.js"></script><script src="https://cdn.rawgit.com/emn178/Chart.PieceLabel.js/master/build/Chart.PieceLabel.min.js"></script>
<canvas id="ctx"></canvas>

Displaying pie chart data value of each slices using react-chartjs-2

You can use this ChartJS Plugin - Chart.PieceLabel.js

first, install it via npm :

npm install chart.piecelabel.js --save

then, import it in your component :

import 'chart.piecelabel.js';

and finally, add the following in your chart options :

pieceLabel: {
render: 'value'
}

note: this is the minimum option needed to be set to display the value and you can find more options here.

ChartJS: datalabels: show percentage value in Pie piece

Updated fiddle with 2 decimal precision.

You were not computing the sum, instead storing the current value in sum only for every value.

Here is the working fiddle : https://jsfiddle.net/a1Lvn4eb/55/

var data = [{
data: [50, 55, 60, 33],
labels: ["India", "China", "US", "Canada"],
backgroundColor: [
"#4b77a9",
"#5f255f",
"#d21243",
"#B27200"
],
borderColor: "#fff"
}];

var options = {
tooltips: {
enabled: false
},
plugins: {
datalabels: {
formatter: (value, ctx) => {
let sum = 0;
let dataArr = ctx.chart.data.datasets[0].data;
dataArr.map(data => {
sum += data;
});
let percentage = (value*100 / sum).toFixed(2)+"%";
return percentage;
},
color: '#fff',
}
}
};

var ctx = document.getElementById("pie-chart").getContext('2d');
var myChart = new Chart(ctx, {
type: 'pie',
data: {
datasets: data
},
options: options
});

How to display data values on Chart.js

There is an official plugin for Chart.js 2.7.0+ to do this: Datalabels

Otherwise, you can loop through the points / bars onAnimationComplete and display the values


Preview

Sample Image


HTML

<canvas id="myChart1" height="300" width="500"></canvas>
<canvas id="myChart2" height="300" width="500"></canvas>

Script

var chartData = {
labels: ["January", "February", "March", "April", "May", "June"],
datasets: [
{
fillColor: "#79D1CF",
strokeColor: "#79D1CF",
data: [60, 80, 81, 56, 55, 40]
}
]
};

var ctx = document.getElementById("myChart1").getContext("2d");
var myLine = new Chart(ctx).Line(chartData, {
showTooltips: false,
onAnimationComplete: function () {

var ctx = this.chart.ctx;
ctx.font = this.scale.font;
ctx.fillStyle = this.scale.textColor
ctx.textAlign = "center";
ctx.textBaseline = "bottom";

this.datasets.forEach(function (dataset) {
dataset.points.forEach(function (points) {
ctx.fillText(points.value, points.x, points.y - 10);
});
})
}
});

var ctx = document.getElementById("myChart2").getContext("2d");
var myBar = new Chart(ctx).Bar(chartData, {
showTooltips: false,
onAnimationComplete: function () {

var ctx = this.chart.ctx;
ctx.font = this.scale.font;
ctx.fillStyle = this.scale.textColor
ctx.textAlign = "center";
ctx.textBaseline = "bottom";

this.datasets.forEach(function (dataset) {
dataset.bars.forEach(function (bar) {
ctx.fillText(bar.value, bar.x, bar.y - 5);
});
})
}
});

Fiddle - http://jsfiddle.net/uh9vw0ao/



Related Topics



Leave a reply



Submit