I'm using react-chartjs-2 (version 4.3.1 ). As you can see in image, even if I use same component, width & height aren't same anymore because of labels. I want to display like left side piechart even though there're many labels in right side. How can I solve that?
codes
<Pie
height={400}
data={{
labels: labels,
datasets: [
{
label: "Label 1",
data: data,
backgroundColor: [
palette.primary.main,
palette.utility.maroonRed,
palette.text.primary,
palette.primary.grey,
palette.secondary.dark,
palette.primary.subtle
],
},
],
}}
options={{
responsive: true,
maintainAspectRatio: false,
plugins: {
legend: {
display: true,
position: "bottom"
},
}
}}
/>
)
CodePudding user response:
Since the chart is limited to the size of the canvas you have 3 options:
- Limit the amount of legend items shown with the filter callback
- Make the canvas bigger so the chart has more space to render everything depending on the labels
- Disable the legend so it will always render the same size
CodePudding user response:
If acceptable for this use case, you could have only a subset of datasets in the legend (for instance top5) and all others in another "others" legend item.
const pieGenerateLabelsLegendHandler = Chart.controllers.doughnut.overrides.plugins.legend.labels.generateLabels;
const pieLegendClickHandler = Chart.controllers.doughnut.overrides.plugins.legend.onClick;
let others = [];
const chart = new Chart("myChart", {
type: 'pie',
data: {
labels: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
datasets: [{
data: [65, 1, 80, 80, 10, 55, 15, 20, 40, 50, 8, 40],
backgroundColor: ['#3366cc','#dc3912','#ff9900','#109618','#990099','#0099c6','#dd4477','#66aa00','#b82e2e','#316395','#994499','#22aa99'],
}],
},
options: {
plugins: {
legend: {
labels: {
generateLabels(chart) {
const labels = pieGenerateLabelsLegendHandler(chart);
const sorted = labels.sort((a, b) => chart.data.datasets[0].data[a.index] <= chart.data.datasets[0].data[b.index]);
const top5 = sorted.filter((el, index) => index <= 5);
others = sorted.filter((el, index) => index > 5);
top5.push({text: 'Others', hidden: others[0].hidden});
return top5;
}
},
onClick(e, legendItem, legend) {
if (legendItem.text === 'Others'){
const ci = legend.chart;
others.forEach(function(item) {
ci.toggleDataVisibility(item.index);
});
ci.update();
return;
}
pieLegendClickHandler(e, legendItem, legend);
}
}
}
}
});
.myChartDiv {
max-width: 600px;
max-height: 400px;
}
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/chart.min.js"></script>
<html>
<body>
<div >
<canvas id="myChart" width="600" height="400"/>
</div>
</body>
</html>