2013-10-26 67 views
3

我正在使用d3的svg元素上的拖動行爲,可能需要將svg元素拖放到可見區域之外。我將它設置在兩個div中,溢出設置爲auto以啓用滾動。我只有一些瀏覽器,但不是全部。使用d3.js拖動元素時滾動

問題是,在某些瀏覽器中,您可以在拖動時滾動,但在其他瀏覽器中,拖動時窗口不會滾動。我至今還無法找到一種使這項工作始終如一的方法。

的工作示例看到小提琴:http://jsfiddle.net/glanotte/qd5Td/1/

這是工作的預期:

鉻 - MAC /窗 野生動物園 - MAC

但不工作的

火狐 - mac/windows IE - windows

html:

<div id="outerFrame"> 
    <div id="innerFrame"> 
     <svg width="600" height="600"> 
     </svg> 
    </div> 
</div> 

CSS:

#outerFrame{ 
    width: 300px; 
    height: 300px; 
    border: 1px solid red; 
    overflow: auto; 
} 

#innerFrame{ 
    width: 600px; 
    height: 600px; 
    background-color: lightgrey; 
} 

的javascript:

var drag = d3.behavior.drag() 
    .on("dragstart", dragstart) 
    .on("drag", dragmove) 
    .on("dragend", dragend); 

function dragstart() { 
    d3.select(this).style("border", "1px solid red"); 
} 

function dragmove(d) { 
    var coordinates = d3.mouse(d3.select("svg").node()); 
    d3.select(this).attr({ 
     x: coordinates[0] - 50, 
     y: coordinates[1] - 25 
    }) 

} 

function dragend() { 
    d3.select(this).style("border", null); 
} 

d3.select("svg") 
    .append("rect") 
    .attr({x: 100, y: 100, width: 100, height: 50}) 
    .call(drag); 

回答

3

你不幸在一個bug in Firefox這已經noticed before by mbostock and marked as WONT-FIX來襲。

按在bug報告建議,你可以把它的工作,但只能通過手動滾動容器:http://jsfiddle.net/62CYD/

的實現是非常簡單,可以通過改進:

  1. 使用動畫
  2. 考慮到滾動條的寬度,like done in DOMUtilityService in ng-grid
  3. Taking current mouse position into account避免捕捉被拖動的物品和平滑的滾動。
  4. 使用setTimeout繼續滾動即使拖動停止
function dragmove(d) { 
    var svg = d3.select("svg").node(), 
     $parent = $('#outerFrame'), 
     w = $parent.width(), h = $parent.height(), 
     sL = $parent.scrollLeft(), sT = $parent.scrollTop(); 

    var coordinates = d3.mouse(svg), 
     x = coordinates[0], 
     y = coordinates[1]; 

    if (x > w + sL) { 
     $parent.scrollLeft(x - w); 
    } else if (x < sL) { 
     $parent.scrollLeft(x); 
    } 

    if (y > h + sT) { 
     $parent.scrollTop(y - h); 
    } else if (y < sT) { 
     $parent.scrollTop(y); 
    } 

    d3.select(this).attr({ 
     x: x - 50, 
     y: y - 25 
    }) 
} 
+0

謝謝你,我希望這只是我是缺少一些簡單的設置。但我喜歡你的工作。我將在當時致力於實施和更新。 –

+0

感謝帖子,很好的回答! –