我需要创建一个矩形并让它听一个拖动事件。根据文档,我必须首先附加'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
究竟是什么?它是功能还是其他什么?任何人都可以解释这段代码的工作流程是什么?另外,如果我想将另一个事件(所说的点击)绑定到它,该怎么办?
答案 0 :(得分:2)
编辑:@altocumulus答案带来有关方法结果的更多细节:)
究竟是什么
rectangleElement
rectangleElement
是d3 Selection,包含您的rect
svg元素。
任何人都可以解释这段代码的工作流程
var dragR = d3.behavior.drag().on('drag', dragRect);
使用此行,您将定义d3 Drag behavior,为拖动事件(和触摸)创建事件侦听器。使用.on()
方法,您可以将处理程序附加到事件。在这里,您在dragRect
事件上附加了drag
函数。 drag
事件是您在拖动元素时触发的事件(您还有dragStart
和dragEnd
)。此行仅定义行为,但尚未与您的rect
元素相关联。
rectangleElement = d3.select('svg').append('rect').attr('class', 'rectangle').call(dragR);
在此行中,您将创建rect
元素。您首先选择第一个匹配的svg
元素,然后在其中添加rect
,在新创建的rectangle
上添加类rect
,最后将拖动侦听器附加到您的rect
元素call()
function doc)。
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()
documentation(对于d3v3)
答案 1 :(得分:2)
首先,通过您使用d3.behavior.drag()
我们可以告诉您,您仍在使用D3 v3(在v4中这将是d3.drag()
以及其他微妙的差异。)
您提供的代码包含在SVG元素上设置drag behavior所需的三个部分。
<强> 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选择。或者,用documentation:
的话来说构建后,您可以将拖动行为应用于所选元素 使用selection.call
查看selection.call()
的文档可以回答您的问题:该函数的返回值是什么:
无论如何,呼叫操作员始终返回当前选择 指定函数的返回值。
因此,rectangleElement
将保留对包含之前附加的<rect>
的D3选择的引用。
由于你要求它,在v3中,选择将是一个数组数组,如处理函数中所示,其中元素被访问为self.rectangleElement[0][0]
)。但是,在初学者级别,您不应过多关注实现细节。只需知道它是D3选择就足够了,它具有定义良好的API。
由于rectangleElement
是D3选择,您可以通过链接对selection.on()
的进一步调用轻松地在其上注册更多事件处理程序:
rectangleElement.on("click", function(d) { });
为了避免在组合点击和拖动处理程序时常见的陷阱,您可能需要查看Mike Bostock的Click vs. Drag阻止。