1👍
✅
Yes, it is possible.
- There might be already a plugin, that can achieve this (but I don’t know any, but I didn’t really look), so you could look for one,
- Or you could simply write your own plugin, with a few lines of code
Here a demo, how I would do this, with an inline plugin:
(three charts with 3 different percentages)
var arrowPlugin = {
id: 'arrowPlugin',
afterDraw: (chart, args, options) => {
const { ctx } = chart;
let midX = chart.width / 2;
let midY = chart.height;
let arrowLength = chart.height / 2;
let text = `${options.value * 100}%`;
let textSize = ctx.measureText(text);
ctx.save();
ctx.save();
ctx.translate(midX, midY);
ctx.rotate( (Math.PI * options.value) - Math.PI /2);
ctx.strokeStyle = options.arrowColor;
ctx.fillStyle = options.arrowColor;
ctx.lineCap = 'butt';
ctx.lineWidth = 3;
ctx.beginPath();
ctx.moveTo(0, - arrowLength * 3 / 4 + 3)
ctx.lineTo(0, - arrowLength * 6 / 4);
ctx.stroke();
ctx.beginPath();
ctx.moveTo(0, - arrowLength * 6 / 4 - 4)
ctx.lineTo(5, - arrowLength * 6 / 4 + 10)
ctx.lineTo(-5, - arrowLength * 6 / 4 + 10)
ctx.closePath();
ctx.fill()
ctx.fillStyle = options.triangleColor;
ctx.beginPath();
ctx.moveTo(0, -midY + 25)
ctx.lineTo(-10, -midY + 10)
ctx.lineTo(10, -midY + 10)
ctx.closePath()
ctx.fill();
ctx.restore();
ctx.fillStyle = options.textColor;
ctx.font = "50px Arial";
ctx.fillText(text, midX - textSize.width * 1.5, midY - 25);
ctx.restore();
},
defaults: {
// set here the percentage
value:.50,
arrowColor: 'black',
textColor: 'black',
triangleColor: 'black'
}
}
var options1 = {
type: 'doughnut',
data: {
datasets: [{
data: [20, 50, 30],
backgroundColor: [
'rgba(231, 76, 60, 1)',
'rgba(255, 164, 46, 1)',
'rgba(46, 204, 113, 1)'
],
borderColor: [
'rgba(255, 255, 255 ,1)',
'rgba(255, 255, 255 ,1)',
'rgba(255, 255, 255 ,1)'
],
borderWidth: 0
}]},
options: {
cutout: 33,
rotation: -90,
circumference: 180,
maintainAspectRatio: false,
legend: { display: false },
plugins:{
tooltip: { enabled: false },
}
},
plugins:[arrowPlugin]
}
var options2 = {
type: 'doughnut',
data: {
datasets: [{
data: [20, 50, 30],
backgroundColor: [
'rgba(231, 76, 60, 1)',
'rgba(255, 164, 46, 1)',
'rgba(46, 204, 113, 1)'
],
borderColor: [
'rgba(255, 255, 255 ,1)',
'rgba(255, 255, 255 ,1)',
'rgba(255, 255, 255 ,1)'
],
borderWidth: 0
}]},
options: {
cutout: 33,
rotation: -90,
circumference: 180,
maintainAspectRatio: false,
legend: { display: false },
plugins:{
tooltip: { enabled: false },
// override default percentage
arrowPlugin: { value: .20 }
}
},
plugins:[arrowPlugin]
}
var options3 = {
type: 'doughnut',
data: {
datasets: [{
data: [20, 50, 30],
backgroundColor: [
'rgba(231, 76, 60, 1)',
'rgba(255, 164, 46, 1)',
'rgba(46, 204, 113, 1)'
],
borderColor: [
'rgba(255, 255, 255 ,1)',
'rgba(255, 255, 255 ,1)',
'rgba(255, 255, 255 ,1)'
],
borderWidth: 0
}]},
options: {
cutout: 33,
rotation: -90,
circumference: 180,
maintainAspectRatio: false,
legend: { display: false },
plugins:{
tooltip: { enabled: false },
// override default percentage
arrowPlugin: { value: .70 }
}
},
plugins:[arrowPlugin]
}
const chart1 = document.getElementById('chart1')
new Chart(chart1, options1);
const chart2 = document.getElementById('chart2')
new Chart(chart2, options2);
const chart3 = document.getElementById('chart3')
new Chart(chart3, options3);
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<div style="width:500px;height:184px">
<canvas id="chart1" width="500" height="184"></canvas>
<canvas id="chart2" width="500" height="184"></canvas>
<canvas id="chart3" width="500" height="184"></canvas>
<div>
the percentage is currently set in the inline plugin-options, default value is set to .5 = 50% (valid range 0 – 1 = 0% – 100%).
Source:stackexchange.com