[英]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.js和d3.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:
很难给出一个可行的示例来进行测试,但是在这里您可以执行以下操作:
I believe that the selectAll
and the data
join should happen together in the redraw
function. 我相信
selectAll
和data
联接应该在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
功能中检查了enter
和exit
选择,则enter
选择将始终包含所有数据点,因为基础选择为空。
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.all
的group.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.