d3 点击创建圆,点击移除
d3 Click to create circle and click to remove
我试图点击一个圆圈将其删除,但点击 canvas 会创建一个圆圈。
我确实想从数据中实际删除圆及其对象,而不是仅仅使其透明。
点击圆圈调用函数
function removeElement(d) {
d3.select(this)
.remove();
}
通过基本点击圆圈调用此函数,
.on("click", removeElement);
我想我没有正确区分单击 canvas 以创建一个存在 none 的圆圈和单击一个现有圆圈将其删除。
<!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.selectAll("circle")
.data(data)
.enter().append("circle")
.attr("cx", function(d) {
return d.x;
})
.attr("cy", function(d) {
return d.y;
})
.attr("r", radius)
.style("fill", "lightblue")
.attr('id', function(d, i) {
return 'rect_' + i;
})
.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("circle") // For new circle, go through the update process
.data(data)
.enter()
.append("circle")
.attr("cx", function(d) {
return d.x;
})
.attr("cy", function(d) {
return d.y;
})
.attr("r", radius)
.style("fill", "red")
.attr('id', function(d, i) {
return 'circle_' + i;
})
.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("cx", d.x = d3.event.x)
.attr("cy", d.y = d3.event.y);
}
function dragended(d) {
d3.select(this)
.classed("active", false);
}
function removeElement(d) {
// need to remove this object from data
d3.select(this)
.remove();
}
</script>
这个问题是
问题的延伸
谢谢,
你的代码现在的问题是,如果你点击一个蓝色圆圈,它会删除那个圆圈并创建一个新的红色圆圈。发生这种情况是因为事件冒泡到 SVG 父元素。
一个简单的解决方案是在 removeElement
函数中执行此操作:
d3.event.stopPropagation();
正如 documentation 所解释的那样,stopPropagation
...
... prevents further propagation of the current event in the capturing and bubbling phases.
这是进行了更改的代码:
<!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.selectAll("circle")
.data(data)
.enter().append("circle")
.attr("cx", function(d) {
return d.x;
})
.attr("cy", function(d) {
return d.y;
})
.attr("r", radius)
.style("fill", "lightblue")
.attr('id', function(d, i) {
return 'rect_' + i;
})
.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("circle") // For new circle, go through the update process
.data(data)
.enter()
.append("circle")
.attr("cx", function(d) {
return d.x;
})
.attr("cy", function(d) {
return d.y;
})
.attr("r", radius)
.style("fill", "red")
.attr('id', function(d, i) {
return 'circle_' + i;
})
.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("cx", 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();
// need to remove this object from data
d3.select(this)
.remove();
}
</script>
PS:正如你现在可能知道的那样,我不太喜欢在同一个问题中回答 不同的 问题(这是我一直建议 OP 避免)。因此,我不处理数据问题,即删除与单击元素关联的数据。您随时可以问 另一个 问题...它是免费的!
我试图点击一个圆圈将其删除,但点击 canvas 会创建一个圆圈。
我确实想从数据中实际删除圆及其对象,而不是仅仅使其透明。
点击圆圈调用函数
function removeElement(d) {
d3.select(this)
.remove();
}
通过基本点击圆圈调用此函数,
.on("click", removeElement);
我想我没有正确区分单击 canvas 以创建一个存在 none 的圆圈和单击一个现有圆圈将其删除。
<!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.selectAll("circle")
.data(data)
.enter().append("circle")
.attr("cx", function(d) {
return d.x;
})
.attr("cy", function(d) {
return d.y;
})
.attr("r", radius)
.style("fill", "lightblue")
.attr('id', function(d, i) {
return 'rect_' + i;
})
.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("circle") // For new circle, go through the update process
.data(data)
.enter()
.append("circle")
.attr("cx", function(d) {
return d.x;
})
.attr("cy", function(d) {
return d.y;
})
.attr("r", radius)
.style("fill", "red")
.attr('id', function(d, i) {
return 'circle_' + i;
})
.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("cx", d.x = d3.event.x)
.attr("cy", d.y = d3.event.y);
}
function dragended(d) {
d3.select(this)
.classed("active", false);
}
function removeElement(d) {
// need to remove this object from data
d3.select(this)
.remove();
}
</script>
这个问题是
谢谢,
你的代码现在的问题是,如果你点击一个蓝色圆圈,它会删除那个圆圈并创建一个新的红色圆圈。发生这种情况是因为事件冒泡到 SVG 父元素。
一个简单的解决方案是在 removeElement
函数中执行此操作:
d3.event.stopPropagation();
正如 documentation 所解释的那样,stopPropagation
...
... prevents further propagation of the current event in the capturing and bubbling phases.
这是进行了更改的代码:
<!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.selectAll("circle")
.data(data)
.enter().append("circle")
.attr("cx", function(d) {
return d.x;
})
.attr("cy", function(d) {
return d.y;
})
.attr("r", radius)
.style("fill", "lightblue")
.attr('id', function(d, i) {
return 'rect_' + i;
})
.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("circle") // For new circle, go through the update process
.data(data)
.enter()
.append("circle")
.attr("cx", function(d) {
return d.x;
})
.attr("cy", function(d) {
return d.y;
})
.attr("r", radius)
.style("fill", "red")
.attr('id', function(d, i) {
return 'circle_' + i;
})
.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("cx", 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();
// need to remove this object from data
d3.select(this)
.remove();
}
</script>
PS:正如你现在可能知道的那样,我不太喜欢在同一个问题中回答 不同的 问题(这是我一直建议 OP 避免)。因此,我不处理数据问题,即删除与单击元素关联的数据。您随时可以问 另一个 问题...它是免费的!