如何将两个d3对象组合成一个用于批量操作

时间:2014-10-23 09:16:32

标签: javascript svg d3.js

我正在用d3.js创建一些静态SVG元素,它们共享很多属性。

var c1 = svg.append('circle').attr('r',20);
var c2 = svg.append('circle').attr('r',40);
...

我想将这些组合在一起以设置其他属性。我以为我可以使用推,即

var circles = svg.append('circle').attr('r',20);
circles.push( svg.append('circle').attr('r',40));
...
circles.attr('stroke','black').attr('stroke-width',2);

但是错误(“this.setAttribute不是函数”)

d3是所有关于东西的集合,它是all about arrays,所以我认为这项工作有效吗?有办法吗?

(我知道我可以进行数据连接,但我想知道一次操作多个事情的更通用的情况)

2 个答案:

答案 0 :(得分:3)

如果您想以这种方式执行操作,则需要了解 d3.selection Array 的区别。

迈克博斯托克写了一篇关于HERE主题的好解释。

以下是重点:

  

您可能被告知选择是DOM元素的数组。假。例如,选择是数组的子类;此子类提供了操作所选元素的方法,例如设置属性和样式。

     

...

     

选择不是字面数组元素的另一个原因是它们是元素的数组元素:选择是一个组的数组,每个组是一个元素数组。

因此,事实证明,您想要.push的数组实际上嵌套在表示选择的Array-subclass中。如果您的选择存储在变量circles中,则可以访问实际的元素数组circles[0]

另一个需要注意的重要事项是:内部数组保存实际的DOM元素引用,而不是它的选择。要从包含单个元素的选择中获取元素引用,只需在选择上调用.node()

您可以先创建一个空选区:

var circles = d3.selectAll('.empty');

假设您的页面上没有任何被归类为“空白”的内容,这是一种很好的语义方式。

然后,您可以.push .node.append直接circles[0] circles[0].push(svg.append('circle').attr('r',40).node()); {/ 1}} {/ 1}}

circles

根据需要多次执行此操作,然后您可以通过调用circles .attr('stroke', 'black') .attr('stroke-width', 2) 上的标准选择方法为所有圈子设置样式/属性:

{{1}}

HERE是一个演示。

答案 1 :(得分:0)

我认为另一种方法是按多个类别进行选择,例如

d3.selectAll(".class1,.class2").attr('...', '...')...

我们可以简单地将两个选择分配给不同的类或相同的类(如果您不需要分别对待它们)。