Chartjs-Labels shrink my PieChart size in react-chartjs

1👍

Since the chart is limited to the size of the canvas you have 3 options:

  1. Limit the amount of legend items shown with the filter callback
  2. Make the canvas bigger so the chart has more space to render everything depending on the labels
  3. Disable the legend so it will always render the same size

0👍

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/chart.js@3.9.1/dist/chart.min.js"></script>
<html>
  <body>
    <div class="myChartDiv">
      <canvas id="myChart" width="600" height="400"/>
    </div>
  </body>
</html>

Leave a comment