I want to ask if there is a way to make Pie Chart As Circle Progress with percent value, I want just one slice colored something like this:
This is my fiddle for now I want just one data.
HTML:
<canvas id="chartProgress" width="300px" height="200"></canvas>
JS:
var chartProgress = document.getElementById("chartProgress");
if (chartProgress) {
var myChartCircle = new Chart(chartProgress, {
type: 'doughnut',
data: {
labels: ["Africa", 'null'],
datasets: [{
label: "Population (millions)",
backgroundColor: ["#5283ff"],
data: [68, 48]
}]
},
plugins: [{
beforeDraw: function(chart) {
var width = chart.chart.width,
height = chart.chart.height,
ctx = chart.chart.ctx;
ctx.restore();
var fontSize = (height / 150).toFixed(2);
ctx.font = fontSize + "em sans-serif";
ctx.fillStyle = "#9b9b9b";
ctx.textBaseline = "middle";
var text = "68%",
textX = Math.round((width - ctx.measureText(text).width) / 2),
textY = height / 2;
ctx.fillText(text, textX, textY);
ctx.save();
}
}],
options: {
legend: {
display: false,
},
responsive: true,
maintainAspectRatio: false,
cutoutPercentage: 85
}
});
}
I know I can do it with normal HTML&CSS or using simple plugin but I want to do it using Chart.js
I want to ask if there is a way to make Pie Chart As Circle Progress with percent value, I want just one slice colored something like this:
This is my fiddle for now I want just one data.
HTML:
<canvas id="chartProgress" width="300px" height="200"></canvas>
JS:
var chartProgress = document.getElementById("chartProgress");
if (chartProgress) {
var myChartCircle = new Chart(chartProgress, {
type: 'doughnut',
data: {
labels: ["Africa", 'null'],
datasets: [{
label: "Population (millions)",
backgroundColor: ["#5283ff"],
data: [68, 48]
}]
},
plugins: [{
beforeDraw: function(chart) {
var width = chart.chart.width,
height = chart.chart.height,
ctx = chart.chart.ctx;
ctx.restore();
var fontSize = (height / 150).toFixed(2);
ctx.font = fontSize + "em sans-serif";
ctx.fillStyle = "#9b9b9b";
ctx.textBaseline = "middle";
var text = "68%",
textX = Math.round((width - ctx.measureText(text).width) / 2),
textY = height / 2;
ctx.fillText(text, textX, textY);
ctx.save();
}
}],
options: {
legend: {
display: false,
},
responsive: true,
maintainAspectRatio: false,
cutoutPercentage: 85
}
});
}
I know I can do it with normal HTML&CSS or using simple plugin but I want to do it using Chart.js
Share Improve this question edited Feb 8, 2019 at 9:48 Cœur 38.7k26 gold badges202 silver badges277 bronze badges asked Apr 25, 2018 at 10:09 Aymen bzAymen bz 3881 gold badge5 silver badges12 bronze badges 2- off the top of my head, you could probably get the required effect by putting a dummy value (like 68 - 32). But it may be difficult to get the text in the middle without some custom code or customisation – Chirag Ravindra Commented Apr 25, 2018 at 10:31
- What amazing approach. I never thinked before use ChartJS to create a Circular Progressbar. It comes already with animation and no problems about the size of the canvas, it will be rendered correctly. – Bruno Freire Commented Sep 16, 2021 at 0:36
1 Answer
Reset to default 16The Plugin Core API offers different hooks that may be used for executing custom code. You already use the beforeDraw
hook to draw text in the middle of the doughnut.
You could now also use the beforeInit
hook to modify the chart configuration in order to fit your needs:
beforeInit: (chart) => {
const dataset = chart.data.datasets[0];
chart.data.labels = [dataset.label];
dataset.data = [dataset.percent, 100 - dataset.percent];
}
Given this code, the definition of your dataset
would look simple as follows:
{
label: 'Africa / Population (millions)',
percent: 68,
backgroundColor: ['#5283ff']
}
Last you have to define a tooltips.filter
, so that the tooltip appears only at the relevant segment.
tooltips: {
filter: tooltipItem => tooltipItem.index == 0
}
Please take a look at your amended code and see how it works.
var myChartCircle = new Chart('chartProgress', {
type: 'doughnut',
data: {
datasets: [{
label: 'Africa / Population (millions)',
percent: 68,
backgroundColor: ['#5283ff']
}]
},
plugins: [{
beforeInit: (chart) => {
const dataset = chart.data.datasets[0];
chart.data.labels = [dataset.label];
dataset.data = [dataset.percent, 100 - dataset.percent];
}
},
{
beforeDraw: (chart) => {
var width = chart.chart.width,
height = chart.chart.height,
ctx = chart.chart.ctx;
ctx.restore();
var fontSize = (height / 150).toFixed(2);
ctx.font = fontSize + "em sans-serif";
ctx.fillStyle = "#9b9b9b";
ctx.textBaseline = "middle";
var text = chart.data.datasets[0].percent + "%",
textX = Math.round((width - ctx.measureText(text).width) / 2),
textY = height / 2;
ctx.fillText(text, textX, textY);
ctx.save();
}
}
],
options: {
maintainAspectRatio: false,
cutoutPercentage: 85,
rotation: Math.PI / 2,
legend: {
display: false,
},
tooltips: {
filter: tooltipItem => tooltipItem.index == 0
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.min.js"></script>
<canvas id="chartProgress"></canvas>