我制作了一个 JSFiddle 来直观地解释我的问题:https://jsfiddle.net/nph/poyxrmn7/
我尝试在 d3 代码中有效地使用
举个例子,我正在尝试制作一个带有标记点的图表。我可以这样做,并且有效:
var labeledCircles1 = function(data){
var svg = d3.select('svg');
var circles = svg.selectAll('circle')
.data(data);
circles.enter().append('circle')
circles.exit().remove()
circles
.attr('cx', function(d,i){ return i; })
.attr('cy', function(d){ return d; })
.attr('r', 10)
var texts = svg.selectAll('text')
.data(data)
texts.enter().append('text')
texts.exit().remove()
texts
.text(function(d){ return d; })
.attr('x', function(d,i){ return i; })
.attr('y', function(d){ return d; })
.attr('dy', -10)
};
它输出类似这样的内容:
<svg>
<circle cx="0" cy="10" r="10"></circle>
<circle cx="1" cy="30" r="10"></circle>
<text x="0" y="10" dy="-10">10</text>
<text x="1" y="30" dy="-10">30</text>
</svg>
但这需要大量重复自己,如果我要向每个点添加更多元素,我就必须再次重复自己。它也不会在生成的 svg 中对元素进行逻辑分组,如上所示。
我希望能够只指定一次位置,并且让组更符合逻辑。我想要输出这个的代码:
<svg>
<g transform="translate(0,10)">
<circle r="10"></circle>
<circle r="10"></circle>
</g>
<g transform="translate(1,30)">
<text dy="-10">10</text>
<text dy="-10">30</text>
</g>
</svg>
但我不知道该怎么做。如何开始已经很清楚了:
var svg = d3.select('svg');
var groups = svg.selectAll('.group')
.data(data)
groups.enter().append('g')
.attr('class', 'group')
groups.exit().remove();
groups
.attr('transform', function(d,i){
var x = i * 20 + 50;
var y = d + 20;
return 'translate(' + x + ',' + y + ')';
})
但是我不知道如何从那里继续。
如果我附加到groups
,它第一次会起作用,但是当我更改数据集时,它会重新绘制我的circle
和text
元素:
groups.append('circle')
.attr('r', 10)
groups.append('text')
.text(function(d) { return d; })
.attr('dy', -10);
但是如果我对组执行selectAll
,那么(当然)它根本不会绘制元素。
我确信我缺少一些简单的东西,但我不确定是什么。
(这似乎很可能是重复的,但我找不到其他人解决这个一般问题。)
最佳答案
如果您想一次性添加数据,最简单的方法是
<g>
<text></text>
<circle></circle>
</g>
<g>
<text></text>
<circle></circle>
</g>
<g>
<text></text>
<circle></circle>
</g>
<g>
<text></text>
<circle></circle>
</g>
<g>
<text></text>
<circle></circle>
</g>
以及js函数
var labeledCircles3 = function(data) {
var svg = d3.select('#svg3');
var groups = svg.selectAll('g').data(data)
// exit
groups.exit().remove()
// new
var newGroups = groups.enter()
var newgroup = newGroups.append('g')
newgroup.append('text')
newgroup.append('circle')
// update + new
groups = newGroups.merge(groups)
groups.select('text')
.text(function(d){ return d; })
.attr('x', function(d,i){ return i * 20 + 50; })
.attr('y', function(d){ return d + 20; })
.attr('dy', -10)
groups.select('circle')
.attr('cx', function(d,i){ return i * 20 + 50; })
.attr('cy', function(d){ return d + 20; })
.attr('r', 10)
}
关于javascript - d3.js:使用 <g> 分组(通过数据连接进入/更新/退出循环),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43297888/