我有一个圆圈包装图,其中许多最上面的圆圈(叶子)具有相同的标题。
我想添加一个交互,当用户单击任何一片叶子时,该叶子用通用标题突出显示每个叶子。因此,例如,如果该数据集有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
答案 0 :(得分:0)
您的代码正在工作!但是,您只是在更改数据,而不是实际的SVG元素。
要更改圈子,您必须重新粉刷它们。例如:
.on('click', d => {
namez(d);
circles.attr('r', d => d.r)
});