在Vue/D3项目中,我需要对某些可拖动元素的移动位置设置一些限制。
下面是dragmove
处理程序的摘录:
dragmove: function(d, i, n) {
// Stop if the node crosses a border
if (parseInt(n[i].getAttribute('x')) > 200) {
this.drag.dragend();
}
}
this.drag.dragend();
取自an older answer on Stackoverflow。不幸的是,它在D3 v5 (this.drag.dragend is not a function
)中不起作用。
这是我的drag
变量:
drag: d3.drag()
.on('drag', this.dragmove)
.on('end', this.dragended),
有没有办法更新我的代码以与更新版本的D3协同工作?
发布于 2019-09-20 17:27:45
您可以使用d3.event.on
临时覆盖事件侦听器。因此,要在拖动事件本身期间以编程方式中断拖动,我们可以使用:
d3.event.on("drag", null)
d3.event.on("end", null)
这会临时删除分配给每个事件侦听器的函数。你会注意到我也删除了end事件-否则它将继续侦听鼠标释放,而不管是否有一个函数被分配给“拖动”事件侦听器。
此功能在event.on下的d3-拖动中进行了描述:
event.on(类型名称,监听程序)
等同于drag.on,但仅适用于当前拖动手势。在拖动手势开始之前,将创建当前拖动事件侦听器的副本。此副本绑定到当前拖动手势,并由event.on修改。这对于仅接收当前拖动手势事件的临时侦听器非常有用。(source)
在下面的示例中,当圆与线相撞时,拖动事件将临时从圆中删除。调度自定义事件以指示拖动以编程方式中断。记录所有事件-表明结束、拖动和中断事件按预期工作:
var svg = d3.select("svg");
var drag = d3.drag()
.on("drag", function() {
log(); // to log events as they are triggered.
var selection = d3.select(this);
// Update the circle as normal (but don't let cx exceed the line visually):
selection.attr("cx", d3.event.x > 300 ? 300 : d3.event.x)
.attr("cy", d3.event.y);
// If event.x > 300, interrupt drag:
if(d3.event.x > 300) {
// Disable the drag events temporarily
d3.event.on("drag", null)
d3.event.on("end", null)
// Optionally trigger some alternative event
selection.dispatch("interrupted");
}
})
.on("end", function() {
log();
})
var circle = svg.select("circle")
.call(drag)
.on("interrupted", function() {
d3.select(this)
.transition()
.attr("fill","orange")
.attr("cx",250)
.transition()
.attr("fill","steelblue");
log();
})
function log() {
console.log(d3.event.type);
}
.as-console-wrapper { max-height: 40% !important; }
circle { cursor: pointer ; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<svg width="500" height="300">
<circle cx="100" cy="50" fill="steelblue" r="10"></circle>
<line x1="305" x2="305" y1="0" y2="400" stroke-width="1" stroke="black"></line>
</svg>
https://stackoverflow.com/questions/58023831
复制