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 }],
}]
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)