pict-section-flow 1.3.0 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (162) hide show
  1. package/package.json +7 -2
  2. package/source/Pict-Section-Flow.js +20 -14
  3. package/source/providers/PictProvider-Flow-Background.js +303 -0
  4. package/source/providers/PictProvider-Flow-CSS.js +99 -7
  5. package/source/providers/PictProvider-Flow-ConnectorShapes.js +8 -0
  6. package/source/providers/PictProvider-Flow-Geometry.js +11 -421
  7. package/source/providers/PictProvider-Flow-Icons.js +20 -0
  8. package/source/providers/PictProvider-Flow-Layouts.js +107 -0
  9. package/source/services/PictService-Flow-ConnectionRenderer.js +77 -5
  10. package/source/services/PictService-Flow-CursorManager.js +113 -0
  11. package/source/services/PictService-Flow-InteractionManager.js +443 -61
  12. package/source/services/PictService-Flow-Layout.js +21 -16
  13. package/source/services/PictService-Flow-PathGenerator.js +30 -417
  14. package/source/services/PictService-Flow-RenderManager.js +9 -1
  15. package/source/services/PictService-Flow-ViewportManager.js +102 -0
  16. package/source/views/PictView-Flow-FloatingToolbar.js +57 -0
  17. package/source/views/PictView-Flow-Node.js +36 -0
  18. package/source/views/PictView-Flow-PropertiesPanel.js +27 -5
  19. package/source/views/PictView-Flow-Toolbar.js +148 -13
  20. package/source/views/PictView-Flow.js +628 -3
  21. package/.claude/launch.json +0 -11
  22. package/docs/.nojekyll +0 -0
  23. package/docs/Architecture.md +0 -163
  24. package/docs/Custom-Styling.md +0 -275
  25. package/docs/Data_Model.md +0 -149
  26. package/docs/Event_System.md +0 -156
  27. package/docs/Getting_Started.md +0 -237
  28. package/docs/Implementation_Reference.md +0 -528
  29. package/docs/Layout_Persistence.md +0 -117
  30. package/docs/README.md +0 -103
  31. package/docs/Theme_Integration.md +0 -150
  32. package/docs/_brand.json +0 -18
  33. package/docs/_cover.md +0 -17
  34. package/docs/_playground.json +0 -24
  35. package/docs/_sidebar.md +0 -57
  36. package/docs/_topbar.md +0 -8
  37. package/docs/_version.json +0 -7
  38. package/docs/api/PictFlowCard.md +0 -216
  39. package/docs/api/PictFlowCardPropertiesPanel.md +0 -235
  40. package/docs/api/addConnection.md +0 -101
  41. package/docs/api/addNode.md +0 -137
  42. package/docs/api/autoLayout.md +0 -77
  43. package/docs/api/getFlowData.md +0 -112
  44. package/docs/api/marshalToView.md +0 -95
  45. package/docs/api/openPanel.md +0 -128
  46. package/docs/api/registerHandler.md +0 -174
  47. package/docs/api/registerNodeType.md +0 -142
  48. package/docs/api/removeConnection.md +0 -57
  49. package/docs/api/removeNode.md +0 -80
  50. package/docs/api/saveLayout.md +0 -152
  51. package/docs/api/screenToSVGCoords.md +0 -68
  52. package/docs/api/selectNode.md +0 -116
  53. package/docs/api/setTheme.md +0 -168
  54. package/docs/api/setZoom.md +0 -97
  55. package/docs/api/toggleFullscreen.md +0 -68
  56. package/docs/card-help/EACH.md +0 -19
  57. package/docs/card-help/FREAD.md +0 -24
  58. package/docs/card-help/FWRITE.md +0 -24
  59. package/docs/card-help/GET.md +0 -22
  60. package/docs/card-help/ITE.md +0 -23
  61. package/docs/card-help/LOG.md +0 -23
  62. package/docs/card-help/NOTE.md +0 -17
  63. package/docs/card-help/PREV.md +0 -18
  64. package/docs/card-help/SET.md +0 -27
  65. package/docs/card-help/SPKL.md +0 -22
  66. package/docs/card-help/STAT.md +0 -23
  67. package/docs/card-help/SW.md +0 -25
  68. package/docs/diagrams/architecture-at-a-glance.excalidraw +0 -4270
  69. package/docs/diagrams/architecture-at-a-glance.mmd +0 -30
  70. package/docs/diagrams/architecture-at-a-glance.svg +0 -2
  71. package/docs/diagrams/data-flow.excalidraw +0 -1451
  72. package/docs/diagrams/data-flow.mmd +0 -17
  73. package/docs/diagrams/data-flow.svg +0 -2
  74. package/docs/diagrams/high-level-design.excalidraw +0 -5767
  75. package/docs/diagrams/high-level-design.mmd +0 -86
  76. package/docs/diagrams/high-level-design.svg +0 -2
  77. package/docs/diagrams/relationships.excalidraw +0 -3852
  78. package/docs/diagrams/relationships.mmd +0 -9
  79. package/docs/diagrams/relationships.svg +0 -2
  80. package/docs/diagrams/service-initialization-sequence.excalidraw +0 -1466
  81. package/docs/diagrams/service-initialization-sequence.mmd +0 -19
  82. package/docs/diagrams/service-initialization-sequence.svg +0 -2
  83. package/docs/diagrams/svg-layer-structure.excalidraw +0 -1060
  84. package/docs/diagrams/svg-layer-structure.mmd +0 -18
  85. package/docs/diagrams/svg-layer-structure.svg +0 -2
  86. package/docs/examples/README.md +0 -9
  87. package/docs/examples/simple_cards/README.md +0 -677
  88. package/docs/examples/simple_cards/css/flowexample.css +0 -65
  89. package/docs/examples/simple_cards/index.html +0 -32
  90. package/docs/examples/simple_cards/js/pict.min.js +0 -12
  91. package/docs/examples/simple_cards/pict-section-flow-example-simple-cards.compatible.min.js +0 -1
  92. package/docs/index.html +0 -38
  93. package/docs/playground/app.json +0 -6
  94. package/docs/playground/appdata.json +0 -85
  95. package/docs/playground/application.js +0 -23
  96. package/docs/playground/pict.json +0 -17
  97. package/docs/playground/runtime/pict-application.min.js +0 -2
  98. package/docs/playground/runtime/pict-section-flow.min.js +0 -2
  99. package/docs/playground/runtime/pict-section-modal.min.js +0 -2
  100. package/docs/playground/runtime/pict.min.js +0 -12
  101. package/docs/retold-catalog.json +0 -244
  102. package/docs/retold-keyword-index.json +0 -26028
  103. package/example_applications/simple_cards/css/flowexample.css +0 -65
  104. package/example_applications/simple_cards/html/index.html +0 -32
  105. package/example_applications/simple_cards/package.json +0 -52
  106. package/example_applications/simple_cards/source/Pict-Application-FlowExample-Configuration.json +0 -15
  107. package/example_applications/simple_cards/source/Pict-Application-FlowExample.js +0 -539
  108. package/example_applications/simple_cards/source/card-help-content.js +0 -16
  109. package/example_applications/simple_cards/source/cards/FlowCard-Comment.js +0 -38
  110. package/example_applications/simple_cards/source/cards/FlowCard-DataPreview.js +0 -44
  111. package/example_applications/simple_cards/source/cards/FlowCard-Each.js +0 -38
  112. package/example_applications/simple_cards/source/cards/FlowCard-FileRead.js +0 -56
  113. package/example_applications/simple_cards/source/cards/FlowCard-FileWrite.js +0 -50
  114. package/example_applications/simple_cards/source/cards/FlowCard-GetValue.js +0 -37
  115. package/example_applications/simple_cards/source/cards/FlowCard-IfThenElse.js +0 -49
  116. package/example_applications/simple_cards/source/cards/FlowCard-LogValues.js +0 -55
  117. package/example_applications/simple_cards/source/cards/FlowCard-SetValue.js +0 -97
  118. package/example_applications/simple_cards/source/cards/FlowCard-Sparkline.js +0 -100
  119. package/example_applications/simple_cards/source/cards/FlowCard-StatusMonitor.js +0 -46
  120. package/example_applications/simple_cards/source/cards/FlowCard-Switch.js +0 -39
  121. package/example_applications/simple_cards/source/providers/PictRouter-FlowExample-Configuration.json +0 -22
  122. package/example_applications/simple_cards/source/sample-flows.js +0 -410
  123. package/example_applications/simple_cards/source/views/PictView-FlowExample-About.js +0 -184
  124. package/example_applications/simple_cards/source/views/PictView-FlowExample-BottomBar.js +0 -77
  125. package/example_applications/simple_cards/source/views/PictView-FlowExample-Documentation.js +0 -325
  126. package/example_applications/simple_cards/source/views/PictView-FlowExample-FileWriteInfo.js +0 -59
  127. package/example_applications/simple_cards/source/views/PictView-FlowExample-Layout.js +0 -90
  128. package/example_applications/simple_cards/source/views/PictView-FlowExample-MainWorkspace.js +0 -453
  129. package/example_applications/simple_cards/source/views/PictView-FlowExample-TopBar.js +0 -95
  130. package/scripts/generate-card-help.js +0 -214
  131. package/source/providers/edges/Edge-Bezier.js +0 -41
  132. package/source/providers/edges/Edge-Orthogonal.js +0 -37
  133. package/source/providers/edges/Edge-OrthogonalSnap.js +0 -72
  134. package/source/providers/edges/Edge-Perimeter-Linear.js +0 -31
  135. package/source/providers/edges/Edge-Perimeter-Orthogonal.js +0 -39
  136. package/source/providers/edges/Edge-Perimeter.js +0 -48
  137. package/source/providers/edges/Edge-PerimeterMath.js +0 -92
  138. package/source/providers/edges/Edge-Straight.js +0 -24
  139. package/source/providers/layouts/Layout-Circular.js +0 -203
  140. package/source/providers/layouts/Layout-Coerce.js +0 -40
  141. package/source/providers/layouts/Layout-Columnar.js +0 -134
  142. package/source/providers/layouts/Layout-Custom.js +0 -27
  143. package/source/providers/layouts/Layout-ForcedFromCenter.js +0 -256
  144. package/source/providers/layouts/Layout-Grid.js +0 -134
  145. package/source/providers/layouts/Layout-Layered.js +0 -155
  146. package/source/providers/layouts/Layout-Rank.js +0 -141
  147. package/source/providers/layouts/Layout-Staggered.js +0 -131
  148. package/source/providers/layouts/Layout-Tabular.js +0 -94
  149. package/test/ConnectionHandleManager_tests.js +0 -717
  150. package/test/ConnectionRenderer_tests.js +0 -591
  151. package/test/DataManager_tests.js +0 -859
  152. package/test/Geometry_tests.js +0 -767
  153. package/test/InteractionManager_tests.js +0 -279
  154. package/test/Layout_tests.js +0 -1604
  155. package/test/NodeView_tests.js +0 -66
  156. package/test/PanelManager_tests.js +0 -172
  157. package/test/PathGenerator_tests.js +0 -978
  158. package/test/PortRenderer_tests.js +0 -376
  159. package/test/RenderManager_tests.js +0 -756
  160. package/test/Renderer_tests.js +0 -133
  161. package/test/SelectionManager_tests.js +0 -185
  162. package/test/StylePresets_tests.js +0 -153
@@ -1,39 +0,0 @@
1
- const libPictFlowCard = require('pict-section-flow').PictFlowCard;
2
- const libCardHelp = require('../card-help-content');
3
-
4
- class FlowCardSwitch extends libPictFlowCard
5
- {
6
- constructor(pFable, pOptions, pServiceHash)
7
- {
8
- super(pFable, Object.assign(
9
- {},
10
- {
11
- Title: 'Switch',
12
- Help: libCardHelp['SW'] || false,
13
- Name: 'Multi-way Branch',
14
- Code: 'SW',
15
- Description: 'Routes flow to one of multiple cases based on a value.',
16
- Icon: 'SW',
17
- Tooltip: 'Switch: Multi-way branch on a value',
18
- Category: 'Control Flow',
19
- TitleBarColor: '#d35400',
20
- BodyStyle: { fill: '#fbeee6', stroke: '#d35400' },
21
- Width: 200,
22
- Height: 120,
23
- Inputs:
24
- [
25
- { Name: 'In', Side: 'left', MinimumInputCount: 1, MaximumInputCount: 1 }
26
- ],
27
- Outputs:
28
- [
29
- { Name: 'Case A', Side: 'right' },
30
- { Name: 'Case B', Side: 'right' },
31
- { Name: 'Default', Side: 'bottom' }
32
- ]
33
- },
34
- pOptions),
35
- pServiceHash);
36
- }
37
- }
38
-
39
- module.exports = FlowCardSwitch;
@@ -1,22 +0,0 @@
1
- {
2
- "ProviderIdentifier": "Pict-Router",
3
-
4
- "AutoInitialize": true,
5
- "AutoInitializeOrdinal": 0,
6
-
7
- "Routes":
8
- [
9
- {
10
- "path": "/Home",
11
- "template": "{~LV:Pict.PictApplication.showView(`FlowExample-MainWorkspace`)~}"
12
- },
13
- {
14
- "path": "/About",
15
- "template": "{~LV:Pict.PictApplication.showView(`FlowExample-About`)~}"
16
- },
17
- {
18
- "path": "/Documentation",
19
- "template": "{~LV:Pict.PictApplication.showView(`FlowExample-Documentation`)~}"
20
- }
21
- ]
22
- }
@@ -1,410 +0,0 @@
1
- /**
2
- * sample-flows.js
3
- *
4
- * Showcase graphs for trying out the seven layout algorithms in
5
- * pict-section-flow. Each sample is a small flow definition with
6
- * `Name`, `Description`, `Recommended` (layout that shines), and
7
- * `Flow` (a `_FlowData`-shaped object).
8
- *
9
- * Use the dropdown above the flow diagram to load a sample, then
10
- * open the Algorithm popup to compare layouts. The descriptions
11
- * call out which layouts shine and which struggle on each shape.
12
- *
13
- * All nodes use the 'default' card type with simple In/Out ports —
14
- * the focus is on graph topology, not on the cards themselves.
15
- */
16
-
17
- // Ultravisor-flavored category palette — same families as
18
- // Ultravisor-CardConfigGenerator's _CategoryColors so the per-node
19
- // hint/border colors here read the same way they do in real flows.
20
- const _CATEGORY_COLORS =
21
- {
22
- 'core': { TitleBarColor: '#ab47bc', BodyStyle: { fill: '#f3e5f5', stroke: '#ab47bc' } },
23
- 'flow': { TitleBarColor: '#78909c', BodyStyle: { fill: '#eceff1', stroke: '#78909c' } },
24
- 'data': { TitleBarColor: '#ff9800', BodyStyle: { fill: '#fff3e0', stroke: '#ff9800' } },
25
- 'file-io': { TitleBarColor: '#42a5f5', BodyStyle: { fill: '#eaf2f8', stroke: '#42a5f5' } },
26
- 'rest': { TitleBarColor: '#29b6f6', BodyStyle: { fill: '#e1f5fe', stroke: '#29b6f6' } },
27
- 'meadow': { TitleBarColor: '#66bb6a', BodyStyle: { fill: '#e8f5e9', stroke: '#66bb6a' } },
28
- 'pipeline': { TitleBarColor: '#ec407a', BodyStyle: { fill: '#fce4ec', stroke: '#ec407a' } },
29
- 'llm': { TitleBarColor: '#26a69a', BodyStyle: { fill: '#e0f7fa', stroke: '#26a69a' } },
30
- 'ext': { TitleBarColor: '#9c6afe', BodyStyle: { fill: '#ede9fe', stroke: '#9c6afe' } }
31
- };
32
-
33
- function _node(pHash, pTitle, pX, pY, pCategory)
34
- {
35
- let tmpNode =
36
- {
37
- Hash: pHash,
38
- Type: 'default',
39
- X: pX,
40
- Y: pY,
41
- Width: 140,
42
- Height: 70,
43
- Title: pTitle,
44
- Ports:
45
- [
46
- { Hash: `${pHash}-in`, Direction: 'input', Side: 'left', Label: 'In' },
47
- { Hash: `${pHash}-out`, Direction: 'output', Side: 'right', Label: 'Out' }
48
- ],
49
- Data: {}
50
- };
51
- if (pCategory && _CATEGORY_COLORS[pCategory])
52
- {
53
- let tmpColors = _CATEGORY_COLORS[pCategory];
54
- tmpNode.TitleBarColor = tmpColors.TitleBarColor;
55
- tmpNode.BodyStyle = tmpColors.BodyStyle;
56
- }
57
- return tmpNode;
58
- }
59
-
60
- function _edge(pSourceHash, pTargetHash, pSuffix)
61
- {
62
- let tmpHash = `c-${pSourceHash}-${pTargetHash}${pSuffix ? `-${pSuffix}` : ''}`;
63
- return {
64
- Hash: tmpHash,
65
- SourceNodeHash: pSourceHash,
66
- SourcePortHash: `${pSourceHash}-out`,
67
- TargetNodeHash: pTargetHash,
68
- TargetPortHash: `${pTargetHash}-in`,
69
- Data: {}
70
- };
71
- }
72
-
73
- function _emptyViewState()
74
- {
75
- return { PanX: 0, PanY: 0, Zoom: 1, SelectedNodeHash: null, SelectedConnectionHash: null, SelectedTetherHash: null };
76
- }
77
-
78
- function _flow(pNodes, pConnections, pAlgorithm, pParameters, pAutoApply)
79
- {
80
- return {
81
- Nodes: pNodes,
82
- Connections: pConnections || [],
83
- OpenPanels: [],
84
- SavedLayouts: [],
85
- ViewState: _emptyViewState(),
86
- LayoutAlgorithm: pAlgorithm || 'Custom',
87
- LayoutParameters: pParameters || {},
88
- LayoutAutoApply: !!pAutoApply
89
- };
90
- }
91
-
92
- // ── 1. Linear Chain ────────────────────────────────────────────────────
93
- // A → B → C → D → E → F
94
- function _linearChain()
95
- {
96
- let tmpCount = 6;
97
- let tmpNodes = [];
98
- let tmpEdges = [];
99
- for (let i = 0; i < tmpCount; i++)
100
- {
101
- let tmpHash = `lc-${String.fromCharCode(65 + i)}`;
102
- tmpNodes.push(_node(tmpHash, String.fromCharCode(65 + i), 100, 100 + i * 110));
103
- if (i > 0)
104
- {
105
- let tmpPrev = `lc-${String.fromCharCode(65 + i - 1)}`;
106
- tmpEdges.push(_edge(tmpPrev, tmpHash));
107
- }
108
- }
109
- return _flow(tmpNodes, tmpEdges);
110
- }
111
-
112
- // ── 2. Binary Tree (depth 3) ───────────────────────────────────────────
113
- // Root → 2 children → 4 grandchildren = 7 nodes
114
- function _binaryTree()
115
- {
116
- let tmpNodes = [];
117
- let tmpEdges = [];
118
- let tmpHashes = ['root', 'l', 'r', 'll', 'lr', 'rl', 'rr'];
119
- let tmpLabels = ['Root', 'L', 'R', 'LL', 'LR', 'RL', 'RR'];
120
- let tmpPositions = [
121
- [400, 100], // root
122
- [250, 240], [550, 240], // l, r
123
- [150, 380], [350, 380], [450, 380], [650, 380] // ll lr rl rr
124
- ];
125
- for (let i = 0; i < tmpHashes.length; i++)
126
- {
127
- tmpNodes.push(_node(`bt-${tmpHashes[i]}`, tmpLabels[i], tmpPositions[i][0], tmpPositions[i][1]));
128
- }
129
- tmpEdges.push(_edge('bt-root', 'bt-l'));
130
- tmpEdges.push(_edge('bt-root', 'bt-r'));
131
- tmpEdges.push(_edge('bt-l', 'bt-ll'));
132
- tmpEdges.push(_edge('bt-l', 'bt-lr'));
133
- tmpEdges.push(_edge('bt-r', 'bt-rl'));
134
- tmpEdges.push(_edge('bt-r', 'bt-rr'));
135
- return _flow(tmpNodes, tmpEdges);
136
- }
137
-
138
- // ── 3. Star Hub (1 hub + 8 spokes) ─────────────────────────────────────
139
- // Each spoke gets a distinct Ultravisor-style category color so the
140
- // hint beziers (which are colored by the *other end's* identity) fan
141
- // out in 8 different colors when you hover the hub's "Out" badge.
142
- function _starHub()
143
- {
144
- let tmpNodes = [];
145
- let tmpEdges = [];
146
- let tmpSpokeKinds =
147
- [
148
- { key: 'rest', label: 'REST API' },
149
- { key: 'meadow', label: 'Meadow' },
150
- { key: 'data', label: 'Transform' },
151
- { key: 'file-io', label: 'File I/O' },
152
- { key: 'pipeline', label: 'Pipeline' },
153
- { key: 'llm', label: 'LLM' },
154
- { key: 'ext', label: 'Extension' },
155
- { key: 'flow', label: 'Control' }
156
- ];
157
- tmpNodes.push(_node('star-hub', 'Hub', 400, 350, 'core'));
158
- for (let i = 0; i < tmpSpokeKinds.length; i++)
159
- {
160
- let tmpAngle = (i / tmpSpokeKinds.length) * 2 * Math.PI;
161
- let tmpX = 400 + Math.round(Math.cos(tmpAngle) * 240);
162
- let tmpY = 350 + Math.round(Math.sin(tmpAngle) * 240);
163
- let tmpHash = `star-s${i}`;
164
- tmpNodes.push(_node(tmpHash, tmpSpokeKinds[i].label, tmpX, tmpY, tmpSpokeKinds[i].key));
165
- tmpEdges.push(_edge('star-hub', tmpHash));
166
- }
167
- return _flow(tmpNodes, tmpEdges);
168
- }
169
-
170
- // ── 4. Diamond Lattice ─────────────────────────────────────────────────
171
- // Start → {A,B,C} → {D,E,F} (cross-edges) → Merge → End. Nine nodes.
172
- function _diamondLattice()
173
- {
174
- let tmpNodes =
175
- [
176
- _node('dl-start', 'Start', 100, 200),
177
- _node('dl-a', 'A', 300, 100),
178
- _node('dl-b', 'B', 300, 250),
179
- _node('dl-c', 'C', 300, 400),
180
- _node('dl-d', 'D', 550, 100),
181
- _node('dl-e', 'E', 550, 250),
182
- _node('dl-f', 'F', 550, 400),
183
- _node('dl-merge', 'Merge', 800, 250),
184
- _node('dl-end', 'End', 1050, 250)
185
- ];
186
- let tmpEdges =
187
- [
188
- _edge('dl-start', 'dl-a'),
189
- _edge('dl-start', 'dl-b'),
190
- _edge('dl-start', 'dl-c'),
191
- _edge('dl-a', 'dl-d'),
192
- _edge('dl-a', 'dl-e'), // cross
193
- _edge('dl-b', 'dl-e'),
194
- _edge('dl-c', 'dl-e'), // cross
195
- _edge('dl-c', 'dl-f'),
196
- _edge('dl-d', 'dl-merge'),
197
- _edge('dl-e', 'dl-merge'),
198
- _edge('dl-f', 'dl-merge'),
199
- _edge('dl-merge', 'dl-end')
200
- ];
201
- return _flow(tmpNodes, tmpEdges);
202
- }
203
-
204
- // ── 5. Disconnected Components (3 chains × 4 nodes) ────────────────────
205
- function _disconnectedComponents()
206
- {
207
- let tmpNodes = [];
208
- let tmpEdges = [];
209
- let tmpClusters = ['α', 'β', 'γ'];
210
- for (let c = 0; c < tmpClusters.length; c++)
211
- {
212
- for (let i = 0; i < 4; i++)
213
- {
214
- let tmpHash = `dc-${tmpClusters[c]}-${i}`;
215
- tmpNodes.push(_node(tmpHash, `${tmpClusters[c]}${i}`, 150 + c * 350, 100 + i * 110));
216
- if (i > 0)
217
- {
218
- let tmpPrev = `dc-${tmpClusters[c]}-${i - 1}`;
219
- tmpEdges.push(_edge(tmpPrev, tmpHash));
220
- }
221
- }
222
- }
223
- return _flow(tmpNodes, tmpEdges);
224
- }
225
-
226
- // ── 6. Dense Cluster (7 nodes, ~15 edges, near-complete) ───────────────
227
- function _denseCluster()
228
- {
229
- let tmpNodes = [];
230
- let tmpEdges = [];
231
- let tmpCount = 7;
232
- for (let i = 0; i < tmpCount; i++)
233
- {
234
- let tmpAngle = (i / tmpCount) * 2 * Math.PI;
235
- let tmpX = 400 + Math.round(Math.cos(tmpAngle) * 200);
236
- let tmpY = 300 + Math.round(Math.sin(tmpAngle) * 200);
237
- tmpNodes.push(_node(`dn-${i}`, `N${i}`, tmpX, tmpY));
238
- }
239
- // Connect each node to ~3 others (skip-1 and skip-2 patterns) — yields ~14 edges
240
- for (let i = 0; i < tmpCount; i++)
241
- {
242
- tmpEdges.push(_edge(`dn-${i}`, `dn-${(i + 1) % tmpCount}`));
243
- tmpEdges.push(_edge(`dn-${i}`, `dn-${(i + 2) % tmpCount}`));
244
- }
245
- return _flow(tmpNodes, tmpEdges);
246
- }
247
-
248
- // ── 7. Cyclic Network (8 nodes, ring + chord) ──────────────────────────
249
- function _cyclicNetwork()
250
- {
251
- let tmpNodes = [];
252
- let tmpEdges = [];
253
- let tmpCount = 8;
254
- for (let i = 0; i < tmpCount; i++)
255
- {
256
- let tmpAngle = (i / tmpCount) * 2 * Math.PI;
257
- let tmpX = 400 + Math.round(Math.cos(tmpAngle) * 220);
258
- let tmpY = 300 + Math.round(Math.sin(tmpAngle) * 220);
259
- tmpNodes.push(_node(`cy-${i}`, `Z${i}`, tmpX, tmpY));
260
- }
261
- // Ring of forward edges 0→1→2→…→7→0 (back-edge creates the cycle)
262
- for (let i = 0; i < tmpCount; i++)
263
- {
264
- tmpEdges.push(_edge(`cy-${i}`, `cy-${(i + 1) % tmpCount}`));
265
- }
266
- // One chord across the ring
267
- tmpEdges.push(_edge('cy-0', 'cy-4'));
268
- return _flow(tmpNodes, tmpEdges);
269
- }
270
-
271
- // ── 8. Mesh 4×4 (16 nodes, 4-neighbor edges) ───────────────────────────
272
- function _mesh4x4()
273
- {
274
- let tmpNodes = [];
275
- let tmpEdges = [];
276
- let tmpRows = 4, tmpCols = 4;
277
- for (let r = 0; r < tmpRows; r++)
278
- {
279
- for (let c = 0; c < tmpCols; c++)
280
- {
281
- let tmpHash = `mesh-${r}-${c}`;
282
- tmpNodes.push(_node(tmpHash, `(${r},${c})`, 150 + c * 180, 100 + r * 130));
283
- }
284
- }
285
- for (let r = 0; r < tmpRows; r++)
286
- {
287
- for (let c = 0; c < tmpCols; c++)
288
- {
289
- if (c < tmpCols - 1) tmpEdges.push(_edge(`mesh-${r}-${c}`, `mesh-${r}-${c + 1}`));
290
- if (r < tmpRows - 1) tmpEdges.push(_edge(`mesh-${r}-${c}`, `mesh-${r + 1}-${c}`));
291
- }
292
- }
293
- return _flow(tmpNodes, tmpEdges);
294
- }
295
-
296
- // ── 9. Floating Widgets (12 isolated nodes, no edges) ──────────────────
297
- function _floatingWidgets()
298
- {
299
- let tmpNodes = [];
300
- let tmpLabels = ['Chart', 'Table', 'KPI', 'Gauge', 'Sparkline', 'Heatmap', 'Pie', 'Bar', 'Map', 'Timeline', 'Note', 'Image'];
301
- for (let i = 0; i < tmpLabels.length; i++)
302
- {
303
- let tmpRow = Math.floor(i / 4);
304
- let tmpCol = i % 4;
305
- tmpNodes.push(_node(`fw-${i}`, tmpLabels[i], 150 + tmpCol * 180, 100 + tmpRow * 130));
306
- }
307
- return _flow(tmpNodes, []);
308
- }
309
-
310
- // ── 10. Wide Fan-Out (1 root → 12 leaves) ──────────────────────────────
311
- function _wideFanOut()
312
- {
313
- let tmpNodes = [];
314
- let tmpEdges = [];
315
- tmpNodes.push(_node('fan-root', 'Source', 100, 400));
316
- for (let i = 0; i < 12; i++)
317
- {
318
- let tmpHash = `fan-leaf-${i}`;
319
- tmpNodes.push(_node(tmpHash, `L${i}`, 400 + (i % 4) * 160, 100 + Math.floor(i / 4) * 130));
320
- tmpEdges.push(_edge('fan-root', tmpHash));
321
- }
322
- return _flow(tmpNodes, tmpEdges);
323
- }
324
-
325
- const SAMPLE_FLOWS =
326
- {
327
- 'linear-chain':
328
- {
329
- Name: 'Linear Chain',
330
- Description: 'A → B → C → D → E → F. Six nodes, single path. Layered (left-to-right) and Tabular (top-to-bottom) read like a story; Circular wastes a ring on what should be a line; ForcedFromCenter is overkill.',
331
- Recommended: 'Layered',
332
- Flow: _linearChain()
333
- },
334
- 'binary-tree':
335
- {
336
- Name: 'Binary Tree (depth 3)',
337
- Description: 'Root branches into 2 children, each into 2 grandchildren. Layered shows the hierarchy clearly (depth-by-depth); Circular puts the root at center with leaves on outer ring; Grid loses the parent-child relationships entirely.',
338
- Recommended: 'Layered',
339
- Flow: _binaryTree()
340
- },
341
- 'star-hub':
342
- {
343
- Name: 'Star Hub (8 spokes)',
344
- Description: 'One hub connected to 8 leaves. Circular shines (root at center, spokes evenly around); Layered crowds all 8 spokes in a single second column; ForcedFromCenter does an OK job; Grid ignores the topology completely.',
345
- Recommended: 'Circular',
346
- Flow: _starHub()
347
- },
348
- 'diamond-lattice':
349
- {
350
- Name: 'Diamond Lattice (DAG)',
351
- Description: 'Start fans out to 3 paths through 6 middle nodes (with cross-edges) and merges at End. Layered is in its element — the parallel depth structure becomes obvious. Tabular flattens it; Circular loses direction.',
352
- Recommended: 'Layered',
353
- Flow: _diamondLattice()
354
- },
355
- 'disconnected-components':
356
- {
357
- Name: 'Disconnected Components',
358
- Description: 'Three independent chains of 4 nodes each, no cross-edges. Grid and Columnar give each chain equal real estate. Layered piles the 3 roots in one column. ForcedFromCenter clusters them naturally but with no separation guarantee.',
359
- Recommended: 'Columnar',
360
- Flow: _disconnectedComponents()
361
- },
362
- 'dense-cluster':
363
- {
364
- Name: 'Dense Cluster (near-complete)',
365
- Description: 'Seven nodes with ~14 edges (each node connects to its two nearest neighbors in both directions). ForcedFromCenter shines — spring forces find a clean radial layout. Layered tries to topo-sort it and produces a wide-and-shallow mess. Circular is also pretty good here.',
366
- Recommended: 'ForcedFromCenter',
367
- Flow: _denseCluster()
368
- },
369
- 'cyclic-network':
370
- {
371
- Name: 'Cyclic Network',
372
- Description: 'Eight nodes in a ring plus one chord. The cycle defeats Kahn topological sort — Layered falls back to a "remaining nodes" pass (correct but ugly). Circular renders the ring cleanly. ForcedFromCenter finds a relaxed equilibrium.',
373
- Recommended: 'Circular',
374
- Flow: _cyclicNetwork()
375
- },
376
- 'mesh-4x4':
377
- {
378
- Name: 'Mesh 4×4',
379
- Description: '16 nodes in a 4×4 grid topology with right/down neighbor edges. Grid is the obvious win (the layout matches the data). Columnar (4 cols, FillOrder=row) also nails it. Layered produces a long zig-zag through 7 layers.',
380
- Recommended: 'Grid',
381
- Flow: _mesh4x4()
382
- },
383
- 'floating-widgets':
384
- {
385
- Name: 'Floating Widgets (no edges)',
386
- Description: '12 unconnected nodes — exactly the dashboard-builder shape. Grid, Columnar, and Tabular all produce clean deterministic arrangements. Layered, Circular, and ForcedFromCenter degrade gracefully (single layer / single ring / random spread).',
387
- Recommended: 'Grid',
388
- Flow: _floatingWidgets()
389
- },
390
- 'wide-fan-out':
391
- {
392
- Name: 'Wide Fan-Out (1 → 12)',
393
- Description: 'One source node connects to 12 leaves. Circular places the source at center with leaves on a single outer ring — clean and balanced. Layered makes the second column 12 nodes tall. Grid spreads leaves and loses the source-to-leaf relationship.',
394
- Recommended: 'Circular',
395
- Flow: _wideFanOut()
396
- }
397
- };
398
-
399
- module.exports =
400
- {
401
- SAMPLE_FLOWS: SAMPLE_FLOWS,
402
- getSampleNames: function ()
403
- {
404
- return Object.keys(SAMPLE_FLOWS);
405
- },
406
- getSample: function (pKey)
407
- {
408
- return SAMPLE_FLOWS[pKey] || null;
409
- }
410
- };
@@ -1,184 +0,0 @@
1
- const libPictView = require('pict-view');
2
-
3
- const _ViewConfiguration =
4
- {
5
- ViewIdentifier: "FlowExample-About",
6
-
7
- DefaultRenderable: "FlowExample-About-Content",
8
- DefaultDestinationAddress: "#FlowExample-Content-Container",
9
-
10
- AutoRender: false,
11
-
12
- CSS: /*css*/`
13
- .flowexample-about {
14
- padding: 2em;
15
- max-width: 800px;
16
- margin: 0 auto;
17
- }
18
- .flowexample-about-header {
19
- text-align: center;
20
- padding-bottom: 1.5em;
21
- border-bottom: 1px solid var(--theme-color-border-light, #eee);
22
- margin-bottom: 2em;
23
- }
24
- .flowexample-about-header h1 {
25
- margin: 0 0 0.25em 0;
26
- font-size: 2em;
27
- font-weight: 300;
28
- color: #2c3e50;
29
- }
30
- .flowexample-about-header p {
31
- margin: 0;
32
- color: #7f8c8d;
33
- font-size: 1.1em;
34
- }
35
- .flowexample-about h2 {
36
- margin: 1.5em 0 0.5em 0;
37
- font-weight: 400;
38
- color: #2c3e50;
39
- font-size: 1.3em;
40
- }
41
- .flowexample-about p {
42
- color: var(--theme-color-text-secondary, #555);
43
- line-height: 1.7;
44
- }
45
- .flowexample-about-tech {
46
- display: grid;
47
- grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
48
- gap: 1em;
49
- margin-top: 1em;
50
- }
51
- .flowexample-about-tech-item {
52
- background: #f8f9fa;
53
- border: 1px solid #e9ecef;
54
- border-radius: 4px;
55
- padding: 1em;
56
- text-align: center;
57
- }
58
- .flowexample-about-tech-item strong {
59
- display: block;
60
- margin-bottom: 0.25em;
61
- color: #2c3e50;
62
- }
63
- .flowexample-about-tech-item span {
64
- font-size: 0.85em;
65
- color: var(--theme-color-text-secondary, #666);
66
- }
67
- .flowexample-about-features {
68
- display: grid;
69
- grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
70
- gap: 1em;
71
- margin-top: 1em;
72
- }
73
- .flowexample-about-feature {
74
- background: var(--theme-color-background-panel, #fff);
75
- border: 1px solid var(--theme-color-border-default, #e0e0e0);
76
- border-radius: 6px;
77
- padding: 1.25em;
78
- }
79
- .flowexample-about-feature h3 {
80
- margin: 0 0 0.35em 0;
81
- font-size: 1em;
82
- color: #2c3e50;
83
- }
84
- .flowexample-about-feature p {
85
- margin: 0;
86
- font-size: 0.9em;
87
- }
88
- `,
89
-
90
- Templates:
91
- [
92
- {
93
- Hash: "FlowExample-About-Template",
94
- Template: /*html*/`
95
- <div class="flowexample-about">
96
- <div class="flowexample-about-header">
97
- <h1>About Pict Section Flow</h1>
98
- <p>A pure SVG flow diagram component for the Pict framework</p>
99
- </div>
100
-
101
- <h2>What It Does</h2>
102
- <p>Pict Section Flow provides a self-contained, extensible flow diagram view for Pict applications. It renders nodes and connections as SVG elements, supports drag-and-drop node positioning, interactive connection creation between ports, and viewport panning and zooming &mdash; all with zero external diagram library dependencies.</p>
103
-
104
- <h2>Key Features</h2>
105
- <div class="flowexample-about-features">
106
- <div class="flowexample-about-feature">
107
- <h3>Pure SVG Rendering</h3>
108
- <p>All diagram elements are rendered as standard SVG, providing native DOM events and CSS styling with no canvas or external libraries required.</p>
109
- </div>
110
- <div class="flowexample-about-feature">
111
- <h3>Drag &amp; Drop Nodes</h3>
112
- <p>Click and drag nodes to reposition them. Connections update in real time with smooth cubic bezier curves.</p>
113
- </div>
114
- <div class="flowexample-about-feature">
115
- <h3>Interactive Connections</h3>
116
- <p>Drag from an output port to an input port to create connections visually. Validation prevents self-connections and duplicates.</p>
117
- </div>
118
- <div class="flowexample-about-feature">
119
- <h3>Pan &amp; Zoom</h3>
120
- <p>Navigate large diagrams with background panning and mouse wheel zoom. Zoom-to-fit centers all nodes automatically.</p>
121
- </div>
122
- <div class="flowexample-about-feature">
123
- <h3>Extensible Node Types</h3>
124
- <p>Register custom node types with different shapes, colors, port configurations, and styles through the Node Type Provider.</p>
125
- </div>
126
- <div class="flowexample-about-feature">
127
- <h3>Event Hooks</h3>
128
- <p>Listen for node selection, movement, connection creation and removal through the Event Handler Provider for full extensibility.</p>
129
- </div>
130
- </div>
131
-
132
- <h2>Built With</h2>
133
- <div class="flowexample-about-tech">
134
- <div class="flowexample-about-tech-item">
135
- <strong>Pict</strong>
136
- <span>Application Framework</span>
137
- </div>
138
- <div class="flowexample-about-tech-item">
139
- <strong>Pict-View</strong>
140
- <span>View Lifecycle</span>
141
- </div>
142
- <div class="flowexample-about-tech-item">
143
- <strong>Pict-Router</strong>
144
- <span>Hash Routing</span>
145
- </div>
146
- <div class="flowexample-about-tech-item">
147
- <strong>SVG</strong>
148
- <span>Diagram Rendering</span>
149
- </div>
150
- <div class="flowexample-about-tech-item">
151
- <strong>Fable</strong>
152
- <span>Service Architecture</span>
153
- </div>
154
- </div>
155
-
156
- <h2>License</h2>
157
- <p>This project is released under the MIT License. It is part of the Retold ecosystem of tools for building complex data-driven applications.</p>
158
- </div>
159
- `
160
- }
161
- ],
162
-
163
- Renderables:
164
- [
165
- {
166
- RenderableHash: "FlowExample-About-Content",
167
- TemplateHash: "FlowExample-About-Template",
168
- DestinationAddress: "#FlowExample-Content-Container",
169
- RenderMethod: "replace"
170
- }
171
- ]
172
- };
173
-
174
- class FlowExampleAboutView extends libPictView
175
- {
176
- constructor(pFable, pOptions, pServiceHash)
177
- {
178
- super(pFable, pOptions, pServiceHash);
179
- }
180
- }
181
-
182
- module.exports = FlowExampleAboutView;
183
-
184
- module.exports.default_configuration = _ViewConfiguration;