[英]Conditionally appending based on nested data with D3
我有这样的数据:
[
{id: 1, x:10, y:20, a: 123},
{id: 2, x:20, y:12},
]
我想生成 DOM 看起来像这样:
<div style='top:20px; left: 10px'>
<strong>1</strong>
<span>123</span>
</div>
<div style='top:12px; left: 20px'>
<strong>2</strong>
</div>
有没有办法根据属性的存在来附加元素?
如果新版本的数据缺少这些属性,还有一种方法可以删除它们吗?
是的,您可以使用子选择。
这是一个生成你想要的 DOM 的函数:
function show(arr) {
//bind data to divs
parent = d3.select("body").selectAll("div")
.data(arr);
//enter-update-exit pattern used to create divs
parent.exit().remove();
parent.enter().append("div");
parent.style({
"top" : function (d) { return d.y} ,
"left" : function (d) { return d.x }
});
//basic subselection bind
strong = parent.selectAll("strong")
.data(function(d) { return [d.id]});
//enter-update-exit
strong.exit().remove();
strong.enter().append("strong")
strong.text(String)
// subselection bind that handles missing attributes
span = parent.selectAll("span")
.data(function(d) { return d.a ? [d.a] : [] });
//enter-update-exit
span.exit().remove();
span.enter().append("span")
span.text(String)
}
我第一次调用show()
data1 = [
{id: 1, x:10, y:20, a: 123},
{id: 2, x:20, y:12},
{id: 3, x:15, y:15},
];
show(data1);
将其附加到 DOM:
<div style="top: 20px; left: 10px;">
<strong>1</strong>
<span>123</span>
</div>
<div style="top: 12px; left: 20px;">
<strong>2</strong>
</div>
<div style="top: 15px; left: 15px;">
<strong>3</strong>
</div>
然后我再次调用它
data2 = [
{id: 1, x:10, y:20},
{id: 2, x:20, y:12, a: 123}
]
show(data2);
我的 DOM 元素变成了
<div style="top: 20px; left: 10px;">
<strong>1</strong>
</div>
<div style="top: 12px; left: 20px;">
<strong>2</strong>
<span>123</span>
</div>
将数据绑定到 div 的块很简单。 无需评论。
parent = d3.select("body").selectAll("div")
.data(arr);
创建元素的块(div、strong、span)都是 d3 中进入-更新-退出习语的直接应用。 我们先退出,然后进入,最后更新——这是模式的常见变化。
parent.exit().remove(); //exit
parent.enter().append("div"); //enter
parent.style({
"top" : function (d) { return d.y} ,
"left" : function (d) { return d.x }
}); //update
子选择是魔法发生的地方(请参阅selection.data
的文档)。 您传递给 data 的函数将接收其父 div 绑定到的数组中的元素(例如{id: 2, x:20, y:12}
)。 该函数返回我们想要将我们的子选择绑定到的任何元素(必须是一个数组)。 对于强元素,我们只是获取 id 并将其包装在一个数组中。
// parent datum {id: 2, x:20, y:12} becomes child data [2]
strong = parent.selectAll("strong")
.data(function(d) { return [d.id]});
对于span元素,当它存在时我们将属性的值包装在数组中,不存在时只返回一个空数组。
// parent datum {id: 1, x:10, y:20, a: 123} becomes [123]
// parent datum {id: 2, x:20, y:12} becomes []
span = parent.selectAll("span")
.data(function(d) { return d.a ? [d.a] : [] });
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.