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, nonTreeEdgesEditor-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:

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. 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 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.

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.

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 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.


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.

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
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 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.