我基于3个元素的数组创建了一组d3js元素:
var data = [[0,0,2],[0,23,5],[2,12,5]];
circleSet = svg.selectAll()
.data(data)
.enter().append('circle');
编辑:
如何按索引选择第二个元素?
答案 0 :(得分:21)
仅操作一个元素的最自然的方法是使用过滤器函数:
var data = [[0,0,2],[0,23,5],[2,12,5]];
var circleSet = svg.selectAll()
.data(data)
.enter()
.append('circle');
var filteredCircleSet = circleSet
.filter(function (d, i) { return i === 1;})
// put all your operations on the second element, e.g.
.append('h1').text('foo');
请注意,根据您对其他元素的处理方式,您可以使用此方法的两种变体之一:
变体a):在数据函数中使用过滤器(减少数据和附加元素)
变体b):使用过滤器排除而不是包含以便最后删除其他元素
另见Filter data in d3 to draw either circle or square
另一种方法是使用selection.each方法:https://github.com/mbostock/d3/wiki/Selections#wiki-each 通过使用带有相应索引的if语句,您可以为一个元素创建一个块。 E.g。
var data = [[0,0,2],[0,23,5],[2,12,5]];
var circleSet = svg.selectAll()
.data(data)
.enter()
.append('circle')
.each(function (d, i) {
if (i === 1) {
// put all your operations on the second element, e.g.
d3.select(this).append('h1').text(i);
}
});
答案 1 :(得分:9)
在d3 v4及更高版本中,您可以使用Selection.nodes()
。假设i
是您想要的索引号:
d3.select(someSelection.nodes()[i])
这是一个自然的单行,它可以说更具可读性:你显然只是按顺序将节点放在i
,作为D3的选择。
它看起来就像它比替代方案更有效,后者涉及用.each()
循环整个选择。因此,您可能认为这是 O(1) ,而其他选项是 O(n)。
不幸的是,Selection.nodes()本身包含一个each
循环,所以它也是 O(n)(并不是说它在现实生活中很重要,除非你称之为数千个有数千个节点的选择次数):
var nodes = new Array(this.size()), i = -1;
this.each(function() { nodes[++i] = this; });
return nodes;
但是,通过这种方式,您可以将循环与获取分开,这在效率是主要问题时非常有用。
例如,如果你想在选择A中遍历each()
并从选择B获取相同位置的项目,并且你想避免循环内循环,因为这些选择可能很大而且你多次调用,你可以像这样构造它,它将是 O(2n)而不是 O(n ^ 2):
var selectionBArray = selectionB.nodes()
selectionA.each(function(d, i) {
var iFromSelectionA = this
var iFromSelectionB = d3.select(selectionBArray[i])
})
...或者如果您使用箭头功能来保存this
上下文:
var selectionBArray = selectionB.nodes()
selectionA.each((d, i, nodes) => {
var iFromSelectionA = d3.select(nodes[i])
var iFromSelectionB = d3.select(selectionBArray[i])
})
你甚至可以(ab)使用Selection._groups
,但我不建议使用这样的私有属性,因为如果D3更新重命名为_groups
属性,{{3} }。
答案 2 :(得分:6)
使用预设函数i
变量,该变量引用数组对象的索引。
var data = [[0,0,2],[0,23,5],[2,12,5]];
circleSet = svg.selectAll()
.data(data)
.enter()
.append('circle')
.attr('fill',function(d,i){i === 1 ? return 'red' : return 'black' };
在d3.js at this tutorial
中查找有关数组结构引用的更多信息您还可以在分配课程时使用i
索引的计数对您追加的每个元素进行编码。
var data = [[0,0,2],[0,23,5],[2,12,5]];
circleSet = svg.selectAll()
.data(data)
.enter()
.append('circle')
.attr("class",function(d,i){ return "yourclass item" + i })
var theSecondElement = d3.select(".item1")
最后,您可以使用.each方法和条件来定位特定元素
circleSet = svg.selectAll()
.data(data)
.enter()
.append('circle')
.each(function (d, i) {
if (i === 1) {
var that = this;
(function textAdd() {
d3.select(that).append('h1').text(i);
)();
}
});