【问题标题】:Implement panning while keeping nodes draggable in d3 force layout实现平移,同时在 d3 强制布局中保持节点可拖动
【发布时间】:2013-12-04 15:27:13
【问题描述】:

我使用d3.layout.force 来可视化图形结构。 我想要节点拖动功能和平移功能。 (“平移”是指谷歌地图行为。)

如几个 d3 示例所示,可以通过nodes.call(force.drag) 使节点可拖动。 并且平移可以通过d3.behavior.drag实现。

但是,它们似乎不能同时使用。

这是一个代码示例:

var width = 400, height = 300;
var svg = d3.select('body').append('svg').attr({width: width, height: height});

var nodes = [{}, {}, {}, {}];
var links = [
    {source: 1, target: 0},
    {source: 2, target: 0},
    {source: 0, target: 3}
];

var nodeSel = svg.selectAll('circle')
    .data(nodes).enter().append('circle')
    .attr('r', 10).attr('fill', 'black');
var linkSel = svg.selectAll('line').data(links).enter().append('line')
    .attr('stroke', 'black');

var force = d3.layout.force()
    .size([width, height])
    .nodes(nodes).links(links)
    .linkDistance(80)
    .charge(-300)
    .on('tick', function() {
        linkSel
            .attr('x1', function(d) { return d.source.x; })
            .attr('y1', function(d) { return d.source.y; })
            .attr('x2', function(d) { return d.target.x; })
            .attr('y2', function(d) { return d.target.y; });
        nodeSel
            .attr('cx', function(d) { return d.x; })
            .attr('cy', function(d) { return d.y; });
    });

nodeSel.call(force.drag);


/* This block of codes spoils force.drag */
/* ****************************************
var drag = d3.behavior.drag();
var viewBoxX = 0, viewBoxY = 0;
drag.on('dragstart', function() {
    console.log('new dragstart is called');
}).on('drag', function() {
    viewBoxX -= d3.event.dx;
    viewBoxY -= d3.event.dy;
    svg.attr('viewBox', [viewBoxX, viewBoxY, width, height].join(' '));
}).on('dragend', function() {
    console.log('new dragend is called');
});
svg.call(drag);
**************************************** */


force.start();

(工作一个在 jsfiddle 上:http://jsfiddle.net/dersinces/hzL8T/1/。)

此代码仅启用节点拖动,而不启用平移。 激活底部的代码块(第 36 行)启用平移,但它使节点不可拖动。

如何在保持节点可拖动的同时实现图形平移?

【问题讨论】:

  • 您只需要缩放行为(它也可以拖动)。参见例如here.
  • 谢谢,@LarsKotthoff!我去看看d3.behavior.zoom。

标签: javascript d3.js drag force-layout pan


【解决方案1】:

您可以这样做:Demo

想法是将具有可拖动行为的区域放在包含节点的区域下方,以便节点仍然可以接收鼠标事件。

// First append the area where the dragging will happen.
svg.append('rect')
  .classed('bg', true)
  .attr('stroke', 'transparent')
  .attr('fill', 'transparent')
  .attr('x', 0)
  .attr('y', 0)
  .attr('width', width)
  .attr('height', height)
  .call(drag);


// Then add the area which will contain the nodes.
var nodeArea = svg.append('g')
                 .classed('node-area', true);

【讨论】:

  • 演示似乎没有解决我的问题。节点不可拖动,平移不适用于链接。也许您的意思是插入不可见的矩形(与@LarsKotthoff 的示例相同)。但是,这种方式平移受到矩形大小的限制。如果可能的话,我想要另一个解决方案。
  • 啊!对于那个很抱歉。我链接到较旧的演示版本。我现在指出的版本应该可以工作。
  • 抱歉回复晚了,@musically_ut。您的新演示完美运行!你解决了我的问题。真的谢谢!
猜你喜欢
  • 1970-01-01
  • 2014-08-29
  • 1970-01-01
  • 1970-01-01
  • 2019-05-14
  • 2014-06-30
  • 2012-09-22
  • 2012-11-06
  • 2019-01-06
相关资源
最近更新 更多