gpt4 book ai didi

javascript - 了解 D3 使用嵌套内容进入、更新和退出选择

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

当使用 D3.js 时,我发现我经常想创建绑定(bind)到我的数据的元素,但出于样式/布局的原因,它们在 div 和包装器中。我很难理解的是嵌套内容和包装器如何与 D3 的进入、更新和退出模式一起工作。

基本上,我通常使用 JSON 数组,其中包含我要显示的每个对象的一些属性。

假设我有一组人,每个人的名字和年龄,看起来像这样:

var array = [
{
name: "John",
age: 31
},
{
name: "Mark",
age: 29
},
]

我想在包装器 div 中用 D3 列出这些数据:

<div id="wrapper"></div>

我想为每个人创建一个,然后在包含 .因此,期望的最终结果将是:

<div id="wrapper">
<div class="person">
<p>John</p>
<p>31</p>
</div>
<div class="person">
<p>Mark</p>
<p>29</p>
</div>
</div>

我一直在尝试做的是选择包装器 div 中的所有 div,根据数据数组输入/更新,然后在段落中附加所需的信息:

var selection = d3.select("#wrapper")
.selectAll("div")
.data(array);

selection.enter()
.append("div")
.classed("person", true)
.merge(selection);

selection.append("p")
.html(d.name);

selection.append("p")
.html(d.age);

selection.exit().remove();

我遇到了一些问题:

  1. 第一次运行时没有追加段落

  2. 如果我有一个将另一个人添加到数组然后再次运行此事件的事件,我只会看到原始数组中的两个人 - John 和 Mark。

  3. 如果我将另一个人添加到数组中,不仅问题 #2 仍然存在,而且现在它会将段落附加到那些人的包装 div 中,因此每个人的 div 中都有重复的内容。

    <

坦率地说,当我想将 D3 元素放置在包装器和嵌套内容中并在同一级别添加多个子元素然后更新整个组时,我有点不确定进入/更新/退出选择应该如何工作当数组更新时。如果对此有任何澄清,我们将不胜感激 - 谢谢。

最佳答案

您必须重新分配选择:

selection = selection.enter()
.append("div")
.classed("person", true)
.merge(selection);

此外,您不能像那样使用第一个参数,您必须将函数传递给方法:

selection.append("p")
.html(d=>d.name);

selection.append("p")
.html(d=>d.age);

这是您的代码,其中包含这些更改:

var array = [{
name: "John",
age: 31
},
{
name: "Mark",
age: 29
},
]

var selection = d3.select("#wrapper")
.selectAll("div")
.data(array);

selection = selection.enter()
.append("div")
.classed("person", true)
.merge(selection);

selection.append("p")
.html(d=>d.name);

selection.append("p")
.html(d=>d.age);

selection.exit().remove();
<script src="https://d3js.org/d3.v5.min.js"></script>
<div id="wrapper"></div>

最后,鉴于您在 your comment 中分享的信息,修复代码的首选似乎是创建嵌套的进入/更新/退出选择。

但是,转念一想,因为您的对象没有嵌套数组,所以一种更简单的解决方案是附加 <p>输入选择中的元素并在更新选择中更新它们。

这是一个演示这一点的片段,包含 3 个不同的数据数组:

var array = [{
name: "John",
age: 31
},
{
name: "Mark",
age: 29
},
]

function display() {
var selection = d3.select("#wrapper")
.selectAll("div")
.data(array);

var selectionEnter = selection.enter()
.append("div")
.classed("person", true);

selectionEnter.append("p")
.classed("name", true)
.html(d => d.name);

selectionEnter.append("p")
.classed("age", true)
.html(d => d.age);

selection.exit().remove();

selection.select(".name")
.html(d => d.name);

selection.select(".age")
.html(d => d.age);
}

display();
setTimeout(function() {
array = [{
name: "John",
age: 31
},
{
name: "Mark",
age: 29
},
{
name: "Andrew",
age: 24,
}
];

display();
}, 2000)

setTimeout(function() {
array = [{
name: "John",
age: 21
},
{
name: "Bob",
age: 49
}
];

display();
}, 4000)
<script src="https://d3js.org/d3.v5.min.js"></script>
<div id="wrapper"></div>

关于javascript - 了解 D3 使用嵌套内容进入、更新和退出选择,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55999911/

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