如何正确使用D3中的call()来绑定拖动行为



我需要创建一个矩形,让它监听拖动事件。根据文档,我必须先附加"rect",然后调用dragR(event)

d3.select('#rectangle').on('click', function(){ new Rectangle(); });
function Rectangle(preloaded = false, box = []) {
.......
var dragR = d3.behavior.drag().on('drag', dragRect);
function dragRect() {
var e = d3.event;
for(var i = 0; i < self.rectData.length; i++){
d3.select(self.rectangleElement[0][0])
.attr('x', self.rectData[i].x += e.dx )
.attr('y', self.rectData[i].y += e.dy );
}
rect.style('cursor', 'move');
updateRect();
}
rectangleElement = d3.select('svg').append('rect').attr('class', 'rectangle').call(dragR);
}

现在我的问题是rectangleElement究竟是什么?这是函数还是什么?有人能解释一下这个代码的工作流程是什么吗?此外,如果我想将另一个事件(说点击)绑定到它,该怎么办?

编辑:@altocumulus答案带来了关于方法结果的更多细节:)

什么是rectangleElement

rectangleElement是一个d3选择,包含您的rectsvg元素。

有人能解释一下这个代码的工作流程是什么吗

var dragR = d3.behavior.drag().on('drag', dragRect);

通过这一行,您定义了d3拖动行为,该行为为拖动事件(和触摸)创建事件侦听器。使用.on()方法,可以将处理程序附加到事件。在这里,您将函数dragRect附加到drag事件上。drag事件是在拖动元素时激发的事件(您还有dragStartdragEnd)。这一行只是定义了行为,它还没有链接到您的rect元素。

rectangleElement = d3.select('svg').append('rect').attr('class', 'rectangle').call(dragR);

在这一行中,您正在创建rect元素。首先选择第一个匹配的svg元素,然后在其中添加一个rect,在新创建的rect上添加类rectangle,最后将拖动侦听器附加到rect元素(call()函数文档)。

function dragRect() {
var e = d3.event;
for(var i = 0; i < self.rectData.length; i++){
d3.select(self.rectangleElement[0][0])
.attr('x', self.rectData[i].x += e.dx )
.attr('y', self.rectData[i].y += e.dy );
}
rect.style('cursor', 'move');
updateRect();
}

这是drag事件的处理程序,每次触发drag事件时都会调用此函数。这个函数使用了您没有在问题中添加的变量,但看起来像是更改了rect的x/y属性,然后移动它。

如果我想让它绑定另一个事件(点击)怎么办

有多种方法:您可以在创建rect元素时附加一个点击处理程序:

d3.select('svg')
.append('rect')
.attr('class', 'rectangle')
.on('click', function(){ console.log('clicked'); })
.call(dragR);

或者稍后通过选择rect元素将其附加:

d3.select('rect.rectangle')
.on('click', function(){ console.log('clicked'); })

以下是on()文档(适用于d3v3)

首先,通过使用d3.behavior.drag(),我们可以看出,您仍在使用D3 v3(这将是v4中的d3.drag()以及其他细微差异)。


您提供的代码包括在SVG元素上设置拖动行为所需的三个部分。

1.阻力行为本身

var dragR = d3.behavior.drag().on('drag', dragRect);

这是D3通过为拖动事件自动创建事件监听器来处理元素上的拖动手势的方法。对此行为调用.on()将注册一个处理程序函数(即dragRect),该函数将由它注册的事件触发(在您的情况下为drag)。

2.处理程序函数

function dragRect() {
// ...
}

该函数将为拖动行为所应用的元素上的拖动手势触发的每个事件调用。在该函数中,您将执行对拖动手势做出图形反应所需的所有操作,即数据操作、DOM更新等。

3.将拖动行为应用于选择

rectangleElement = d3.select('svg').append('rect').attr('class', 'rectangle').call(dragR);

创建拖动行为实例并指定适当的事件处理程序函数后,可以将此行为应用于D3选择。或者,用文件的话来说:

构建后,可以将拖动行为应用于选定的元素使用选择。调用

查看selection.call()的文档可以回答您的问题:此函数的返回值是什么:

无论指定函数的返回值。

因此,rectangleElement将保存对包含先前附加的<rect>的D3选择的引用。


由于您要求它,在v3中,一个选择将是一个数组数组,如处理程序函数中所示,其中元素以self.rectangleElement[0][0]的形式访问)。然而,对于初学者来说,您不应该过于关注实现细节。只要知道它是一个D3选择就足够了,它有一个定义良好的API。


因为rectangleElement是一个D3选择,所以您可以通过链接对selection.on():的进一步调用来轻松地在其上注册更多的事件处理程序

rectangleElement.on("click", function(d) { });

为了避免组合单击和拖动处理程序时的常见陷阱,您可能需要查看Mike Bostock的单击与拖动块。

最新更新