在我的d3心智模型中,调用.select()不应该改变绑定到选择的数据。
我遇到过这样一种情况,即调用.select()并传递一个函数来改变绑定数据,我希望能解释一下我的心理模型有什么问题。
这是一个极小的案例:
// Setup
let body = d3.selectAll('body')
let exampleData =
[
{_id:"groupOne", items:['one','two']},
{_id:"groupTwo", items:['three','four']}
];
// Add some divs
body.selectAll('div').data(exampleData).enter().append('div');
// Add some p children of the divs
body.selectAll('div').selectAll('p').data((d)=>d.items).enter().append('p').text((d)=>d);
// Issue
console.log(body.selectAll('div').data()); // data is the same as exampleData
body.selectAll('p').select(function(){return this.parentNode}); // Select parents of all p
console.log(body.selectAll('div').data()); // Data is now ["two","four"]
这是bl.ocks.org上的实时版本。
答案 0 :(得分:1)
来自d3的文档:https://github.com/d3/d3/wiki/Selections#select
如果当前元素具有关联数据,则此数据将由返回的子选择继承,并自动绑定到新选择的元素。
因此,您选择body.selectAll('p')
的p元素,其中包含数据["one,"two","three","four"]
(此数据由返回的子选择继承,并自动绑定到新选择的元素。)
然后使用.select(function(){return this.parentNode});
子选择将“迭代”4次。
哪个将是div:
前两个<div><p>one</p><p>two</p></div>
和<div><p>three</p><p>four</p></div>
为最后两个。
第一次迭代; parentNode <div><p>one</p><p>two</p></div>
,
将获得(继承)数据"one"
。
第二次迭代:数据"two"
。
在第3次迭代中; parentNode <div><p>three</p><p>four</p></div>
,
将获得数据"three"
。
第四次迭代:数据"four"
。
但是,我认为你要做的是这样的事情:
body.selectAll('p').select(this.parentNode); // Select parents of all p
console.log(body.selectAll('div').data()); // Data is now the same as exampleData
(没有return语句)