toolness/collusion — Issue #48: Graph gets all flickery when you're dragging a node
Author: jonoxia
Created: 2012-02-09 19:01:54+00:00
State: open
Labels: Bugs, Visuals

Because the act of dragging a node means repeatedly mousing over and then mousing out of a the node you're dragging, and possibly other nodes as well, which keeps triggering the fadeout/fadein of the other nodes.

Need to disable the fadeout/fadein while you're dragging. Leave it in one state. The mouseover/mouseout handlers should not do anything while you're dragging.

How to implement this, though? There's not a way to poll the current state of the mouse button - we have to use an event listener. Thing is, force.drag is capturing the mouse down events on the nodes, so if we try to add an extra listener for mouse down, either force.drag won't get the event, or our extra listener won't get the event.

Possible solutions:

1. have our listener trigger first and not consume the event (how to do this?); maintain a variable to track state of the mouse button, have the mouseover/mouseout handlers return immediately if the mouse button is down. Will also need to catch the mouseup event whether it is in a node or not -- you might let go in a node or you might let go over the background, so probably there needs to be multiple mouse up handlers.

2. This would all be much easier if we could just ask the force object in d3.layout.js to tell us whether the mouse button is down or not, since it is already maintaining this state internally. However, it doesn't expose its internal state (the variable is hidden using closures). There's a fairly trivial modification that would make it expose this state:

force.isDragging = function() {
return (d3_layout_forceDragNode != null);
};

... which our code could then easily use to solve this problem. However, modifying a 3rd-party library could cause maintainance problems especially when that library issues an update of its own.