d3 v4 + react + es6 + crossfilter: Selection.exit().remove() 不工作
d3 v4 + react + es6 + crossfilter: Selection.exit().remove() not working
我正在使用 crossfilter.js and d3.js v4 with ES6 style React in an attempt to make dimensional charts with context brushing. Essentially, I took this example 并将其转换为 ES6。
我遇到的问题是 selection.exit().remove()
不起作用,以至于在每次重绘时,越来越多的圆圈附加到 svg g 元素。创建画笔时会触发重绘。我通过 运行
检查
selection.exit()
.attr('class', d => {
console.log('anything');
return 'anything';
})
.remove();
但没有输出任何内容,所以我认为我的数据选择无效。
上下文如下:
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();
}
我也知道 v4 中 d3-selection 的这一变化,但我不太确定哪些行是我的 update
哪些是我的 update + enter
.
如有任何帮助,我们将不胜感激。谢谢!
我怀疑问题出在以下两点之一。可能在下面#1。如果没有一个工作示例来测试事情,很难说清楚,但是你去吧:
我认为 selectAll
和 data
连接应该在 redraw
函数中一起发生。因为您永远不会在重绘函数中重做 selectAll
,所以您的选择永远不会包含任何元素。如果您在 redraw
函数中检查 enter
和 exit
选择,您的 enter
选择将始终包含所有数据点,因为基础选择是空的。
你的数据键函数returns一个对象。由于该对象是 Crossfilter 的 group.all
的结果,它们应该可以通过引用进行比较,但是 circles.data(all, d => d.key)
.
会更安全
解决方案应该是:
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();
}
我正在使用 crossfilter.js and d3.js v4 with ES6 style React in an attempt to make dimensional charts with context brushing. Essentially, I took this example 并将其转换为 ES6。
我遇到的问题是 selection.exit().remove()
不起作用,以至于在每次重绘时,越来越多的圆圈附加到 svg g 元素。创建画笔时会触发重绘。我通过 运行
selection.exit()
.attr('class', d => {
console.log('anything');
return 'anything';
})
.remove();
但没有输出任何内容,所以我认为我的数据选择无效。
上下文如下:
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();
}
我也知道 v4 中 d3-selection 的这一变化,但我不太确定哪些行是我的 update
哪些是我的 update + enter
.
如有任何帮助,我们将不胜感激。谢谢!
我怀疑问题出在以下两点之一。可能在下面#1。如果没有一个工作示例来测试事情,很难说清楚,但是你去吧:
我认为
selectAll
和data
连接应该在redraw
函数中一起发生。因为您永远不会在重绘函数中重做selectAll
,所以您的选择永远不会包含任何元素。如果您在redraw
函数中检查enter
和exit
选择,您的enter
选择将始终包含所有数据点,因为基础选择是空的。你的数据键函数returns一个对象。由于该对象是 Crossfilter 的
group.all
的结果,它们应该可以通过引用进行比较,但是circles.data(all, d => d.key)
. 会更安全
解决方案应该是:
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();
}