首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >d3.behavior.zoom()跳跃

d3.behavior.zoom()跳跃
EN

Stack Overflow用户
提问于 2016-10-15 05:31:50
回答 1查看 418关注 0票数 1

我有下面的d3图表。它只是几个节点和它们之间的链接。这个图表做了两件事:

  1. 您可以单击并拖动图形周围的各个节点。
  2. 您可以单击并拖动svg,以便使用d3.behavior.zoom进行平移(并使用鼠标轮进行缩放)。

我看到的问题是,如果我拖动一个节点(例如,向右移动一个节点20 per),然后尝试平移图表,整个图会立即向右跳20 per(如本例所示)。d3.behavior.zoom最初似乎使用了拖动节点的d3.event之类的方法。不确定。以下是代码:

代码语言:javascript
复制
var data = {
  nodes: [{
    name: "A",
    x: 200,
    y: 150,
    size: 30
  }, {
    name: "B",
    x: 140,
    y: 300,
    size: 15
  }, {
    name: "C",
    x: 300,
    y: 300,
    size: 15
  }, {
    name: "D",
    x: 300,
    y: 180,
    size: 45
  }],
  links: [{
    source: 0,
    target: 1
  }, {
    source: 1,
    target: 2
  }, {
    source: 2,
    target: 3
  }, ]
};

var dragging = false;

var svg = d3.select("body")
  .append("svg")
  .attr("width", "100%")
  .attr("height", "100%")
  .call(d3.behavior.zoom().on("zoom", function() {
    if (dragging === false) {
      svg.attr("transform", "translate(" + d3.event.translate + ") scale(" + d3.event.scale + ")")
    }
  })).append("g");

var links = svg.selectAll("link")
  .data(data.links)
  .enter()
  .append("line")
  .attr("class", "link")
  .attr("x1", function(l) {
    var sourceNode = data.nodes.filter(function(d, i) {
      return i == l.source
    })[0];
    d3.select(this).attr("y1", sourceNode.y);
    return sourceNode.x
  })
  .attr("x2", function(l) {
    var targetNode = data.nodes.filter(function(d, i) {
      return i == l.target
    })[0];
    d3.select(this).attr("y2", targetNode.y);
    return targetNode.x
  })
  .attr("fill", "none")
  .attr("stroke", "white");

var nodes = svg.selectAll("node")
  .data(data.nodes)
  .enter()
  .append("circle")
  .each(function(d, i) {
    d.object = d3.select(this);
    console.log(d);
  })
  .attr("class", "node")
  .attr("cx", function(d) {
    return d.x
  })
  .attr("cy", function(d) {
    return d.y
  })
  .attr("r", function(d) {
    return d.size;
  })
  .on('click', function(d) {

  })
  .call(d3.behavior.drag()
    .on('dragstart', function() {
      dragging = true;
    })
    .on('dragend', function() {
      dragging = false;
    })
    .on("drag", function(d, i) {
      d.x += d3.event.dx
      d.y += d3.event.dy
      d3.select(this).attr("cx", d.x).attr("cy", d.y);
      links.each(function(l, li) {
        if (l.source == i) {
          d3.select(this).attr("x1", d.x).attr("y1", d.y);
        } else if (l.target == i) {
          d3.select(this).attr("x2", d.x).attr("y2", d.y);
        }
      });
    })
  );

下面是一个演示:

https://jsfiddle.net/25q1Lu3x/2/

我怎样才能防止最初的跳跃,当我试图在周围翻滚?我读过一些东西,它们建议制作一个额外的嵌套svg g元素,并在其中移动,但这似乎没有什么区别。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-10-15 06:18:40

根据D3 v3 API:

将拖动行为与其他事件侦听器组合用于交互事件时(例如拖动优先于缩放),还可以考虑停止在源事件上的传播,以防止多个操作。

所以,在您的dragstart中,只需添加d3.event.sourceEvent.stopPropagation();

代码语言:javascript
复制
.on('dragstart', function() {
    d3.event.sourceEvent.stopPropagation();
    dragging = true;
});

这是你的小提琴:https://jsfiddle.net/hj7krohd/

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/40055351

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档