Skip to main content

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.

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:

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, mermaidPolicy, sharedStems, nonTreeEdges, siblingOrderEditor-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 (see the Removed mxGraph layouts section below). 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:

KeyValuesDefaultDescription
elk.directionDOWN, UP, RIGHT, LEFTDOWNLayout direction
elk.spacing.nodeNodenumber (string)"30"Spacing between shapes in the same layout column/row
elk.layered.spacing.nodeNodeBetweenLayersnumber (string)"30"Spacing between layout columns/rows ("rank spacing")
elk.layered.layering.strategyNETWORK_SIMPLEX, LONGEST_PATH, COFFMAN_GRAHAMNETWORK_SIMPLEXAlgorithm that picks how shapes are assigned to layout columns/rows
elk.edgeRoutingORTHOGONAL, POLYLINE, SPLINESORTHOGONALHow connectors are routed between shapes

2.2 elkTree — mrtree​

Replaces mxCompactTreeLayout (see the Removed mxGraph layouts section below). 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 (see the Removed mxGraph layouts section below). 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 (see the Removed mxGraph layouts section below). 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 shape 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. 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:

KeyValuesDefaultDescription
edgeStyleauto, keep, orthogonal, straight, orthogonalEdgeStyleautoRouting 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.
cornerskeep, straight, rounded, curvedkeepCorner treatment. Independent from edgeStyle.
resizeNodesbooleanfalseLet ELK resize shapes to fit their labels.
preserveOriginbooleanfalseTranslate 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.
rootCellIdsarray of cell idsnullForce 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.
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.
sharedStemsbooleantrueelkTree 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.
nonTreeEdgesroute, elkrouteelkTree 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.
siblingOrdergeometry, modelgeometryelkTree only: what decides the order of a shape's child shapes. geometry keeps the order the shapes are currently placed in (top-to-bottom for horizontal trees, left-to-right for vertical ones; shapes at the same position keep their relative file order). model restores the legacy behavior — the order the connectors appear in the file, so re-creating or re-fronting a connector moves its child. Setting elk.mrtree.weighting in the config also disables the geometric ordering.

3. Legacy mxGraph layouts​

The original mxGraph layouts that ELK doesn't cover are still available: mxCircleLayout, mxParallelEdgeLayout, mxOrgChartLayout and 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.

NameAPI reference
mxCircleLayoutdocs
mxParallelEdgeLayoutdocs
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 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 }
}
KeyDefaultDescription
spacing20Distance in pixels between adjacent parallel connectors.
checkOverlaptrue (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.

3.3 Removed mxGraph layouts​

mxHierarchicalLayout, mxCompactTreeLayout, mxRadialTreeLayout, mxFastOrganicLayout, mxPartitionLayout and mxEdgeLabelLayout are no longer available.

mxPartitionLayout and mxEdgeLabelLayout have no replacement. Entries with these names are skipped, so the other layouts in the spec still run. A childLayout with no other layouts leaves the children where they are.

The names of the other four are still accepted in every layout spec and run the ELK layout that replaces them. The direction and spacing options are translated (missing values take the defaults of the old layouts, shown in brackets); all other options are ignored.

Old nameRuns asTranslated options
mxHierarchicalLayoutelkLayered with edgeStyle: orthogonalEdgeStyleorientation (north), the side of the roots → elk.direction: north → DOWN, west → RIGHT, east → LEFT, south → UP; intraCellSpacing (30) → elk.spacing.nodeNode; interRankCellSpacing (100) → elk.layered.spacing.nodeNodeBetweenLayers; interHierarchySpacing (60) → elk.spacing.componentComponent; parallelEdgeSpacing (10) → elk.spacing.edgeEdge
mxCompactTreeLayoutelkTreehorizontal (true) and invert (false) → elk.direction: RIGHT, LEFT, DOWN or UP; the larger of levelDistance (10) and nodeDistance (20) → elk.spacing.nodeNode
mxRadialTreeLayoutelkRadial—
mxFastOrganicLayoutelkOrganicforceConstant (50) divided by 5 → elk.spacing.nodeNode

The flowLayout, treeLayout and organicLayout values of the childLayout style run as elkLayered, elkTree and elkOrganic in the same way, with the options read from the style: flowOrientation (east), intraCellSpacing, interRankCellSpacing, interHierarchySpacing and parallelEdgeSpacing for flowLayout, horizontalTree (1) and treeLevelDistance (30) for treeLayout, and parentPadding (20) and resizeParent (1) for all three. Shape sizes are kept, and treeLayout keeps the connector styles.


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 }
}
KeyDefaultDescription
shapeBufferDistance16Clearance in pixels kept between a connector and the shapes it passes (the menu entry's Spacing prompt).
idealNudgingDistance14Separation 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. All of them except circle and orgchart use ELK.

ShorthandMaps to
autoPicks verticaltree, verticalflow or organic based on the graph's topology
noneSkip layout — keep the imported positions
circlemxCircleLayout
verticaltreeelkTree + elk.direction: DOWN; connectors keep their style
horizontaltreeelkTree + elk.direction: RIGHT; connectors keep their style
verticalflowelkLayered + elk.direction: DOWN
horizontalflowelkLayered + elk.direction: RIGHT
organicelkOrganic; connectors keep their style
orgchartmxOrgChartLayout
elkRadialelkRadial
elkOrganicelkOrganic
elkStresselkStress
libavoidorthogonalEdge — obstacle-avoiding orthogonal connector routing (§4); shapes keep their positions
parallelsmxParallelEdgeLayout — 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 CSV layout listed above (connectors keep their style, spacing from # nodespacing), 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.