开发者问题收集

自定义图例 Chart.js / Angular 5 上的 OnClick 事件

2018-01-03
2558

我正在使用 Angular 5 和 Chart.js 开展一个项目。 我需要在我的图表中创建自定义图例,因此我关注这个 git 问题以获得一些帮助: Github Issue Chart.js

它非常有用,并且它仅在使用纯 javascript 时才按预期工作,但尝试将示例回复到 Angular 5 App 中不起作用,它抛出了 this.updateDataset() 不是函数 。 这是我目前正在 Chart.js 库的 options 对象 中执行的操作的片段:

legendCallback: (chart) => {
        const legendHtml = [];
        legendHtml.push('<table>');
        legendHtml.push('<tr>');
        for (let i=0; i<chart.data.datasets.length; i++) {
            const color    = chart.data.datasets[i].borderColor;
            const legendId = 'linear-d'+i;
            legendHtml.push(
                '<td onclick="this.updateDataset(event,' + '\'' + chart.legend.legendItems[i].datasetIndex + '\'' + ', ' + '\'' + legendId + '\'' + ')">' +
                '<div id="'+legendId+'-square" style="background-color:' + color +'; border: 2px solid ' + color +'; width: 15px; height: 15px;"></div>' +
                '</td>'
            );
            if (chart.data.datasets[i].label) {
                legendHtml.push('<td id="'+legendId+'-text" style="cursor: default; font-size: 12px;" onclick="this.updateDataset(event,' + '\'' + chart.legend.legendItems[i].datasetIndex + '\'' + ', ' + '\'' + legendId + '\'' + ')">' + chart.data.datasets[i].label + '</td>');
            }
        }
        legendHtml.push('</tr>');
        legendHtml.push('</table>');
        return legendHtml.join("");
    },

因此,重要的部分是这个 '<td onclick="this.updateDataset(event,' + '\'' + chart.legend.legendItems[i].datasetIndex + '\'' + ', ' + '\'' + legendId + '\'' + ')">' ,其中 onclick 试图调用 this.updateDataset()

我应该如何将函数 updateDataset() 调用到元素的 onclick 事件或者我应该如何声明该函数以便我可以从 onclick 事件访问它。

1个回答

这不是一个完美的解决方案,但这是我目前找到的唯一解决方案。 我没有使用 onclick 事件,而是在添加新图例后添加了一个 eventListener 。然后,您需要对 updateDataset() 函数进行微小更改。

legendCallback 应如下所示:

legendCallback: (chart) => {
      var legendHtml = [];
      legendHtml.push('<table>');
      legendHtml.push('<tr>');
      for (var i=0; i<chart.data.datasets.length; i++) {
          legendHtml.push('<td><div class="chart-legend" style="background-color:' + chart.data.datasets[i].backgroundColor + '"></div></td>');                    
          if (chart.data.datasets[i].label) {
              legendHtml.push('<td class="chart-legend-label-text" id="' + chart.id + '_' + chart.legend.legendItems[i].datasetIndex + '">' + chart.data.datasets[i].label + '</td>');
          }
      }                                                                                  
      legendHtml.push('</tr>');                                                          
      legendHtml.push('</table>');
      return legendHtml.join("");                                                        
    },

然后在声明 Chart 后添加监听器和 updateDataset() 函数:

document.getElementById("customLegend" + this.chartId).innerHTML = myChart.generateLegend();
var legenTags = document.getElementsByClassName("chart-legend-label-text");
var updateDataset = function(e) {
  var id = e.currentTarget.id;
  var index = id.split('_')[1];
  var chartId= id.split('_')[0];
  if (myChart.id == chartId) {
    var meta = myChart.getDatasetMeta(index);
    // See controller.isDatasetVisible comment
    meta.hidden = meta.hidden === null? !myChart.data.datasets[index].hidden : null;

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

for (var i = 0; i < legenTags.length; i++) {
  legenTags[i].addEventListener('click', updateDataset, false);
}

希望对您有所帮助。 如果有人有更好的解决方案,请分享。

Bredock Stark
2018-03-22