D3 layout: drag-and-drop panning (zooming) smoother

I have a d3.js static forces layout graph that can get quite large (sometimes parts of it are cropped), so I would like to allow the user to pan the entire graph by dragging it. I don’t think that I need to drag and drop individual nodes, I have a feeling that it will just be confusing, but I would like to show parts of the graph that are cut off by svg borders.

I have a minimal example at http://bl.ocks.org/3811811 that uses

visF.append("rect") .attr("class", "background") .attr("width", width) .attr("height", height) .call(d3.behavior.zoom().on("zoom", redrawVisF)); function redrawVisF () { visF.attr("transform","translate(" + d3.event.translate + ")" + " scale(" + d3.event.scale + ")"); } 

to implement panning, but I find it really β€œskittery” and not very smooth at all, to the extent that I suppose this will stop people from trying to drag and drop in general. Has anyone understood why this is happening and / or an idea how to fix it?

+7
source share
1 answer

The problem is that d3.behavior.zoom retrieves the current mouse position relative to the container element of the clicked item element, and you move the container element! Thus, the relative position is constantly changing, hence the jitter effect that you see.

You probably want to move the background <rect> so that it is a direct child of the <svg> element. This is achieved by two things:

  • Now the position will refer to the <svg> container, which is not moving.
  • You are currently moving <rect> when zooming or panning, so the resizable zoom area and parts of the viewport no longer scale. Having the background <rect> in the same place also fixes this problem.
+13
source

All Articles