JSON layout specification for Apply Layouts and CSV import
This page describes the JSON format used by the
Custom Layout dialog (Arrange > Layout > Custom) and by the
# layout: … line in CSV imports.
The same array format is also accepted by several other interfaces.
- the desktop
--layoutcommand-line flag, - the embed protocol's
layoutaction and loadlayoutparameter, and - the
#createURL/hashlayoutfield.
These three additionally accept a preset name (verticalFlow,
horizontalFlow, verticalTree, horizontalTree, radialTree,
organic — the Arrange > Layout menu presets), the libavoid
shorthand (obstacle-avoiding orthogonal connector routing, §4) or
parallels (the parallel-connecor router, §3.2) as a shorthand for a
single-entry array. The same shorthands work on the CSV # layout: …
line, alongside the CSV-specific names listed in §5.
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 a morph animation in
between; chains of pure-mxGraph layouts still run as a single
mxCompositeLayout for byte-identical legacy behavior.
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 §5 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, sharedStems, nonTreeEdges | 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, directed acyclic graphs (DAG), 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 | Layout direction |
elk.spacing.nodeNode | number (string) | "30" | Spacing between shapes in the same layout column/row |
elk.layered.spacing.nodeNodeBetweenLayers | number (string) | "30" | Spacing between layout columns/rows ("rank spacing") |
elk.layered.layering.strategy | NETWORK_SIMPLEX, LONGEST_PATH, COFFMAN_GRAHAM | NETWORK_SIMPLEX | Algorithm that picks how shapes are assigned to layout columns/rows |
elk.edgeRouting | ORTHOGONAL, POLYLINE, SPLINES | ORTHOGONAL | How connectors are routed between shapes |
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 shape 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. An alternative to elkOrganic's Fruchterman-Reingold
force-directed model and better when connectors carry intended lengths,
otherwise the two algorithms produce visually similar results.
Select Arrange > Layout > Organic , then choose the Stress option in the Method
dropdown to switch the visible fields and run the same dialog flow.
Alternatively, write this in JSON or use 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 shapes 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 accepted:
| Key | Values | Default | Description |
|---|---|---|---|
edgeStyle | auto, keep, orthogonal, straight, orthogonalEdgeStyle | auto | Routing style of the rendered connectors. auto matches what ELK produced (orthogonal for ORTHOGONAL, straight for POLYLINE/SPLINES); keep preserves the existing connector style and skips ELK's bend points. |
corners | keep, straight, rounded, curved | keep | Corner treatment. Independent from edgeStyle. |
resizeNodes | boolean | false | Let ELK resize shapes to fit their labels. |
preserveOrigin | boolean | false | Translate the laid-out cluster back to the original top-left so it doesn't drift to ELK's near-(0, 0) packing. Off by default so programmatic runs get raw ELK coordinates. |
rootCellIds | array of cell ids | null | Force these shape cells to be tree roots (layered, mrtree, radial only), and limit the run to the roots' connected components — disconnected shapes are left untouched. |
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. |
sharedStems | boolean | true | elkTree only: collapse a parent's outgoing connectors onto one shared stem at the side's center (the classic compact-tree look). false keeps ELK's spread exit points — one per child connector. |
nonTreeEdges | route, elk | route | elkTree applies to connectors that don’t follow the tree structure, such as second connectors into the same shape, bi-directional or reversed connectors. route lays out the tree first then routes nonTreeEdges as orthogonal connectors overlaying the tree structure; elk uses ELK's own routing. |
3. Legacy mxGraph layouts
The original mxGraph layouts are still available and are used for mxCircleLayout, mxParallelEdgeLayout, mxOrgChartLayout, as well as a handful of niche layouts that ELK doesn't
cover (mxEdgeLabelLayout, mxPartitionLayout, mxStackLayout).
For each, set the config object's keys 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 connectors (two or more connectors between the same pair of shapes) apart so they do not draw on top of each other. Shapes are left where they are — only connectors are moved. This is normally added as the final step after a node-positioning layout (see §6).
{
"layout": "mxParallelEdgeLayout",
"config": { "spacing": 20, "checkOverlap": true }
}
| Key | Default | Description |
|---|---|---|
spacing | 20 | Distance in pixels between adjacent parallel connectors. |
checkOverlap | true (recommended) | Only spread connectors that actually overlap, rather than every parallel group. |
In the Custom Layout dialog, select parallels from the Add dropdown
(see §7). The shorthand parallels stands for a single entry with
checkOverlap: true and the default spacing. 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. orthogonalEdge — orthogonal edge routing (libavoid)
Obstacle-avoiding orthogonal connector routing via the libavoid router —
the same engine behind Arrange > Layout > Orthogonal Routing. Like
mxParallelEdgeLayout it never moves a shape: every vertex becomes an
obstacle and the connectors are re-routed orthogonally around them, honouring
fixed connection points.
{
"layout": "orthogonalEdge",
"config": { "shapeBufferDistance": 16, "idealNudgingDistance": 14 }
}
| Key | Default | Description |
|---|---|---|
shapeBufferDistance | 16 | Clearance in pixels kept between a connector and the shapes it passes (the menu entry's Spacing prompt). |
idealNudgingDistance | 14 | Separation in pixels between parallel segments of different connectors. |
The shorthand libavoid stands for a single orthogonalEdge entry
with default options. Use it in the the CSV # layout: … line when you want to place shapes via the left/top columns and only need the connectors routed.
5. CSV shorthand names
In a CSV import the # layout: … line can name a single layout
without JSON.
| 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 |
libavoid | orthogonalEdge — obstacle-avoiding orthogonal connector routing (§4); shapes keep their positions |
parallels | mxParallelEdgeLayout — spread overlapping parallel connectors (§3.2); shapes keep their positions |
The Arrange > Layout preset names (verticalFlow, horizontalFlow,
verticalTree, horizontalTree, radialTree — see the introduction)
are also accepted. Note that lowercase organic names the legacy
mxFastOrganicLayout listed above, not the ELK menu preset.
For anything beyond the shorthand defaults — different spacing, layout column/row strategy, connector style, multi-layout chains — use the JSON form:
# layout: [{"layout":"elkLayered","config":{"elk.direction":"RIGHT","elk.spacing.nodeNode":"50"}}]
6. 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 connectors:
[
{ "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 result, morph-animates the updated, then runs the next step. Pure-mxGraph chains still run as a single
mxCompositeLayout in one batch (the same behaviour as pre-ELK).
7. Building entries via the Add dropdown
Select Arrange > Layout > Custom then select Add from the dropdown list to pick one of the default layouts and open that layout's configuration. Click Apply to appends a {"layout": …, "config": {…}} object to the JSON in the text area. Edit this text area — use
the dropdown for the common parameters, then edit to access the ELK
options that are not shown in the configuration dialog.
The dropdown list 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}).
(Use elkStress via JSON or in the CSV shorthand as it is not available via the Arrange > Layout menu.)
Click Cancel to reopen the layout dialog with the unchanged JSON.
Related
- See how to apply layouts to organise diagrams quickly.
- Insert from CSV using the
# layout:line in a CSV import. - See the full Eclipse Layout Kernel reference.