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.
Files changed (88) hide show
  1. package/.claude/launch.json +1 -1
  2. package/README.md +176 -0
  3. package/docs/.nojekyll +0 -0
  4. package/docs/Architecture.md +303 -0
  5. package/docs/Custom-Styling.md +275 -0
  6. package/docs/Data_Model.md +158 -0
  7. package/docs/Event_System.md +156 -0
  8. package/docs/Getting_Started.md +237 -0
  9. package/docs/Implementation_Reference.md +528 -0
  10. package/docs/Layout_Persistence.md +117 -0
  11. package/docs/README.md +115 -52
  12. package/docs/_cover.md +11 -0
  13. package/docs/_sidebar.md +52 -0
  14. package/docs/_topbar.md +8 -0
  15. package/docs/api/PictFlowCard.md +216 -0
  16. package/docs/api/PictFlowCardPropertiesPanel.md +235 -0
  17. package/docs/api/addConnection.md +101 -0
  18. package/docs/api/addNode.md +137 -0
  19. package/docs/api/autoLayout.md +77 -0
  20. package/docs/api/getFlowData.md +112 -0
  21. package/docs/api/marshalToView.md +95 -0
  22. package/docs/api/openPanel.md +128 -0
  23. package/docs/api/registerHandler.md +174 -0
  24. package/docs/api/registerNodeType.md +142 -0
  25. package/docs/api/removeConnection.md +57 -0
  26. package/docs/api/removeNode.md +80 -0
  27. package/docs/api/saveLayout.md +152 -0
  28. package/docs/api/screenToSVGCoords.md +68 -0
  29. package/docs/api/selectNode.md +116 -0
  30. package/docs/api/setTheme.md +168 -0
  31. package/docs/api/setZoom.md +97 -0
  32. package/docs/api/toggleFullscreen.md +68 -0
  33. package/docs/card-help/EACH.md +19 -0
  34. package/docs/card-help/FREAD.md +24 -0
  35. package/docs/card-help/FWRITE.md +24 -0
  36. package/docs/card-help/GET.md +22 -0
  37. package/docs/card-help/ITE.md +23 -0
  38. package/docs/card-help/LOG.md +23 -0
  39. package/docs/card-help/NOTE.md +17 -0
  40. package/docs/card-help/PREV.md +18 -0
  41. package/docs/card-help/SET.md +27 -0
  42. package/docs/card-help/SPKL.md +22 -0
  43. package/docs/card-help/STAT.md +23 -0
  44. package/docs/card-help/SW.md +25 -0
  45. package/docs/css/docuserve.css +73 -0
  46. package/docs/index.html +39 -0
  47. package/docs/retold-catalog.json +169 -0
  48. package/docs/retold-keyword-index.json +13942 -0
  49. package/example_applications/simple_cards/package.json +1 -0
  50. package/example_applications/simple_cards/source/card-help-content.js +16 -0
  51. package/example_applications/simple_cards/source/cards/FlowCard-Comment.js +2 -0
  52. package/example_applications/simple_cards/source/cards/FlowCard-DataPreview.js +2 -0
  53. package/example_applications/simple_cards/source/cards/FlowCard-Each.js +2 -0
  54. package/example_applications/simple_cards/source/cards/FlowCard-FileRead.js +2 -0
  55. package/example_applications/simple_cards/source/cards/FlowCard-FileWrite.js +2 -0
  56. package/example_applications/simple_cards/source/cards/FlowCard-GetValue.js +2 -0
  57. package/example_applications/simple_cards/source/cards/FlowCard-IfThenElse.js +2 -0
  58. package/example_applications/simple_cards/source/cards/FlowCard-LogValues.js +2 -0
  59. package/example_applications/simple_cards/source/cards/FlowCard-SetValue.js +2 -0
  60. package/example_applications/simple_cards/source/cards/FlowCard-Sparkline.js +2 -0
  61. package/example_applications/simple_cards/source/cards/FlowCard-StatusMonitor.js +2 -0
  62. package/example_applications/simple_cards/source/cards/FlowCard-Switch.js +2 -0
  63. package/package.json +11 -7
  64. package/scripts/generate-card-help.js +214 -0
  65. package/source/Pict-Section-Flow.js +4 -0
  66. package/source/PictFlowCard.js +3 -1
  67. package/source/providers/PictProvider-Flow-CSS.js +245 -152
  68. package/source/providers/PictProvider-Flow-ConnectorShapes.js +24 -0
  69. package/source/providers/PictProvider-Flow-Geometry.js +195 -38
  70. package/source/providers/PictProvider-Flow-PanelChrome.js +14 -12
  71. package/source/services/PictService-Flow-ConnectionHandleManager.js +263 -0
  72. package/source/services/PictService-Flow-ConnectionRenderer.js +134 -183
  73. package/source/services/PictService-Flow-DataManager.js +338 -0
  74. package/source/services/PictService-Flow-InteractionManager.js +165 -7
  75. package/source/services/PictService-Flow-PathGenerator.js +282 -0
  76. package/source/services/PictService-Flow-PortRenderer.js +269 -0
  77. package/source/services/PictService-Flow-RenderManager.js +281 -0
  78. package/source/services/PictService-Flow-Tether.js +6 -42
  79. package/source/views/PictView-Flow-Node.js +2 -220
  80. package/source/views/PictView-Flow-PropertiesPanel.js +89 -44
  81. package/source/views/PictView-Flow.js +130 -882
  82. package/test/ConnectionHandleManager_tests.js +717 -0
  83. package/test/ConnectionRenderer_tests.js +591 -0
  84. package/test/DataManager_tests.js +859 -0
  85. package/test/Geometry_tests.js +767 -0
  86. package/test/PathGenerator_tests.js +978 -0
  87. package/test/PortRenderer_tests.js +367 -0
  88. package/test/RenderManager_tests.js +756 -0
@@ -0,0 +1,95 @@
1
+ # marshalToView / marshalFromView
2
+
3
+ Two-way data binding between the flow view and Pict's `AppData` store. Requires the `FlowDataAddress` configuration option to be set.
4
+
5
+ ## Signatures
6
+
7
+ ```javascript
8
+ flowView.marshalToView();
9
+ flowView.marshalFromView();
10
+ ```
11
+
12
+ ## marshalToView
13
+
14
+ Load flow data from the AppData address specified in `FlowDataAddress` into the view and render it.
15
+
16
+ This is the "pull" direction: AppData → Flow View.
17
+
18
+ ## marshalFromView
19
+
20
+ Write the current flow data back to the AppData address specified in `FlowDataAddress`.
21
+
22
+ This is the "push" direction: Flow View → AppData.
23
+
24
+ ## Configuration
25
+
26
+ Set `FlowDataAddress` when registering the view:
27
+
28
+ ```javascript
29
+ _Pict.addView('MyFlow',
30
+ {
31
+ FlowDataAddress: 'AppData.Workflows.MainFlow'
32
+ },
33
+ libPictSectionFlow);
34
+ ```
35
+
36
+ ## Examples
37
+
38
+ ### Load from AppData on initialization
39
+
40
+ ```javascript
41
+ // Set up initial data in AppData
42
+ _Pict.AppData.Workflows =
43
+ {
44
+ MainFlow:
45
+ {
46
+ Nodes:
47
+ [
48
+ {
49
+ Hash: 'node-1',
50
+ Type: 'start',
51
+ X: 50, Y: 100,
52
+ Width: 140, Height: 80,
53
+ Title: 'Entry',
54
+ Ports:
55
+ [
56
+ { Hash: 'port-1', Direction: 'output', Side: 'right', Label: 'Out' }
57
+ ],
58
+ Data: {}
59
+ }
60
+ ],
61
+ Connections: [],
62
+ OpenPanels: [],
63
+ SavedLayouts: [],
64
+ ViewState: { PanX: 0, PanY: 0, Zoom: 1 }
65
+ }
66
+ };
67
+
68
+ // The flow view pulls this data on render
69
+ let tmpFlowView = _Pict.views.MyFlow;
70
+ tmpFlowView.marshalToView();
71
+ ```
72
+
73
+ ### Push changes back to AppData
74
+
75
+ ```javascript
76
+ // After the user edits the flow, persist to AppData
77
+ tmpFlowView.marshalFromView();
78
+
79
+ // Now AppData.Workflows.MainFlow reflects the current flow state
80
+ console.log(_Pict.AppData.Workflows.MainFlow.Nodes.length);
81
+ ```
82
+
83
+ ### Auto-sync on flow changes
84
+
85
+ ```javascript
86
+ tmpFlowView._EventHandlerProvider.registerHandler('onFlowChanged',
87
+ () =>
88
+ {
89
+ tmpFlowView.marshalFromView();
90
+ });
91
+ ```
92
+
93
+ ## See Also
94
+
95
+ - [getFlowData / setFlowData](getFlowData.md) — Direct get/set without AppData
@@ -0,0 +1,128 @@
1
+ # openPanel / closePanel / closePanelForNode / togglePanel / updatePanelPosition
2
+
3
+ Manage the lifecycle and positioning of properties panels. Panels are floating UI elements tethered to nodes by a line. They display when a node is double-clicked or opened programmatically.
4
+
5
+ ## Signatures
6
+
7
+ ```javascript
8
+ flowView.openPanel(pNodeHash);
9
+ flowView.closePanel(pPanelHash);
10
+ flowView.closePanelForNode(pNodeHash);
11
+ flowView.togglePanel(pNodeHash);
12
+ flowView.updatePanelPosition(pPanelHash, pX, pY);
13
+ ```
14
+
15
+ ## openPanel
16
+
17
+ Open a properties panel for a node. The panel type and configuration come from the node type's `PropertiesPanel` definition.
18
+
19
+ | Parameter | Type | Description |
20
+ |-----------|------|-------------|
21
+ | `pNodeHash` | string | Hash of the node to open a panel for |
22
+
23
+ **Returns:** Panel data object, or `false` if the node type has no panel configuration.
24
+
25
+ **Events Fired:** `onPanelOpened`
26
+
27
+ ## closePanel
28
+
29
+ Close a panel by its hash.
30
+
31
+ | Parameter | Type | Description |
32
+ |-----------|------|-------------|
33
+ | `pPanelHash` | string | Hash of the panel to close |
34
+
35
+ **Returns:** `boolean`
36
+
37
+ **Events Fired:** `onPanelClosed`
38
+
39
+ ## closePanelForNode
40
+
41
+ Close all panels associated with a node.
42
+
43
+ | Parameter | Type | Description |
44
+ |-----------|------|-------------|
45
+ | `pNodeHash` | string | Hash of the node whose panels to close |
46
+
47
+ **Returns:** `boolean`
48
+
49
+ ## togglePanel
50
+
51
+ Toggle a node's panel. Opens it if closed, closes it if open.
52
+
53
+ | Parameter | Type | Description |
54
+ |-----------|------|-------------|
55
+ | `pNodeHash` | string | Hash of the node |
56
+
57
+ **Returns:** Panel data object if opened, `false` if closed.
58
+
59
+ ## updatePanelPosition
60
+
61
+ Move a panel to new coordinates.
62
+
63
+ | Parameter | Type | Description |
64
+ |-----------|------|-------------|
65
+ | `pPanelHash` | string | Hash of the panel |
66
+ | `pX` | number | New X coordinate |
67
+ | `pY` | number | New Y coordinate |
68
+
69
+ **Events Fired:** `onPanelMoved`
70
+
71
+ ## Examples
72
+
73
+ ### Open a panel programmatically
74
+
75
+ ```javascript
76
+ let tmpNode = flowView.addNode('FREAD', 200, 150, 'Read Config');
77
+ let tmpPanel = flowView.openPanel(tmpNode.Hash);
78
+
79
+ if (tmpPanel)
80
+ {
81
+ console.log('Panel opened:', tmpPanel.Hash);
82
+ console.log('Panel type:', tmpPanel.PanelType);
83
+ }
84
+ ```
85
+
86
+ ### Toggle on button click
87
+
88
+ ```javascript
89
+ document.getElementById('toggle-props').addEventListener('click', () =>
90
+ {
91
+ let tmpFlowData = flowView.getFlowData();
92
+ if (tmpFlowData.ViewState.SelectedNodeHash)
93
+ {
94
+ flowView.togglePanel(tmpFlowData.ViewState.SelectedNodeHash);
95
+ }
96
+ });
97
+ ```
98
+
99
+ ### Close all open panels
100
+
101
+ ```javascript
102
+ let tmpFlowData = flowView.getFlowData();
103
+ tmpFlowData.OpenPanels.forEach((pPanel) =>
104
+ {
105
+ flowView.closePanel(pPanel.Hash);
106
+ });
107
+ ```
108
+
109
+ ### Listen for panel events
110
+
111
+ ```javascript
112
+ flowView._EventHandlerProvider.registerHandler('onPanelOpened',
113
+ (pPanelData) =>
114
+ {
115
+ console.log('Panel opened for node:', pPanelData.NodeHash);
116
+ });
117
+
118
+ flowView._EventHandlerProvider.registerHandler('onPanelClosed',
119
+ (pPanelData) =>
120
+ {
121
+ console.log('Panel closed:', pPanelData.Hash);
122
+ });
123
+ ```
124
+
125
+ ## See Also
126
+
127
+ - [PictFlowCard](PictFlowCard.md) — Define PropertiesPanel configuration on card types
128
+ - [PictFlowCardPropertiesPanel](PictFlowCardPropertiesPanel.md) — Custom panel base class
@@ -0,0 +1,174 @@
1
+ # registerHandler / removeHandler / fireEvent
2
+
3
+ The event system for hooking into flow diagram lifecycle events. Register callbacks to react to user actions, data changes, and state transitions without modifying core code.
4
+
5
+ ## Signatures
6
+
7
+ ```javascript
8
+ let tmpHash = flowView._EventHandlerProvider.registerHandler(pEventName, pHandler, pHandlerHash);
9
+ flowView._EventHandlerProvider.removeHandler(pEventName, pHandlerHash);
10
+ flowView._EventHandlerProvider.fireEvent(pEventName, pData);
11
+ ```
12
+
13
+ ## registerHandler
14
+
15
+ Register a callback for a named event.
16
+
17
+ | Parameter | Type | Required | Description |
18
+ |-----------|------|----------|-------------|
19
+ | `pEventName` | string | Yes | Event name from the supported events list |
20
+ | `pHandler` | function | Yes | Callback function receiving event data |
21
+ | `pHandlerHash` | string | No | Optional unique ID for later removal |
22
+
23
+ **Returns:** Handler hash (string). Auto-generated if not provided.
24
+
25
+ ## removeHandler
26
+
27
+ Unregister a previously registered handler.
28
+
29
+ | Parameter | Type | Required | Description |
30
+ |-----------|------|----------|-------------|
31
+ | `pEventName` | string | Yes | Event name |
32
+ | `pHandlerHash` | string | Yes | Hash returned from `registerHandler` |
33
+
34
+ **Returns:** `boolean`
35
+
36
+ ## fireEvent
37
+
38
+ Manually fire all handlers for a named event. Typically used internally by services, but available for custom events.
39
+
40
+ | Parameter | Type | Required | Description |
41
+ |-----------|------|----------|-------------|
42
+ | `pEventName` | string | Yes | Event name |
43
+ | `pData` | any | No | Data passed to each handler |
44
+
45
+ ## Supported Events
46
+
47
+ | Event | Payload | Description |
48
+ |-------|---------|-------------|
49
+ | `onNodeSelected` | Node object or null | A node is selected or deselected |
50
+ | `onNodeAdded` | Node object | A node is created |
51
+ | `onNodeRemoved` | Node object | A node is deleted |
52
+ | `onNodeMoved` | Node object | A node's position changes |
53
+ | `onConnectionSelected` | Connection object or null | A connection is selected |
54
+ | `onConnectionCreated` | Connection object | A connection is created |
55
+ | `onConnectionRemoved` | Connection object | A connection is deleted |
56
+ | `onConnectionHandleMoved` | Connection object | A bezier handle is dragged |
57
+ | `onConnectionModeChanged` | Connection object | Line mode switches |
58
+ | `onPanelOpened` | Panel data | A properties panel opens |
59
+ | `onPanelClosed` | Panel data | A properties panel closes |
60
+ | `onPanelMoved` | Panel data | A panel is repositioned |
61
+ | `onTetherSelected` | Panel data | A tether line is selected |
62
+ | `onTetherHandleMoved` | Panel data | A tether handle is dragged |
63
+ | `onTetherModeChanged` | Panel data | Tether mode switches |
64
+ | `onLayoutSaved` | Layout data | A layout is saved |
65
+ | `onLayoutRestored` | Layout data | A layout is restored |
66
+ | `onLayoutDeleted` | Layout data | A layout is deleted |
67
+ | `onFlowChanged` | Flow data | Any structural change |
68
+ | `onThemeChanged` | Theme key (string) | The active theme changes |
69
+
70
+ ## Examples
71
+
72
+ ### Track all changes for undo/redo
73
+
74
+ ```javascript
75
+ let tmpHistory = [];
76
+ let tmpHistoryIndex = -1;
77
+
78
+ flowView._EventHandlerProvider.registerHandler('onFlowChanged',
79
+ (pFlowData) =>
80
+ {
81
+ // Trim future states if we've undone
82
+ tmpHistory = tmpHistory.slice(0, tmpHistoryIndex + 1);
83
+ tmpHistory.push(JSON.parse(JSON.stringify(pFlowData)));
84
+ tmpHistoryIndex = tmpHistory.length - 1;
85
+ },
86
+ 'undo-redo-tracker');
87
+
88
+ function undo()
89
+ {
90
+ if (tmpHistoryIndex > 0)
91
+ {
92
+ tmpHistoryIndex--;
93
+ flowView.setFlowData(tmpHistory[tmpHistoryIndex]);
94
+ }
95
+ }
96
+
97
+ function redo()
98
+ {
99
+ if (tmpHistoryIndex < tmpHistory.length - 1)
100
+ {
101
+ tmpHistoryIndex++;
102
+ flowView.setFlowData(tmpHistory[tmpHistoryIndex]);
103
+ }
104
+ }
105
+ ```
106
+
107
+ ### Sync to server on every change
108
+
109
+ ```javascript
110
+ flowView._EventHandlerProvider.registerHandler('onFlowChanged',
111
+ (pFlowData) =>
112
+ {
113
+ fetch('/api/flows/my-flow',
114
+ {
115
+ method: 'PUT',
116
+ headers: { 'Content-Type': 'application/json' },
117
+ body: JSON.stringify(pFlowData)
118
+ });
119
+ },
120
+ 'server-sync');
121
+ ```
122
+
123
+ ### Update a sidebar when selection changes
124
+
125
+ ```javascript
126
+ flowView._EventHandlerProvider.registerHandler('onNodeSelected',
127
+ (pNode) =>
128
+ {
129
+ let tmpSidebar = document.getElementById('sidebar');
130
+
131
+ if (!pNode)
132
+ {
133
+ tmpSidebar.innerHTML = '<p>Select a node to view details</p>';
134
+ return;
135
+ }
136
+
137
+ tmpSidebar.innerHTML =
138
+ '<h3>' + pNode.Title + '</h3>' +
139
+ '<p>Type: ' + pNode.Type + '</p>' +
140
+ '<p>Ports: ' + pNode.Ports.length + '</p>';
141
+ });
142
+ ```
143
+
144
+ ### Remove a handler
145
+
146
+ ```javascript
147
+ let tmpHandlerHash = flowView._EventHandlerProvider.registerHandler('onNodeAdded',
148
+ (pNode) =>
149
+ {
150
+ console.log('Node added:', pNode.Title);
151
+ });
152
+
153
+ // Later, unregister it
154
+ flowView._EventHandlerProvider.removeHandler('onNodeAdded', tmpHandlerHash);
155
+ ```
156
+
157
+ ### Multiple handlers for the same event
158
+
159
+ ```javascript
160
+ // Both handlers fire when a node is added
161
+ flowView._EventHandlerProvider.registerHandler('onNodeAdded',
162
+ (pNode) => { console.log('Handler 1:', pNode.Title); },
163
+ 'logger');
164
+
165
+ flowView._EventHandlerProvider.registerHandler('onNodeAdded',
166
+ (pNode) => { updateNodeCount(); },
167
+ 'counter');
168
+ ```
169
+
170
+ ## See Also
171
+
172
+ - [addNode](addNode.md) — Triggers `onNodeAdded` and `onFlowChanged`
173
+ - [selectNode](selectNode.md) — Triggers `onNodeSelected`
174
+ - [setTheme](setTheme.md) — Triggers `onThemeChanged`
@@ -0,0 +1,142 @@
1
+ # registerNodeType / removeNodeType / getNodeType
2
+
3
+ Register, remove, and query node types in the flow diagram's type registry. Most developers will use `PictFlowCard.registerWithFlowView()` instead, but these methods provide direct access for dynamic or programmatic type management.
4
+
5
+ ## Signatures
6
+
7
+ ```javascript
8
+ flowView._NodeTypeProvider.registerNodeType(pNodeTypeConfig);
9
+ flowView._NodeTypeProvider.removeNodeType(pTypeHash);
10
+ flowView._NodeTypeProvider.getNodeType(pTypeHash);
11
+ flowView._NodeTypeProvider.getNodeTypes();
12
+ flowView._NodeTypeProvider.getNodeTypeList();
13
+ flowView._NodeTypeProvider.getEnabledCards();
14
+ flowView._NodeTypeProvider.getCardsByCategory();
15
+ ```
16
+
17
+ ## registerNodeType
18
+
19
+ Register a node type configuration directly.
20
+
21
+ | Parameter | Type | Description |
22
+ |-----------|------|-------------|
23
+ | `pNodeTypeConfig` | object | Node type configuration |
24
+
25
+ **Returns:** `boolean`
26
+
27
+ ### Configuration Shape
28
+
29
+ ```javascript
30
+ {
31
+ Hash: 'FREAD',
32
+ Label: 'File Read',
33
+ DefaultWidth: 160,
34
+ DefaultHeight: 70,
35
+ TitleBarColor: '#2980b9',
36
+ DefaultPorts:
37
+ [
38
+ { Hash: null, Direction: 'input', Side: 'left', Label: 'Path', PortType: 'value' },
39
+ { Hash: null, Direction: 'output', Side: 'right', Label: 'Data', PortType: 'value' },
40
+ { Hash: null, Direction: 'output', Side: 'bottom', Label: 'Error', PortType: 'error' }
41
+ ],
42
+ CardMetadata:
43
+ {
44
+ Name: 'File Read',
45
+ Code: 'FREAD',
46
+ Description: 'Read contents from a file path',
47
+ Category: 'File I/O',
48
+ Enabled: true
49
+ }
50
+ }
51
+ ```
52
+
53
+ ## removeNodeType
54
+
55
+ Unregister a node type by hash.
56
+
57
+ **Returns:** `boolean`
58
+
59
+ ## getNodeType
60
+
61
+ Retrieve a node type configuration by hash. Returns the default type if the hash is not found.
62
+
63
+ **Returns:** Node type configuration object.
64
+
65
+ ## getNodeTypes
66
+
67
+ **Returns:** Map of all registered node types (hash → config).
68
+
69
+ ## getNodeTypeList
70
+
71
+ **Returns:** Array of registered type hash strings.
72
+
73
+ ## getEnabledCards
74
+
75
+ **Returns:** Array of card configurations where `CardMetadata.Enabled` is `true`.
76
+
77
+ ## getCardsByCategory
78
+
79
+ **Returns:** Object mapping category names to arrays of card configurations. Useful for building palette UIs.
80
+
81
+ ## Examples
82
+
83
+ ### Register a type directly
84
+
85
+ ```javascript
86
+ flowView._NodeTypeProvider.registerNodeType(
87
+ {
88
+ Hash: 'FILTER',
89
+ Label: 'Filter',
90
+ DefaultWidth: 140,
91
+ DefaultHeight: 60,
92
+ TitleBarColor: '#9b59b6',
93
+ DefaultPorts:
94
+ [
95
+ { Hash: null, Direction: 'input', Side: 'left', Label: 'In' },
96
+ { Hash: null, Direction: 'output', Side: 'right', Label: 'Pass' },
97
+ { Hash: null, Direction: 'output', Side: 'bottom', Label: 'Reject' }
98
+ ],
99
+ CardMetadata:
100
+ {
101
+ Code: 'FILTER',
102
+ Category: 'Data',
103
+ Enabled: true
104
+ }
105
+ });
106
+ ```
107
+
108
+ ### List all categories
109
+
110
+ ```javascript
111
+ let tmpCategories = flowView._NodeTypeProvider.getCardsByCategory();
112
+
113
+ Object.keys(tmpCategories).forEach((pCategory) =>
114
+ {
115
+ console.log(pCategory + ':');
116
+ tmpCategories[pCategory].forEach((pCard) =>
117
+ {
118
+ console.log(' -', pCard.Label, '(' + pCard.Hash + ')');
119
+ });
120
+ });
121
+ ```
122
+
123
+ ### Check if a type exists
124
+
125
+ ```javascript
126
+ let tmpType = flowView._NodeTypeProvider.getNodeType('FREAD');
127
+ if (tmpType.Hash === 'FREAD')
128
+ {
129
+ console.log('File Read type is registered');
130
+ }
131
+ ```
132
+
133
+ ### Remove a type at runtime
134
+
135
+ ```javascript
136
+ flowView._NodeTypeProvider.removeNodeType('FREAD');
137
+ ```
138
+
139
+ ## See Also
140
+
141
+ - [PictFlowCard](PictFlowCard.md) — Higher-level card class (recommended approach)
142
+ - [addNode](addNode.md) — Create nodes from registered types
@@ -0,0 +1,57 @@
1
+ # removeConnection
2
+
3
+ Delete a connection from the flow canvas.
4
+
5
+ ## Signature
6
+
7
+ ```javascript
8
+ flowView.removeConnection(pConnectionHash)
9
+ ```
10
+
11
+ ## Parameters
12
+
13
+ | Parameter | Type | Required | Description |
14
+ |-----------|------|----------|-------------|
15
+ | `pConnectionHash` | string | Yes | Hash of the connection to remove |
16
+
17
+ ## Returns
18
+
19
+ `boolean` — `true` if the connection was found and removed, `false` otherwise.
20
+
21
+ ## Events Fired
22
+
23
+ - `onConnectionRemoved` — with the removed connection object
24
+ - `onFlowChanged` — with the updated flow data
25
+
26
+ ## Examples
27
+
28
+ ### Basic removal
29
+
30
+ ```javascript
31
+ let tmpConn = flowView.addConnection(
32
+ tmpA.Hash, tmpOutPort.Hash,
33
+ tmpB.Hash, tmpInPort.Hash
34
+ );
35
+
36
+ flowView.removeConnection(tmpConn.Hash);
37
+ ```
38
+
39
+ ### Remove all connections for a specific node
40
+
41
+ ```javascript
42
+ let tmpFlowData = flowView.getFlowData();
43
+ let tmpTargetHash = myNode.Hash;
44
+
45
+ tmpFlowData.Connections.forEach((pConn) =>
46
+ {
47
+ if (pConn.SourceNodeHash === tmpTargetHash || pConn.TargetNodeHash === tmpTargetHash)
48
+ {
49
+ flowView.removeConnection(pConn.Hash);
50
+ }
51
+ });
52
+ ```
53
+
54
+ ## See Also
55
+
56
+ - [addConnection](addConnection.md) — Create a connection
57
+ - [removeNode](removeNode.md) — Remove a node (cascades connections)
@@ -0,0 +1,80 @@
1
+ # removeNode
2
+
3
+ Delete a node from the flow canvas. All connections attached to the node are also removed. Any open properties panel for the node is closed. The canvas is re-rendered.
4
+
5
+ ## Signature
6
+
7
+ ```javascript
8
+ flowView.removeNode(pNodeHash)
9
+ ```
10
+
11
+ ## Parameters
12
+
13
+ | Parameter | Type | Required | Description |
14
+ |-----------|------|----------|-------------|
15
+ | `pNodeHash` | string | Yes | Hash of the node to remove |
16
+
17
+ ## Returns
18
+
19
+ `boolean` — `true` if the node was found and removed, `false` otherwise.
20
+
21
+ ## Events Fired
22
+
23
+ - `onNodeRemoved` — with the removed node object
24
+ - `onConnectionRemoved` — for each connection that was cascaded
25
+ - `onFlowChanged` — with the updated flow data
26
+
27
+ ## Examples
28
+
29
+ ### Basic removal
30
+
31
+ ```javascript
32
+ let tmpNode = flowView.addNode('default', 100, 100, 'Temporary');
33
+
34
+ // Later, remove it
35
+ let tmpRemoved = flowView.removeNode(tmpNode.Hash);
36
+ console.log(tmpRemoved); // true
37
+ ```
38
+
39
+ ### Remove with cascading connections
40
+
41
+ ```javascript
42
+ let tmpA = flowView.addNode('start', 50, 100, 'A');
43
+ let tmpB = flowView.addNode('default', 250, 100, 'B');
44
+ let tmpC = flowView.addNode('end', 450, 100, 'C');
45
+
46
+ // Connect A -> B -> C
47
+ flowView.addConnection(tmpA.Hash, tmpA.Ports[0].Hash, tmpB.Hash, tmpB.Ports[0].Hash);
48
+ flowView.addConnection(tmpB.Hash, tmpB.Ports[1].Hash, tmpC.Hash, tmpC.Ports[0].Hash);
49
+
50
+ // Removing B also removes both connections
51
+ flowView.removeNode(tmpB.Hash);
52
+
53
+ let tmpFlowData = flowView.getFlowData();
54
+ console.log(tmpFlowData.Connections.length); // 0
55
+ ```
56
+
57
+ ### Conditional removal with event tracking
58
+
59
+ ```javascript
60
+ flowView._EventHandlerProvider.registerHandler('onNodeRemoved',
61
+ (pNode) =>
62
+ {
63
+ console.log('Removed:', pNode.Title);
64
+ });
65
+
66
+ // Only remove nodes of a certain type
67
+ let tmpFlowData = flowView.getFlowData();
68
+ tmpFlowData.Nodes.forEach((pNode) =>
69
+ {
70
+ if (pNode.Type === 'default')
71
+ {
72
+ flowView.removeNode(pNode.Hash);
73
+ }
74
+ });
75
+ ```
76
+
77
+ ## See Also
78
+
79
+ - [addNode](addNode.md) — Create a node
80
+ - [deleteSelected](selectNode.md) — Delete the currently selected element