我的update()
功能出现问题。在svg.append('rect')
{}} {}} {}}} {}}} {}} {{}} {}}我在.on('click')
内我只需更改数据,然后运行update()
。
为什么这不起作用?我如何使它工作?
var width = 640,
height = 480;
var graphNodes = [
{ id: 0, x: 39, y: 343, r: 15 },
{ id: 1, x: 425, y: 38, r: 15 },
{ id: 2, x: 183, y: 417, r: 15 },
{ id: 3, x: 564, y: 31, r: 15 },
{ id: 4, x: 553, y: 351, r: 15 },
{ id: 5, x: 454, y: 298, r: 15 },
{ id: 6, x: 493, y: 123, r: 15 },
{ id: 7, x: 471, y: 427, r: 15 },
{ id: 8, x: 142, y: 154, r: 15 }
];
var svg = d3.select('body').append('svg')
.attr('width', width)
.attr('height', height);
svg.append('rect')
.attr('class', 'graph')
.attr('width', width)
.attr('height', height)
.attr('fill', 'lightblue')
.attr('opacity', 0.3)
.on('click', function(){
graphNodes[8].id = 'hey there'; // <----- Why doesn't this happen?
update();
});
var nodeGroup = svg.selectAll('.nodes')
.data(graphNodes, function(d){ return d.id; })
.enter().append('g')
.attr('class', 'node');
nodeGroup.append('circle')
.attr('cx', function(d) { return d.x })
.attr('cy', function(d) { return d.y })
.attr("r", function(d){ return d.r; })
.attr("fill", "gray");
nodeGroup.append('text')
.attr("dx", function(d){ return d.x + 20; })
.attr("dy", function(d){ return d.y + 5; })
.text(function(d) { return d.id });
function update() {
if(nodeGroup){
// Update nodes
var node = nodeGroup.data(graphNodes, function(d){ return d.id; }),
nodeEnter = node.enter().append('g')
.attr('class', 'node');
nodeEnter.append('circle')
.attr('cx', function(d) { return d.x; })
.attr('cy', function(d) { return d.y; })
.attr('r', function(d){ return d.r; })
.attr('fill', 'gray');
nodeEnter.append('text')
.attr("dx", function(d){ return d.x + 20; })
.attr("dy", function(d){ return d.y + 5; })
.text(function(d) { return d.id });
nodeGroup = nodeEnter.merge(node);
node.exit().remove();
}
}
这是fiddle
答案 0 :(得分:1)
在你留给我的邮件中输入此作为评论,但这里是答案。
您需要将在输入,更新和退出时执行的操作分开。在输入时,您只想追加并设置任何永不改变的属性。在更新时,您要添加/更改文本并添加/更改半径。退出时,您将删除。在这里,我已经正确处理了输入,更新,退出范例:
// bind the data
var node = nodeGroup.data(graphNodes, function(d){ return d.id; }),
// this is the enter selection
nodeEnter = node.enter().append('g')
.attr('class', 'node');
// append to enter selection
// append and set color, we never change color
nodeEnter.append('circle')
.attr('cx', function(d) { return d.x; })
.attr('cy', function(d) { return d.y; })
.attr('fill', 'gray');
// again entering, append text and set position
nodeEnter.append('text')
.attr("dx", function(d){ return d.x + 20; })
.attr("dy", function(d){ return d.y + 5; });
// nodeGroup is the enter + update selection
nodeGroup = nodeEnter.merge(node);
// change the things we want to change on every update
nodeGroup.select("text")
.text(function(d) { return d.text ? d.text : d.id });
nodeGroup.select("circle")
.attr('r', function(d){ return d.r; })
// exit, just remove
node.exit().remove();
运行代码:
var width = 640,
height = 480;
var graphNodes = [
{ id: 0, x: 39, y: 343, r: 15 },
{ id: 1, x: 425, y: 38, r: 15 },
{ id: 2, x: 183, y: 417, r: 15 },
{ id: 3, x: 564, y: 31, r: 15 },
{ id: 4, x: 553, y: 351, r: 15 },
{ id: 5, x: 454, y: 298, r: 15 },
{ id: 6, x: 493, y: 123, r: 15 },
{ id: 7, x: 471, y: 427, r: 15 },
{ id: 8, x: 142, y: 154, r: 15 }
];
var svg = d3.select('body').append('svg')
.attr('width', width)
.attr('height', height);
svg.append('rect')
.attr('class', 'graph')
.attr('width', width)
.attr('height', height)
.attr('fill', 'lightblue')
.attr('opacity', 0.3)
.on('click', function(){
/*graphNodes.push({
x: d3.mouse(this)[0],
y: d3.mouse(this)[1],
id: graphNodes.length,
r: 15
});*/
graphNodes.splice(2, 1);
graphNodes[Math.floor(Math.random() * graphNodes.length)].text = "Tomato!";
graphNodes[Math.floor(Math.random() * graphNodes.length)].r = Math.random() * 30;
update();
});
var nodeGroup = svg.selectAll('.nodes')
.data(graphNodes, function(d){ return d.id; })
.enter().append('g')
.attr('class', 'node');
nodeGroup.append('circle')
.attr('cx', function(d) { return d.x })
.attr('cy', function(d) { return d.y })
.attr("r", function(d){ return d.r; })
.attr("fill", "gray");
nodeGroup.append('text')
.attr("dx", function(d){ return d.x + 20; })
.attr("dy", function(d){ return d.y + 5; })
.text(function(d) { return d.id });
function update() {
if(nodeGroup){
// Update nodes
var node = nodeGroup.data(graphNodes, function(d){ return d.id; }),
nodeEnter = node.enter().append('g')
.attr('class', 'node');
// this is the enter selection
// append and set color, we never change color
nodeEnter.append('circle')
.attr('cx', function(d) { return d.x; })
.attr('cy', function(d) { return d.y; })
.attr('fill', 'gray');
nodeEnter.append('text')
.attr("dx", function(d){ return d.x + 20; })
.attr("dy", function(d){ return d.y + 5; });
// nodeGroup is the enter + update selection
nodeGroup = nodeEnter.merge(node);
// change the things we want to change on every update
nodeGroup.select("text")
.text(function(d) { return d.text ? d.text : d.id });
nodeGroup.select("circle")
.attr('r', function(d){ return d.r; })
// exit, just remove
node.exit().remove();
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.5.0/d3.min.js"></script>