gpt4 book ai didi

javascript - 嵌套选择不更新

转载 作者:行者123 更新时间:2023-11-30 11:10:01 25 4
gpt4 key购买 nike

我要使用 d3js 显示一组数据。嵌套选择似乎确实看到了更新。我怎样才能更新内部分组?

我创建了 this ( http://jsfiddle.net/f0m574wp/17/ ) fiddle 。

我有一些嵌套数据,我的应用程序异步检索这些数据,并在数据传入时构建和显示这些数据。

dat = [{
key: 'asdf',
values:[{
key:'1',
value:'hello'
},{
key:'2',
value:''
}]
},{
key:'xyz',
values:[{
key:'1',
value:'foo'
},{
key:'3',
value:'bar'
}]
}];

随着数据对象的更新,我想重新运行显示函数来更新可视化效果。

function display(mydata){
//let x = mydata;
let x = JSON.parse(JSON.stringify(mydata));
console.log('x', x);
let root = d3.select('div');

// create the outer groupings
let outer = root.selectAll('div.outer').data(x, d=>d.key);
let outerEnter = outer.enter()
.append('div')
.classed('outer', true)
.attr('id', d=>d.key);

// add a heading and body to contain data
outerEnter.append('div').classed('heading', true).append('h1');
outerEnter.append('div').classed('body', true);
outer.exit().remove();

// get prevoius and existing outer groups
let outerall = outerEnter.merge(outer);
let headings = outerall.selectAll('div.heading');
let bodies = outerEnter.selectAll('div.body')
headings.selectAll('h1').text(d=>d.key); // update outer group heading

//lets work with the inner arrays of data
let innerGroup = bodies.selectAll('div.mid')
.data(d=>{ console.log(d); return d.values}, k=>k.key);

let innerGpEnter = innerGroup.enter()
.append('div')
.classed('mid', true);

let innerGpAll = innerGpEnter.merge(innerGroup);

// inner heading
let inner = innerGpAll.selectAll('h4.inner')
//.call(function(sel){console.log(sel.nodes());})
.data(d=>{ console.log(d); return [d];}, k=>k.key);
let innerEnter = inner.enter()
.append('h4')
.classed('inner', true);
innerEnter.merge(inner).text(k=>{console.log(k); return k.key});

// inner detail
let p = innerGpAll.selectAll('p.inner').data(d=>[d], k=>k.key);
let pEnter = p.enter().append('p').classed('inner', true);
pEnter.merge(p).text(v=>v.value);
}

问题似乎出在内部数据绑定(bind)上:

//lets work with the inner arrays of data
let innerGroup = bodies.selectAll('div.mid')
.data(d=>{ console.log(d); return d.values}, k=>k.key);

它似乎不会随着数据的变化而更新内部绑定(bind)。

最佳答案

这里的主要问题是使用两个链式 selectAll .你有...

let bodies = outerEnter.selectAll('div.body');

...接着...

let innerGroup = bodies.selectAll('div.mid').etc...

,这给了我们这个:

let innerGroup = outerEnter.selectAll('div.body').selectAll('div.mid').etc...

首先,你应该选择outerall , 不是 outerEnter , 自 outerall是更新选择。但这里的主要问题是链接 selectAll s:第一个之后没有数据绑定(bind),就在第二个之后。因此,数据不会传送到内部选择。

重要的是要记住,与 select 不同, selectAll不传播数据。看看我做的这张表:

<表类="s-表"><头>方法选择()selectAll()<正文>选择选择与选择器字符串匹配的第一个元素选择所有匹配选择器字符串的元素分组不影响分组影响分组数据传播传播数据不传播数据

注意传播数据不传播数据

解决方案:

让我们把它变成一个 selectAll , 其次是 data方法:

let innerGroup = outerall.selectAll('div.mid').etc...

这里是你的代码有那个变化:

dat = [{
key: 'asdf',
values: [{
key: '1',
value: 'hello'
}, {
key: '2',
value: ''
}]
}, {
key: 'xyz',
values: [{
key: '1',
value: 'foo'
}, {
key: '3',
value: 'bar'
}]
}];

function display(mydata) {
//let x = mydata;
let x = JSON.parse(JSON.stringify(mydata));
console.log('x', x);
let root = d3.select('div');

// create the outer groupings
let outer = root.selectAll('div.outer').data(x, d => d.key);
let outerEnter = outer.enter()
.append('div')
.classed('outer', true)
.attr('id', d => d.key);

// add a heading and body to contain data
outerEnter.append('div').classed('heading', true).append('h1');
outerEnter.append('div').classed('body', true);
outer.exit().remove();

// get prevoius and existing outer groups
let outerall = outerEnter.merge(outer);
let headings = outerall.selectAll('div.heading');
headings.selectAll('h1').text(d => d.key); // update outer group heading

//lets work with the inner arrays of data
let innerGroup = outerall.selectAll('div.mid')
.data(d => {
console.log(d);
return d.values
}, k => k.key);

let innerGpEnter = innerGroup.enter()
.append('div')
.classed('mid', true);

let innerGpAll = innerGpEnter.merge(innerGroup);

// inner heading
let inner = innerGpAll.selectAll('h4.inner')
//.call(function(sel){console.log(sel.nodes());})
.data(d => {
console.log(d);
return [d];
}, k => k.key);
inner.exit().remove();
let innerEnter = inner.enter()
.append('h4')
.classed('inner', true);
innerEnter.merge(inner).text(k => {
console.log(k);
return k.key
});

// inner detail
let p = innerGpAll.selectAll('p.inner').data(d => [d], k => k.key);
p.exit().remove();
let pEnter = p.enter().append('p').classed('inner', true);
pEnter.merge(p).text(v => v.value);
}

display(dat);
setTimeout(function() {
console.log('Send New data');
//dat[0].key = 'abc';
dat[0].values[1].value = 'good bye';
dat[1].values.push({
key: 2,
value: 'baz'
});
display(dat);
}, 3000)
* {
margin: 2px;
padding: 2px;
border: 0;
}

body {
background: #ffd;
}

.outer {
border: 1px solid green;
width:
}

.mid {
border: 1px solid red;
}

.inner {
border: 1px solid blue;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<div>
</div>

解决方案 2:

根据 your comment ,您需要保留该 HTML 结构。在这种情况下,使用 select :

let bodies = outerall.select('div.body');

您可以安全地使用select在这里是因为您只附加了一个 <div>上课 body .

这是新的片段:

dat = [{
key: 'asdf',
values: [{
key: '1',
value: 'hello'
}, {
key: '2',
value: ''
}]
}, {
key: 'xyz',
values: [{
key: '1',
value: 'foo'
}, {
key: '3',
value: 'bar'
}]
}];

function display(mydata) {
//let x = mydata;
let x = JSON.parse(JSON.stringify(mydata));
console.log('x', x);
let root = d3.select('div');

// create the outer groupings
let outer = root.selectAll('div.outer').data(x, d => d.key);
let outerEnter = outer.enter()
.append('div')
.classed('outer', true)
.attr('id', d => d.key);

// add a heading and body to contain data
outerEnter.append('div').classed('heading', true).append('h1');
outerEnter.append('div').classed('body', true);
outer.exit().remove();

// get prevoius and existing outer groups
let outerall = outerEnter.merge(outer);
let headings = outerall.selectAll('div.heading');
let bodies = outerall.select('div.body');
headings.selectAll('h1').text(d => d.key); // update outer group heading

//lets work with the inner arrays of data
let innerGroup = bodies.selectAll('div.mid')
.data(d => {
console.log(d);
return d.values
}, k => k.key);

let innerGpEnter = innerGroup.enter()
.append('div')
.classed('mid', true);

let innerGpAll = innerGpEnter.merge(innerGroup);

// inner heading
let inner = innerGpAll.selectAll('h4.inner')
//.call(function(sel){console.log(sel.nodes());})
.data(d => {
console.log(d);
return [d];
}, k => k.key);
inner.exit().remove();
let innerEnter = inner.enter()
.append('h4')
.classed('inner', true);
innerEnter.merge(inner).text(k => {
console.log(k);
return k.key
});

// inner detail
let p = innerGpAll.selectAll('p.inner').data(d => [d], k => k.key);
p.exit().remove();
let pEnter = p.enter().append('p').classed('inner', true);
pEnter.merge(p).text(v => v.value);
}

display(dat);
setTimeout(function() {
console.log('Send New data');
//dat[0].key = 'abc';
dat[0].values[1].value = 'good bye';
dat[1].values.push({
key: 2,
value: 'baz'
});
display(dat);
}, 3000)
* {
margin: 2px;
padding: 2px;
border: 0;
}

body {
background: #ffd;
}

.outer {
border: 1px solid green;
width:
}

.mid {
border: 1px solid red;
}

.inner {
border: 1px solid blue;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<div>
</div>

关于javascript - 嵌套选择不更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54082853/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com