有很多help我已经能够点击矩形来移除它们。
但我怎样才能删除数据呢?目前存在一些奇怪的行为,例如先前删除的矩形重新出现以及创建与点击位于不同位置的矩形。我认为所有这些都是由于数据没有被删除这一事实造成的。
我想也许.exit()可能有用,但它没有。
这是一个工作片段。
<!DOCTYPE html>
<meta charset="utf-8">
<style>
.active {
stroke: #000;
stroke-width: 2px;
}
</style>
<svg width="960" height="500"></svg>
<script src="//d3js.org/d3.v4.min.js"></script>
<script>
var svg = d3.select("svg"),
width = +svg.attr("width"),
height = +svg.attr("height"),
radius = 32;
var data = [{
x: 100,
y: 200
},
{
x: 200,
y: 300
},
{
x: 300,
y: 200
},
{
x: 400,
y: 300
}
];
var xScale = d3.scaleLinear()
.domain([0, d3.max(data, function(d) {
return d.x_pos
})]).range([0, width]);
svg.append("rect")
.attr("x", 100)
.attr("y", 250)
.attr("rx", 2)
.attr("ry", 2)
.attr("height", 6)
.attr("width", 800)
.style("fill", "grey");
svg.append("rect")
.attr("x", 102)
.attr("y", 252)
.attr("rx", 2)
.attr("ry", 2)
.attr("height", 2)
.attr("width", 796)
.style("fill", "black");
svg.selectAll("rect")
.data(data)
.enter().append("rect")
.attr("x", function(d) {
return d.x;
})
.attr("y", 200)
.attr("height", 100)
.attr("width", 15)
.style("fill", "lightblue")
.attr('id', function(d, i) {
return 'rect_' + i;
})
.attr("rx", 6)
.attr("ry", 6)
.attr("stroke-width", 2)
.attr("stroke", "black")
.call(d3.drag()
.on("start", dragstarted)
.on("drag", dragged)
.on("end", dragended))
.on("click", removeElement);
svg.on("click", function() {
var coords = d3.mouse(this);
var newData = {
x: d3.event.x,
y: d3.event.y
};
data.push(newData);
svg.selectAll("rect")
.data(data)
.enter()
.append("rect")
.attr("x", function(d) {
return d.x;
})
.attr("y", 200)
.attr("height", 100)
.attr("width", 15)
.style("fill", "steelblue")
.attr('id', function(d, i) {
return 'circle_' + i;
})
.attr("rx", 6)
.attr("ry", 6)
.attr("stroke-width", 2)
.attr("stroke", "black")
.call(d3.drag()
.on("start", dragstarted)
.on("drag", dragged)
.on("end", dragended))
.on("click", removeElement);
})
function dragstarted(d) {
d3.select(this).raise().classed("active", true);
}
function dragged(d) {
d3.select(this)
.attr("x", d.x = d3.event.x)
// .attr("cy", d.y = d3.event.y);
}
function dragended(d) {
d3.select(this)
.classed("active", false);
}
function removeElement(d) {
d3.event.stopPropagation();
d3.select(this)
.remove();
}
</script>
&#13;
这个问题来自here。
答案 0 :(得分:2)
首先,您的数据数组有4个元素,但是您只附加了2个矩形。发生这种情况是因为您在该SVG中选择以前存在的矩形。因此,而不是:
svg.selectAll("rect")
.data(data)
.enter().append("rect")
应该是:
svg.selectAll(null)
.data(data)
.enter().append("rect")
回到你的问题:
D3有基于数据操作元素的方法,但不基于元素操纵数据。
因此,您必须自己更改数据阵列。例如,在removeElement
内:
function removeElement(d) {
data = data.filter(function(e){
return e != d;
});
};
以下是包含这些更改的代码:
<!DOCTYPE html>
<meta charset="utf-8">
<style>
.active {
stroke: #000;
stroke-width: 2px;
}
</style>
<svg width="960" height="500"></svg>
<script src="//d3js.org/d3.v4.min.js"></script>
<script>
var svg = d3.select("svg"),
width = +svg.attr("width"),
height = +svg.attr("height"),
radius = 32;
var data = [{
x: 100,
y: 200
},
{
x: 200,
y: 300
},
{
x: 300,
y: 200
},
{
x: 400,
y: 300
}
];
var xScale = d3.scaleLinear()
.domain([0, d3.max(data, function(d) {
return d.x_pos
})]).range([0, width]);
svg.append("rect")
.attr("x", 100)
.attr("y", 250)
.attr("rx", 2)
.attr("ry", 2)
.attr("height", 6)
.attr("width", 800)
.style("fill", "grey");
svg.append("rect")
.attr("x", 102)
.attr("y", 252)
.attr("rx", 2)
.attr("ry", 2)
.attr("height", 2)
.attr("width", 796)
.style("fill", "black");
svg.selectAll(null)
.data(data)
.enter().append("rect")
.attr("x", function(d) {
return d.x;
})
.attr("y", 200)
.attr("height", 100)
.attr("width", 15)
.style("fill", "lightblue")
.attr('id', function(d, i) {
return 'rect_' + i;
})
.attr("rx", 6)
.attr("ry", 6)
.attr("stroke-width", 2)
.attr("stroke", "black")
.call(d3.drag()
.on("start", dragstarted)
.on("drag", dragged)
.on("end", dragended))
.on("click", removeElement);
svg.on("click", function() {
var coords = d3.mouse(this);
var newData = {
x: d3.event.x,
y: d3.event.y
};
data.push(newData);
svg.selectAll("rect")
.data(data)
.enter()
.append("rect")
.attr("x", function(d) {
return d.x;
})
.attr("y", 200)
.attr("height", 100)
.attr("width", 15)
.style("fill", "steelblue")
.attr('id', function(d, i) {
return 'circle_' + i;
})
.attr("rx", 6)
.attr("ry", 6)
.attr("stroke-width", 2)
.attr("stroke", "black")
.call(d3.drag()
.on("start", dragstarted)
.on("drag", dragged)
.on("end", dragended))
.on("click", removeElement);
})
function dragstarted(d) {
d3.select(this).raise().classed("active", true);
}
function dragged(d) {
d3.select(this)
.attr("x", d.x = d3.event.x)
// .attr("cy", d.y = d3.event.y);
}
function dragended(d) {
d3.select(this)
.classed("active", false);
}
function removeElement(d) {
d3.event.stopPropagation();
data = data.filter(function(e){
return e != d;
});
d3.select(this)
.remove();
}
</script>