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

时间:2014-06-28 10:29:01

标签: javascript svg d3.js

我有一个包含复杂组模板的现有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;})

Here是一个小提琴,它将克隆与数据相乘,但我无法修改第一个矩形的填充颜色,例如

<use>标记没有用,因为它引用了元素,但是如果不修改this SO question

中的所有实例,则无法修改内部元素

事实上,我想和使用D3的this proposal做同样的事情。 我怎么能这样做?

2 个答案:

答案 0 :(得分:2)

这类似于我经常遇到的问题,即获取元素以从父节点继承数据。解决方案隐藏在Mike Bokstock的article on selections中。关键是数据可以通过insert,append或select从父级传递给子级。请注意,使用selectAll不会将数据传递给子级。

在您的情况下,您只需要更改

.selectAll("#fillPart").attr('fill', function(d){return 'red'})

.select("#fillPart").attr('fill', function(d){return d})

Here是对此更改的更新。

答案 1 :(得分:0)

问题是,当您已经选择了所有selectAll时,您正在使用fillPart选择.instance,从而创建了一个嵌套选择,这不是您的选择想。

此外,由于您正在克隆元素,因此您不希望在其中包含id,因为这样您将拥有多个具有相同ID的元素。首先将id="fillPart"更改为class="fillPart"

当您选择所有.instance元素时,您在选择中调用的方法将应用于选择中的每个元素一次,因此而不是调用selectAll('.fillPart'),会选择每个实例中的所有fillPart元素,你只想调用select('.fillPart')来选择附加到当前实例的单个fillPart。

完成后,您现在可以根据数据分配填充颜色:

.select(".fillPart")
  .attr('fill', function(d){ return d; });

现在你应该得到理想的结果。这是更新的JSFiddle