1

我正在尝试创建将包含一些可视化的面板组件。我正在用 svgs 制作面板组件。它们看起来不错,但是在调整面板大小和移动面板时出现了一些奇怪的行为。

var groups = ["uno", "dos", "tres", "cuatro"];
var w = 350;
var x = 0;
var y = 0;
var width = 800;
var h = 200;
var height = 800;

var val = [];

var drag = d3.behavior.drag()
    .origin(Object)
    .on("drag", move);

var resize = d3.behavior.drag()
    .origin(Object)
    .on("drag", dragResize);

svg = d3.select("body").append("div").append("svg");
charts = svg.selectAll("g.chart")
           .data(groups); //(dims);
box = charts.enter()
    .append("g").classed("chart", true)
    .attr("id", function(d,i) { return "box"+i})
//.data([{x: 95, y: 0}]);


box.append("rect").classed("box", true)

var t = box.append("rect").classed("titleBox", true)
t.call(drag);
box.append("text").classed("title", true).data(groups)
box.append("text").classed("legend", true).data(groups)
box.append("rect").classed("icon", true)
    .call(resize);

box.selectAll("rect.box")
     .data([{x: 95, y: 0}])
     .attr({
           x: function(d) { return d.x; },
           y: function(d) { return d.y; },
           width: w,
           height: function(d) { return 200}//d.length*30 + 60}
      })

box.selectAll("rect.titleBox")
    .classed("drag", true)
    .data([{x: 95, y: 0}])
    .attr({
           x: function(d) { return d.x; },
           y: function(d) { return d.y; },
           width: w,
           height: 25,
           fill: "#000000"
     })


box.selectAll("text.title")
    .attr({
           x: 105,
           y: 20,
           width: 350,
           height: 25,
           fill: "#ffffff"
     })
    .text(function(d) {
           console.log("i from title "+ d);
             return d;
     })

box.selectAll("text.legend")
     .attr({
           x: 105,
           y: 45,
           width: 200,
           height: 25,
           fill: "#999999"
      })
      .text(function(d) {
           return d;
      })

box.selectAll("rect.icon")
    .data([{x: 429, y: 184}])
    .attr({
          x: function(d) { return d.x; },
          y: function(d) { return d.y; },
          width: 16,
          height: 16,
          fill: "#999999"
    })

var dx = 429;
var dy = 184;       

function move(){
     var dragTarget = d3.select(this);
     var dragObject = d3.select(this.parentNode);

     console.log("move x:"+x+" y:"+y);
     //console.log("d3.event.x:"+d3.event.x+" d3.event.y:"+d3.event.y);

     x += d3.event.x - parseInt(dragTarget.attr('x'));
     y += d3.event.y - parseInt(dragTarget.attr("y"));
     console.log("x:"+x+" y:"+y);

    dragObject
         .attr("transform", "translate(" + x + "," + y + ")")
};

function dragResize(){
     var dragx = Math.max(dx + (16/2), Math.min(w, dx + width + d3.event.dx));
     var dragy = Math.max(dy + (16/2), Math.min(h, dy + height + d3.event.dy));

     //console.log("resize x:"+x+" y:"+y);
     console.log("d3.event.x:"+d3.event.dx+" d3.event.y:"+d3.event.dy);

     var dragTarget = d3.select(this);
     var dragObject = d3.select(this.parentNode);

     var o = dragObject.select("rect.box");
     var o1 = dragObject.select("rect.titleBox");


     var oldx = dx; 
     var oldy = dy;

    dx = Math.max(0, Math.min(dx + width - (16 / 2), d3.event.x)); 
    dy = Math.max(0, Math.min(dy + height - (16 ), d3.event.y));
    w = w - (oldx - dx);
    h = h - (oldy - dy);


    dragTarget
         .attr("x", function(d) { return dragx - (16/2) })
         .attr("y", function(d) { return dragy - (16) })

    o.attr("width", w)
     .attr("height", h);

    o1.attr("width", w);
};

我已将代码发布在http://jsfiddle.net/dtqY5/

问题如下:我可以通过拖动标题区域来移动每个面板,没有问题。Howvwer,在调整任何面板的大小后,我无法再移动它们。他们跳到原来的位置。x 和 y 变成 NaN,但我不明白为什么。

欢迎任何想法和建议。

4

1 回答 1

2

D3 使用drag.origin您提供的访问器来计算偏移量。由于您提供的访问权限只是一个空对象,因此此偏移量为 NaN,这导致事件xy事件上也为 NaN。

如果您drag.origin完全删除,它将使用当前鼠标位置作为原点,当您开始拖动时,面板会跳转。如果您将原点指定为被拖动形状的位置,它看起来会更好:

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

这是一个更新的小提琴:http: //jsfiddle.net/4nvhc/

于 2013-09-19T20:58:34.810 回答