简体   繁体   English

d3 v4 + react + es6 + crossfilter:Selection.exit()。remove()无法正常工作

[英]d3 v4 + react + es6 + crossfilter: Selection.exit().remove() not working

I'm using crossfilter.js and d3.js v4 with ES6 style React in an attempt to make dimensional charts with context brushing. 我正在使用带有ES6风格React的crossfilter.jsd3.js v4 ,以尝试使用上下文画笔制作尺寸图。 Essentially, I took this example and converted it to ES6. 本质上,我以这个示例为例 ,并将其转换为ES6。

The problem I have is selection.exit().remove() is not working such that on each redraw, more and more circles are appended to the svg g element. 我遇到的问题是selection.exit().remove()无法正常工作,因此在每次重绘时,越来越多的圆圈会附加到svg g元素上。 Redraws are triggered when a brush is created. 创建笔刷时会触发重画。 I checked by running 我通过跑步检查

selection.exit()
  .attr('class', d => {
    console.log('anything');
    return 'anything';
  })
  .remove();

but nothing was outputted so I'm thinking my data selection is not valid. 但没有输出任何内容,因此我认为我的数据选择无效。

Here is the context: 这里是上下文:

componentDidMount() {
  const el = ReactDOM.findDOMNode(this); // the mounted svg element

  const svg = d3.select(el)
    .attr('width', 300)
    .attr('height', 500);

  const g = svg.append('g')
    .attr('transform', 'translate(32,32)');

  let circles = g.append('g')
    .selectAll('circle');

  const brushGroup = g.append('g')
    .attr('class', 'brush')
    .call(brush);

  function redraw() {
    const all = group.all(); // crossfilter group returns an array

    xAxisGroup.call(xAxis);
    yAxisGroup.call(yAxis);

    circles = circles.data(all, d => d); // keyFn for data constancy

    circles.enter().append('circle')
      .attr('r', radius)
      .attr('cx', plotX) // radius + plotX/Y are simple curry functions
      .attr('cy', plotY);

    circles.exit().remove(); // not working!!
  }

  redraw();
}

I am also aware of this change in d3-selection in v4 but I'm not super confident which lines are my update and which ones are my update + enter . 我也知道v4中d3-selection的这一变化,但是我不太确定哪些行是我的update ,哪些行是我的update + enter

Any help would be much appreciated. 任何帮助将非常感激。 Thank you! 谢谢!

I suspect the problem is one of 2 things. 我怀疑问题是2件事之一。 Probably #1 below. 可能是下面的#1。 It's a bit hard to tell with out a working example to test things out in, but here you go: 很难给出一个可行的示例来进行测试,但是在这里您可以执行以下操作:

  1. I believe that the selectAll and the data join should happen together in the redraw function. 我相信selectAlldata联接应该在redraw函数中一起发生。 Because you never redo the selectAll in the redraw function, your selection will never contain any elements. 因为您从未在重绘函数中重做selectAll ,所以您的选择将永远不会包含任何元素。 If you check your enter and exit selections in your redraw function, your enter selection will always contain all your data points because the underlying selection is empty. 如果您在redraw功能中检查了enterexit选择,则enter选择将始终包含所有数据点,因为基础选择为空。

  2. That your data key function returns an object. 您的数据键函数返回一个对象。 Since the object is the result of Crossfilter's group.all , they should be comparable by reference, but it would be safer to do circles.data(all, d => d.key) . 由于该对象是group.allgroup.all的结果,因此它们应通过引用进行比较,但是使用circles.data(all, d => d.key)会更安全。

The solution should be to do something like: 解决方案应该是执行以下操作:

componentDidMount() {
  const el = ReactDOM.findDOMNode(this); // the mounted svg element

  const svg = d3.select(el)
    .attr('width', 300)
    .attr('height', 500);

  const g = svg.append('g')
    .attr('transform', 'translate(32,32)');

  let circlesGroup = g.append('g'); // Just hang on to the group

  const brushGroup = g.append('g')
    .attr('class', 'brush')
    .call(brush);

  function redraw() {
    const all = group.all(); // crossfilter group returns an array

    xAxisGroup.call(xAxis);
    yAxisGroup.call(yAxis);

    let circles = circlesGroup // Do the selection and data join here
      .selectAll('circle')
        .data(all, d => d.key); // Have the key function return a key, not an object

    circles.enter().append('circle')
      .attr('r', radius)
      .attr('cx', plotX) // radius + plotX/Y are simple curry functions
      .attr('cy', plotY);

    circles.exit().remove();
  }

  redraw();
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM