Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/127.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
d3.js:使用selection.on创建扩展列表viz_D3.js - Fatal编程技术网

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; });
}