pict-section-flow 0.0.10 → 0.0.13
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.
- package/.claude/launch.json +1 -1
- package/README.md +176 -0
- package/docs/.nojekyll +0 -0
- package/docs/Architecture.md +303 -0
- package/docs/Custom-Styling.md +275 -0
- package/docs/Data_Model.md +158 -0
- package/docs/Event_System.md +156 -0
- package/docs/Getting_Started.md +237 -0
- package/docs/Implementation_Reference.md +528 -0
- package/docs/Layout_Persistence.md +117 -0
- package/docs/README.md +115 -52
- package/docs/_cover.md +11 -0
- package/docs/_sidebar.md +52 -0
- package/docs/_topbar.md +8 -0
- package/docs/api/PictFlowCard.md +216 -0
- package/docs/api/PictFlowCardPropertiesPanel.md +235 -0
- package/docs/api/addConnection.md +101 -0
- package/docs/api/addNode.md +137 -0
- package/docs/api/autoLayout.md +77 -0
- package/docs/api/getFlowData.md +112 -0
- package/docs/api/marshalToView.md +95 -0
- package/docs/api/openPanel.md +128 -0
- package/docs/api/registerHandler.md +174 -0
- package/docs/api/registerNodeType.md +142 -0
- package/docs/api/removeConnection.md +57 -0
- package/docs/api/removeNode.md +80 -0
- package/docs/api/saveLayout.md +152 -0
- package/docs/api/screenToSVGCoords.md +68 -0
- package/docs/api/selectNode.md +116 -0
- package/docs/api/setTheme.md +168 -0
- package/docs/api/setZoom.md +97 -0
- package/docs/api/toggleFullscreen.md +68 -0
- package/docs/card-help/EACH.md +19 -0
- package/docs/card-help/FREAD.md +24 -0
- package/docs/card-help/FWRITE.md +24 -0
- package/docs/card-help/GET.md +22 -0
- package/docs/card-help/ITE.md +23 -0
- package/docs/card-help/LOG.md +23 -0
- package/docs/card-help/NOTE.md +17 -0
- package/docs/card-help/PREV.md +18 -0
- package/docs/card-help/SET.md +27 -0
- package/docs/card-help/SPKL.md +22 -0
- package/docs/card-help/STAT.md +23 -0
- package/docs/card-help/SW.md +25 -0
- package/docs/css/docuserve.css +73 -0
- package/docs/index.html +39 -0
- package/docs/retold-catalog.json +169 -0
- package/docs/retold-keyword-index.json +13942 -0
- package/example_applications/simple_cards/package.json +1 -0
- package/example_applications/simple_cards/source/card-help-content.js +16 -0
- package/example_applications/simple_cards/source/cards/FlowCard-Comment.js +2 -0
- package/example_applications/simple_cards/source/cards/FlowCard-DataPreview.js +2 -0
- package/example_applications/simple_cards/source/cards/FlowCard-Each.js +2 -0
- package/example_applications/simple_cards/source/cards/FlowCard-FileRead.js +2 -0
- package/example_applications/simple_cards/source/cards/FlowCard-FileWrite.js +2 -0
- package/example_applications/simple_cards/source/cards/FlowCard-GetValue.js +2 -0
- package/example_applications/simple_cards/source/cards/FlowCard-IfThenElse.js +2 -0
- package/example_applications/simple_cards/source/cards/FlowCard-LogValues.js +2 -0
- package/example_applications/simple_cards/source/cards/FlowCard-SetValue.js +2 -0
- package/example_applications/simple_cards/source/cards/FlowCard-Sparkline.js +2 -0
- package/example_applications/simple_cards/source/cards/FlowCard-StatusMonitor.js +2 -0
- package/example_applications/simple_cards/source/cards/FlowCard-Switch.js +2 -0
- package/package.json +11 -7
- package/scripts/generate-card-help.js +214 -0
- package/source/Pict-Section-Flow.js +4 -0
- package/source/PictFlowCard.js +3 -1
- package/source/providers/PictProvider-Flow-CSS.js +245 -152
- package/source/providers/PictProvider-Flow-ConnectorShapes.js +24 -0
- package/source/providers/PictProvider-Flow-Geometry.js +195 -38
- package/source/providers/PictProvider-Flow-PanelChrome.js +14 -12
- package/source/services/PictService-Flow-ConnectionHandleManager.js +263 -0
- package/source/services/PictService-Flow-ConnectionRenderer.js +134 -183
- package/source/services/PictService-Flow-DataManager.js +338 -0
- package/source/services/PictService-Flow-InteractionManager.js +165 -7
- package/source/services/PictService-Flow-PathGenerator.js +282 -0
- package/source/services/PictService-Flow-PortRenderer.js +269 -0
- package/source/services/PictService-Flow-RenderManager.js +281 -0
- package/source/services/PictService-Flow-Tether.js +6 -42
- package/source/views/PictView-Flow-Node.js +2 -220
- package/source/views/PictView-Flow-PropertiesPanel.js +89 -44
- package/source/views/PictView-Flow.js +130 -882
- package/test/ConnectionHandleManager_tests.js +717 -0
- package/test/ConnectionRenderer_tests.js +591 -0
- package/test/DataManager_tests.js +859 -0
- package/test/Geometry_tests.js +767 -0
- package/test/PathGenerator_tests.js +978 -0
- package/test/PortRenderer_tests.js +367 -0
- package/test/RenderManager_tests.js +756 -0
|
@@ -0,0 +1,528 @@
|
|
|
1
|
+
# Implementation Reference
|
|
2
|
+
|
|
3
|
+
Complete API reference for Pict-Section-Flow. This document covers every public method on the main `PictViewFlow` class and the key internal services and providers developers interact with.
|
|
4
|
+
|
|
5
|
+
## PictViewFlow — Main View API
|
|
6
|
+
|
|
7
|
+
The primary class exported by `pict-section-flow`. Extends `pict-view`.
|
|
8
|
+
|
|
9
|
+
### Configuration
|
|
10
|
+
|
|
11
|
+
```javascript
|
|
12
|
+
const libPictSectionFlow = require('pict-section-flow');
|
|
13
|
+
|
|
14
|
+
_Pict.addView('MyFlow',
|
|
15
|
+
{
|
|
16
|
+
ViewIdentifier: 'Pict-Flow',
|
|
17
|
+
DefaultDestinationAddress: '#flow-container',
|
|
18
|
+
FlowDataAddress: 'AppData.MyFlow',
|
|
19
|
+
|
|
20
|
+
EnableToolbar: true,
|
|
21
|
+
EnablePanning: true,
|
|
22
|
+
EnableZooming: true,
|
|
23
|
+
EnableNodeDragging: true,
|
|
24
|
+
EnableConnectionCreation: true,
|
|
25
|
+
EnableGridSnap: false,
|
|
26
|
+
GridSnapSize: 20,
|
|
27
|
+
|
|
28
|
+
MinZoom: 0.1,
|
|
29
|
+
MaxZoom: 5.0,
|
|
30
|
+
ZoomStep: 0.1,
|
|
31
|
+
|
|
32
|
+
DefaultNodeType: 'default',
|
|
33
|
+
DefaultNodeWidth: 180,
|
|
34
|
+
DefaultNodeHeight: 80,
|
|
35
|
+
|
|
36
|
+
Theme: 'default'
|
|
37
|
+
},
|
|
38
|
+
libPictSectionFlow);
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
| Option | Type | Default | Description |
|
|
42
|
+
|--------|------|---------|-------------|
|
|
43
|
+
| `ViewIdentifier` | string | `'Pict-Flow'` | Unique identifier for debugging and DOM IDs |
|
|
44
|
+
| `DefaultDestinationAddress` | string | `'#Flow-Container'` | CSS selector for the container element |
|
|
45
|
+
| `FlowDataAddress` | string/false | `false` | AppData path for two-way binding |
|
|
46
|
+
| `EnableToolbar` | boolean | `true` | Show the toolbar UI |
|
|
47
|
+
| `EnablePanning` | boolean | `true` | Allow canvas panning |
|
|
48
|
+
| `EnableZooming` | boolean | `true` | Allow canvas zooming |
|
|
49
|
+
| `EnableNodeDragging` | boolean | `true` | Allow node repositioning |
|
|
50
|
+
| `EnableConnectionCreation` | boolean | `true` | Allow creating port-to-port connections |
|
|
51
|
+
| `EnableGridSnap` | boolean | `false` | Snap node positions to grid |
|
|
52
|
+
| `GridSnapSize` | number | `20` | Grid cell size in pixels |
|
|
53
|
+
| `MinZoom` | number | `0.1` | Minimum zoom level |
|
|
54
|
+
| `MaxZoom` | number | `5.0` | Maximum zoom level |
|
|
55
|
+
| `ZoomStep` | number | `0.1` | Zoom increment per scroll tick |
|
|
56
|
+
| `DefaultNodeType` | string | `'default'` | Node type when none specified |
|
|
57
|
+
| `DefaultNodeWidth` | number | `180` | Default node width in pixels |
|
|
58
|
+
| `DefaultNodeHeight` | number | `80` | Default node height in pixels |
|
|
59
|
+
| `Theme` | string | `'default'` | Active theme key |
|
|
60
|
+
|
|
61
|
+
---
|
|
62
|
+
|
|
63
|
+
## Data Management Methods
|
|
64
|
+
|
|
65
|
+
### addNode(pType, pX, pY, pTitle, pData)
|
|
66
|
+
|
|
67
|
+
Create a new node on the canvas.
|
|
68
|
+
|
|
69
|
+
| Parameter | Type | Description |
|
|
70
|
+
|-----------|------|-------------|
|
|
71
|
+
| `pType` | string | Node type key (e.g. `'start'`, `'default'`, or a custom card code) |
|
|
72
|
+
| `pX` | number | X coordinate in SVG space |
|
|
73
|
+
| `pY` | number | Y coordinate in SVG space |
|
|
74
|
+
| `pTitle` | string | Display title |
|
|
75
|
+
| `pData` | object | Optional custom data attached to the node |
|
|
76
|
+
|
|
77
|
+
**Returns:** Node object with `Hash`, `Ports`, `Type`, etc.
|
|
78
|
+
|
|
79
|
+
### removeNode(pNodeHash)
|
|
80
|
+
|
|
81
|
+
Delete a node and all its connections.
|
|
82
|
+
|
|
83
|
+
| Parameter | Type | Description |
|
|
84
|
+
|-----------|------|-------------|
|
|
85
|
+
| `pNodeHash` | string | Hash of the node to remove |
|
|
86
|
+
|
|
87
|
+
**Returns:** `boolean` — `true` if the node was found and removed.
|
|
88
|
+
|
|
89
|
+
### addConnection(pSourceNode, pSourcePort, pTargetNode, pTargetPort, pData)
|
|
90
|
+
|
|
91
|
+
Connect two ports.
|
|
92
|
+
|
|
93
|
+
| Parameter | Type | Description |
|
|
94
|
+
|-----------|------|-------------|
|
|
95
|
+
| `pSourceNode` | string | Source node hash |
|
|
96
|
+
| `pSourcePort` | string | Source port hash |
|
|
97
|
+
| `pTargetNode` | string | Target node hash |
|
|
98
|
+
| `pTargetPort` | string | Target port hash |
|
|
99
|
+
| `pData` | object | Optional connection data (e.g. `{ LineMode: 'orthogonal' }`) |
|
|
100
|
+
|
|
101
|
+
**Returns:** Connection object, or `false` if validation failed.
|
|
102
|
+
|
|
103
|
+
### removeConnection(pConnectionHash)
|
|
104
|
+
|
|
105
|
+
Delete a connection.
|
|
106
|
+
|
|
107
|
+
| Parameter | Type | Description |
|
|
108
|
+
|-----------|------|-------------|
|
|
109
|
+
| `pConnectionHash` | string | Hash of the connection to remove |
|
|
110
|
+
|
|
111
|
+
**Returns:** `boolean` — `true` if the connection was found and removed.
|
|
112
|
+
|
|
113
|
+
### getFlowData()
|
|
114
|
+
|
|
115
|
+
Get a deep clone of the complete flow state.
|
|
116
|
+
|
|
117
|
+
**Returns:** `{ Nodes, Connections, OpenPanels, SavedLayouts, ViewState }`
|
|
118
|
+
|
|
119
|
+
### setFlowData(pFlowData)
|
|
120
|
+
|
|
121
|
+
Replace the entire flow state and re-render.
|
|
122
|
+
|
|
123
|
+
| Parameter | Type | Description |
|
|
124
|
+
|-----------|------|-------------|
|
|
125
|
+
| `pFlowData` | object | Complete flow data structure |
|
|
126
|
+
|
|
127
|
+
### getNode(pNodeHash)
|
|
128
|
+
|
|
129
|
+
Retrieve a node object by hash.
|
|
130
|
+
|
|
131
|
+
**Returns:** Node object or `undefined`.
|
|
132
|
+
|
|
133
|
+
### getConnection(pConnectionHash)
|
|
134
|
+
|
|
135
|
+
Retrieve a connection object by hash.
|
|
136
|
+
|
|
137
|
+
**Returns:** Connection object or `undefined`.
|
|
138
|
+
|
|
139
|
+
### marshalToView()
|
|
140
|
+
|
|
141
|
+
Load flow data from the AppData address specified in `FlowDataAddress` and render.
|
|
142
|
+
|
|
143
|
+
### marshalFromView()
|
|
144
|
+
|
|
145
|
+
Write the current flow data back to the AppData address specified in `FlowDataAddress`.
|
|
146
|
+
|
|
147
|
+
---
|
|
148
|
+
|
|
149
|
+
## Selection Methods
|
|
150
|
+
|
|
151
|
+
### selectNode(pNodeHash)
|
|
152
|
+
|
|
153
|
+
Select a node. Pass `null` to deselect.
|
|
154
|
+
|
|
155
|
+
### selectConnection(pConnectionHash)
|
|
156
|
+
|
|
157
|
+
Select a connection. Pass `null` to deselect.
|
|
158
|
+
|
|
159
|
+
### selectTether(pPanelHash)
|
|
160
|
+
|
|
161
|
+
Select a tether line. Pass `null` to deselect.
|
|
162
|
+
|
|
163
|
+
### deselectAll()
|
|
164
|
+
|
|
165
|
+
Clear all selections (node, connection, and tether).
|
|
166
|
+
|
|
167
|
+
### deleteSelected()
|
|
168
|
+
|
|
169
|
+
Delete the currently selected node or connection.
|
|
170
|
+
|
|
171
|
+
**Returns:** `boolean` — `true` if something was deleted.
|
|
172
|
+
|
|
173
|
+
---
|
|
174
|
+
|
|
175
|
+
## Viewport Methods
|
|
176
|
+
|
|
177
|
+
### setZoom(pZoom, pFocusX, pFocusY)
|
|
178
|
+
|
|
179
|
+
Set the zoom level with an optional focus point.
|
|
180
|
+
|
|
181
|
+
| Parameter | Type | Description |
|
|
182
|
+
|-----------|------|-------------|
|
|
183
|
+
| `pZoom` | number | Target zoom level (clamped to MinZoom..MaxZoom) |
|
|
184
|
+
| `pFocusX` | number | Optional X focus point in SVG space |
|
|
185
|
+
| `pFocusY` | number | Optional Y focus point in SVG space |
|
|
186
|
+
|
|
187
|
+
### zoomToFit()
|
|
188
|
+
|
|
189
|
+
Automatically adjust pan and zoom to fit all nodes in the viewport.
|
|
190
|
+
|
|
191
|
+
### updateViewportTransform()
|
|
192
|
+
|
|
193
|
+
Apply the current pan/zoom state to the SVG viewport group. Called automatically after pan/zoom changes.
|
|
194
|
+
|
|
195
|
+
### toggleFullscreen()
|
|
196
|
+
|
|
197
|
+
Toggle fullscreen overlay mode.
|
|
198
|
+
|
|
199
|
+
**Returns:** `boolean` — the new fullscreen state.
|
|
200
|
+
|
|
201
|
+
### exitFullscreen()
|
|
202
|
+
|
|
203
|
+
Exit fullscreen mode.
|
|
204
|
+
|
|
205
|
+
### screenToSVGCoords(pScreenX, pScreenY)
|
|
206
|
+
|
|
207
|
+
Convert screen pixel coordinates to SVG coordinate space.
|
|
208
|
+
|
|
209
|
+
**Returns:** `{ x, y }`
|
|
210
|
+
|
|
211
|
+
### autoLayout()
|
|
212
|
+
|
|
213
|
+
Run the topological auto-layout algorithm to arrange nodes automatically.
|
|
214
|
+
|
|
215
|
+
---
|
|
216
|
+
|
|
217
|
+
## Panel Methods
|
|
218
|
+
|
|
219
|
+
### openPanel(pNodeHash)
|
|
220
|
+
|
|
221
|
+
Open a properties panel for a node.
|
|
222
|
+
|
|
223
|
+
**Returns:** Panel data object, or `false` if the node has no panel configuration.
|
|
224
|
+
|
|
225
|
+
### closePanel(pPanelHash)
|
|
226
|
+
|
|
227
|
+
Close a panel by its hash.
|
|
228
|
+
|
|
229
|
+
**Returns:** `boolean`
|
|
230
|
+
|
|
231
|
+
### closePanelForNode(pNodeHash)
|
|
232
|
+
|
|
233
|
+
Close all panels associated with a node.
|
|
234
|
+
|
|
235
|
+
**Returns:** `boolean`
|
|
236
|
+
|
|
237
|
+
### togglePanel(pNodeHash)
|
|
238
|
+
|
|
239
|
+
Toggle a node's panel open or closed.
|
|
240
|
+
|
|
241
|
+
**Returns:** Panel data object or `false`.
|
|
242
|
+
|
|
243
|
+
### updatePanelPosition(pPanelHash, pX, pY)
|
|
244
|
+
|
|
245
|
+
Move a panel to new coordinates.
|
|
246
|
+
|
|
247
|
+
---
|
|
248
|
+
|
|
249
|
+
## Theming Methods
|
|
250
|
+
|
|
251
|
+
### setTheme(pThemeKey)
|
|
252
|
+
|
|
253
|
+
Switch to a registered theme and re-render.
|
|
254
|
+
|
|
255
|
+
| Parameter | Type | Description |
|
|
256
|
+
|-----------|------|-------------|
|
|
257
|
+
| `pThemeKey` | string | Theme key (e.g. `'default'`, `'sketch'`, `'blueprint'`) |
|
|
258
|
+
|
|
259
|
+
### setNoiseLevel(pLevel)
|
|
260
|
+
|
|
261
|
+
Set the hand-drawn noise level.
|
|
262
|
+
|
|
263
|
+
| Parameter | Type | Description |
|
|
264
|
+
|-----------|------|-------------|
|
|
265
|
+
| `pLevel` | number | 0 (precise) to 1 (wobbly) |
|
|
266
|
+
|
|
267
|
+
### getNoiseLevel()
|
|
268
|
+
|
|
269
|
+
**Returns:** Current noise level (number).
|
|
270
|
+
|
|
271
|
+
### getThemeKey()
|
|
272
|
+
|
|
273
|
+
**Returns:** Active theme key (string).
|
|
274
|
+
|
|
275
|
+
---
|
|
276
|
+
|
|
277
|
+
## Rendering Methods
|
|
278
|
+
|
|
279
|
+
### renderFlow()
|
|
280
|
+
|
|
281
|
+
Full re-render of all nodes, connections, panels, and tethers.
|
|
282
|
+
|
|
283
|
+
### updateNodePosition(pNodeHash, pX, pY)
|
|
284
|
+
|
|
285
|
+
Update a node's position during drag. Performs selective re-rendering of only the affected elements for smooth performance.
|
|
286
|
+
|
|
287
|
+
### getPortPosition(pNodeHash, pPortHash)
|
|
288
|
+
|
|
289
|
+
Get the absolute SVG coordinates of a port's center.
|
|
290
|
+
|
|
291
|
+
**Returns:** `{ x, y }`
|
|
292
|
+
|
|
293
|
+
---
|
|
294
|
+
|
|
295
|
+
## Connection Handle Methods
|
|
296
|
+
|
|
297
|
+
### updateConnectionHandle(pConnectionHash, pHandleType, pX, pY)
|
|
298
|
+
|
|
299
|
+
Update a bezier control point on a connection.
|
|
300
|
+
|
|
301
|
+
### addConnectionHandle(pConnectionHash, pX, pY)
|
|
302
|
+
|
|
303
|
+
Add a new control point to a connection.
|
|
304
|
+
|
|
305
|
+
### removeConnectionHandle(pConnectionHash, pIndex)
|
|
306
|
+
|
|
307
|
+
Remove a control point from a connection.
|
|
308
|
+
|
|
309
|
+
### updateTetherHandle(pPanelHash, pHandleType, pX, pY)
|
|
310
|
+
|
|
311
|
+
Update a bezier control point on a tether line.
|
|
312
|
+
|
|
313
|
+
---
|
|
314
|
+
|
|
315
|
+
## Internal Service Accessors
|
|
316
|
+
|
|
317
|
+
Developers access services and providers through underscore-prefixed properties on the flow view instance:
|
|
318
|
+
|
|
319
|
+
| Property | Service/Provider |
|
|
320
|
+
|----------|-----------------|
|
|
321
|
+
| `_DataManager` | Node and connection CRUD |
|
|
322
|
+
| `_RenderManager` | Rendering orchestration |
|
|
323
|
+
| `_SelectionManager` | Selection state |
|
|
324
|
+
| `_ViewportManager` | Pan, zoom, fullscreen |
|
|
325
|
+
| `_PanelManager` | Panel lifecycle |
|
|
326
|
+
| `_InteractionManager` | Event handling |
|
|
327
|
+
| `_LayoutService` | Grid snap, auto-layout |
|
|
328
|
+
| `_ConnectionRenderer` | Bezier/orthogonal drawing |
|
|
329
|
+
| `_NodeTypeProvider` | Node type registry |
|
|
330
|
+
| `_EventHandlerProvider` | Custom event hooks |
|
|
331
|
+
| `_LayoutProvider` | Layout persistence |
|
|
332
|
+
| `_ThemeProvider` | Theme system |
|
|
333
|
+
| `_CSSProvider` | CSS generation and injection |
|
|
334
|
+
| `_GeometryProvider` | Port positioning math |
|
|
335
|
+
| `_NoiseProvider` | Hand-drawn effects |
|
|
336
|
+
| `_SVGHelperProvider` | SVG DOM utilities |
|
|
337
|
+
| `_ConnectorShapesProvider` | Arrowhead marker definitions |
|
|
338
|
+
| `_IconProvider` | Icon templates |
|
|
339
|
+
| `_PanelChromeProvider` | Panel UI template |
|
|
340
|
+
|
|
341
|
+
---
|
|
342
|
+
|
|
343
|
+
## EventHandler Provider API
|
|
344
|
+
|
|
345
|
+
### registerHandler(pEventName, pHandler, pHandlerHash)
|
|
346
|
+
|
|
347
|
+
Register a callback for a named event.
|
|
348
|
+
|
|
349
|
+
| Parameter | Type | Description |
|
|
350
|
+
|-----------|------|-------------|
|
|
351
|
+
| `pEventName` | string | Event name (see list below) |
|
|
352
|
+
| `pHandler` | function | Callback function |
|
|
353
|
+
| `pHandlerHash` | string | Optional unique identifier for removal |
|
|
354
|
+
|
|
355
|
+
**Returns:** Handler hash (string).
|
|
356
|
+
|
|
357
|
+
### removeHandler(pEventName, pHandlerHash)
|
|
358
|
+
|
|
359
|
+
Remove a previously registered handler.
|
|
360
|
+
|
|
361
|
+
**Returns:** `boolean`
|
|
362
|
+
|
|
363
|
+
### fireEvent(pEventName, pData)
|
|
364
|
+
|
|
365
|
+
Fire all handlers for a named event.
|
|
366
|
+
|
|
367
|
+
### Supported Events
|
|
368
|
+
|
|
369
|
+
| Event | Payload | Fired When |
|
|
370
|
+
|-------|---------|------------|
|
|
371
|
+
| `onNodeSelected` | Node object | A node is selected |
|
|
372
|
+
| `onNodeAdded` | Node object | A node is created |
|
|
373
|
+
| `onNodeRemoved` | Node object | A node is deleted |
|
|
374
|
+
| `onNodeMoved` | Node object | A node's position changes |
|
|
375
|
+
| `onConnectionSelected` | Connection object | A connection is selected |
|
|
376
|
+
| `onConnectionCreated` | Connection object | A connection is created |
|
|
377
|
+
| `onConnectionRemoved` | Connection object | A connection is deleted |
|
|
378
|
+
| `onConnectionHandleMoved` | Connection object | A bezier handle is dragged |
|
|
379
|
+
| `onConnectionModeChanged` | Connection object | Line mode switches (bezier/orthogonal) |
|
|
380
|
+
| `onPanelOpened` | Panel data | A properties panel opens |
|
|
381
|
+
| `onPanelClosed` | Panel data | A properties panel closes |
|
|
382
|
+
| `onPanelMoved` | Panel data | A panel is dragged |
|
|
383
|
+
| `onTetherSelected` | Panel data | A tether line is selected |
|
|
384
|
+
| `onTetherHandleMoved` | Panel data | A tether handle is dragged |
|
|
385
|
+
| `onTetherModeChanged` | Panel data | Tether mode switches |
|
|
386
|
+
| `onLayoutSaved` | Layout data | A layout is saved |
|
|
387
|
+
| `onLayoutRestored` | Layout data | A layout is restored |
|
|
388
|
+
| `onLayoutDeleted` | Layout data | A layout is deleted |
|
|
389
|
+
| `onFlowChanged` | Flow data | Any structural change to the flow |
|
|
390
|
+
| `onThemeChanged` | Theme key | The active theme changes |
|
|
391
|
+
|
|
392
|
+
---
|
|
393
|
+
|
|
394
|
+
## NodeTypes Provider API
|
|
395
|
+
|
|
396
|
+
### registerNodeType(pNodeTypeConfig)
|
|
397
|
+
|
|
398
|
+
Register a new node type.
|
|
399
|
+
|
|
400
|
+
| Parameter | Type | Description |
|
|
401
|
+
|-----------|------|-------------|
|
|
402
|
+
| `pNodeTypeConfig` | object | Node type configuration (see PictFlowCard docs) |
|
|
403
|
+
|
|
404
|
+
**Returns:** `boolean`
|
|
405
|
+
|
|
406
|
+
### removeNodeType(pTypeHash)
|
|
407
|
+
|
|
408
|
+
Unregister a node type.
|
|
409
|
+
|
|
410
|
+
**Returns:** `boolean`
|
|
411
|
+
|
|
412
|
+
### getNodeType(pTypeHash)
|
|
413
|
+
|
|
414
|
+
Retrieve a node type configuration by hash.
|
|
415
|
+
|
|
416
|
+
**Returns:** Node type config object, or the default type if not found.
|
|
417
|
+
|
|
418
|
+
### getNodeTypes()
|
|
419
|
+
|
|
420
|
+
**Returns:** Map of all registered node types.
|
|
421
|
+
|
|
422
|
+
### getNodeTypeList()
|
|
423
|
+
|
|
424
|
+
**Returns:** Array of registered type hashes.
|
|
425
|
+
|
|
426
|
+
### getEnabledCards()
|
|
427
|
+
|
|
428
|
+
**Returns:** Array of card configurations where `Enabled` is `true`.
|
|
429
|
+
|
|
430
|
+
### getCardsByCategory()
|
|
431
|
+
|
|
432
|
+
**Returns:** Object mapping category names to arrays of card configurations.
|
|
433
|
+
|
|
434
|
+
---
|
|
435
|
+
|
|
436
|
+
## Theme Provider API
|
|
437
|
+
|
|
438
|
+
### registerTheme(pThemeKey, pThemeConfig)
|
|
439
|
+
|
|
440
|
+
Register a named theme.
|
|
441
|
+
|
|
442
|
+
| Parameter | Type | Description |
|
|
443
|
+
|-----------|------|-------------|
|
|
444
|
+
| `pThemeKey` | string | Unique theme identifier |
|
|
445
|
+
| `pThemeConfig` | object | Theme configuration (see below) |
|
|
446
|
+
|
|
447
|
+
**Theme config shape:**
|
|
448
|
+
|
|
449
|
+
```javascript
|
|
450
|
+
{
|
|
451
|
+
Key: 'dark',
|
|
452
|
+
Label: 'Dark Mode',
|
|
453
|
+
CSSVariables:
|
|
454
|
+
{
|
|
455
|
+
'--pf-canvas-bg': '#1a1a2e',
|
|
456
|
+
'--pf-node-body-fill': '#16213e'
|
|
457
|
+
},
|
|
458
|
+
AdditionalCSS: '/* Extra rules */',
|
|
459
|
+
NodeBodyMode: 'rect',
|
|
460
|
+
NoiseConfig: { Enabled: true, Amount: 0.5 },
|
|
461
|
+
ConnectionConfig: { StrokeDashArray: '5,5' }
|
|
462
|
+
}
|
|
463
|
+
```
|
|
464
|
+
|
|
465
|
+
### setTheme(pThemeKey)
|
|
466
|
+
|
|
467
|
+
Activate a registered theme and re-render.
|
|
468
|
+
|
|
469
|
+
**Returns:** `boolean` — `true` if the theme was found and activated.
|
|
470
|
+
|
|
471
|
+
### getActiveTheme()
|
|
472
|
+
|
|
473
|
+
**Returns:** Active theme configuration object.
|
|
474
|
+
|
|
475
|
+
### getActiveThemeKey()
|
|
476
|
+
|
|
477
|
+
**Returns:** Active theme key string.
|
|
478
|
+
|
|
479
|
+
### Built-in Themes
|
|
480
|
+
|
|
481
|
+
| Key | Label | Style |
|
|
482
|
+
|-----|-------|-------|
|
|
483
|
+
| `default` | Modern | Clean, professional |
|
|
484
|
+
| `sketch` | Sketch | Hand-drawn, informal |
|
|
485
|
+
| `blueprint` | Blueprint | Technical blueprint |
|
|
486
|
+
| `mono` | Monochrome | Black and white |
|
|
487
|
+
| `retro-80s` | Retro 80s | Neon retro |
|
|
488
|
+
| `retro-90s` | Retro 90s | Vaporwave |
|
|
489
|
+
|
|
490
|
+
---
|
|
491
|
+
|
|
492
|
+
## Layouts Provider API
|
|
493
|
+
|
|
494
|
+
### saveLayout(pName)
|
|
495
|
+
|
|
496
|
+
Save the current spatial arrangement.
|
|
497
|
+
|
|
498
|
+
**Returns:** Layout data object.
|
|
499
|
+
|
|
500
|
+
### restoreLayout(pLayoutHash)
|
|
501
|
+
|
|
502
|
+
Restore a previously saved layout.
|
|
503
|
+
|
|
504
|
+
**Returns:** `boolean`
|
|
505
|
+
|
|
506
|
+
### deleteLayout(pLayoutHash)
|
|
507
|
+
|
|
508
|
+
Delete a saved layout.
|
|
509
|
+
|
|
510
|
+
**Returns:** `boolean`
|
|
511
|
+
|
|
512
|
+
### loadPersistedLayouts()
|
|
513
|
+
|
|
514
|
+
Load layouts from the storage backend (localStorage by default).
|
|
515
|
+
|
|
516
|
+
### getLayouts()
|
|
517
|
+
|
|
518
|
+
**Returns:** Array of saved layout objects.
|
|
519
|
+
|
|
520
|
+
### Storage Hooks
|
|
521
|
+
|
|
522
|
+
Override these methods to use a custom storage backend:
|
|
523
|
+
|
|
524
|
+
| Method | Signature | Description |
|
|
525
|
+
|--------|-----------|-------------|
|
|
526
|
+
| `storageWrite` | `(pLayouts, fCallback)` | Persist layouts |
|
|
527
|
+
| `storageRead` | `(fCallback)` | Load layouts |
|
|
528
|
+
| `storageDelete` | `(fCallback)` | Clear all layouts |
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
# Layout Persistence
|
|
2
|
+
|
|
3
|
+
Pict-Section-Flow can save and restore spatial arrangements of nodes and panels independently of the flow data itself. This lets users maintain multiple views of the same flow graph.
|
|
4
|
+
|
|
5
|
+
## How It Works
|
|
6
|
+
|
|
7
|
+
A **layout** captures the position, size, and viewport state of a flow diagram at a point in time. It does not store the flow's logical content (nodes, connections, data) — only where things are on screen.
|
|
8
|
+
|
|
9
|
+
Each saved layout contains:
|
|
10
|
+
|
|
11
|
+
| Property | Description |
|
|
12
|
+
|----------|-------------|
|
|
13
|
+
| `Hash` | Unique identifier for the layout |
|
|
14
|
+
| `Name` | Display name chosen by the user |
|
|
15
|
+
| `CreatedAt` | ISO 8601 timestamp |
|
|
16
|
+
| `NodePositions` | Map of node hash to `{ X, Y, Width, Height }` |
|
|
17
|
+
| `PanelPositions` | Map of node hash to `{ X, Y, Width, Height }` |
|
|
18
|
+
| `ViewState` | `{ PanX, PanY, Zoom }` |
|
|
19
|
+
|
|
20
|
+
## Default Behavior: localStorage
|
|
21
|
+
|
|
22
|
+
Saved layouts persist to `localStorage` by default, keyed by the flow view identifier (e.g. `pict-flow-layouts-MyFlowDiagram`). Layouts survive page refreshes without any configuration.
|
|
23
|
+
|
|
24
|
+
```javascript
|
|
25
|
+
// Save the current layout
|
|
26
|
+
flowView._LayoutProvider.saveLayout('My Layout');
|
|
27
|
+
|
|
28
|
+
// List all saved layouts
|
|
29
|
+
let tmpLayouts = flowView._LayoutProvider.getLayouts();
|
|
30
|
+
|
|
31
|
+
// Restore a layout
|
|
32
|
+
flowView._LayoutProvider.restoreLayout(tmpLayouts[0].Hash);
|
|
33
|
+
|
|
34
|
+
// Delete a layout
|
|
35
|
+
flowView._LayoutProvider.deleteLayout(tmpLayouts[0].Hash);
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Overriding Storage (e.g. REST API)
|
|
39
|
+
|
|
40
|
+
The `LayoutProvider` exposes three hookable storage methods that follow the `fCallback(pError, pResult)` convention. Replace them on the instance to use any backend:
|
|
41
|
+
|
|
42
|
+
```javascript
|
|
43
|
+
// After your flow view is initialized:
|
|
44
|
+
let layoutProvider = flowView._LayoutProvider;
|
|
45
|
+
|
|
46
|
+
// Persist layouts to a server
|
|
47
|
+
layoutProvider.storageWrite = function(pLayouts, fCallback)
|
|
48
|
+
{
|
|
49
|
+
fetch('/api/my-flow/layouts',
|
|
50
|
+
{
|
|
51
|
+
method: 'PUT',
|
|
52
|
+
headers: { 'Content-Type': 'application/json' },
|
|
53
|
+
body: JSON.stringify(pLayouts)
|
|
54
|
+
})
|
|
55
|
+
.then(() => fCallback(null))
|
|
56
|
+
.catch((pError) => fCallback(pError));
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
// Load layouts from a server
|
|
60
|
+
layoutProvider.storageRead = function(fCallback)
|
|
61
|
+
{
|
|
62
|
+
fetch('/api/my-flow/layouts')
|
|
63
|
+
.then((pResponse) => pResponse.json())
|
|
64
|
+
.then((pLayouts) => fCallback(null, pLayouts))
|
|
65
|
+
.catch((pError) => fCallback(pError, []));
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
// Delete all layouts on the server
|
|
69
|
+
layoutProvider.storageDelete = function(fCallback)
|
|
70
|
+
{
|
|
71
|
+
fetch('/api/my-flow/layouts', { method: 'DELETE' })
|
|
72
|
+
.then(() => fCallback(null))
|
|
73
|
+
.catch((pError) => fCallback(pError));
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
// Load from the new backend now that hooks are set
|
|
77
|
+
layoutProvider.loadPersistedLayouts();
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## Configuration Options
|
|
81
|
+
|
|
82
|
+
- **`StorageKey`** (string) — Override the localStorage key. Passed via options when instantiating the provider.
|
|
83
|
+
- **`StorageKey: false`** — Disable localStorage persistence entirely (useful when using only a remote backend).
|
|
84
|
+
|
|
85
|
+
## Events
|
|
86
|
+
|
|
87
|
+
The layout system fires events you can hook into:
|
|
88
|
+
|
|
89
|
+
```javascript
|
|
90
|
+
flowView._EventHandlerProvider.registerHandler('onLayoutSaved',
|
|
91
|
+
(pLayoutData) =>
|
|
92
|
+
{
|
|
93
|
+
console.log('Layout saved:', pLayoutData.Name);
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
flowView._EventHandlerProvider.registerHandler('onLayoutRestored',
|
|
97
|
+
(pLayoutData) =>
|
|
98
|
+
{
|
|
99
|
+
console.log('Layout restored:', pLayoutData.Name);
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
flowView._EventHandlerProvider.registerHandler('onLayoutDeleted',
|
|
103
|
+
(pLayoutData) =>
|
|
104
|
+
{
|
|
105
|
+
console.log('Layout deleted:', pLayoutData.Name);
|
|
106
|
+
});
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
## Restore Behavior
|
|
110
|
+
|
|
111
|
+
When a layout is restored, the provider:
|
|
112
|
+
|
|
113
|
+
1. Positions each node whose hash appears in `NodePositions`
|
|
114
|
+
2. Positions each panel whose node hash appears in `PanelPositions`
|
|
115
|
+
3. Applies the saved `ViewState` (pan and zoom)
|
|
116
|
+
4. Any nodes that exist in the flow but not in the layout remain in their current position
|
|
117
|
+
5. Triggers a full re-render
|