我正在尝试在SVG中创建三组圆圈。我打电话给他们circleA
circleB
和circleC
,我打算对它们进行不同的着色。
var circleA = [
[50,48],[106,35],[107,42],[119,52],[139,58],
[26,60],[65,68],[117,73],[123,70],[145,78]
];
var circleB = [
[38,81],[48,69],[48,81],
[111,99],[128,92],[153,92]
];
var circleC = [
[24,106],[46,99],[43,112],[63,105],
[62,122],[92,126],[141,122],[132,145],
[23,145]
];
//... omitting code for scale handling ...
var svg = d3.select("body")
.append("svg")
.attr("width", svgw)
.attr("height", svgh);
svg.selectAll("circle")
.data(circleA)
.enter()
.append("circle")
.attr("cx", function(d) { return xScale(d[0]); })
.attr("cy", function(d) { return yScale(d[1]); })
.attr("r", 10);
svg.selectAll("circle")
.data(circleB)
.enter()
.append("circle")
.attr("cx", function(d) { return xScale(d[0]); })
.attr("cy", function(d) { return yScale(d[1]); })
.attr("r", 10);
svg.selectAll("circle")
.data(circleC)
.enter()
.append("circle")
.attr("cx", function(d) { return xScale(d[0]); })
.attr("cy", function(d) { return yScale(d[1]); })
.attr("r", 10);
但是只有circleA
被添加到SVG中。 B组和C组不存在。我检查了DOM确实只创建了10个<circle>
个标签而不是10 + 6 + 9 = 25个圆圈。
为什么?谢谢。
答案 0 :(得分:1)
svg.selectAll("circle")
.data(circleB)
将选择所有现有的circle
元素并将数据circleB
绑定到它们。您在绑定circle
后已经创建了10 circleA
,因此现在circleB
绑定到前6个现有circle
元素。由于不必创建 new 元素(现有的元素被“重用”),.enter()
选项为空并且没有任何反应。
因此,整体问题是您尝试将不同的数据绑定到相同的元素。如果要为每个数据集创建元素,则必须修改选择器。例如,您可以为属于不同数据集的元素提供不同的类:
svg.selectAll("circle.a")
.data(circleA)
.enter()
.append('circle')
.attr('class', 'a')
//...
svg.selectAll("circle.b")
.data(circleB)
.enter()
.append('circle')
.attr('class', 'b')
//...
答案 1 :(得分:1)
这是因为D3将数据与元素匹配的方式。默认情况下,匹配由索引完成。也就是说,在随后的.data(...).selectAll(...)
次调用中,您选择现有的圈子并按索引将它们与数据匹配。由于圈数多于数据项,因此.enter()
选项为空。
对此的解决方案是通过.data()
的可选第二个参数提供匹配函数,例如类似于.data(..., function(d) { return d; })
。