I'm trying to create a line in Canvas. Everything was going well until I got stuck on this part:
import { Doughnut } from "react-chartjs-2";
import "chart.js/auto";
import { Chart, ChartData, ChartDataset, ChartOptions } from "chart.js";
function DoughnutChart(){
const doughnutLabelsLine = {
id: "doughnutLabelsLine",
afterDraw(chart: Chart<"doughnut">, args: any, options: ChartOptions) {
const {
ctx,
chartArea: { top, bottom, left, right, width, height },
} = chart;
chart.data.datasets.forEach((dataset, i) => {
// console.log(chart.getDatasetMeta(i));
chart.getDatasetMeta(i).data.forEach((datapoint, index) => {
console.log(dataset);
const { x, y } = datapoint.tooltipPosition();
//Object is possibly undefined
ctx.fillStyle = dataset?.borderColor[index];
ctx.fillRect(x, y, 2, 2);
});
});
},
};
//config...
//dataDoughnut
return (
<div className="col-span-6">
<Doughnut
data={dataDoughnut}
options={config}
width={200}
height={300}
plugins={[doughnutLabelsLine]}
/>
</div>
);
}
export default DoughnutChart;
I have tried putting it into an if statement as well and using an exclamation mark, but that didn't work. Am I missing something here?
Edit: Made an adjustment based on user2057925's suggestion
DoughnutLabelsLine
const doughnutLabelsLine = {
id: "doughnutLabelsLine",
afterDraw(chart: Chart<"doughnut">, args: any, options: ChartOptions) {
const {
ctx,
chartArea: { top, bottom, left, right, width, height },
} = chart;
chart.data.datasets.forEach((dataset, i) => {
// console.log(chart.getDatasetMeta(i));
chart.getDatasetMeta(i).data.forEach((datapoint, index) => {
console.log(dataset);
const { x, y } = datapoint.tooltipPosition();
ctx.save();
const borderColor = datapoint.options.borderColor as
| string
| CanvasGradient
| CanvasPattern;
ctx.fillStyle = borderColor;
// ctx.fillStyle = dataset?.borderColor[index];
ctx.fillRect(x, y, 10, 10);
ctx.restore();
});
});
},
};
I think the undefined
error is not related to the dataset
instance but due to the borderColor
one.
Anyway the best thing could be to use the datapoint.options.borderColor
because:
ArcElement
, provides in options
node all its options, even if they are configured (using default).const p = {
id: "doughnutLabelsLine",
afterDraw(chart, args, options) {
chart.data.datasets.forEach((dataset, i) => {
chart.getDatasetMeta(i).data.forEach((datapoint, index) => {
const { x, y } = datapoint.tooltipPosition();
ctx.save();
ctx.fillStyle = datapoint.options.borderColor;
ctx.fillRect(x -5, y - 5, 10, 10);
ctx.restore();
});
});
}
};
const config = {
type: 'doughnut',
plugins: [p],
data: {
labels: [6, 6, 4, 3, 2, 2, 1],
datasets: [{
label: 'Simple treemap',
data: [6, 6, 4, 3, 2, 2, 1],
borderColor: ['red', 'blue']
}]
},
};
const ctx = document.getElementById('myChart').getContext('2d');
new Chart(ctx, config);
.myChartDiv {
max-width: 600px;
max-height: 400px;
}
<html>
<head>
<script src="https://cdn.jsdelivr.net/npm/chart.js@3.9.1/dist/chart.min.js"></script>
</head>
<body>
<div class="myChartDiv">
<canvas id="myChart" width="600" height="400"/>
</div>
</body>
</html>