A diagram from a table

You can draw a table as a Mermaid flowchart, with one row per step. When you edit the table, the diagram follows.
New tab

Quick start

This needs the chart.linkTables option, as a chart that follows a table does. Take this table:

StepNextTeamLabelShape
Order inCheck stockSalesstart
Check stockPack, Back orderWarehousein stock, missingdecision
PackInvoiceWarehouse

Place the selection in the table and call:

editor.commands.insertDiagramFromTable({
  columns: { step: 'Step', next: 'Next', lane: 'Team', label: 'Label', shape: 'Shape' },
  title: 'Order process',
})

One undo takes back an edit of the table and the update of the diagram together.

How the table is read

columns maps each role to a column, by its header text (ignoring case) or by its position from 0. Without columns, the extension guesses the roles from headers such as Step, Task, Next, Then, Team, Owner, Label, Condition and Shape. When no header names step and next, it takes the first remaining columns for them. It uses each column once.

RoleRequiredCell holdsBecomes
stepYesThe step's nameA node
nextYesThe steps that follow, separated by commasArrows to those steps
laneNoA lane nameA subgraph with the step
labelNoArrow labels, separated by commasText on the arrows
shapeNoA shape name, see ShapesThe node's shape
  • A step named only in a next cell is drawn too.
  • A label cell gives one label per next step when the counts match. Otherwise, every arrow gets the whole cell.
  • With header: 'none', columns must give positions.

Shapes

ShapeCell text
Boxbox, rect, task
Rounded boxrounded, round
Stadiumstart, end, stadium, terminal
Diamonddecision, diamond, gateway
Circlecircle, event
Parallelogramdata
Cylinderdatabase
Subroutinesubroutine

Any other text gives a box.

When the table changes

  • Renaming a step in its row renames it in every next cell too, so its arrows stay. Names are compared ignoring case and the spaces around them.
  • Emptying a step cell, or giving it another step's name, is not a rename. The next cells stay as they are.
  • Changing a lane cell moves that one step to another lane. To rename a lane in every row, use renameDiagramLane. Lanes are compared by their text without the spaces around it, case included.
  • Removing a column that the link names keeps the diagram as it is, until the column is back.
  • Changing the source with updateFlowDiagram ends the link, as detachDiagramFromTable does.
  • Double-clicking a shape does not edit its text. The text belongs to the table.

Stored in the document

WhereWhat
The diagram's options.link{ tableId, columns, header?, range? }
The tableA chartTableId

Read the link with flowDiagramLink(diagram), or as link in listDiagrams(), which also returns the lanes as lanes. updateLinkedTable changes how the table is read.

Commands

insertDiagramFromTable

Inserts a flowchart drawn from the table at the selection, or at table.

editor.commands.insertDiagramFromTable({
  columns: { step: 'Step', next: 'Next', lane: 'Team' },
  title: 'Order process',
})

// A table without a header, without its last row
editor.commands.insertDiagramFromTable({
  header: 'none',
  range: { rows: { to: -2 } },
  columns: { step: 0, next: 1 },
})
OptionTypeDescription
columns{ step, next, lane?, label?, shape? }Header texts or positions from 0. Guessed from the header when left out
header'none'Reads every row as a step. Without it, the first row is the header
range{ rows }Reads only some rows, as for insertLinkedChart. range.columns does not apply
tablenumberThe table's position. Defaults to the table at the selection
titlestringThe diagram's title
belowbooleanfalse inserts the diagram above the table. Default true

Returns false when a named column is not in the table, when the table has fewer than two columns, when the selection is outside a table, or when chart.linkTables is off.

linkDiagramToTable

Draws an existing diagram from a table, replacing its source, and makes it follow that table.

editor.commands.linkDiagramToTable({ table: tablePos, columns: { step: 'Step', next: 'Next' } })

It takes table, columns, header? and range? as insertDiagramFromTable does, and pos? for a diagram other than the selected one.

detachDiagramFromTable

Stops a diagram from following its table. The source stays, and you can edit it.

editor.commands.detachDiagramFromTable({ removeTable: true })
OptionTypeDescription
posnumberThe diagram's position. Defaults to the selected diagram
removeTablebooleanAlso removes the table, unless another chart or diagram follows it. It works like setChartLayout({ layout: 'chart' }) for a chart

Returns false for a diagram that follows no table.

renameDiagramLane

Renames a lane in every row of the table, also in rows outside range. The diagram follows in the same undo step.

editor.commands.renameDiagramLane({ lane: 'Warehouse', name: 'Warehouse North' })
OptionTypeDescription
lanestringThe lane's current name
namestringThe new name
posnumberThe diagram's position. Defaults to the selected diagram

Returns false for a diagram that follows no table, for a link without a lane column, for a lane that no cell names, and for an empty name.

Without an editor

These functions from @tiptap-pro/extension-diagrams/core do the work of the commands on the cell texts of a table, such as on a server. rows is the cell texts, header row first unless read.header is 'none'.

FunctionReturns
tableToMermaid(rows, columns, read?)The flowchart source, or null when a named column is missing
guessTableDiagramColumns(header)columns guessed from the header row, or null for fewer than two columns
tableStepRenames(before, after, columns, read?){ renames, firstRow, nextColumn }. renames maps each old name (lower-cased, trimmed) to the new one, or is null
stepRenameEdits(text, renames)The { from, to, text } replacements for one next cell
tableDiagramLanes(rows, columns, read?)The lanes, in the order they appear
tableLaneCells(rows, columns, read, lane)The { row, column } of every cell below the header that names lane