[英]Implement panning while keeping nodes draggable in d3 force layout
我使用d3.layout.force
可视化图形结构。 我想要节点拖动功能和平移功能。 (通过“平移”,我的意思是类似Google Maps的行为。)
如几个d3示例中所示,可以使nodes.call(force.drag)
成为可拖动节点。 可以通过d3.behavior.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行)可以进行平移,但会使节点变得无法拖动。
如何在保持节点可拖动的同时实现图形平移?
这是您的操作方法: 演示
想法是将具有可拖动行为的区域放在包含节点的区域下,以便节点仍可以接收鼠标事件。
// 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);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.