Skip to main content

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:

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:

KeyGoes 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, mermaidPolicyEditor-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:

KeyValuesDefaultDescription
elk.directionDOWN, UP, RIGHT, LEFTDOWNLayering direction
elk.spacing.nodeNodenumber (string)"30"Spacing between nodes in the same layer
elk.layered.spacing.nodeNodeBetweenLayersnumber (string)"30"Spacing between layers ("rank spacing")
elk.layered.layering.strategyNETWORK_SIMPLEX, LONGEST_PATH, COFFMAN_GRAHAMNETWORK_SIMPLEXAlgorithm that picks how nodes are assigned to layers
elk.edgeRoutingORTHOGONAL, POLYLINE, SPLINESORTHOGONALHow 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"
}
}
KeyValuesDefaultDescription
elk.directionDOWN, UP, RIGHT, LEFTDOWNTree direction
elk.spacing.nodeNodenumber (string)"20"Spacing between siblings
elk.mrtree.weightingMODEL_ORDER, DESCENDANTS, CONSTRAINT, FANMODEL_ORDERHeuristic 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"
}
}
KeyValuesDefaultDescription
elk.spacing.nodeNodenumber (string)"20"Spacing within a ring
elk.radial.optimizationCriteriaNONE, EDGE_LENGTH, EDGE_LENGTH_BY_POSITION, CROSSING_MINIMIZATION_BY_POSITIONNONEWhat 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"
}
}
KeyValuesDefaultDescription
elk.spacing.nodeNodenumber (string)"10"Target node distance (Fruchterman-Reingold k)
elk.force.iterationsnumber (string)"300"Force-directed iterations
elk.force.repulsivePowernumber (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:

KeyValuesDefaultDescription
edgeStyleauto, keep, orthogonal, straight, orthogonalEdgeStyleautoRouting 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.
cornerskeep, straight, rounded, curvedkeepCorner treatment. Independent from edgeStyle.
resizeNodesbooleanfalseLet ELK resize nodes to fit their labels.
preserveOriginbooleantrueTranslate the laid-out cluster back to the original top-left so it doesn't drift to (0, 0).
rootCellIdsarray of cell idsnullForce these cells to be tree roots (layered, mrtree, radial only).
useViewStateSizingbooleantrueReport rendered (view-state) sizes to ELK, not raw geometry.
respectFixedPositionbooleantruePin cells whose isCellMovable is false at their current position.
mermaidPolicybooleantrue for elkLayered, else falseApply 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.

NameAPI reference
mxHierarchicalLayoutdocs
mxCircleLayoutdocs
mxCompactTreeLayoutdocs
mxEdgeLabelLayoutdocs
mxFastOrganicLayoutdocs
mxParallelEdgeLayoutdocs
mxPartitionLayoutdocs
mxRadialTreeLayoutdocs
mxStackLayoutdocs
mxOrgChartLayoutspecial — 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:

ValueStyle
0Linear
1Hanger 2
2Hanger 4 (default)
3Fishbone 1
4Fishbone 2
51-Column Left
61-Column Right
7Smart

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 }
}
KeyDefaultDescription
spacing20Distance in pixels between adjacent parallel edges.
checkOverlaptrue (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:

ShorthandMaps to
autoPicks mxHierarchicalLayout, mxCompactTreeLayout, or mxFastOrganicLayout based on the graph's topology
noneSkip layout — keep the imported positions
circlemxCircleLayout
verticaltreemxCompactTreeLayout (vertical)
horizontaltreemxCompactTreeLayout (horizontal)
verticalflowmxHierarchicalLayout (DIRECTION_NORTH)
horizontalflowmxHierarchicalLayout (DIRECTION_WEST)
organicmxFastOrganicLayout
orgchartmxOrgChartLayout
elkVerticalFlowelkLayered + elk.direction: DOWN
elkHorizontalFlowelkLayered + elk.direction: RIGHT
elkVerticalTreeelkTree + elk.direction: DOWN
elkHorizontalTreeelkTree + elk.direction: RIGHT
elkRadialelkRadial
elkOrganicelkOrganic
elkStresselkStress

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.