我有一个矩形绑定到一个称为数据的数据数组。当我单击svg时,将调用函数removeElement。此函数从数据中删除与该矩形相关的元素。然后调用函数render()。
问题是以前的矩形没有被删除。所以render()函数没有正确更新。
点击一个矩形并将其移除后,如果我拖动另一个矩形,可以看到下面还有一个矩形。
类似的相关问题是我必须双击rects才能删除它们。不知道为什么会这样。
以下是代码段(所谓的代码段,实际上是完整代码)
<!DOCTYPE html>
<meta charset="utf-8">
<style>
/*.active {
stroke: #000;
stroke-width: 2px;
}*/
svg {
border: 1px solid black;
}
</style>
<svg width="800" height="300"></svg>
<script src="//d3js.org/d3.v4.min.js"></script>
<script>
var margin = {
top: 20,
right: 20,
bottom: 20,
left: 20
},
width = 840 - margin.left - margin.right,
height = 640 - margin.top - margin.bottom;
var svg = d3.select("svg");
var data = [{
x: 100
}, {
x: 300
}, {
x: 400
}, {
x: 600
}];
var ind = 0;
var groove = svg.append("g")
.attr("class", "groove_group");
groove.append("rect")
.attr("x", 0)
.attr("y", 150)
.attr("rx", 2)
.attr("ry", 2)
.attr("height", 6)
.attr("width", width)
.style("fill", "grey");
groove.append("rect")
.attr("x", 2)
.attr("y", 152)
.attr("rx", 2)
.attr("ry", 2)
.attr("height", 2)
.attr("width", 796)
.style("fill", "black");
render();
function render() {
// create group
var group = svg.selectAll(null)
.data(data, function(d) {
return d.x
});
group.exit().remove();
var groupEnter = group.enter().append("g")
.attr("class", "group");
groupEnter.call(d3.drag()
.on("start", dragstarted)
.on("drag", dragged)
.on("end", dragended))
.on("click", removeElement);
groupEnter.append("rect")
.attr("x", function(d) {
return d.x;
})
.attr("y", 100)
.attr("height", 100)
.attr("width", 15)
.style("fill", "lightblue")
.attr('id', function(d, i) {
return 'handle_' + i;
})
.attr("rx", 6)
.attr("ry", 6)
.attr("stroke-width", 2)
.attr("stroke", "black");
groupEnter.append("text")
.attr("x", function(d, i) {
if (i == 0) { // first element
return ((data[i].x / 2));
} else {
return (data[i].x - (data[i].x - data[i - 1].x) / 2);
}
})
.attr("y", 100)
.attr("text-anchor", "middle")
.style("fill", "black")
.attr('id', function(d, i) {
return 'text_' + i;
})
.text(function(d, i) {
if (i == 0) { // first set
return i + ": " + (data[i].x) + "m";
} else {
return i + ": " + ((data[i].x - data[i - 1].x)) + "m";
}
});
}
svg.on("click", function() {
var coords = d3.mouse(this);
getPosition(ind, coords[0]);
render();
});
function dragstarted(d) {
d3.select(this).raise().classed("active", true);
}
function dragged(d, i) {
if (i == 0) {
d3.select("#text_" + i)
.attr("x", d.x = (d3.event.x / 2))
.text(function(d) {
return i + " " + d3.event.x
});
d3.select("#text_" + (i + 1))
.attr("x", d.x = d3.event.x + ((data[i + 1].x - d3.event.x) / 2))
.text(function(d) {
return (i + 1) + " " + (data[i + 1].x - d3.event.x) + "m"
});
d3.select(this).select("rect")
.attr("x", d.x = d3.event.x);
} else if (i == data.length - 1) {
d3.select("#text_" + i)
.attr("x", d.x = (d3.event.x - data[i - 1].x) / 2 + data[i - 1].x)
.text(function(d) {
return i + ": " + (d3.event.x - data[i - 1].x) + "m"
});
d3.select("#text_" + (i + 1))
.attr("x", d.x = d3.event.x + (width - d3.event.x) / 2)
.text(function(d) {
return (i + 1) + ": " + (width - d3.event.x) + "m"
});
d3.select(this).select("rect")
.attr("x", d.x = d3.event.x);
} else {
d3.select("#text_" + i)
.attr("x", d.x = d3.event.x - ((d3.event.x - data[i - 1].x) / 2))
.text(function(d) {
return i + ": " + (d3.event.x - data[i - 1].x) + "m"
});
d3.select("#text_" + (i + 1))
.attr("x", d.x = d3.event.x + ((data[i + 1].x - d3.event.x) / 2))
.text(function(d) {
return (i + 1) + ": " + (data[i + 1].x - d3.event.x) + "m"
});
d3.select(this).select("rect")
.attr("x", d.x = d3.event.x);
}
}
function dragended(d) {
d3.select(this)
.classed("active", false);
}
function removeElement(d, i) {
d3.event.stopPropagation();
data = data.filter(function(e) {
return e != d;
});
d3.select(this)
.remove();
render();
}
function getPosition(ind, coords) {
if (coords[0] > data[ind].x) {
getPosition(++ind);
} else {
data.splice(1, 0, {
x: coords
});
}
}
</script>
这个问题来自here。
答案 0 :(得分:1)
您.exit()
无法正常工作的原因,因此您的旧元素在更新后仍然可见,因为您正在进行数据加入.data()
.selectAll(null)
。
在进行数据连接时,d3会根据您的选择器查看所有现有元素,然后在已经存在的内容之外附加所需的任何元素,或者反过来删除任何不再需要的元素。
根据您的代码选择null
,d3无法找到任何现有元素。通过将其更改为.selectAll('.group')