JSON layout specification for Apply Layouts and CSV import
This page is the canonical reference for the JSON format used by the
Custom Layout dialog (Arrange > Layout > Apply…) and by the
# layout: … line in CSV imports. Both surfaces share the same
dispatch code, so anything you can write in one works in the other.
The same array format is also accepted by several other surfaces, all of which share this dispatch code:
- the desktop
--layoutcommand-line flag, - the embed protocol's
layoutaction and loadlayoutparameter, and - the
#createURL/hashlayoutfield.
Those three additionally accept a preset name (verticalFlow,
horizontalFlow, verticalTree, horizontalTree, radialTree,
organic — the Arrange > Layout menu presets) as a shorthand for a
single-entry array.
1. JSON format at a glance
The JSON is an array of layout entries. Each entry is an object with two keys:
[
{ "layout": "elkLayered", "config": { "elk.direction": "DOWN" } },
{ "layout": "mxParallelEdgeLayout", "config": { "spacing": 30 } }
]
layout— the layout's name (see the catalogue below)config— an object whose keys are layout-specific parameters
Entries run in order. When an ELK entry sits next to an mxGraph entry,
each layout runs in its own update batch with morph animation in
between; chains of pure-mx layouts still run as a single
mxCompositeLayout for byte-identical legacy behavior.
You can also write the same JSON inline in a CSV import:
# layout: [{"layout":"elkLayered","config":{"elk.direction":"RIGHT"}}]
If you only need a single layout with the menu's defaults, use the shorthand strings instead — see §4 below.
2. ELK layouts
ELK layouts replace and extend the original mxGraph layouts. They
share a common bridge whose config object splits by key prefix:
| Key | Goes to |
|---|---|
elk.* (e.g. elk.direction, elk.spacing.nodeNode) | ELK layout option, forwarded verbatim to the ELK engine |
edgeStyle, corners, resizeNodes, preserveOrigin, rootCellIds, useViewStateSizing, respectFixedPosition, mermaidPolicy | Editor-side option (see §2.7) |
The full list of ELK options is documented at eclipse.dev/elk/reference/options.html; this page only lists the ones you'll usually want.
2.1 elkLayered — layered (Sugiyama)
Replaces mxHierarchicalLayout. Best for flow charts, DAGs, and any
diagram with a clear top-down or left-to-right direction.
{
"layout": "elkLayered",
"config": {
"elk.direction": "DOWN",
"elk.spacing.nodeNode": "30",
"elk.layered.spacing.nodeNodeBetweenLayers": "30",
"elk.layered.layering.strategy": "NETWORK_SIMPLEX",
"elk.edgeRouting": "ORTHOGONAL",
"edgeStyle": "auto",
"corners": "rounded"
}
}
Common options:
| Key | Values | Default | Description |
|---|---|---|---|
elk.direction | DOWN, UP, RIGHT, LEFT | DOWN | Layering direction |
elk.spacing.nodeNode | number (string) | "30" | Spacing between nodes in the same layer |
elk.layered.spacing.nodeNodeBetweenLayers | number (string) | "30" | Spacing between layers ("rank spacing") |
elk.layered.layering.strategy | NETWORK_SIMPLEX, LONGEST_PATH, COFFMAN_GRAHAM | NETWORK_SIMPLEX | Algorithm that picks how nodes are assigned to layers |
elk.edgeRouting | ORTHOGONAL, POLYLINE, SPLINES | ORTHOGONAL | How edges are routed between nodes |
2.2 elkTree — mrtree
Replaces mxCompactTreeLayout. Best for trees and small org charts.
{
"layout": "elkTree",
"config": {
"elk.direction": "DOWN",
"elk.spacing.nodeNode": "20",
"elk.mrtree.weighting": "MODEL_ORDER"
}
}
| Key | Values | Default | Description |
|---|---|---|---|
elk.direction | DOWN, UP, RIGHT, LEFT | DOWN | Tree direction |
elk.spacing.nodeNode | number (string) | "20" | Spacing between siblings |
elk.mrtree.weighting | MODEL_ORDER, DESCENDANTS, CONSTRAINT, FAN | MODEL_ORDER | Heuristic for ordering siblings |
2.3 elkRadial — radial
Replaces mxRadialTreeLayout. Concentric rings around a chosen root.
{
"layout": "elkRadial",
"config": {
"elk.spacing.nodeNode": "20",
"elk.radial.optimizationCriteria": "NONE"
}
}
| Key | Values | Default | Description |
|---|---|---|---|
elk.spacing.nodeNode | number (string) | "20" | Spacing within a ring |
elk.radial.optimizationCriteria | NONE, EDGE_LENGTH, EDGE_LENGTH_BY_POSITION, CROSSING_MINIMIZATION_BY_POSITION | NONE | What the radial pass tries to minimize |
2.4 elkOrganic — force
Replaces mxFastOrganicLayout. Force-directed; good for mind maps,
networks, and arbitrary undirected graphs.
{
"layout": "elkOrganic",
"config": {
"elk.spacing.nodeNode": "10",
"elk.force.iterations": "300",
"elk.force.repulsivePower": "0"
}
}
| Key | Values | Default | Description |
|---|---|---|---|
elk.spacing.nodeNode | number (string) | "10" | Target node distance (Fruchterman-Reingold k) |
elk.force.iterations | number (string) | "300" | Force-directed iterations |
elk.force.repulsivePower | number (string) | "0" | Exponent of the repulsive force |
2.5 elkStress — stress
Stress majorization. Alternative to elkOrganic's Fruchterman-Reingold
force-directed model — better when edges carry intended lengths,
otherwise the two produce visually similar results.
Surfaced in the editor as the Stress option of the Method
dropdown inside Arrange > Layout > Organic… — picking it switches
the visible fields and runs the same dialog flow. Also reachable
directly via JSON or the elkStress CSV shorthand.
{
"layout": "elkStress",
"config": {
"elk.spacing.nodeNode": "80",
"elk.stress.desiredEdgeLength": "100",
"elk.stress.iterationLimit": "-1"
}
}
2.6 elkDisco, elkBox
elkDisco (disconnected component spacing) and elkBox (box packing)
are post-processing layouts: they don't position individual nodes but
arrange already-positioned groups. Use them after another layout in a
multi-step JSON.
2.7 Editor-side options (all ELK layouts)
These bare keys (no elk. prefix) are recognized by the bridge:
| Key | Values | Default | Description |
|---|---|---|---|
edgeStyle | auto, keep, orthogonal, straight, orthogonalEdgeStyle | auto | Routing style of the rendered edges. auto matches what ELK produced (orthogonal for ORTHOGONAL, straight for POLYLINE/SPLINES); keep preserves the existing edge style and skips ELK's bend points. |
corners | keep, straight, rounded, curved | keep | Corner treatment. Independent from edgeStyle. |
resizeNodes | boolean | false | Let ELK resize nodes to fit their labels. |
preserveOrigin | boolean | true | Translate the laid-out cluster back to the original top-left so it doesn't drift to (0, 0). |
rootCellIds | array of cell ids | null | Force these cells to be tree roots (layered, mrtree, radial only). |
useViewStateSizing | boolean | true | Report rendered (view-state) sizes to ELK, not raw geometry. |
respectFixedPosition | boolean | true | Pin cells whose isCellMovable is false at their current position. |
mermaidPolicy | boolean | true for elkLayered, else false | Apply mermaid-elk's SEPARATE_CHILDREN / LCA INCLUDE_CHILDREN hierarchyHandling policy to compound graphs. |
3. Legacy mxGraph layouts
The original mxGraph layouts are still available — they remain the
canonical choice for mxCircleLayout, mxParallelEdgeLayout,
mxOrgChartLayout, and a handful of niche layouts that ELK doesn't
cover (mxEdgeLabelLayout, mxPartitionLayout, mxStackLayout).
For each, the config object's keys are set directly as JavaScript
properties on the layout instance — refer to each class's mxGraph API
docs for the full property list.
| Name | API reference |
|---|---|
mxHierarchicalLayout | docs |
mxCircleLayout | docs |
mxCompactTreeLayout | docs |
mxEdgeLabelLayout | docs |
mxFastOrganicLayout | docs |
mxParallelEdgeLayout | docs |
mxPartitionLayout | docs |
mxRadialTreeLayout | docs |
mxStackLayout | docs |
mxOrgChartLayout | special — see §3.1 |
3.1 mxOrgChartLayout
{
"layout": "mxOrgChartLayout",
"config": {
"branchOptimizer": 2,
"parentChildSpacing": 20,
"siblingSpacing": 20
}
}
branchOptimizer is passed as a constructor argument and selects the
chart style:
| Value | Style |
|---|---|
0 | Linear |
1 | Hanger 2 |
2 | Hanger 4 (default) |
3 | Fishbone 1 |
4 | Fishbone 2 |
5 | 1-Column Left |
6 | 1-Column Right |
7 | Smart |
3.2 mxParallelEdgeLayout — parallel-edge router
Spaces overlapping parallel edges (two or more connectors between the same pair of nodes) apart so they no longer draw on top of each other. It only moves edges — nodes are left where they are — so it is normally added as the final step after a node-positioning layout (see §5).
{
"layout": "mxParallelEdgeLayout",
"config": { "spacing": 20, "checkOverlap": true }
}
| Key | Default | Description |
|---|---|---|
spacing | 20 | Distance in pixels between adjacent parallel edges. |
checkOverlap | true (recommended) | Only spread edges that actually overlap, rather than every parallel group. |
In the Custom Layout dialog's Add dropdown this is the parallels entry
(see §6). CSV imports run this pass automatically after the chosen layout, using
the # edgespacing value as the spacing, so you only need to add it explicitly
in a JSON layout array.
4. CSV shorthand names
In a CSV import the # layout: … line can name a single layout
without JSON. The complete list:
| Shorthand | Maps to |
|---|---|
auto | Picks mxHierarchicalLayout, mxCompactTreeLayout, or mxFastOrganicLayout based on the graph's topology |
none | Skip layout — keep the imported positions |
circle | mxCircleLayout |
verticaltree | mxCompactTreeLayout (vertical) |
horizontaltree | mxCompactTreeLayout (horizontal) |
verticalflow | mxHierarchicalLayout (DIRECTION_NORTH) |
horizontalflow | mxHierarchicalLayout (DIRECTION_WEST) |
organic | mxFastOrganicLayout |
orgchart | mxOrgChartLayout |
elkVerticalFlow | elkLayered + elk.direction: DOWN |
elkHorizontalFlow | elkLayered + elk.direction: RIGHT |
elkVerticalTree | elkTree + elk.direction: DOWN |
elkHorizontalTree | elkTree + elk.direction: RIGHT |
elkRadial | elkRadial |
elkOrganic | elkOrganic |
elkStress | elkStress |
For anything beyond the shorthand defaults — different spacing, layer strategy, edge style, multi-layout chains — use the JSON form:
# layout: [{"layout":"elkLayered","config":{"elk.direction":"RIGHT","elk.spacing.nodeNode":"50"}}]
5. Composing multiple layouts
The array form runs each layout in order. A common composition is to run a layered/tree layout first, then space out parallel edges:
[
{ "layout": "elkLayered", "config": { "elk.direction": "DOWN" } },
{ "layout": "mxParallelEdgeLayout", "config": { "spacing": 30, "checkOverlap": true } }
]
When an entry's layout is an ELK layout (any elk* name), that step
runs asynchronously: the layout dispatcher awaits the ELK promise and
applies the result inside a regular morph-animated update before
running the next step. Pure-mx chains still run as a single
mxCompositeLayout in one batch (no behaviour change versus
pre-ELK).
6. Building entries via the Add dropdown
In the Custom Layout dialog (Arrange > Layout > Apply…) the Add
dropdown lets you pick a layout from the same vocabulary as the
Arrange > Layout menu. Picking an entry opens that layout's config
dialog; clicking Apply appends a {"layout": …, "config": {…}} object
to the JSON in the textarea. The textarea stays editable on top — use
the dropdown for the common parameters, then hand-edit to access ELK
options that the config dialog doesn't surface.
The dropdown offers:
- the ELK presets Vertical Flow, Horizontal Flow, Vertical Tree, Horizontal Tree, Radial Tree and Organic (each opens its ELK config dialog);
- Org Chart (opens the org-chart config dialog);
- circle (
mxCircleLayout); and - parallels (
mxParallelEdgeLayout— the parallel-edge router from §3.2, appended as{"spacing": 20, "checkOverlap": true}).
(elkStress is reachable via JSON or the CSV shorthand but is intentionally not
in this dropdown, since it isn't on the Arrange > Layout menu.)
Cancelling the per-layout dialog re-opens the textarea with the unchanged JSON, so unsaved hand-edits are preserved.
Related
- Apply layouts to organise diagrams quickly — the menu dialogs that drive these layouts.
- Insert from CSV — using the
# layout:line in a CSV import. - Eclipse Layout Kernel reference — the full ELK option set.