如何将现有的组克隆并修改为一个选择?

4

我有一个包含复杂组模板的现有SVG。我希望在一些数据的上下文中重用和复制它(selection.data().enter())。

<svg>
<g id="template">
  *** complex inner ***
</g>
</svg>

我想使用D3根据一些数据克隆这个#template,但我希望根据数据修改每个克隆。
d3.select("svg").selectAll('g')
        .data(['red', 'blue', 'yellow', 'lime']).enter()
        .append(***A CLONE OF MY TEMPLATE****)
        .select(***SOMETHING IN MY COMPLEX INNER***)
        .attr('fill', function(d){return d;})

这里有一个可以使用数据来克隆的小例子,但我无法修改第一个矩形的填充颜色。

<use>标签并不实用,因为它引用元素,但是如果要修改所有实例的内部元素,则无法修改单个实例,就像这个SO问题中所述。

事实上,我想使用D3做与这个提案相同的事情。我该怎么做?

2个回答

2
这与我经常遇到的一个问题类似,我无法让元素从父节点继承数据。解决方案在Mike Bokstock的选择文章中隐藏着。关键是可以通过使用 insert、append 或 select 将数据从父级传递到子级。请注意,使用 selectAll 不会将数据传递给子节点。
对于您的情况,您只需要更改
``` .selectAll("#fillPart").attr('fill', function(d){return 'red'}) ```

``` .select("#fillPart").attr('fill', function(d){return d}) ```
这里是带有更改的更新后的 fiddle

0
问题在于您正在使用selectAll选择fillPart,而您已经选择了所有的.instance,从而创建了一个嵌套选择,这不是您想要的。
此外,由于您正在克隆元素,因此您不希望其中有一个id,因为那样您将拥有具有相同id的多个元素。首先将id="fillPart"更改为class="fillPart"
当您选择所有.instance元素时,对选择调用的方法将应用于选择中的每个元素一次,因此,您只需调用select('.fillPart')来选择附加到当前实例的单个fillPart,而不是调用selectAll('.fillPart'),这将选择每个实例中的所有fillPart元素。
完成上述步骤后,您现在可以根据数据直接分配填充颜色。
.select(".fillPart")
  .attr('fill', function(d){ return d; });

现在你应该获得所需的结果。这是更新后的JSFiddle


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接