Home > Blockchain >  Labels shrink my PieChart size in react-chartjs
Labels shrink my PieChart size in react-chartjs

Time:08-10

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?

enter image description here

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:

  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

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>

  • Related