feat(flowchart): alignment + distribution tools (C15)

8 new toolbar buttons (Align L/R/T/B, Center H/V, Distribute H/V)
plus a Select All button. Each operation takes the current
selection and applies a pure-function transform to the (x, y)
positions, then commits each result via store.moveNode().

Architecture:

  - src/flowchart/flowchart-align.js: pure module with 8 helpers
    + nodeWidth / nodeHeight utility. UMD wrapper for browser
    global + CommonJS, same pattern as the other pure modules.
  - src/renderer/flowchart-bundle.js: pure module inlined so the
    standalone window doesn't need a separate bundle build; the
    inlined functions are exposed as window.FlowchartAlign for
    jsdom tests.
  - Bundle's _selectedNodeIds Set tracks the alignment selection.
    Empty by default; populated by Select All or by future
    canvas-side shift+click (item 1: multi-select).
  - Each align button no-ops with a status hint if fewer than 2
    nodes are selected. Distribute needs 3+.
  - Each moveNode call creates its own undo snapshot, which is
    fine for typical 2-10 node selections and lets the user undo
    a misalignment one node at a time.

Tests: 14 new (1376 total) covering all 8 functions plus
immutability, no-op for insufficient nodes, and unsorted-input
sorting for distribute.

Amit Haridas
This commit is contained in:
2026-09-30 22:28:13 +05:30
parent 7bb062a464
commit f133efe025
4 changed files with 513 additions and 0 deletions
+68
View File
@@ -395,6 +395,74 @@
Reset All
</button>
</div>
<h3 class="fc-section-title">Align (multi-select)</h3>
<div class="fc-toolbar-row">
<button
class="fc-btn"
id="fc-btn-select-all"
title="Select every node so the alignment buttons work"
>
Select All
</button>
</div>
<div class="fc-toolbar-row">
<button
class="fc-btn"
id="fc-btn-align-left"
title="Align selected nodes to the left edge"
>
Align Left
</button>
<button
class="fc-btn"
id="fc-btn-align-right"
title="Align selected nodes to the right edge"
>
Align Right
</button>
<button
class="fc-btn"
id="fc-btn-align-top"
title="Align selected nodes to the top edge"
>
Align Top
</button>
<button
class="fc-btn"
id="fc-btn-align-bottom"
title="Align selected nodes to the bottom edge"
>
Align Bottom
</button>
<button
class="fc-btn"
id="fc-btn-align-center-h"
title="Align selected nodes to a common horizontal center"
>
Center H
</button>
<button
class="fc-btn"
id="fc-btn-align-center-v"
title="Align selected nodes to a common vertical center"
>
Center V
</button>
<button
class="fc-btn"
id="fc-btn-distribute-h"
title="Distribute selected nodes evenly between leftmost and rightmost"
>
Distribute H
</button>
<button
class="fc-btn"
id="fc-btn-distribute-v"
title="Distribute selected nodes evenly between topmost and bottommost"
>
Distribute V
</button>
</div>
<h3 class="fc-section-title">Export Image</h3>
<div class="fc-toolbar-row">
<button class="fc-btn" id="fc-btn-export-svg" title="Export the canvas as a .svg file">