1👍
✅
There is no native ChartJS API for drawing an image inside a donut chart.
But you can manually add the images after the chart has been drawn.
For each wedge in the donut:
Warning: untested code … some tweaking might be required
-
Translate inward to the middle of the donut.
// calculate donut center (cx,cy) & translate to it var cx=chart.width/2; var cy=chart.height/2; context.translate(cx,cy);
-
Rotate to the mid-angle of the target donut-wedge
var startAngle = chart.segments[thisWedgeIndex].startAngle; var endAngle = chart.segments[thisWedgeIndex].endAngle; var midAngle = startAngle+(endAngle-startAngle)/2; // rotate by the midAngle context.rotate(midAngle);
-
Translate outward to the midpoint of the target donut-wedge:
// given the donut radius (innerRadius) and donut radius (radius) var midWedgeRadius=chart.innerRadius+(chart.radius-chart.innerRadius)/2; context.translate(midWedgeRadius,0);
-
Draw the image offset by half the image width & height:
// given the image width & height context.drawImage(theImage,-theImage.width/2,-theImage.height/2);
-
Clean up the transformations by resetting the transform matrix to default:
// undo translate & rotate context.setTransform(1,0,0,1,0,0);
1👍
In the new version use the following example, (it requires chartjs-plugin-labels
):
import React from 'react';
import { Doughnut } from 'react-chartjs-2';
import 'chartjs-plugin-labels';
const imageURLs = [
'https://avatars.githubusercontent.com/u/43679262?v=4',
'https://avatars.githubusercontent.com/u/43679262?v=4',
'https://avatars.githubusercontent.com/u/43679262?v=4',
];
const images = imageURLs.map((v) => {
var image = new Image();
image.src = v;
return image;
});
export const data_doughnut = {
labels: ['a', 'b', 'c'],
datasets: [
{
data: [30, 15, 10],
backgroundColor: [
'#B1A9FF',
'#877CF8',
'#6456F2',
],
weight: 1,
},
],
};
export const chartOptions = {
responsive: true,
plugins: {
legend: {
display: false,
},
},
scales: {
ticks: {
display: false,
},
},
};
export const plugins = [
{
afterDatasetsDraw: (chart) => {
var ctx = chart.ctx;
ctx.save();
var xCenter = chart.canvas.width / 2;
var yCenter = chart.canvas.height / 2;
var data = chart.config.data.datasets[0].data;
var vTotal = data.reduce((a, b) => a + b, 0);
data.forEach((v, i) => {
var vAngle =
data.slice(0, i).reduce((a, b) => a + b, 0) + v / 2;
var angle = (360 / vTotal) * vAngle - 90;
var radians = angle * (Math.PI / 180);
var r = yCenter;
// modify position
var x = xCenter + (Math.cos(radians) * r) / 1.4;
var y = yCenter + (Math.sin(radians) * r) / 1.4;
ctx.translate(x, y);
var image = images[i];
ctx.drawImage(image, -image.width / 2, -image.height / 2);
ctx.translate(-x, -y);
});
ctx.restore();
},
},
];
export function DoughnutChartFeekers() {
return (
<Doughnut
data={data_doughnut}
plugins={plugins}
options={chartOptions}
/>
);
}
Source:stackexchange.com