pict-section-flow 0.0.2 → 0.0.3

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 (38) hide show
  1. package/.claude/launch.json +11 -0
  2. package/docs/README.md +51 -0
  3. package/example_applications/simple_cards/source/Pict-Application-FlowExample.js +105 -0
  4. package/example_applications/simple_cards/source/cards/FlowCard-Comment.js +36 -0
  5. package/example_applications/simple_cards/source/cards/FlowCard-DataPreview.js +42 -0
  6. package/example_applications/simple_cards/source/cards/FlowCard-Each.js +1 -1
  7. package/example_applications/simple_cards/source/cards/FlowCard-FileRead.js +1 -1
  8. package/example_applications/simple_cards/source/cards/FlowCard-FileWrite.js +1 -1
  9. package/example_applications/simple_cards/source/cards/FlowCard-GetValue.js +1 -1
  10. package/example_applications/simple_cards/source/cards/FlowCard-IfThenElse.js +1 -1
  11. package/example_applications/simple_cards/source/cards/FlowCard-LogValues.js +1 -1
  12. package/example_applications/simple_cards/source/cards/FlowCard-SetValue.js +1 -1
  13. package/example_applications/simple_cards/source/cards/FlowCard-Sparkline.js +98 -0
  14. package/example_applications/simple_cards/source/cards/FlowCard-StatusMonitor.js +44 -0
  15. package/example_applications/simple_cards/source/cards/FlowCard-Switch.js +1 -1
  16. package/example_applications/simple_cards/source/views/PictView-FlowExample-MainWorkspace.js +9 -1
  17. package/package.json +2 -2
  18. package/source/Pict-Section-Flow.js +8 -1
  19. package/source/PictFlowCard.js +49 -1
  20. package/source/providers/PictProvider-Flow-CSS.js +1440 -0
  21. package/source/providers/PictProvider-Flow-ConnectorShapes.js +413 -0
  22. package/source/providers/PictProvider-Flow-Geometry.js +43 -0
  23. package/source/providers/PictProvider-Flow-Icons.js +335 -0
  24. package/source/providers/PictProvider-Flow-Layouts.js +214 -2
  25. package/source/providers/PictProvider-Flow-NodeTypes.js +30 -7
  26. package/source/providers/PictProvider-Flow-Noise.js +241 -0
  27. package/source/providers/PictProvider-Flow-PanelChrome.js +19 -0
  28. package/source/providers/PictProvider-Flow-Theme.js +755 -0
  29. package/source/services/PictService-Flow-ConnectionRenderer.js +95 -32
  30. package/source/services/PictService-Flow-PanelManager.js +188 -0
  31. package/source/services/PictService-Flow-SelectionManager.js +109 -0
  32. package/source/services/PictService-Flow-Tether.js +52 -25
  33. package/source/services/PictService-Flow-ViewportManager.js +176 -0
  34. package/source/views/PictView-Flow-FloatingToolbar.js +352 -0
  35. package/source/views/PictView-Flow-Node.js +654 -169
  36. package/source/views/PictView-Flow-PropertiesPanel.js +176 -1
  37. package/source/views/PictView-Flow-Toolbar.js +846 -379
  38. package/source/views/PictView-Flow.js +279 -671
@@ -0,0 +1,11 @@
1
+ {
2
+ "version": "0.0.1",
3
+ "configurations": [
4
+ {
5
+ "name": "simple-cards",
6
+ "runtimeExecutable": "npx",
7
+ "runtimeArgs": ["http-server", "example_applications/simple_cards", "-p", "8085", "-c-1"],
8
+ "port": 8085
9
+ }
10
+ ]
11
+ }
package/docs/README.md CHANGED
@@ -14,6 +14,57 @@ npm install pict-section-flow
14
14
  npx quack build
15
15
  ```
16
16
 
17
+ ## Layout Persistence
18
+
19
+ Saved layouts are persisted to `localStorage` by default, keyed by the flow view identifier (e.g. `pict-flow-layouts-MyFlowDiagram`). Layouts survive page refreshes without any configuration.
20
+
21
+ ### Overriding Storage (e.g. REST API)
22
+
23
+ The `LayoutProvider` exposes three hookable storage methods that follow the `fCallback(pError, pResult)` convention. Replace them on the instance to use any backend:
24
+
25
+ ```javascript
26
+ // After your flow view is initialized:
27
+ let layoutProvider = myFlowView._LayoutProvider;
28
+
29
+ // Persist layouts to a server
30
+ layoutProvider.storageWrite = function(pLayouts, fCallback)
31
+ {
32
+ fetch('/api/my-flow/layouts',
33
+ {
34
+ method: 'PUT',
35
+ headers: { 'Content-Type': 'application/json' },
36
+ body: JSON.stringify(pLayouts)
37
+ })
38
+ .then(() => fCallback(null))
39
+ .catch((pError) => fCallback(pError));
40
+ };
41
+
42
+ // Load layouts from a server
43
+ layoutProvider.storageRead = function(fCallback)
44
+ {
45
+ fetch('/api/my-flow/layouts')
46
+ .then((pResponse) => pResponse.json())
47
+ .then((pLayouts) => fCallback(null, pLayouts))
48
+ .catch((pError) => fCallback(pError, []));
49
+ };
50
+
51
+ // Delete all layouts on the server
52
+ layoutProvider.storageDelete = function(fCallback)
53
+ {
54
+ fetch('/api/my-flow/layouts', { method: 'DELETE' })
55
+ .then(() => fCallback(null))
56
+ .catch((pError) => fCallback(pError));
57
+ };
58
+
59
+ // Load from the new backend now that hooks are set
60
+ layoutProvider.loadPersistedLayouts();
61
+ ```
62
+
63
+ ### Configuration Options
64
+
65
+ - **`StorageKey`** (string) -- Override the localStorage key. Passed via options when instantiating the provider.
66
+ - **`StorageKey: false`** -- Disable localStorage persistence entirely (useful when using only a remote backend).
67
+
17
68
  ## License
18
69
 
19
70
  MIT
@@ -242,6 +242,83 @@ class FlowExampleApplication extends libPictApplication
242
242
  { Hash: 'port-logerr-out', Direction: 'output', Side: 'right', Label: 'Pass' }
243
243
  ],
244
244
  Data: {}
245
+ },
246
+ // ── Halt: premature termination on write error ────
247
+ {
248
+ Hash: 'node-halt',
249
+ Type: 'halt',
250
+ X: 1870,
251
+ Y: 380,
252
+ Width: 140,
253
+ Height: 80,
254
+ Title: 'Halt',
255
+ Ports:
256
+ [
257
+ { Hash: 'port-halt-in', Direction: 'input', Side: 'left', Label: 'In' }
258
+ ],
259
+ Data: {}
260
+ },
261
+ // ── Body Content Examples ──────────────────────────
262
+ // SVG body: Status Monitor
263
+ {
264
+ Hash: 'node-status',
265
+ Type: 'STAT',
266
+ X: 50,
267
+ Y: 530,
268
+ Width: 200,
269
+ Height: 110,
270
+ Title: 'Service Health',
271
+ Ports:
272
+ [
273
+ { Hash: 'port-stat-in', Direction: 'input', Side: 'left', Label: 'Check' },
274
+ { Hash: 'port-stat-ok', Direction: 'output', Side: 'right', Label: 'Healthy' },
275
+ { Hash: 'port-stat-warn', Direction: 'output', Side: 'bottom', Label: 'Degraded' }
276
+ ],
277
+ Data: {}
278
+ },
279
+ // HTML body: Data Preview
280
+ {
281
+ Hash: 'node-preview',
282
+ Type: 'PREV',
283
+ X: 340,
284
+ Y: 530,
285
+ Width: 200,
286
+ Height: 120,
287
+ Title: 'Inspect Payload',
288
+ Ports:
289
+ [
290
+ { Hash: 'port-prev-in', Direction: 'input', Side: 'left', Label: 'Data' },
291
+ { Hash: 'port-prev-out', Direction: 'output', Side: 'right', Label: 'Pass' }
292
+ ],
293
+ Data: {}
294
+ },
295
+ // Canvas body: Sparkline
296
+ {
297
+ Hash: 'node-spark',
298
+ Type: 'SPKL',
299
+ X: 630,
300
+ Y: 530,
301
+ Width: 220,
302
+ Height: 110,
303
+ Title: 'Throughput',
304
+ Ports:
305
+ [
306
+ { Hash: 'port-spark-in', Direction: 'input', Side: 'left', Label: 'Values' },
307
+ { Hash: 'port-spark-out', Direction: 'output', Side: 'right', Label: 'Stats' }
308
+ ],
309
+ Data: {}
310
+ },
311
+ // HTML body (template): Comment
312
+ {
313
+ Hash: 'node-comment',
314
+ Type: 'NOTE',
315
+ X: 940,
316
+ Y: 540,
317
+ Width: 180,
318
+ Height: 100,
319
+ Title: 'Note',
320
+ Ports: [],
321
+ Data: { NoteText: 'These four cards demonstrate the three BodyContent renderer types: SVG, HTML, and Canvas.' }
245
322
  }
246
323
  ],
247
324
  Connections:
@@ -380,6 +457,34 @@ class FlowExampleApplication extends libPictApplication
380
457
  TargetNodeHash: 'node-end',
381
458
  TargetPortHash: 'port-end-in',
382
459
  Data: {}
460
+ },
461
+ // Write error → Halt
462
+ {
463
+ Hash: 'conn-16',
464
+ SourceNodeHash: 'node-fwrite',
465
+ SourcePortHash: 'port-fwrite-err',
466
+ TargetNodeHash: 'node-halt',
467
+ TargetPortHash: 'port-halt-in',
468
+ Data: {}
469
+ },
470
+ // ── Body Content example connections ────────────────
471
+ // Service Health → Inspect Payload
472
+ {
473
+ Hash: 'conn-17',
474
+ SourceNodeHash: 'node-status',
475
+ SourcePortHash: 'port-stat-ok',
476
+ TargetNodeHash: 'node-preview',
477
+ TargetPortHash: 'port-prev-in',
478
+ Data: {}
479
+ },
480
+ // Inspect Payload → Throughput
481
+ {
482
+ Hash: 'conn-18',
483
+ SourceNodeHash: 'node-preview',
484
+ SourcePortHash: 'port-prev-out',
485
+ TargetNodeHash: 'node-spark',
486
+ TargetPortHash: 'port-spark-in',
487
+ Data: {}
383
488
  }
384
489
  ],
385
490
  ViewState:
@@ -0,0 +1,36 @@
1
+ const libPictFlowCard = require('pict-section-flow').PictFlowCard;
2
+
3
+ class FlowCardComment extends libPictFlowCard
4
+ {
5
+ constructor(pFable, pOptions, pServiceHash)
6
+ {
7
+ super(pFable, Object.assign(
8
+ {},
9
+ {
10
+ Title: 'Comment',
11
+ Name: 'Annotation',
12
+ Code: 'NOTE',
13
+ Description: 'A floating annotation or comment node for documenting flow logic.',
14
+ Icon: 'NOTE',
15
+ Tooltip: 'Comment: Add a note to the diagram',
16
+ Category: 'Documentation',
17
+ TitleBarColor: '#f39c12',
18
+ BodyStyle: { fill: '#fef9e7', stroke: '#f39c12' },
19
+ Width: 180,
20
+ Height: 100,
21
+ Inputs: [],
22
+ Outputs: [],
23
+ ShowTypeLabel: false,
24
+ LabelsInFront: false,
25
+ BodyContent:
26
+ {
27
+ ContentType: 'html',
28
+ Template: '<div style="padding:6px 8px;font-size:10px;line-height:1.5;color:#7d6608;font-style:italic">{~D:Record.Data.NoteText~}</div>'
29
+ }
30
+ },
31
+ pOptions),
32
+ pServiceHash);
33
+ }
34
+ }
35
+
36
+ module.exports = FlowCardComment;
@@ -0,0 +1,42 @@
1
+ const libPictFlowCard = require('pict-section-flow').PictFlowCard;
2
+
3
+ class FlowCardDataPreview extends libPictFlowCard
4
+ {
5
+ constructor(pFable, pOptions, pServiceHash)
6
+ {
7
+ super(pFable, Object.assign(
8
+ {},
9
+ {
10
+ Title: 'Data Preview',
11
+ Name: 'Inspect Data',
12
+ Code: 'PREV',
13
+ Description: 'Displays a preview of the data flowing through this node.',
14
+ Icon: 'PREV',
15
+ Tooltip: 'Data Preview: View data summary',
16
+ Category: 'Debug',
17
+ TitleBarColor: '#2980b9',
18
+ BodyStyle: { fill: '#ebf5fb', stroke: '#2980b9' },
19
+ Width: 200,
20
+ Height: 120,
21
+ Inputs:
22
+ [
23
+ { Name: 'Data', Side: 'left', MinimumInputCount: 1, MaximumInputCount: 1 }
24
+ ],
25
+ Outputs:
26
+ [
27
+ { Name: 'Pass', Side: 'right' }
28
+ ],
29
+ ShowTypeLabel: false,
30
+ PortLabelPadding: true,
31
+ BodyContent:
32
+ {
33
+ ContentType: 'html',
34
+ Template: '<table style="width:100%;border-collapse:collapse;font-size:9px;color:#2c3e50"><tr style="background:#d6eaf8"><td style="padding:3px 5px;font-weight:600">Field</td><td style="padding:3px 5px;font-weight:600">Type</td><td style="padding:3px 5px;font-weight:600">Value</td></tr><tr><td style="padding:2px 5px;border-top:1px solid #d5dbdb">name</td><td style="padding:2px 5px;border-top:1px solid #d5dbdb;color:#8e44ad">str</td><td style="padding:2px 5px;border-top:1px solid #d5dbdb;color:#7f8c8d">&#x22;config&#x22;</td></tr><tr><td style="padding:2px 5px;border-top:1px solid #d5dbdb">count</td><td style="padding:2px 5px;border-top:1px solid #d5dbdb;color:#8e44ad">num</td><td style="padding:2px 5px;border-top:1px solid #d5dbdb;color:#7f8c8d">42</td></tr><tr><td style="padding:2px 5px;border-top:1px solid #d5dbdb">active</td><td style="padding:2px 5px;border-top:1px solid #d5dbdb;color:#8e44ad">bool</td><td style="padding:2px 5px;border-top:1px solid #d5dbdb;color:#27ae60">true</td></tr></table>'
35
+ }
36
+ },
37
+ pOptions),
38
+ pServiceHash);
39
+ }
40
+ }
41
+
42
+ module.exports = FlowCardDataPreview;
@@ -11,7 +11,7 @@ class FlowCardEach extends libPictFlowCard
11
11
  Name: 'Loop Iterator',
12
12
  Code: 'EACH',
13
13
  Description: 'Iterates over a collection, executing the body for each item.',
14
- Icon: '\uD83D\uDD01',
14
+ Icon: 'EACH',
15
15
  Tooltip: 'Each: Iterate over items in a collection',
16
16
  Category: 'Control Flow',
17
17
  TitleBarColor: '#8e44ad',
@@ -11,7 +11,7 @@ class FlowCardFileRead extends libPictFlowCard
11
11
  Name: 'Read File',
12
12
  Code: 'FREAD',
13
13
  Description: 'Reads the contents of a file from the filesystem.',
14
- Icon: '\uD83D\uDCC4',
14
+ Icon: 'FREAD',
15
15
  Tooltip: 'File Read: Read data from a file',
16
16
  Category: 'I/O',
17
17
  TitleBarColor: '#2980b9',
@@ -11,7 +11,7 @@ class FlowCardFileWrite extends libPictFlowCard
11
11
  Name: 'Write File',
12
12
  Code: 'FWRITE',
13
13
  Description: 'Writes data to a file on the filesystem.',
14
- Icon: '\uD83D\uDCBE',
14
+ Icon: 'FWRITE',
15
15
  Tooltip: 'File Write: Write data to a file',
16
16
  Category: 'I/O',
17
17
  TitleBarColor: '#27ae60',
@@ -11,7 +11,7 @@ class FlowCardGetValue extends libPictFlowCard
11
11
  Name: 'Read Value',
12
12
  Code: 'GET',
13
13
  Description: 'Retrieves a named value from the flow context.',
14
- Icon: '\uD83D\uDD0D',
14
+ Icon: 'GET',
15
15
  Tooltip: 'Get Value: Read a value from the context',
16
16
  Category: 'Data',
17
17
  TitleBarColor: '#2c3e50',
@@ -11,7 +11,7 @@ class FlowCardIfThenElse extends libPictFlowCard
11
11
  Name: 'Conditional Branch',
12
12
  Code: 'ITE',
13
13
  Description: 'Evaluates a condition and routes to the Then or Else branch.',
14
- Icon: '\u2753',
14
+ Icon: 'ITE',
15
15
  Tooltip: 'If-Then-Else: Routes flow based on a boolean condition',
16
16
  Category: 'Control Flow',
17
17
  TitleBarColor: '#e67e22',
@@ -11,7 +11,7 @@ class FlowCardLogValues extends libPictFlowCard
11
11
  Name: 'Log to Console',
12
12
  Code: 'LOG',
13
13
  Description: 'Logs input values to the console or log output.',
14
- Icon: '\uD83D\uDCDD',
14
+ Icon: 'LOG',
15
15
  Tooltip: 'Log Values: Output values to the log',
16
16
  Category: 'Debug',
17
17
  TitleBarColor: '#7f8c8d',
@@ -11,7 +11,7 @@ class FlowCardSetValue extends libPictFlowCard
11
11
  Name: 'Assign Value',
12
12
  Code: 'SET',
13
13
  Description: 'Sets a named value in the flow context.',
14
- Icon: '\u270F\uFE0F',
14
+ Icon: 'SET',
15
15
  Tooltip: 'Set Value: Assign a value in the context',
16
16
  Category: 'Data',
17
17
  TitleBarColor: '#16a085',
@@ -0,0 +1,98 @@
1
+ const libPictFlowCard = require('pict-section-flow').PictFlowCard;
2
+
3
+ class FlowCardSparkline extends libPictFlowCard
4
+ {
5
+ constructor(pFable, pOptions, pServiceHash)
6
+ {
7
+ super(pFable, Object.assign(
8
+ {},
9
+ {
10
+ Title: 'Sparkline',
11
+ Name: 'Metric Chart',
12
+ Code: 'SPKL',
13
+ Description: 'Renders a live sparkline visualization of numeric throughput data.',
14
+ Icon: 'SPKL',
15
+ Tooltip: 'Sparkline: Visualize numeric throughput',
16
+ Category: 'Visualization',
17
+ TitleBarColor: '#c0392b',
18
+ BodyStyle: { fill: '#fdedec', stroke: '#c0392b' },
19
+ Width: 220,
20
+ Height: 110,
21
+ Inputs:
22
+ [
23
+ { Name: 'Values', Side: 'left', MinimumInputCount: 1, MaximumInputCount: 1 }
24
+ ],
25
+ Outputs:
26
+ [
27
+ { Name: 'Stats', Side: 'right' }
28
+ ],
29
+ ShowTypeLabel: false,
30
+ PortLabelsVertical: true,
31
+ PortLabelPadding: true,
32
+ LabelsInFront: true,
33
+ BodyContent:
34
+ {
35
+ ContentType: 'canvas',
36
+ RenderCallback: function (pCanvas, pNodeData, pNodeTypeConfig, pBounds)
37
+ {
38
+ let tmpCtx = pCanvas.getContext('2d');
39
+ if (!tmpCtx) return;
40
+
41
+ let tmpW = pCanvas.width;
42
+ let tmpH = pCanvas.height;
43
+
44
+ // Sample data points (simulated throughput)
45
+ let tmpData = [12, 19, 8, 25, 15, 30, 22, 18, 35, 28, 14, 32, 20, 26, 10, 24, 33, 17, 29, 21];
46
+ let tmpMax = Math.max.apply(null, tmpData);
47
+ let tmpMin = Math.min.apply(null, tmpData);
48
+ let tmpRange = tmpMax - tmpMin || 1;
49
+ let tmpPadding = 6;
50
+ let tmpChartW = tmpW - (tmpPadding * 2);
51
+ let tmpChartH = tmpH - (tmpPadding * 2);
52
+ let tmpStep = tmpChartW / (tmpData.length - 1);
53
+
54
+ // Draw filled area
55
+ tmpCtx.beginPath();
56
+ tmpCtx.moveTo(tmpPadding, tmpH - tmpPadding);
57
+ for (let i = 0; i < tmpData.length; i++)
58
+ {
59
+ let tmpX = tmpPadding + (i * tmpStep);
60
+ let tmpY = tmpPadding + tmpChartH - ((tmpData[i] - tmpMin) / tmpRange) * tmpChartH;
61
+ tmpCtx.lineTo(tmpX, tmpY);
62
+ }
63
+ tmpCtx.lineTo(tmpPadding + tmpChartW, tmpH - tmpPadding);
64
+ tmpCtx.closePath();
65
+ tmpCtx.fillStyle = 'rgba(192, 57, 43, 0.12)';
66
+ tmpCtx.fill();
67
+
68
+ // Draw line
69
+ tmpCtx.beginPath();
70
+ for (let i = 0; i < tmpData.length; i++)
71
+ {
72
+ let tmpX = tmpPadding + (i * tmpStep);
73
+ let tmpY = tmpPadding + tmpChartH - ((tmpData[i] - tmpMin) / tmpRange) * tmpChartH;
74
+ if (i === 0) tmpCtx.moveTo(tmpX, tmpY);
75
+ else tmpCtx.lineTo(tmpX, tmpY);
76
+ }
77
+ tmpCtx.strokeStyle = '#c0392b';
78
+ tmpCtx.lineWidth = 1.5;
79
+ tmpCtx.lineJoin = 'round';
80
+ tmpCtx.lineCap = 'round';
81
+ tmpCtx.stroke();
82
+
83
+ // Draw end dot
84
+ let tmpLastX = tmpPadding + ((tmpData.length - 1) * tmpStep);
85
+ let tmpLastY = tmpPadding + tmpChartH - ((tmpData[tmpData.length - 1] - tmpMin) / tmpRange) * tmpChartH;
86
+ tmpCtx.beginPath();
87
+ tmpCtx.arc(tmpLastX, tmpLastY, 3, 0, Math.PI * 2);
88
+ tmpCtx.fillStyle = '#c0392b';
89
+ tmpCtx.fill();
90
+ }
91
+ }
92
+ },
93
+ pOptions),
94
+ pServiceHash);
95
+ }
96
+ }
97
+
98
+ module.exports = FlowCardSparkline;
@@ -0,0 +1,44 @@
1
+ const libPictFlowCard = require('pict-section-flow').PictFlowCard;
2
+
3
+ class FlowCardStatusMonitor extends libPictFlowCard
4
+ {
5
+ constructor(pFable, pOptions, pServiceHash)
6
+ {
7
+ super(pFable, Object.assign(
8
+ {},
9
+ {
10
+ Title: 'Status Monitor',
11
+ Name: 'Health Check',
12
+ Code: 'STAT',
13
+ Description: 'Monitors the health status of upstream services and reports availability.',
14
+ Icon: 'STAT',
15
+ Tooltip: 'Status Monitor: Check service health',
16
+ Category: 'Monitoring',
17
+ TitleBarColor: '#27ae60',
18
+ BodyStyle: { fill: '#eafaf1', stroke: '#27ae60' },
19
+ Width: 200,
20
+ Height: 110,
21
+ Inputs:
22
+ [
23
+ { Name: 'Check', Side: 'left', MinimumInputCount: 1, MaximumInputCount: -1 }
24
+ ],
25
+ Outputs:
26
+ [
27
+ { Name: 'Healthy', Side: 'right' },
28
+ { Name: 'Degraded', Side: 'bottom' }
29
+ ],
30
+ ShowTypeLabel: false,
31
+ PortLabelsOnHover: true,
32
+ LabelsInFront: false,
33
+ BodyContent:
34
+ {
35
+ ContentType: 'svg',
36
+ Template: '<circle cx="30" cy="28" r="6" fill="#27ae60" opacity="0.9"/><text x="42" y="32" font-size="9" fill="#2c3e50">API</text><circle cx="100" cy="28" r="6" fill="#27ae60" opacity="0.9"/><text x="112" y="32" font-size="9" fill="#2c3e50">DB</text><circle cx="30" cy="54" r="6" fill="#f39c12" opacity="0.9"/><text x="42" y="58" font-size="9" fill="#2c3e50">Cache</text><circle cx="100" cy="54" r="6" fill="#27ae60" opacity="0.9"/><text x="112" y="58" font-size="9" fill="#2c3e50">Queue</text>'
37
+ }
38
+ },
39
+ pOptions),
40
+ pServiceHash);
41
+ }
42
+ }
43
+
44
+ module.exports = FlowCardStatusMonitor;
@@ -11,7 +11,7 @@ class FlowCardSwitch extends libPictFlowCard
11
11
  Name: 'Multi-way Branch',
12
12
  Code: 'SW',
13
13
  Description: 'Routes flow to one of multiple cases based on a value.',
14
- Icon: '\uD83D\uDD00',
14
+ Icon: 'SW',
15
15
  Tooltip: 'Switch: Multi-way branch on a value',
16
16
  Category: 'Control Flow',
17
17
  TitleBarColor: '#d35400',
@@ -10,6 +10,10 @@ const libFlowCardFileWrite = require('../cards/FlowCard-FileWrite.js');
10
10
  const libFlowCardLogValues = require('../cards/FlowCard-LogValues.js');
11
11
  const libFlowCardSetValue = require('../cards/FlowCard-SetValue.js');
12
12
  const libFlowCardGetValue = require('../cards/FlowCard-GetValue.js');
13
+ const libFlowCardStatusMonitor = require('../cards/FlowCard-StatusMonitor.js');
14
+ const libFlowCardDataPreview = require('../cards/FlowCard-DataPreview.js');
15
+ const libFlowCardSparkline = require('../cards/FlowCard-Sparkline.js');
16
+ const libFlowCardComment = require('../cards/FlowCard-Comment.js');
13
17
 
14
18
  const _ViewConfiguration =
15
19
  {
@@ -219,7 +223,11 @@ class FlowExampleMainWorkspaceView extends libPictView
219
223
  libFlowCardFileWrite,
220
224
  libFlowCardLogValues,
221
225
  libFlowCardSetValue,
222
- libFlowCardGetValue
226
+ libFlowCardGetValue,
227
+ libFlowCardStatusMonitor,
228
+ libFlowCardDataPreview,
229
+ libFlowCardSparkline,
230
+ libFlowCardComment
223
231
  ];
224
232
 
225
233
  let tmpNodeTypes = {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pict-section-flow",
3
- "version": "0.0.2",
3
+ "version": "0.0.3",
4
4
  "description": "Pict Section Flow Diagram",
5
5
  "main": "source/Pict-Section-Flow.js",
6
6
  "scripts": {
@@ -17,6 +17,6 @@
17
17
  },
18
18
  "devDependencies": {
19
19
  "pict": "^1.0.354",
20
- "quackage": "^1.0.58"
20
+ "quackage": "^1.0.59"
21
21
  }
22
22
  }
@@ -6,8 +6,9 @@ module.exports = require('./views/PictView-Flow.js');
6
6
  // Node rendering view
7
7
  module.exports.PictViewFlowNode = require('./views/PictView-Flow-Node.js');
8
8
 
9
- // Toolbar view
9
+ // Toolbar views
10
10
  module.exports.PictViewFlowToolbar = require('./views/PictView-Flow-Toolbar.js');
11
+ module.exports.PictViewFlowFloatingToolbar = require('./views/PictView-Flow-FloatingToolbar.js');
11
12
 
12
13
  // Services
13
14
  module.exports.PictServiceFlowInteractionManager = require('./services/PictService-Flow-InteractionManager.js');
@@ -15,6 +16,9 @@ module.exports.PictServiceFlowConnectionRenderer = require('./services/PictServi
15
16
  module.exports.PictServiceFlowTether = require('./services/PictService-Flow-Tether.js');
16
17
  module.exports.PictServiceFlowLayout = require('./services/PictService-Flow-Layout.js');
17
18
  module.exports.PictServiceFlowPathGenerator = require('./services/PictService-Flow-PathGenerator.js');
19
+ module.exports.PictServiceFlowViewportManager = require('./services/PictService-Flow-ViewportManager.js');
20
+ module.exports.PictServiceFlowSelectionManager = require('./services/PictService-Flow-SelectionManager.js');
21
+ module.exports.PictServiceFlowPanelManager = require('./services/PictService-Flow-PanelManager.js');
18
22
 
19
23
  // Providers
20
24
  module.exports.PictProviderFlowNodeTypes = require('./providers/PictProvider-Flow-NodeTypes.js');
@@ -23,6 +27,9 @@ module.exports.PictProviderFlowLayouts = require('./providers/PictProvider-Flow-
23
27
  module.exports.PictProviderFlowSVGHelpers = require('./providers/PictProvider-Flow-SVGHelpers.js');
24
28
  module.exports.PictProviderFlowGeometry = require('./providers/PictProvider-Flow-Geometry.js');
25
29
  module.exports.PictProviderFlowPanelChrome = require('./providers/PictProvider-Flow-PanelChrome.js');
30
+ module.exports.PictProviderFlowCSS = require('./providers/PictProvider-Flow-CSS.js');
31
+ module.exports.PictProviderFlowIcons = require('./providers/PictProvider-Flow-Icons.js');
32
+ module.exports.PictProviderFlowConnectorShapes = require('./providers/PictProvider-Flow-ConnectorShapes.js');
26
33
 
27
34
  // FlowCard base class
28
35
  module.exports.PictFlowCard = require('./PictFlowCard.js');
@@ -31,6 +31,18 @@ const libFableServiceProviderBase = require('fable-serviceproviderbase');
31
31
  * - DefaultHeight (number) - Panel height (default 200)
32
32
  * - Title (string) - Panel title bar text
33
33
  * - Configuration (object) - Panel-type-specific configuration
34
+ * - BodyContent (object, optional) - Custom content rendered in the node body area
35
+ * - ContentType (string) - 'svg', 'html', or 'canvas'
36
+ * - Template (string) - Pict template string (html/svg only)
37
+ * - TemplateHash (string) - Registered template hash (takes precedence over Template)
38
+ * - Templates (array) - Template definitions to register [{Hash, Template}]
39
+ * - RenderCallback (function)- Imperative render callback (required for canvas)
40
+ * - Padding (number) - Inner padding in pixels (default 2)
41
+ * - ShowTypeLabel (boolean, default true) - Whether to show the type label/code badge on hover
42
+ * - PortLabelsOnHover (boolean, default false) - When true, port labels only appear on hover
43
+ * - PortLabelsVertical (boolean, default false) - When true, port labels render vertically
44
+ * - PortLabelPadding (boolean, default false) - When true, port labels have extra padding to avoid overlapping body content
45
+ * - LabelsInFront (boolean, default true) - When true, labels render in front of body content; when false, behind
34
46
  *
35
47
  * Usage:
36
48
  * class MyCard extends PictFlowCard {
@@ -82,6 +94,18 @@ class PictFlowCard extends libFableServiceProviderBase
82
94
  this.cardPropertiesPanel = (tmpOptions.PropertiesPanel && typeof tmpOptions.PropertiesPanel === 'object')
83
95
  ? tmpOptions.PropertiesPanel
84
96
  : null;
97
+
98
+ // --- Body content configuration ---
99
+ this.cardBodyContent = (tmpOptions.BodyContent && typeof tmpOptions.BodyContent === 'object')
100
+ ? tmpOptions.BodyContent
101
+ : null;
102
+
103
+ // --- Label display booleans ---
104
+ this.cardShowTypeLabel = (typeof tmpOptions.ShowTypeLabel === 'boolean') ? tmpOptions.ShowTypeLabel : true;
105
+ this.cardPortLabelsOnHover = (typeof tmpOptions.PortLabelsOnHover === 'boolean') ? tmpOptions.PortLabelsOnHover : false;
106
+ this.cardPortLabelsVertical = (typeof tmpOptions.PortLabelsVertical === 'boolean') ? tmpOptions.PortLabelsVertical : false;
107
+ this.cardPortLabelPadding = (typeof tmpOptions.PortLabelPadding === 'boolean') ? tmpOptions.PortLabelPadding : false;
108
+ this.cardLabelsInFront = (typeof tmpOptions.LabelsInFront === 'boolean') ? tmpOptions.LabelsInFront : true;
85
109
  }
86
110
 
87
111
  /**
@@ -155,12 +179,30 @@ class PictFlowCard extends libFableServiceProviderBase
155
179
  }
156
180
  };
157
181
 
182
+ // Include label display booleans
183
+ tmpResult.ShowTypeLabel = this.cardShowTypeLabel;
184
+ tmpResult.PortLabelsOnHover = this.cardPortLabelsOnHover;
185
+ tmpResult.PortLabelsVertical = this.cardPortLabelsVertical;
186
+ tmpResult.PortLabelPadding = this.cardPortLabelPadding;
187
+ tmpResult.LabelsInFront = this.cardLabelsInFront;
188
+
158
189
  // Include properties panel config if defined
159
190
  if (this.cardPropertiesPanel)
160
191
  {
161
192
  tmpResult.PropertiesPanel = JSON.parse(JSON.stringify(this.cardPropertiesPanel));
162
193
  }
163
194
 
195
+ // Include body content config if defined
196
+ if (this.cardBodyContent)
197
+ {
198
+ tmpResult.BodyContent = JSON.parse(JSON.stringify(this.cardBodyContent));
199
+ // RenderCallback cannot be serialized — preserve the original function reference
200
+ if (typeof this.options.BodyContent.RenderCallback === 'function')
201
+ {
202
+ tmpResult.BodyContent.RenderCallback = this.options.BodyContent.RenderCallback;
203
+ }
204
+ }
205
+
164
206
  return tmpResult;
165
207
  }
166
208
 
@@ -203,5 +245,11 @@ module.exports.default_configuration =
203
245
  Width: 180,
204
246
  Height: 80,
205
247
  Category: 'General',
206
- PropertiesPanel: null
248
+ PropertiesPanel: null,
249
+ BodyContent: null,
250
+ ShowTypeLabel: true,
251
+ PortLabelsOnHover: false,
252
+ PortLabelsVertical: false,
253
+ PortLabelPadding: false,
254
+ LabelsInFront: true
207
255
  };