Skip to content

Flowchart

Loading interactive example…Open in new tab ↗
Opening the live canvas…

Drag shapes to reroute their connectors. Double-click node or branch labels to edit them. Use the toolbar to add a process, decision, start/end or note; drag between ports to connect them. Undo restores edits.

dart
DiagramDocument flowchartDocument() => DiagramDocument(
  id: 'flowchart',
  revision: 0,
  elements: [
    for (final (id, title, type, x, y, w, h) in [
      ('start', 'New request', 'flowchart.terminal', 180.0, 0.0, 180.0, 65.0),
      (
        'review',
        'Review request',
        'flowchart.process',
        180.0,
        130.0,
        180.0,
        80.0,
      ),
      (
        'decision',
        'Approved?',
        'flowchart.decision',
        180.0,
        270.0,
        180.0,
        120.0,
      ),
      ('revise', 'Revise', 'flowchart.process', -100.0, 290.0, 180.0, 80.0),
      ('done', 'Ship it', 'flowchart.terminal', 180.0, 460.0, 180.0, 65.0),
    ])
      ShapeElement(
        id: id,
        type: type,
        polygonSides: type == 'flowchart.decision' ? 4 : null,
        frame: DiagramRect.fromLTWH(x, y, w, h),
        style: flowchartStyle(type),
        textStory: TextStory.paragraph(
          id: '$id-story',
          blockId: '$id-block',
          text: title,
        ),
      ),
    for (final (id, source, target, label) in [
      ('receive', 'start', 'review', ''),
      ('check', 'review', 'decision', ''),
      ('yes', 'decision', 'done', 'Yes'),
      ('no', 'decision', 'revise', 'No'),
      ('retry', 'revise', 'review', 'Try again'),
    ])
      ConnectorElement(
        id: id,
        start: BoundEndpoint(
          elementId: source,
          portId: id == 'no'
              ? 'left'
              : id == 'retry'
              ? 'top'
              : 'bottom',
        ),
        end: BoundEndpoint(
          elementId: target,
          portId: id == 'no'
              ? 'right'
              : id == 'retry'
              ? 'left'
              : 'top',
        ),
        router: ConnectorRoute.orthogonal,
        color: const DiagramColor(0xFF64748B),
        labels: [
          if (label.isNotEmpty)
            ConnectorLabel(
              id: '$id-label',
              story: TextStory.paragraph(
                id: '$id-story',
                blockId: '$id-block',
                text: label,
              ),
            ),
        ],
      ),
  ],
);