d3.js:使用selection.on创建扩展列表viz
我有一个数据结构,比如d3.js:使用selection.on创建扩展列表viz,d3.js,D3.js,我有一个数据结构,比如 [ {"name":"foo", "links":["a", "b", "c"]}, {"name":"bar", "links":["d", "e", "f"]} ] 我想列一张这样的清单 <ul> <li> foo </li> <li> bar </li> </ul> 添加子列表甚至很容易: items = toplist.append("ul") .
[
{"name":"foo", "links":["a", "b", "c"]},
{"name":"bar", "links":["d", "e", "f"]}
]
我想列一张这样的清单
<ul>
<li> foo </li>
<li> bar </li>
</ul>
添加子列表甚至很容易:
items = toplist.append("ul")
.selectAll("li")
.data(function(d){return d.links})
.enter()
.append("li")
.text(function(d){return d})
我可以在toplist
中的每个li
中添加一个(“单击”。
),如
toplist.selectAll("li")
.data(data)
.enter()
.append("li")
.text(function(d){return d.name;})
.on("click", expand)
并将子列表代码移动到一个名为expand的函数中
function expand(d,i){
然后将上面的项=…
代码包含在其中
问题在于,这样会同时扩展foo
和bar
我如何给foo
list元素一个单独的点击事件,以bar
只展开该元素?本质上,我需要传递expand
数据元素的索引,让它只对DOM的特定部分进行操作
如果您需要任何帮助,我们将不胜感激。当调用
展开时,您拥有所需的一切。此上下文是单击的li元素,d
是关联的数据。如果您只想展开(而不是在展开和折叠之间切换),则可以通过选择以下内容来创建子列表:
function expand(d) {
d3.select(this)
.on("click", null)
.append("ul")
.selectAll("li")
.data(d.links)
.enter().append("li")
.text(function(d) { return d; });
}
请注意,expand
还会从单击的项目中删除单击处理程序;单击两次时,您不希望再次添加列表
如果要在“展开”和“删除”之间切换,则需要跟踪某些状态:子菜单是打开的还是关闭的。您可以通过在d
(d.open
)上存储布尔值来执行此操作,也可以通过查询DOM来查看子菜单是否已存在:d3.select(this)。select(“ul”).empty()
另一种方法是提前创建所有子菜单,然后通过display
style属性切换可见性。如果所有数据都可用,这是最简单的选择;如果异步加载链接数据,我可能只需要动态创建子菜单
实例:我应该补充一点,如果在展开函数中输入console.log d、I、this和d3.event,我只会看到单击的元素
function expand(d,i){
function expand(d) {
d3.select(this)
.on("click", null)
.append("ul")
.selectAll("li")
.data(d.links)
.enter().append("li")
.text(function(d) { return d; });
}