Javascript d3.js:使用<;g>;(数据连接进入/更新/退出周期)
我用JSFiddle直观地解释了我的问题: 我试图在我的d3代码中有效地使用元素,以一种与转换一起工作的方式移动对象组 作为一个例子,我试图制作一个带有标记点的图。我可以这样做,而且很有效:Javascript d3.js:使用<;g>;(数据连接进入/更新/退出周期),javascript,d3.js,svg,Javascript,D3.js,Svg,我用JSFiddle直观地解释了我的问题: 我试图在我的d3代码中有效地使用元素,以一种与转换一起工作的方式移动对象组 作为一个例子,我试图制作一个带有标记点的图。我可以这样做,而且很有效: var labeledCircles1 = function(data){ var svg = d3.select('svg'); var circles = svg.selectAll('circle') .data(data); circles.enter().append('c
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>
但我不知道如何从那里开始
如果我附加到组
,它会第一次工作,但当我更改数据集时,它会重新绘制我的圆圈
和文本
元素:
groups.append('circle')
.attr('r', 10)
groups.append('text')
.text(function(d) { return d; })
.attr('dy', -10);
但是如果我对组执行selectAll
,那么(当然)它根本不会绘制元素
我肯定我遗漏了一些简单的东西,但我不确定是什么
(这很可能是重复的,但我找不到其他人来回答这个一般性问题。)
您需要继续在嵌套选择中执行数据联接。也就是说,圆和文本的数据连接。您每次都要添加一个新的圆,这就是为什么要重新绘制它
var circles = groups.selectAll('circle')
.data(d=>[d])
circles.enter().append('circle')
circles.attr('r', 10)
.attr('cx', 0)
.attr('cy', 0)
您需要继续在嵌套选择中执行数据联接。也就是说,圆和文本的数据连接。您每次都要添加一个新的圆,这就是为什么要重新绘制它
var circles = groups.selectAll('circle')
.data(d=>[d])
circles.enter().append('circle')
circles.attr('r', 10)
.attr('cx', 0)
.attr('cy', 0)
如果要一次性添加数据,简单的方法是
<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>
如果要一次性添加数据,简单的方法是
<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>
谢谢我想有一个简单的方法。另外,如果有人需要支持IE,您可以用
function(d){return[d]}
替换d=>[d]
,谢谢!我想有一个简单的方法。另外,如果有人需要支持IE,您可以用function(d){return[d]}
替换d=>[d]
,因为我使用的是v3,所以我不需要groups=newGroups.merge(groups)
,但没有这一行,这就可以按预期工作。谢谢对于其他使用v3的人:我也更改了var newGroups=groups.enter();var newgroup=newGroups.append('g')
到var newgroup=groups.enter().append('g')
,因为您不需要再次引用newGroups
。我使用的是v3,所以我不需要groups=newGroups.merge(groups)
,但如果没有这一行,这会按预期工作。谢谢对于其他使用v3的人:我也更改了var newGroups=groups.enter();var newgroup=newGroups.append('g')
到var newgroup=groups.enter().append('g')
,因为您不需要再次引用newGroups
。
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)
}