“点击”可以更改嵌套组的属性吗?

时间:2019-02-14 00:19:00

标签: d3.js svg

我有一个圆圈包装图,其中许多最上面的圆圈(叶子)具有相同的标题。

我想添加一个交互,当用户单击任何一片叶子时,该叶子用通用标题突出显示每个叶子。因此,例如,如果该数据集有1000个叶子,则用户可以单击任何标记为“ CD 19”的叶子,并轻松查看所有其他“ CD 19”叶子。

我这样做是为了自己的教育。我有一个半工半解的解决方案。如果能为我指明正确的方向,还是对我的解决方案无法正常工作的任何解释,我将不胜感激。

这是我的幼稚解决方案:

使用d3.nest和.object按名称对叶子分组。

const nodes = packLayout(root).descendants()
const nameNest = d3.nest().key(d => d.data.name).object(nodes);

现在,nameNest在传递名称作为键时,会返回具有相同名称的对象数组。

console.log(nameNest['CD 19']) // => Array(3)

然后使用.forEach(...)在数组的每个成员上设置一个公共属性。

nameNest['CD 19'].forEach(item => item.r = 50)

这具有预期的效果。所有标记为“ CD 19”的圆的半径为50。但是我要做的是将这段代码片段转换为一个函数,然后将该函数传递到我的圆上的事件中,如下所示:

const namez = d => nameNest[d.data.name]
                    .forEach(item => item.r = 50)
...

const circles = nodesEnter
       .append('circle')
       ...
       .on('click', d => namez(d));

这不起作用。 cosnole.log(d => namez(d))返回'undefined'。

但是,当我取下.forEach(...)console.log(d => namez(d))时,将返回与我单击的节点同名的预期对象数组。那么,为什么不能使用.forEach从.on()内部修改namez(d)返回的数组?

这是我的代码:bl.ocks: circle packing diagram with common node names

1 个答案:

答案 0 :(得分:0)

您的代码正在工作!但是,您只是在更改数据,而不是实际的SVG元素。

要更改圈子,您必须重新粉刷它们。例如:

.on('click', d => {
    namez(d);
    circles.attr('r', d => d.r)
});

这是更新的代码:https://bl.ocks.org/GerardoFurtado/raw/3caee8c936d1cb3b98cce0706d52d890/f1a38bf56af9a66f418cc08b55f04a64b3c4b494/