简体   繁体   English

无法拖入d3

[英]Unable to drag in d3

I have the following D3 code, but I'm unable to drag the rect element successfully. 我有以下D3代码,但无法成功拖动rect元素。 (please ignore bad indentation) I'm unable to understand what I'm doing wrong here. (请忽略错误的缩进),我无法理解我在做什么错。

var svg = d3.select('#slider').append('svg')
    .attr('width', width)
    .attr('height', height);


var drag = d3.behavior.drag()
    .origin(function (d) {
        return d;
    })
    .on("dragstart", dragstarted)
    .on("drag", dragged);

//Called when drag event starts. It stop the propagation of the click event
function dragstarted(d) {
    d3.event.sourceEvent.stopPropagation();
}

//Called when the drag event occurs (object should be moved)
function dragged(d) {
    d.x = d3.event.x;
    d.y = d3.event.y;
    //Translate the object on the actual moved point
    d3.select(this).attr({
        transform: "translate(" + d.x + "," + d.y + ")"
    });
};

svg.append('rect')
    .attr('width', 500)
    .attr('height', 250)
    .attr('x', 10)
    .attr('y', 50)
    .attr('fill', "transparent")
    .attr('stroke', "orange")
    .attr('stroke-width', 2)
    .append("title")
    .text(function (d) {
        return "Zone 1";
    })
    .call(drag);

There are some issues: 有一些问题:

  1. You are not binding any data to your <rect> . 您没有将任何数据绑定到<rect> Your callbacks for .origin() and .on() will fail when trying to refer to that data via their parameter d . 当尝试通过参数d引用该数据时, .origin().on()回调将失败。 You could set up an object with your <rect> s configuration which may be used throughout your code. 您可以使用<rect>的配置设置一个对象,该对象可以在您的整个代码中使用。

     // Configuration for rect var rect = { x: 50, y: 50, w: 500, h: 250, t: "Zone 1" }; svg.selectAll("rect") .data([rect]) // bind your config to the rect to be appended .enter().append('rect') .attr('width', function(d) { return dw; }) .attr('height', function(d) { return dh; }) 

    This way it is bound to your <rect> and will therefore be accessible even from within the drag handler. 这样,它绑定到了<rect> ,因此即使在拖动处理程序中也可以访问它。 This is a very common pattern in D3.js. 这是D3.js中非常常见的模式。

  2. You are calling .drag() after appending the <title> element to the <rect> , which adds the drag behaviour to the title instead of to the <rect> . <title>元素附加到<rect> ,您将调用.drag() ,这会将拖动行为添加到标题而不是<rect> To add the drag to the <rect> you have to move it up the call chain. 要将拖动添加到<rect>您必须将其向上移动到调用链中。

     svg.selectAll("rect").data([rect]).enter().append('rect') // ... .call(drag) .append("title") .text(function(d){return dt;}); 
  3. To position your <rect> you are using a combination of a) its attributes x and y and b) a transformation when setting translate while handling the drag's offset. 要定位你的<rect>您正在使用)及其属性的组合xy当设置和b)转换translate在处理拖动的偏移。 Mixing both methods will usually screw things up. 混合这两种方法通常会搞砸。 You should choose either one of those methods and then consistently stick to it. 您应该选择其中一种方法,然后始终坚持下去。

I have set up a working snippet with some more comments explaining the changes. 我已经建立了一个工作片段,并提供了更多注释来解释更改。

 var width = 10000, height = 10000; var svg = d3.select('body').append('svg') .attr('width', width) .attr('height', height); var drag = d3.behavior.drag() .origin(function(d) { return d; }) // this will access the bound config accessing its x and y .on("dragstart", dragstarted) .on("drag", dragged); //Called when drag event starts. It stop the propagation of the click event function dragstarted(d) { d3.event.sourceEvent.stopPropagation(); } //Called when the drag event occurs (object should be moved) function dragged(d) { dx = d3.event.x; // update x of the config object dy = d3.event.y; // update y of the config object // Set new x and y on drag d3.select(this).attr({ "x": dx, "y": dy }); }; // Configuration for rect var rect = { x: 50, y: 50, w: 500, h: 250, t: "Zone 1" }; svg.selectAll("rect") .data([rect]) .enter().append('rect') .attr('width', function(d) { return dw; }) .attr('height', function(d) { return dh; }) .attr('x', function(d) { return dx; }) .attr('y', function(d) { return dy; }) .attr('fill', "transparent") .attr('stroke', "orange") .attr('stroke-width', 2) .call(drag) // call this before the title is appended .append("title") .text(function(d) { return dt; }); 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script> 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM