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

Problems hovering over ChartJS bar chart after being redrawn

我将 ChartJS 与 KnockoutJS 一起使用,但在对我的一个条形图进行排序时遇到了一些问题。

举个例子:http://jsfiddle.net/norbiu/aqa8w19d/

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

我做错了什么吗?

这是我的更新函数:

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;
}

已更新 fiddle:http://jsfiddle.net/aqa8w19d/3/