javascript - dc.js:dispose() 和 deregisterChart() 的问题

标签 javascript charts dispose dc.js crossfilter

我正在创建一个可以动态添加和删除图表的应用程序。一切正常,但删除图表。

当我有一个折线图和一个条形图(其中之一是复合图)并且我删除其中一个(处理维度并取消注册图表)时,就会出现我遇到的问题。此时,我尚未处理的图表停止对其他图表的过滤器使用react,并停止对其自身的事件使用react,即使其他图表已被它们过滤。另外,正如您在 fiddle 中看到的,我从 dc 中删除的折线图仍然对其他图表过滤器使用react。

我发现问题出在 deregisterChart dc 调用上,但由于我的应用程序可以创建和删除无限图表,我需要一种方法从 dc 中删除我不再需要的图表,而不会破坏留下的图表。

这是代码:

resetFilter = function() {
  lineData.dispose()
  dc.deregisterChart(linechart);
}


for (var j = 0; j < axis.length; j++) {

    var dimData = __cfArray[dataId].dimension(function(d) {
      return d[axis[j].xaxis];
    });
    var barGroup = getGroup(dimData, axis[j].xaxis, axis[j].yaxis, operation, isDate);

    barCharts.push(dc.barChart(composite)
      .valueAccessor(accesor)
      .dimension(dimData)
      .group(barGroup, xAxisTitle[j])
      .transitionDuration(1000)
      .gap(gap)
      .colors(barColors[j])
      .centerBar(function() {
        if (axis.length > 1) return false;
        else return true;
      })
      .title(function(d) {
        if (operation === count) {
          if (isDate) return format(d.key) + ": " + d.value.count;
          else return d.key + ": " + d.value.count;
        } else {
          if (isDate) return format(d.key) + ": " + d.value.total;
          else return d.key + ": " + d.value.total;
        }
      })
    );


    lineData = __cfArray[dataId].dimension(function(d) {
      return d[axis[j].xaxis];
    });
    var lineGroup = getGroupLine(lineData, axis[j].xaxis, axis[j].yaxis, true, operation, isDate);

    linechart = dc.lineChart(lineDom)
      .dimension(lineData)
      .group(lineGroup, xAxisTitle[j] + "/" + yAxisTitle)
      .useRightYAxis(true)
      .colors(lineColors[j])
      .title(function(d) {
        if (operation === count) {
          if (isDate) return format(d.key) + ": " + d.valueCount;
          else return d.key + ": " + d.valueCount;
        } else {
          if (isDate) return format(d.key) + ": " + d.valueTotal;
          else return d.key + ": " + d.valueTotal;
        }
      })
      .valueAccessor(function(p) {
        if (operation === count) {
          return p.valueCount;
        } else {
          return p.valueTotal;
        }
      });

  }

  var xMine;


  var dom = [];
  for (var i = 0; i < axis.length; i++) {
    if (dom.length === 0) {
      dom = __dataArray[dataId].map(function(d) {
        return d[axis[i].xaxis]
      });
    } else {
      dom = dom.concat(__dataArray[dataId].map(function(d) {
        return d[axis[i].xaxis]
      }));
    }
  }
  if (isNaN(dom[0])) {
    xMine = d3.scale.ordinal().domain(dom.sort());
  } else {
    xMine = d3.scale.ordinal().domain(dom.sort(function(a, b) {
      return a - b;
    }));
  }
  composite.xUnits(dc.units.ordinal)
  linechart.xUnits(dc.units.ordinal)


  linechart.width(width)
    .height(height)
    .margins(margin)
    .x(xMine)
    .elasticY(true)
    .legend(dc.legend().x(80).y(10).itemHeight(13).gap(5))
    ._rangeBandPadding(1)
    .brushOn(false);

  composite.width(width)
    .height(height)
    .margins(margin)
    .x(xMine)
    .rightYAxisLabel(yAxisRightTitle)
    .elasticY(true)
    .legend(dc.legend().x(80).y(10).itemHeight(13).gap(5))
    ._rangeBandPadding(1)
    .brushOn(false)
    .shareTitle(false)
    .mouseZoomable(true)
    .yAxisPadding('10%')
    .compose(barCharts)
    .renderHorizontalGridLines(true);

  composite.yAxis().tickFormat(d3.format('s'));
  composite.rightYAxis().tickFormat(d3.format('s'));

  composite.render();

  linechart.render();

这是我根据问题创建的 fiddle : https://jsfiddle.net/nofknndf/9/

谢谢!

最佳答案

恭喜您,这是一个复杂而精密的系统。

我承认我没有弄清楚为什么你会看到当前的奇怪行为,但我确实发现了问题,并且我想我已经解决了它。

getGroupLine 中,每次调用 fake-group .all() 方法时,您实际上都会创建一个组:

    function getGroupLine(dimension, xaxis, yaxis, isCum, operation, isDate){
        return {
            all:function () {
        // ...
                var _group = dimension.group().reduce(reduceAdd, reduceRemove, reduceInitial).orderNatural();

这很快就会让人感到困惑!我通过在调试器中单步执行 dimension.dispose() 来查看它是否正常工作,从而发现了这一点 - 每次运行时都会有越来越多的组。

组存储在维度中,并且可以独立处理。

您希望在调用函数时创建“基本组”_group,并且返回的假组将仅获取_group.all():

    function getGroupLine(dimension, xaxis, yaxis, isCum, operation, isDate){
        var reduceAdd = function(p, v) {
            if (!(isDate && v[xaxis] === 0 )) {
                ++p.count;
                p.total += v[yaxis];
            }
            return p;
        }

        var reduceRemove = function(p, v) {
            if (!(isDate && v[xaxis] === 0 )) {
                --p.count;
                p.total -= v[yaxis];
            }
            return p;
        }

        var reduceInitial = function() {
            return {
                count: 0, 
                total: 0,
                elements: []
            };
        }
        var _group = dimension.group().reduce(reduceAdd, reduceRemove, reduceInitial).orderNatural();
        return {
            all:function () {
                var totalCount = 0;
                var total = 0;
                var g = [];


                _group.all().forEach(function(d,i) {
                    if(isCum){
                        totalCount += d.value.count;
                        total += d.value.total;
                    } else {
                        totalCount = d.value.count;
                        total = d.value.total;
                    }
                    g.push({key:d.key,valueTotal:total,valueCount:totalCount})
                });
                return g;
            }
        }; 
    }

这似乎可以解释为什么折线图继续被过滤。

另一个问题是错误的图表被注销。这是因为您的每个图表都需要有自己唯一的 anchor (id) - 在您的示例中,它们都被命名为“composite”。 dc.js 在取消注册时依赖于比较 anchor 名称,因此如果两个图表具有相同的 id,则错误的图表将被删除。 HTML 要求 id 是唯一的,因此您可能会遇到其他问题。

将折线图的 id 重命名为“line”可修复取消注册问题。

在这里更新了你的 fiddle 分支:https://jsfiddle.net/dnrxxjyo/4/

关于javascript - dc.js:dispose() 和 deregisterChart() 的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39829773/

相关文章:

java - SWT JFace如何在moveBelow()后重绘

javascript - 如何在 JavaScript 条件语句中添加 CSS 'left' 属性?

c# - "Dispose"是否处理设置为同一对象的类的每个实例?

javascript - Angularjs 检查范围内的所有内容

c# - DataVisualization.Chart 的图形和工具提示的样式化

google-maps - 刚刚开始出现的 MissingKeyMapError 与 Google Charts + displayMode = text

javascript - 访问 D3 多线图表上工具提示中的数据

c# - 如何正确处理元素?为什么代码分析不断改变主意?

javascript - 带有jQuery的音频html5播放下一首轨道

javascript - 如何以 24 小时格式比较 2 个时间,以检查 1 个时间是否早于另一个时间