javascript - 使用 d3.js 拖动元素时滚动

标签 javascript d3.js

我在 svg 元素上使用 d3 的拖动行为,可能需要将其拖放到可见区域之外。我在两个 div 中设置了它,并将溢出设置为自动以启用滚动。我有这个只适用于一些浏览器,但不是全部。

问题是在某些浏览器中,您可以在拖动时滚动,但在其他浏览器中窗口不会在拖动时滚动。到目前为止,我还无法找到使这项工作始终如一的方法。

有关工作示例,请参阅 fiddle :http://jsfiddle.net/glanotte/qd5Td/1/

这按预期工作:

Chrome - 苹果电脑/ window Safari - mac

但没有工作

Firefox - 苹果电脑/ window IE-窗口

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);

最佳答案

不幸的是,您遇到了 bug in Firefox这是noticed before by mbostock and marked as WONT-FIX .

根据错误报告中的建议,您可以让它工作,但只能通过手动滚动容器: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
    })
}

关于javascript - 使用 d3.js 拖动元素时滚动,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19602404/

相关文章:

javascript - 如何在类中设置局部变量

javascript - 网页的加载和执行顺序?

javascript - 安卓 WebView : Very laggy button response

javascript - 在<li>中放置onClick事件来调用AJAX

text - 旋转 d3 中的 x 轴文本

javascript - 将 if 语句与创建映射变量结合使用 (Javascript)

Javascript - 检查对象属性存在时避免异步竞争条件

javascript - 无法将值插入数组

javascript - 重复应用 d3 转换导致内存泄漏

d3.js-堆叠的条形图中的第2组数据值