让我们考虑一下,我需要用<g>
元素包裹一圈圆圈,并将数据绑定到该父对象。(initialNodes
当我按下更新按钮时,update
函数将接收新数据(newNodes
),并且我希望圆的x / y位置会得到更新,但是如您在控制台中所见,尽管d.x
/ d.y
的打印正确,但是return d.x
中并未考虑到它,因此仅将Enter
组添加到画布。
我在做什么错?如何在父元素<g>
和子元素上反映更新的数据?
var color = d3.schemeCategory10;
var initialNodes = [
{"id": 0, "x": 50, "y": 50},
{"id": 1, "x": 100, "y": 100},
];
var vis = d3.select("body").append("svg").attr("width", 200).attr("height", 200);
update(initialNodes);
function update(data) {
// DATA JOIN
// Join new data with old elements, if any.
var circlesGroup = vis.selectAll("g.stop").data(data, function(d){return d.id});
var circlesEnter = circlesGroup.enter().append("g").attr("class", "stop");
var circlesExit = circlesGroup.exit().remove();
// ENTER
// Create new elements as needed.
circlesEnter
.append("circle")
.attr("r", 15)
.transition().duration(750)
.attr("cx", function (d) {
console.log('ENTERING: id:'+d.id+' position:'+d.x+','+d.y);
return d.x;
})
.attr("cy", function (d) {return d.y;})
.style("fill", 'red');
// UPDATE
// Update old elements as needed.
circlesGroup
.transition().duration(750)
.attr("cx", function (d) {
console.log('ENTERING: id:'+d.id+' position:'+d.x+','+d.y);
return d.x;})
.attr("cy", function (d) {return d.y;});
// EXIT
// Remove old elements as needed.
circlesExit
.remove();
}
var newNodes = [
{"id": 0, "x": 50, "y": 100},
{"id": 1, "x": 50, "y": 30},
{"id": 2, "x": 100, "y": 50}
];
var updateNodes = function() {
update(newNodes);
}
// Add the onclick callback to the button
d3.select("#updatebutton").on("click", updateNodes);
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<button id="updatebutton">Update</button>
答案 0 :(得分:1)
circleGroup
是g
元素的选择。没必要为cx
元素设置cy
和g
。
创建新节点后,选择所有g.stop
,然后。为什么?阅读d3选择文档。
没有理由添加第二个remove()
。
var color = d3.schemeCategory10;
var initialNodes = [
{"id": 0, "x": 50, "y": 50},
{"id": 1, "x": 100, "y": 100},
];
var vis = d3.select("body").append("svg").attr("width", 200).attr("height", 200);
update(initialNodes);
function update(data) {
// DATA JOIN
// Join new data with old elements, if any.
var circlesGroup = vis.selectAll("g.stop").data(data, function(d){return d.id});
var circlesEnter = circlesGroup.enter().append("g").attr("class", "stop");
var circlesExit = circlesGroup.exit().remove();
// ENTER
// Create new elements as needed.
circlesEnter
.append("circle")
.attr("r", 15)
.style("fill", 'red');
vis.selectAll("g.stop").select("circle")
.transition().duration(750)
.attr("cx", function (d) {
console.log('ENTERING2: id:'+d.id+' position:'+d.x+','+d.y);
return d.x;})
.attr("cy", function (d) {return d.y;});
}
var newNodes = [
{"id": 0, "x": 50, "y": 100},
{"id": 1, "x": 50, "y": 30},
{"id": 2, "x": 100, "y": 50}
];
var updateNodes = function() {
update(newNodes);
}
// Add the onclick callback to the button
d3.select("#updatebutton").on("click", updateNodes);
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<div><button id="updatebutton">Update</button></div>