如何将两个d3对象合并为一个进行批量操作

How to combine two d3 objects into one for bulk operations

本文关键字:一个 批量操作 合并 d3 两个 对象      更新时间:2023-09-26

我正在用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都是关于集合的东西,都是关于数组的,所以我认为这项工作有效吗?有办法吗?

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

如果您想以这种方式做事,您需要了解d3.selectionArray的区别。

Mike Bostock写了一篇很好的关于这个话题的解释HERE

以下是重要的部分:

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

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

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

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

你可以从创建一个空的选择开始:

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

这是一种很好的语义方式,假设你没有任何分类的东西;"空";在您的页面上。

然后您可以将您.append直接.push中选择的每个圆的.node circles[0]:

circles[0].push(svg.append('circle').attr('r',40).node());

根据需要多次执行此操作,然后可以通过调用circles:上的标准选择方法为所有圆设置样式/属性

circles
  .attr('stroke', 'black')
  .attr('stroke-width', 2)

此处是一个演示。

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

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

我们可以简单地将两个选项分配给不同的类或相同的类(如果不需要单独处理的话)。