DEV Community

Ramy Othman
Ramy Othman

Posted on Originally published at grafloria.com

Draggable edges that stay routed

Originally published on the Grafloria engineering blog.

The single most-voted react-flow question on Stack Overflow is disarmingly simple: "Is it possible to shape reactflow edges by dragging them?" The accepted reality in the answers: not built in — write a custom edge, manage your own control points. Anyone who has built a wiring UI knows why users keep asking: the router's idea of a good path and a human's idea of a readable path are different things.

Why "just add drag handles" fails

The naive version stores pixel positions for a bend and draws through them. It works until anything moves. Then you face the real question: when the router recomputes — because a node moved, because an obstacle appeared — what happens to the user's bend?

  • If the router discards it, users learn their edits don't stick and stop
    making them. (This is the classic smart-router-vs-segment-tool conflict — the same one JointJS users hit when the Manhattan router and the vertex tool fight over the same path.)

  • If the router defers to it entirely, the edge happily runs through the
    node your bend now overlaps, and the diagram starts lying.

Bends as constraints

The version that works treats a user's bend as a waypoint in the model — serialized with the edge, undoable like any edit, and handed to the router as a constraint: route through these points, avoid obstacles between them.

edges: [{
  source: 'r1', target: 'c1',
  type: 'orthogonal', router: 'avoid',
  // A user dragged the wire here once. It survives node drags, re-routes,
  // serialization, and undo — the router works around it, not over it.
  points: [{ x: 340, y: 90 }],
}]
Enter fullscreen mode Exit fullscreen mode

In Grafloria you don't write the drag handling: grab any segment of a routed edge and bend it; the bend lands in points; the avoid router keeps dodging nodes on the spans between your waypoints. Delete the bend and the router owns the whole path again. The mechanics of that router — the obstacle index, the grid search, what a turn costs — are in their own deep-dive.

The details users actually feel

  • Fat hit targets. A 2px line is a 2px click target — another
    long-lived request elsewhere. Grafloria edges hit-test against a widened invisible band, so grabbing a wire doesn't require surgical aim.

  • Labels ride along. An edge label is anchored to the path and draggable
    itself; its position persists in the model too.

  • One undo per gesture. A bend, a reconnect, a label move — each is one
    command, so ⌘Z behaves the way muscle memory expects.

Try it: the editable-edge demo · the concepts: Edges & routing.


Grafloria is an MIT-licensed diagram engine for React, Angular, Vue and plain JavaScript — grafloria.com. If this post was useful, the demo gallery is where the ideas live as running code.

Top comments (0)