2013-04-12 40 views
9

我正在嘗試使用d3框架爲由HTML文本和背景矩形組成的組實現拖動行爲。我能夠得到它的工作,雖然沒有設置drag.origin時,我可以看到由於鼠標位置/元素座標偏移而引起的明顯跳轉。具體如何描述d3 wiki-page 儘管該頁面描述瞭如何設置拖動的原點,但我沒有正確理解TI如何在我的示例中實現它。我嘗試了兩種不同的方法:使用元素將元素分組在一起,並定義新元素。在第一種情況下,我不得不使用翻譯功能,我甚至不知道如何獲得組的座標。如何在d3 JavaScript庫中爲拖動行爲設置Origin(drag.origin)

var svg = d3.select("body").append("svg") 
    .attr("width", 960) 
    .attr("height", 500); 

var group = svg.append("svg:g") 
    .attr("transform", "translate(10, 10)") 
    .attr("id", "group"); 

var rect1 = group.append("svg:rect") 
    .attr("rx", 6) 
    .attr("ry", 6) 
    .attr("x", 5/2) 
    .attr("y", 5/2) 
    .attr("id", "rect") 
    .attr("width", 250) 
    .attr("height", 125) 
    .style("fill", 'white') 
    .style("stroke", d3.scale.category20c()) 
    .style('stroke-width', 5); 


var html1 = group.append("foreignObject") 
    .attr("x", 50) 
    .attr("y", 25) 
    .attr("width", 200) 
    .attr("height", 100) 
    .attr("id", "fobject") 
    .style("border-color", d3.scale.category20c()) 
    .append("xhtml:div") 
    .style("font", "14px 'Helvetica Neue'") 
    .html("Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec eu enim quam."); 

var innerSvg = svg.append("svg") 
    .attr("x", 500) 
    .attr("y", 10) 
    .attr("id", "innerSvg"); 

var rect2 = innerSvg.append("svg:rect") 
    .attr("rx", 6) 
    .attr("ry", 6) 
    .attr("x", 5/2) 
    .attr("y", 5/2) 
    .attr("id", "rect") 
    .attr("width", 250) 
    .attr("height", 125) 
    .style("fill", 'white') 
    .style("stroke", d3.scale.category20c()) 
    .style('stroke-width', 5); 

var html2 = innerSvg.append("foreignObject") 
    .attr("x", 50) 
    .attr("y", 25) 
    .attr("width", 200) 
    .attr("height", 100) 
    .attr("id", "fobject") 
    .style("border-color", d3.scale.category20c()) 
    .append("xhtml:div") 
    .style("font", "14px 'Helvetica Neue'") 
    .html("Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec eu enim quam."); 

var drag1 = d3.behavior.drag() 
    .on("drag", function(d,i) { 
     d3.select(this).attr("transform", function(d,i){ 
      return "translate(" + [ d3.event.x,d3.event.y ] + ")" 
     }) 
    }); 

var drag2 = d3.behavior.drag() 
    .on("drag", function(d,i) { 
     d3.select(this) 
     .attr("x", d3.event.x) 
     .attr("y", d3.event.y); 
    }); 

group.call(drag1); 
innerSvg.call(drag2); 

我會非常感激任何的解釋,自然我準備在這裏工作的例子:http://jsfiddle.net/Y8y7V/

回答

22

您只需要設置相應的origin()功能。在第二種情況下,這很簡單,在第一種情況下比較困難,因爲您正在使用座標以及變換。基本模式(第二種情況)是這樣的:

.origin(function() { 
     var t = d3.select(this); 
     return {x: t.attr("x"), y: t.attr("y")}; 
    }) 

更新的jsfiddle here

+0

非常感謝您對您的解釋。在第一種情況下,我可以簡單地將x/y座標作爲元素的參數。我想知道如何根據定義的x/y參數設置翻譯參數,例如:var group = svg.append(「svg:g」) .attr(「x」,50) .attr(「y」 ,25) .attr(「transform」,「translate(」+ [this.attr(「x」),this.attr(「y」)] +「)」) 這個ocourse不會工作,因爲這個引用窗口對象。 – karlitos

+0

如果您適當地設置了'origin()',則不需要根據靜態座標設置變換。 –

+2

哪個不能解決我的問題 - 我還無法找到答案的問題 - 如何獲取組的位置,當我只能使用「變換」設置其位置時。 謝謝無論如何,您先前的解釋解決了我的問題,並且我能夠找到適用於展位箱的工作解決方案。 – karlitos

0

組元素沒有x/y屬性 - 沒問題!創建者:

var node = svg.append("g") 
      .attr('x',x_1) 
      .attr('y',y_1) 
      .attr("class","node") 
      .attr("name","Node_A") 
      .attr("transform","translate(" + x_1 + ", " + y_1 +")") 
      .call(drag); 

時,從拉斯的.origin功能將工作

不要忘記更新的x,y屬性,同時拖動:

function dragged() { 

    d3.select(this).attr("transform","translate(" + d3.event.x + ", " + d3.event.y +")"); 
    d3.select(this).attr("x",d3.event.x); 
    d3.select(this).attr("y",d3.event.y); 
}