重绘后悬停在 ChartJS 条形图上的问题

Problems hovering over ChartJS bar chart after being redrawn

本文关键字:条形图 问题 ChartJS 悬停      更新时间:2023-09-26

我正在使用带有KnockoutJS的ChartJS,我在排序我的一个条形图时遇到了一些问题。

下面是一个示例:http://jsfiddle.net/norbiu/aqa8w19d/

点击顶部的排序按钮后,条形图会正确重绘,但是如果我尝试将鼠标悬停在图表的右侧,它会跳回条形的原始顺序。移除鼠标将使条形返回到整列顺序。

我做错了什么吗?

这是我的更新功能:

update: function (element, valueAccessor, allBindings, viewModel, bindingContext) {
  var ctx = element.getContext('2d'),
    type = ko.unwrap(valueAccessor()),
    data = ko.toJS(allBindings.get('chartData')),
    options = ko.unwrap(allBindings.get('chartOptions')) || {};
  if (chart) {
    chart.destroy();
    delete chart;
  }
  if (Object.keys(data).length != 0) {
    var chart = new Chart(ctx)[type](data, options);
  }
}

在创建新图表之前,应修改chartType绑定处理程序以明确以前创建的图表。否则,悬停在新图表的区域将干扰旧图表的区域。

ko.bindingHandlers.chartType = {
    init: function (element, valueAccessor, allBindings, viewModel, bindingContext) {
        if (!allBindings.has('chartData')) {
            throw Error('chartType must be used in conjunction with chartData and (optionally) chartOptions');
        }
    },
    update: function (element, valueAccessor, allBindings, viewModel, bindingContext) {
      var ctx = element.getContext('2d'),
        type = ko.unwrap(valueAccessor()),
        data = ko.toJS(allBindings.get('chartData')),
        options = ko.unwrap(allBindings.get('chartOptions')) || {};
      if (chart) {
        console.debug(chart)
        chart.destroy();
        delete chart;
      }
      if (Object.keys(data).length != 0) {
        // destroy old chart
        var self = ko.bindingHandlers.chartType;
        self.chart && self.chart.destroy();
        // create new
        var chart = new Chart(ctx)[type](data, options);
        self.chart = chart;
      }
    },
    chart: null
};

http://jsfiddle.net/aqa8w19d/1/

更新

是的,上面的处理程序将当前图表存储在其定义中,因此chartType绑定的所有实例共享相同的属性ko.bindingHandlers.chartType.chart。这个问题可以通过为每个绑定元素单独存储每个图表对象来解决(例如,作为元素用户属性<canvas>):

if (Object.keys(data).length != 0) {
    // destroy old chart
    element.chart && element.chart.destroy();
    // create new
    var chart = new Chart(ctx)[type](data, options);
    element.chart = chart;
}

更新的小提琴:http://jsfiddle.net/aqa8w19d/3/