d3拖动行为在html元素上无法正常工作

时间:2014-05-29 15:05:40

标签: html d3.js mouse drag

我想在表格中显示多个图表,每个图表都是一个单独的svg,用d3生成。

每个图表的高度必须易于调整 - 我希望通过在jsFiddle中调整4个面板(html,javaScript,css,output)的方式来完成,方法是将鼠标拖到边框上在这些面板之间 - 在我看来,它只是水平边框。

我想使用d3.behavior.drag()。当拖动边框(表格的td中的div或类似的东西)时,某些svg元素的高度必须改变。在我到目前为止的代码中,我只是简单的div而不是svg,以保持简单。

我有两个版本;一个“应该”正在工作,但不是,一个工作,但我不喜欢它(它使用d3.mouse(),“应该”不必要地复杂化);我想知道我是否在d3中发现了一个错误,或者(更有可能),我在“应该”工作的版本中没有做到这一点。

这是一个fiddle,它显示了工作版本;要查看不工作的版本(发生“抖动”),请切换ondragmove和_ondragmove的名称。

Voilà代码:

<table cellspacing="0" cellpadding="0">
    <tr><td><div class="content" id="content_0" style="height: 100px; background-color: yellow;"></div></td></tr>
    <tr><td><div class="spacer"  id="spacer_0"></div></td></tr>
    <tr><td><div class="content" id="content_1" style="height: 200px; background-color: green;"></div></td></tr>
    <tr><td><div class="spacer"  id="spacer_1"></div></td></tr>
    <tr><td><div class="content" id="content_2" style="height: 70px; background-color: orange;"></div></td></tr>
    <tr><td><div class="spacer"  id="spacer_2"></div></td></tr>
</table>

<div><br/>
    x&nbsp; <span id="xLog"></span><br/>
    y&nbsp; <span id="yLog"></span><br/>
    dx&nbsp; <span id="dxLog"></span><br/>
    dy&nbsp; <span id="dyLog"></span><br/>
    datumX&nbsp; <span id="datumXLog"></span><br/>
    datumY&nbsp; <span id="datumYLog"></span><br/>
    mouse &nbsp; <span id="mouseLog"></span><br/>
    body mouse &nbsp; <span id="bodyMouseLog"></span>
</div>






div.spacer {
    width: 400px;
    height:  5px;
    background-color: #ddd;
    cursor: ns-resize;
    position: relative;
    left: 0;
    top: 0;
}
div.content {
    width: 400px;
}

var heights = d3.selectAll(".content")[0].map(function(elt){return parseInt(d3.select(elt).style("height"));});

var xElt         = d3.select("#xLog");
var yElt         = d3.select("#yLog");
var dxElt        = d3.select("#dxLog");
var dyElt        = d3.select("#dyLog");
var datumXElt    = d3.select("#datumXLog");
var datumYElt    = d3.select("#datumYLog");
var mouseElt    = d3.select("#mouseLog");
var bodyMouseElt    = d3.select("#bodyMouseLog");
var theBody = d3.select("body").node();

var drag = d3.behavior.drag()
    .origin(function(x){return x;})
    .on("drag", dragmove)
    .on("dragstart", function(d){
        console.log("start" + d.index);
        y0 = d3.mouse(theBody)[1];
    })
    .on("dragend", function(d){
        console.log("end " + d.index);
        var newHeight = parseFloat(d3.select("#content_" + d.index).style("height"));
        heights[d.index] = newHeight;
    });

var spacers = d3.selectAll("div.spacer");
spacers.data(d3.range(heights.length).map(function(d,i){ return {x:0, y:0, index: i }}));

spacers.call(drag);

function showDebugOutput(d, that){
    xElt.text(d3.event.x);
    yElt.text(d3.event.y);
    dxElt.text(d3.event.dx);
    dyElt.text(d3.event.dy);
    datumXElt.text(d.x);
    datumYElt.text(d.y);
    mouseElt.text(d3.mouse(that).join(", "));
    bodyMouseElt.text(d3.mouse(theBody).join(", "));
}

function dragmove_NOT_WORKING(d){
    showDebugOutput(d, this);
    var elt = d3.select("#content_" + d.index);
    var originalHeight = heights[d.index];
    var newHeight = originalHeight + d3.event.y;
    elt.style("height",  newHeight + "px");
    d.x = d3.event.x;
    d.y = d3.event.y;
    elt.html("<br />" + newHeight);
}
function dragmove(d){
    showDebugOutput(d, this);
    var elt = d3.select("#content_" + d.index);
    var originalHeight = heights[d.index];
    y1 = d3.mouse(theBody)[1];
    var dy = y1 - y0;
    var newHeight = originalHeight + dy;
    elt.style("height",  newHeight + "px");
    d.x = d3.event.x;
    d.y = dy;
    elt.html("<br />" + newHeight);
}

这里是another fiddle,它完成了一个更简单的任务(使用d3拖动行为移动html div元素 - 移动的元素(调用拖动)对其他元素没有“副作用”,并且style.left和style.top是一对一的x和y的拖动行为,所以非常简单,我正在尝试做的更复杂。)只是为了表明它可以在非svg元素上使用拖动行为。

0 个答案:

没有答案