开发者问题收集

如何在不中断其正常工作的情况下触发 ChartJS 图例 onClick

2021-05-19
4084

当 chart.js 饼图 (v2.5.0) 中的图例被点击时,我想记录被点击的是哪个图例。为此,我向图例添加了一个 onClick 函数,并在其中调用默认函数 Chart.defaults.global.legend.onClick。但它出错了,图表没有更新。

这是我使用的配置

"legend": {
    "position": "top",
    "onClick": function(e,l){
            console.log("l.text");
            Chart.defaults.global.legend.onClick.call(this, e, l);
    }
}

单击图例时出现此错误

未捕获的 TypeError:无法读取未定义的属性“_meta”

也试过了。它也没有用。

var original = Chart.defaults.global.legend.onClick;
Chart.defaults.global.legend.onClick = function(e, legendItem) {
  /* do custom stuff here */
  original.call(this, e, legendItem);
};
2个回答

看起来文档中的例子几乎是错误的,好像他们没有提供图表,这就是它失败的原因,如果你自己提供图表并编写完整的 onclick 它确实有效

示例:

const defaultLegendClickHandler = Chart.defaults.global.legend.onClick;
var newLegendClickHandler = function(e, legendItem) {
  alert(legendItem.text)
  const index = legendItem.index;


  const {
    type
  } = chart.config;
  if (type === 'pie' || type === 'doughnut') {
    // Pie and doughnut charts only have a single dataset and visibility is per item
    for (i = 0, ilen = (chart.data.datasets || []).length; i < ilen; ++i) {
      meta = chart.getDatasetMeta(i);
      // toggle visibility of index if exists
      if (meta.data[index]) {
        meta.data[index].hidden = !meta.data[index].hidden;
      }
    }
  } else {
    const index = legendItem.datasetIndex;
    const ci = this.chart;
    const meta = ci.getDatasetMeta(index);

    // See controller.isDatasetVisible comment
    meta.hidden = meta.hidden === null ? !ci.data.datasets[index].hidden : null;

    // We hid a dataset ... rerender the chart
    ci.update();
  }
  chart.update();

};

const options = {
  type: 'pie',
  data: {
    labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
    datasets: [{
      label: '# of Votes',
      data: [12, 19, 3, 5, 2, 3],
      borderWidth: 1
    }, {
      label: '# of Votes2',
      data: [12, 19, 3, 5, 2, 3],
      borderWidth: 1
    }, {
      label: '# of Votes3',
      data: [12, 19, 3, 5, 2, 3],
      borderWidth: 1
    }, {
      label: '# of Votes4',
      data: [12, 19, 3, 5, 2, 3],
      borderWidth: 1
    }]
  },
  options: {
    legend: {
      onClick: newLegendClickHandler
    }

  }
}

const ctx = document.getElementById('chartJSContainer').getContext('2d');
const chart = new Chart(ctx, options);
<body>
  <canvas id="chartJSContainer" width="600" height="400"></canvas>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.4/Chart.js"></script>
</body>
LeeLenalee
2021-05-19

您可以通过以下行更新图例来在单击时更新图例。

@ViewChild('barChart') barChart: BaseChartDirective;

legend: {
    labels: {
    onClick: (event, barLegendItem, legend) => {
      const datasetIndex = barLegendItem.datasetIndex;
      const scatterDataset = this.barChartData.datasets[datasetIndex - this.noOfInnings];
      const barDataset = this.barChartData.datasets[datasetIndex];
      scatterDataset.hidden = !scatterDataset.hidden;
      barDataset.hidden = !barDataset.hidden;
      legend.chart.update(this.barChart);
    }
  }

HTML :
canvas id="chart1" class="w-100 h-100" baseChart
            #barChart
            [data]="barChartData"
            [options]="barChartOptions"
            [plugins]="barChartPlugins"
            [legend]="barChartLegend">
    </canvas>
Isuru Munasinghe
2023-11-17