I am rendering a series of Doughtnut charts with center text rendered via plugin.
While initial render is working as expected, when I implement a client side search and hence re-render the series of doughnuts, the plugin pulls in irrelevant dataset and hence renders the wrong Center text.
Note: Doughnut still renders correctly after searching. It's the Center Text that is causing the issue.
What I tried: I changed the plugin methods (from beforeDatasetsDraw) to other plugin methods, hoping that the render lifecycle could be the issue. But no luck there.
Refer images for better clarity.
What am I missing ?
DoughNut:
<>
{props.microservices &&
Array.isArray(props.microservices) &&
props.microservices.map((e) => (
<>
<p>{e?.serviceInfo?.name}</p>
<DoughnutChart
containerClassName="h-[75px] flex justify-center"
data={{
datasets: [
{
data: [Math.round(e.cpu), 100 - Math.round(e.cpu)],
weight: 3,
backgroundColor:
Math.round(e.cpu) === 0
? ["transparent", "transparent"]
: ["#BB723F", "#21262D"],
borderColor: "#232323",
borderWidth: 0,
},
{
weight: 3,
data: [100],
borderColor: "#232323",
borderWidth: 0,
backgroundColor:
Math.round(e.cpu) === 0 || Math.round(e.memory) === 0
? ["transparent"]
: ["#29292A"],
},
{
data: [Math.round(e.memory), 100 - Math.round(e.memory)],
weight: 3,
borderColor: "#232323",
borderWidth: 0,
backgroundColor:
Math.round(e.memory) === 0
? ["transparent", "transparent"]
: ["#31737B", "transparent"],
},
],
}}
options={{
responsive: true,
cutout: "80%",
plugins: {
tooltip: {
enabled: false,
},
datalabels: {
display: false,
},
},
}}
plugins={[
centerText({
text: e.serviceInfo?.name,
fillColor:
Math.round(e.cpu) === 0 || Math.round(e.memory) === 0
? "#3E4249"
: "#0C1117",
arcX: props.isPopUp ? 30 : 34,
arcY: 38,
arcRadius: props.isPopUp ? 24 : 27,
arcStart: 0,
arcEnd: 2 * Math.PI,
activePods: e.serviceInfo?.activePods,
totalPods: 16,
isDisabledDoughNut:
Math.round(e.cpu) === 0 || Math.round(e.memory) === 0,
}),
]}
isDisabledDoughNut={
Math.round(e.cpu) === 0 || Math.round(e.memory) === 0
}
onClickHandler={(_) => {
const {
cpu,
memory,
traffic,
errorRate,
serviceInfo: { instance, activePods },
} = e;
props.setOverLayData({
cpu,
memory,
traffic,
errorRate,
activePods,
totalPods: 99,
title: instance?.split("-").join(" "),
});
props.op.current?.toggle(_);
}}
/>
</>
))}
</>
Center Text Plugin:
const centerText = ({
text = "HELLO WORLD",
fillColor = "#F86E6E",
textColor = "#fff",
arcX = 220,
arcY = 230,
arcRadius = 200,
arcStart = 0,
arcEnd = 2 * Math.PI,
isDisabledDoughNut = false,
activePods = 0,
totalPods = 0,
}) => ({
id: "centerText",
beforeDatasetsDraw(chart) {
let warningIcon;
if (isDisabledDoughNut) {
warningIcon = new Image();
warningIcon.src = `data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMS41ODIiIGhlaWdodD0iMTAiIHZpZXdCb3g9IjAgMCAxMS41ODIgMTAiPgogIDxwYXRoIGlkPSJ3YXJuaW5nX0ZJTEwxX3dnaHQzMDBfR1JBRDBfb3BzejI0IiBkPSJNNzQuNjE4LTgzMGw1Ljc5MS0xMEw4Ni4yLTgzMFptNS43OTEtMS41MzlhLjQ0Ni40NDYsMCwwLDAsLjMyOS0uMTMzLjQ0Ni40NDYsMCwwLDAsLjEzMy0uMzI5LjQ0Ny40NDcsMCwwLDAtLjEzMy0uMzI5LjQ0Ny40NDcsMCwwLDAtLjMyOS0uMTMzLjQ0Ny40NDcsMCwwLDAtLjMyOS4xMzMuNDQ3LjQ0NywwLDAsMC0uMTMzLjMyOS40NDYuNDQ2LDAsMCwwLC4xMzMuMzI5QS40NDYuNDQ2LDAsMCwwLDgwLjQwOS04MzEuNTM2Wm0tLjQyOS0xLjQ5NGguODU3di0yLjg1N2gtLjg1N1oiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC03NC42MTggODM5Ljk5NykiIGZpbGw9IiNmYmZiZmMiLz4KPC9zdmc+Cg==`;
}
const { ctx } = chart;
ctx.save();
const x = chart.getDatasetMeta(0).data[0].x;
const y = chart.getDatasetMeta(0).data[0].y;
ctx.beginPath();
ctx.arc(arcX, arcY, arcRadius, arcStart, arcEnd);
ctx.fillStyle = fillColor;
ctx.fill();
ctx.stroke();
ctx.textAlign = "center";
ctx.textBaseline = "middle";
ctx.font = "12px Helvetica";
ctx.fillStyle = textColor;
ctx.fillText(text, x - 1, y - 5);
if (!isDisabledDoughNut) {
ctx.font = "8px Helvetica";
ctx.fillText(`${activePods}/${totalPods}`, x, y + 10);
}
if (isDisabledDoughNut && warningIcon.complete) {
ctx.drawImage(warningIcon, x - 5, y + 5, 10, 10);
}
},
});


For those arriving at this question in the future, adding the following to the chart component resolved my issue.
redraw={true}