pict-section-flow 1.4.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.
- package/package.json +7 -2
- package/source/Pict-Section-Flow.js +20 -14
- package/source/providers/PictProvider-Flow-Background.js +303 -0
- package/source/providers/PictProvider-Flow-CSS.js +73 -7
- package/source/providers/PictProvider-Flow-Geometry.js +11 -421
- package/source/providers/PictProvider-Flow-Icons.js +12 -0
- package/source/providers/PictProvider-Flow-Layouts.js +107 -0
- package/source/services/PictService-Flow-ConnectionRenderer.js +1 -1
- package/source/services/PictService-Flow-CursorManager.js +113 -0
- package/source/services/PictService-Flow-InteractionManager.js +439 -59
- package/source/services/PictService-Flow-Layout.js +21 -16
- package/source/services/PictService-Flow-PathGenerator.js +30 -417
- package/source/services/PictService-Flow-RenderManager.js +9 -1
- package/source/services/PictService-Flow-ViewportManager.js +102 -0
- package/source/views/PictView-Flow-FloatingToolbar.js +5 -1
- package/source/views/PictView-Flow-Node.js +29 -0
- package/source/views/PictView-Flow-Toolbar.js +50 -3
- package/source/views/PictView-Flow.js +591 -2
- package/.claude/launch.json +0 -11
- package/docs/.nojekyll +0 -0
- package/docs/Architecture.md +0 -163
- package/docs/Custom-Styling.md +0 -275
- package/docs/Data_Model.md +0 -149
- package/docs/Event_System.md +0 -156
- package/docs/Getting_Started.md +0 -237
- package/docs/Implementation_Reference.md +0 -528
- package/docs/Layout_Persistence.md +0 -117
- package/docs/README.md +0 -103
- package/docs/Theme_Integration.md +0 -150
- package/docs/_brand.json +0 -18
- package/docs/_cover.md +0 -17
- package/docs/_playground.json +0 -24
- package/docs/_sidebar.md +0 -57
- package/docs/_topbar.md +0 -8
- package/docs/_version.json +0 -7
- package/docs/api/PictFlowCard.md +0 -216
- package/docs/api/PictFlowCardPropertiesPanel.md +0 -235
- package/docs/api/addConnection.md +0 -101
- package/docs/api/addNode.md +0 -137
- package/docs/api/autoLayout.md +0 -77
- package/docs/api/getFlowData.md +0 -112
- package/docs/api/marshalToView.md +0 -95
- package/docs/api/openPanel.md +0 -128
- package/docs/api/registerHandler.md +0 -174
- package/docs/api/registerNodeType.md +0 -142
- package/docs/api/removeConnection.md +0 -57
- package/docs/api/removeNode.md +0 -80
- package/docs/api/saveLayout.md +0 -152
- package/docs/api/screenToSVGCoords.md +0 -68
- package/docs/api/selectNode.md +0 -116
- package/docs/api/setTheme.md +0 -168
- package/docs/api/setZoom.md +0 -97
- package/docs/api/toggleFullscreen.md +0 -68
- package/docs/card-help/EACH.md +0 -19
- package/docs/card-help/FREAD.md +0 -24
- package/docs/card-help/FWRITE.md +0 -24
- package/docs/card-help/GET.md +0 -22
- package/docs/card-help/ITE.md +0 -23
- package/docs/card-help/LOG.md +0 -23
- package/docs/card-help/NOTE.md +0 -17
- package/docs/card-help/PREV.md +0 -18
- package/docs/card-help/SET.md +0 -27
- package/docs/card-help/SPKL.md +0 -22
- package/docs/card-help/STAT.md +0 -23
- package/docs/card-help/SW.md +0 -25
- package/docs/diagrams/architecture-at-a-glance.excalidraw +0 -4270
- package/docs/diagrams/architecture-at-a-glance.mmd +0 -30
- package/docs/diagrams/architecture-at-a-glance.svg +0 -2
- package/docs/diagrams/data-flow.excalidraw +0 -1451
- package/docs/diagrams/data-flow.mmd +0 -17
- package/docs/diagrams/data-flow.svg +0 -2
- package/docs/diagrams/high-level-design.excalidraw +0 -5767
- package/docs/diagrams/high-level-design.mmd +0 -86
- package/docs/diagrams/high-level-design.svg +0 -2
- package/docs/diagrams/relationships.excalidraw +0 -3852
- package/docs/diagrams/relationships.mmd +0 -9
- package/docs/diagrams/relationships.svg +0 -2
- package/docs/diagrams/service-initialization-sequence.excalidraw +0 -1466
- package/docs/diagrams/service-initialization-sequence.mmd +0 -19
- package/docs/diagrams/service-initialization-sequence.svg +0 -2
- package/docs/diagrams/svg-layer-structure.excalidraw +0 -1060
- package/docs/diagrams/svg-layer-structure.mmd +0 -18
- package/docs/diagrams/svg-layer-structure.svg +0 -2
- package/docs/examples/README.md +0 -9
- package/docs/examples/simple_cards/README.md +0 -677
- package/docs/examples/simple_cards/css/flowexample.css +0 -65
- package/docs/examples/simple_cards/index.html +0 -32
- package/docs/examples/simple_cards/js/pict.min.js +0 -12
- package/docs/examples/simple_cards/pict-section-flow-example-simple-cards.compatible.min.js +0 -1
- package/docs/index.html +0 -38
- package/docs/playground/app.json +0 -6
- package/docs/playground/appdata.json +0 -85
- package/docs/playground/application.js +0 -23
- package/docs/playground/pict.json +0 -17
- package/docs/playground/runtime/pict-application.min.js +0 -2
- package/docs/playground/runtime/pict-section-flow.min.js +0 -2
- package/docs/playground/runtime/pict-section-modal.min.js +0 -2
- package/docs/playground/runtime/pict.min.js +0 -12
- package/docs/retold-catalog.json +0 -244
- package/docs/retold-keyword-index.json +0 -26028
- package/example_applications/simple_cards/css/flowexample.css +0 -65
- package/example_applications/simple_cards/html/index.html +0 -32
- package/example_applications/simple_cards/package.json +0 -52
- package/example_applications/simple_cards/source/Pict-Application-FlowExample-Configuration.json +0 -15
- package/example_applications/simple_cards/source/Pict-Application-FlowExample.js +0 -539
- package/example_applications/simple_cards/source/card-help-content.js +0 -16
- package/example_applications/simple_cards/source/cards/FlowCard-Comment.js +0 -38
- package/example_applications/simple_cards/source/cards/FlowCard-DataPreview.js +0 -44
- package/example_applications/simple_cards/source/cards/FlowCard-Each.js +0 -38
- package/example_applications/simple_cards/source/cards/FlowCard-FileRead.js +0 -56
- package/example_applications/simple_cards/source/cards/FlowCard-FileWrite.js +0 -50
- package/example_applications/simple_cards/source/cards/FlowCard-GetValue.js +0 -37
- package/example_applications/simple_cards/source/cards/FlowCard-IfThenElse.js +0 -49
- package/example_applications/simple_cards/source/cards/FlowCard-LogValues.js +0 -55
- package/example_applications/simple_cards/source/cards/FlowCard-SetValue.js +0 -97
- package/example_applications/simple_cards/source/cards/FlowCard-Sparkline.js +0 -100
- package/example_applications/simple_cards/source/cards/FlowCard-StatusMonitor.js +0 -46
- package/example_applications/simple_cards/source/cards/FlowCard-Switch.js +0 -39
- package/example_applications/simple_cards/source/providers/PictRouter-FlowExample-Configuration.json +0 -22
- package/example_applications/simple_cards/source/sample-flows.js +0 -410
- package/example_applications/simple_cards/source/views/PictView-FlowExample-About.js +0 -184
- package/example_applications/simple_cards/source/views/PictView-FlowExample-BottomBar.js +0 -77
- package/example_applications/simple_cards/source/views/PictView-FlowExample-Documentation.js +0 -325
- package/example_applications/simple_cards/source/views/PictView-FlowExample-FileWriteInfo.js +0 -59
- package/example_applications/simple_cards/source/views/PictView-FlowExample-Layout.js +0 -90
- package/example_applications/simple_cards/source/views/PictView-FlowExample-MainWorkspace.js +0 -453
- package/example_applications/simple_cards/source/views/PictView-FlowExample-TopBar.js +0 -95
- package/scripts/generate-card-help.js +0 -214
- package/source/providers/edges/Edge-Bezier.js +0 -41
- package/source/providers/edges/Edge-Orthogonal.js +0 -37
- package/source/providers/edges/Edge-OrthogonalSnap.js +0 -72
- package/source/providers/edges/Edge-Perimeter-Linear.js +0 -31
- package/source/providers/edges/Edge-Perimeter-Orthogonal.js +0 -39
- package/source/providers/edges/Edge-Perimeter.js +0 -48
- package/source/providers/edges/Edge-PerimeterMath.js +0 -92
- package/source/providers/edges/Edge-Straight.js +0 -24
- package/source/providers/layouts/Layout-Circular.js +0 -203
- package/source/providers/layouts/Layout-Coerce.js +0 -40
- package/source/providers/layouts/Layout-Columnar.js +0 -134
- package/source/providers/layouts/Layout-Custom.js +0 -27
- package/source/providers/layouts/Layout-ForcedFromCenter.js +0 -256
- package/source/providers/layouts/Layout-Grid.js +0 -134
- package/source/providers/layouts/Layout-Layered.js +0 -155
- package/source/providers/layouts/Layout-Rank.js +0 -141
- package/source/providers/layouts/Layout-Staggered.js +0 -131
- package/source/providers/layouts/Layout-Tabular.js +0 -94
- package/test/CardPalette_tests.js +0 -43
- package/test/ConnectionHandleManager_tests.js +0 -717
- package/test/ConnectionRenderer_tests.js +0 -591
- package/test/ConnectionStyle_tests.js +0 -90
- package/test/DataManager_tests.js +0 -859
- package/test/Geometry_tests.js +0 -767
- package/test/InteractionManager_tests.js +0 -279
- package/test/Layout_tests.js +0 -1604
- package/test/NodeView_tests.js +0 -66
- package/test/PanelManager_tests.js +0 -172
- package/test/PathGenerator_tests.js +0 -978
- package/test/PortRenderer_tests.js +0 -376
- package/test/RenderManager_tests.js +0 -756
- package/test/Renderer_tests.js +0 -133
- package/test/SelectionManager_tests.js +0 -185
- package/test/StylePresets_tests.js +0 -153
- package/test/ToolbarExtraButtons_tests.js +0 -138
- package/test/UndirectedConnections_tests.js +0 -70
|
@@ -1,677 +0,0 @@
|
|
|
1
|
-
# Simple Cards - Every Flow Card Type, Every Panel Type
|
|
2
|
-
|
|
3
|
-
<!-- docuserve:example-launch:start -->
|
|
4
|
-
> **[Launch the live app](examples/simple%5Fcards/index.html)** - runs in your browser, opens in a new tab.
|
|
5
|
-
<!-- docuserve:example-launch:end -->
|
|
6
|
-
|
|
7
|
-
Simple Cards is the **reference example** for `pict-section-flow`. It
|
|
8
|
-
defines twelve custom card classes covering every category
|
|
9
|
-
(control flow, I/O, data, debug, monitoring, visualization), wires
|
|
10
|
-
them into a single Pict application with `pict-section-form`-driven
|
|
11
|
-
properties panels, ships a curated catalog of sample flows that
|
|
12
|
-
exercise each layout algorithm, and provides a fully-functional
|
|
13
|
-
multi-page shell (Home / About / Documentation) around the canvas.
|
|
14
|
-
|
|
15
|
-
If you are looking for "what does a card class look like?" - read
|
|
16
|
-
`source/cards/`. If you are looking for "how do I host the flow
|
|
17
|
-
view inside an application?" - read
|
|
18
|
-
`source/views/PictView-FlowExample-MainWorkspace.js`. If you are
|
|
19
|
-
looking for "what does a real seed graph look like?" - see
|
|
20
|
-
`source/Pict-Application-FlowExample.js`, which inlines a 16-node
|
|
21
|
-
flow with every card type, every panel type, and an error branch.
|
|
22
|
-
|
|
23
|
-
## What it demonstrates
|
|
24
|
-
|
|
25
|
-
| Capability | Where you see it |
|
|
26
|
-
|------------|------------------|
|
|
27
|
-
| Custom `PictFlowCard` subclasses | `source/cards/FlowCard-*.js` - 12 cards across 6 categories |
|
|
28
|
-
| Properties panel type: `Markdown` | If-Then-Else card - static markdown blurb |
|
|
29
|
-
| Properties panel type: `Template` | Log Values card - `pict-template` over `Record.Data.*` |
|
|
30
|
-
| Properties panel type: `Form` | Set Value card - full `pict-section-form` manifest inside the panel |
|
|
31
|
-
| Properties panel type: `View` | File Write card - host-registered Pict view rendered into the panel |
|
|
32
|
-
| `BodyContent` rendering type: SVG | Status Monitor card - inline SVG circles + labels |
|
|
33
|
-
| `BodyContent` rendering type: HTML | Data Preview / Note cards - HTML table / multi-line text |
|
|
34
|
-
| `BodyContent` rendering type: Canvas | Sparkline card - `RenderCallback(canvas, ...)` paints a 2D chart |
|
|
35
|
-
| Pre-registered node types | `NodeTypes: this._buildFlowCardNodeTypes()` - toolbar palette ready on first render |
|
|
36
|
-
| Seed flow data on `AppData` | `AppData.FlowExample.SampleFlow` - 16 nodes, 18 connections, an error branch |
|
|
37
|
-
| Sample-graph catalog + layout algorithm hint | Dropdown above the canvas; each sample suggests a `Recommended` layout |
|
|
38
|
-
| Multi-page routing inside the shell | `pict-router` with `/Home`, `/About`, `/Documentation` routes |
|
|
39
|
-
| `LayoutAlgorithm` driven re-layout | `setFlowData(...)` carries `LayoutAlgorithm`; the toolbar's Algorithm popup compares them live |
|
|
40
|
-
| Help overlay for the canvas | "?" button toggles a CSS-grid hint panel with 8 cards covering Add / Connect / Pan etc. |
|
|
41
|
-
|
|
42
|
-
## Key files
|
|
43
|
-
|
|
44
|
-
- `source/Pict-Application-FlowExample.js` - application class.
|
|
45
|
-
Registers the router + every page view, declares the seed
|
|
46
|
-
`SampleFlow` with one of every card type, and exposes
|
|
47
|
-
`navigateTo()` / `showView()` for the router callbacks.
|
|
48
|
-
- `source/Pict-Application-FlowExample-Configuration.json` - Pict
|
|
49
|
-
config: product name, main viewport, auto-render flags.
|
|
50
|
-
- `source/providers/PictRouter-FlowExample-Configuration.json` -
|
|
51
|
-
route map. Each route's `template` calls into
|
|
52
|
-
`Pict.PictApplication.showView('FlowExample-...')`.
|
|
53
|
-
- `source/views/PictView-FlowExample-Layout.js` - top-level shell.
|
|
54
|
-
Renders the topbar, content, and bottombar containers, then
|
|
55
|
-
resolves the router so the current hash lands on the right page.
|
|
56
|
-
- `source/views/PictView-FlowExample-TopBar.js` /
|
|
57
|
-
`PictView-FlowExample-BottomBar.js` - branded chrome views with
|
|
58
|
-
inline navigation links.
|
|
59
|
-
- `source/views/PictView-FlowExample-MainWorkspace.js` - the page
|
|
60
|
-
that hosts the flow canvas. Builds the FlowCard node type map,
|
|
61
|
-
instantiates the flow view, wires the help toggle and the
|
|
62
|
-
sample-graph selector.
|
|
63
|
-
- `source/views/PictView-FlowExample-About.js` /
|
|
64
|
-
`PictView-FlowExample-Documentation.js` - the two other pages.
|
|
65
|
-
- `source/views/PictView-FlowExample-FileWriteInfo.js` - the host
|
|
66
|
-
view that the File Write card's `View`-type panel renders.
|
|
67
|
-
- `source/cards/FlowCard-*.js` - twelve card classes. Each is
|
|
68
|
-
one file, each extends `pict-section-flow.PictFlowCard`.
|
|
69
|
-
- `source/sample-flows.js` - the curated catalog of sample graphs
|
|
70
|
-
that the dropdown above the canvas exposes.
|
|
71
|
-
|
|
72
|
-
## The seed flow
|
|
73
|
-
|
|
74
|
-
`AppData.FlowExample.SampleFlow` is a complete `_FlowData` object
|
|
75
|
-
declared inline in `onAfterInitializeAsync`. It is the "Hello World"
|
|
76
|
-
the canvas opens to:
|
|
77
|
-
|
|
78
|
-
```js
|
|
79
|
-
this.pict.AppData.FlowExample.SampleFlow =
|
|
80
|
-
{
|
|
81
|
-
Nodes:
|
|
82
|
-
[
|
|
83
|
-
{ Hash: 'node-start', Type: 'start', X: 50, Y: 180, Width: 140, Height: 80, Title: 'Start',
|
|
84
|
-
Ports: [ { Hash: 'port-start-out', Direction: 'output', Side: 'right', Label: 'Out' } ], Data: {} },
|
|
85
|
-
{ Hash: 'node-fread', Type: 'FREAD', /* ... */ },
|
|
86
|
-
{ Hash: 'node-check', Type: 'ITE', /* ... */ },
|
|
87
|
-
{ Hash: 'node-each', Type: 'EACH', /* ... */ },
|
|
88
|
-
{ Hash: 'node-get', Type: 'GET', /* ... */ },
|
|
89
|
-
{ Hash: 'node-set', Type: 'SET', /* ... */ },
|
|
90
|
-
{ Hash: 'node-switch', Type: 'SW', /* ... */ },
|
|
91
|
-
{ Hash: 'node-log', Type: 'LOG', /* ... */ },
|
|
92
|
-
{ Hash: 'node-fwrite', Type: 'FWRITE', /* ... */ },
|
|
93
|
-
{ Hash: 'node-end', Type: 'end', /* ... */ },
|
|
94
|
-
/* error branch: node-log-err, node-halt */
|
|
95
|
-
/* body-content showcase: node-status, node-preview, node-spark, node-comment */
|
|
96
|
-
],
|
|
97
|
-
Connections: [ /* 18 edges including an error branch */ ],
|
|
98
|
-
ViewState: { PanX: 0, PanY: 0, Zoom: 1, SelectedNodeHash: null, SelectedConnectionHash: null }
|
|
99
|
-
};
|
|
100
|
-
```
|
|
101
|
-
|
|
102
|
-
Every node references a card type by its `Code` (`FREAD`, `ITE`,
|
|
103
|
-
etc.); the host registers the card classes in the workspace view so
|
|
104
|
-
the flow view's `NodeTypeProvider` knows how to paint them.
|
|
105
|
-
|
|
106
|
-
---
|
|
107
|
-
|
|
108
|
-
## Feature 1 - Defining a custom card class
|
|
109
|
-
|
|
110
|
-
A custom card is a `PictFlowCard` subclass. The constructor passes
|
|
111
|
-
its declarative configuration into the parent class - title,
|
|
112
|
-
description, ports, sizing, colors, optional panel, optional body
|
|
113
|
-
content. Here is the If-Then-Else card in full:
|
|
114
|
-
|
|
115
|
-
```js
|
|
116
|
-
const libPictFlowCard = require('pict-section-flow').PictFlowCard;
|
|
117
|
-
const libCardHelp = require('../card-help-content');
|
|
118
|
-
|
|
119
|
-
class FlowCardIfThenElse extends libPictFlowCard
|
|
120
|
-
{
|
|
121
|
-
constructor(pFable, pOptions, pServiceHash)
|
|
122
|
-
{
|
|
123
|
-
super(pFable, Object.assign(
|
|
124
|
-
{},
|
|
125
|
-
{
|
|
126
|
-
Title: 'If-Then-Else',
|
|
127
|
-
Name: 'Conditional Branch',
|
|
128
|
-
Code: 'ITE',
|
|
129
|
-
Description: 'Evaluates a condition and routes to the Then or Else branch.',
|
|
130
|
-
Help: libCardHelp['ITE'] || false,
|
|
131
|
-
Icon: 'ITE',
|
|
132
|
-
Tooltip: 'If-Then-Else: Routes flow based on a boolean condition',
|
|
133
|
-
Category: 'Control Flow',
|
|
134
|
-
TitleBarColor: '#e67e22',
|
|
135
|
-
BodyStyle: { fill: '#fef5e7', stroke: '#e67e22' },
|
|
136
|
-
Width: 200,
|
|
137
|
-
Height: 100,
|
|
138
|
-
Inputs: [ { Name: 'In', Side: 'left', MinimumInputCount: 1, MaximumInputCount: 1 } ],
|
|
139
|
-
Outputs: [ { Name: 'Then', Side: 'right' }, { Name: 'Else', Side: 'bottom' } ],
|
|
140
|
-
PropertiesPanel:
|
|
141
|
-
{
|
|
142
|
-
PanelType: 'Markdown',
|
|
143
|
-
DefaultWidth: 300,
|
|
144
|
-
DefaultHeight: 200,
|
|
145
|
-
Title: 'If-Then-Else Info',
|
|
146
|
-
Configuration: { Markdown: '## Conditional Branch\n\nEvaluates a **boolean condition**...' }
|
|
147
|
-
}
|
|
148
|
-
},
|
|
149
|
-
pOptions),
|
|
150
|
-
pServiceHash);
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
module.exports = FlowCardIfThenElse;
|
|
155
|
-
```
|
|
156
|
-
|
|
157
|
-
`Code` is the wire-shape identifier - what each node in the flow
|
|
158
|
-
data carries as its `Type`. `Category` groups the card in the
|
|
159
|
-
toolbar palette. `Inputs` and `Outputs` declare port slots with
|
|
160
|
-
their side (top/right/bottom/left) and cardinality
|
|
161
|
-
(`MinimumInputCount` / `MaximumInputCount`; `-1` means unbounded).
|
|
162
|
-
The `Help` block (lazy-loaded from `card-help-content.js`) is the
|
|
163
|
-
content for the per-card help drawer.
|
|
164
|
-
|
|
165
|
-
This is the entire card. Twelve such files cover the example.
|
|
166
|
-
|
|
167
|
-
---
|
|
168
|
-
|
|
169
|
-
## Feature 2 - Pre-registered node types
|
|
170
|
-
|
|
171
|
-
The host workspace view builds a `NodeTypes` map by instantiating
|
|
172
|
-
each card class once, calling its `getNodeTypeConfiguration()`, and
|
|
173
|
-
keying the resulting config by its `Hash`. The map is then handed
|
|
174
|
-
to the flow view at registration time:
|
|
175
|
-
|
|
176
|
-
```js
|
|
177
|
-
_buildFlowCardNodeTypes()
|
|
178
|
-
{
|
|
179
|
-
let tmpCardClasses =
|
|
180
|
-
[
|
|
181
|
-
libFlowCardIfThenElse, libFlowCardSwitch, libFlowCardEach,
|
|
182
|
-
libFlowCardFileRead, libFlowCardFileWrite,
|
|
183
|
-
libFlowCardLogValues, libFlowCardSetValue, libFlowCardGetValue,
|
|
184
|
-
libFlowCardStatusMonitor, libFlowCardDataPreview,
|
|
185
|
-
libFlowCardSparkline, libFlowCardComment
|
|
186
|
-
];
|
|
187
|
-
|
|
188
|
-
let tmpNodeTypes = {};
|
|
189
|
-
for (let i = 0; i < tmpCardClasses.length; i++)
|
|
190
|
-
{
|
|
191
|
-
let tmpCard = new tmpCardClasses[i](this.fable, {}, `FlowCard-${i}`);
|
|
192
|
-
let tmpConfig = tmpCard.getNodeTypeConfiguration();
|
|
193
|
-
tmpNodeTypes[tmpConfig.Hash] = tmpConfig;
|
|
194
|
-
}
|
|
195
|
-
return tmpNodeTypes;
|
|
196
|
-
}
|
|
197
|
-
```
|
|
198
|
-
|
|
199
|
-
The flow view receives `NodeTypes` as part of its options, which
|
|
200
|
-
means the `NodeTypeProvider` is fully populated **before the
|
|
201
|
-
toolbar renders**. Without pre-registration, the toolbar palette
|
|
202
|
-
would show an empty list on first paint and fill in only after a
|
|
203
|
-
later `registerNodeType(...)` call - visible flicker, no benefit.
|
|
204
|
-
|
|
205
|
-
```js
|
|
206
|
-
this._FlowView = this.pict.addView('FlowExample-FlowDiagram',
|
|
207
|
-
{
|
|
208
|
-
ViewIdentifier: 'FlowExample-FlowDiagram',
|
|
209
|
-
FlowDataAddress: 'AppData.FlowExample.SampleFlow',
|
|
210
|
-
TargetElementAddress: '#Flow-SVG-Container',
|
|
211
|
-
EnableToolbar: true, EnablePanning: true, EnableZooming: true,
|
|
212
|
-
EnableNodeDragging: true, EnableConnectionCreation: true,
|
|
213
|
-
EnableGridSnap: false, GridSnapSize: 20,
|
|
214
|
-
MinZoom: 0.1, MaxZoom: 5.0, ZoomStep: 0.1,
|
|
215
|
-
DefaultNodeType: 'default', DefaultNodeWidth: 180, DefaultNodeHeight: 80,
|
|
216
|
-
NodeTypes: this._buildFlowCardNodeTypes(),
|
|
217
|
-
/* Renderables ... */
|
|
218
|
-
},
|
|
219
|
-
libPictSectionFlow
|
|
220
|
-
);
|
|
221
|
-
```
|
|
222
|
-
|
|
223
|
-
`FlowDataAddress` points at the AppData slot the seed flow lives
|
|
224
|
-
in; the flow view two-way binds against it. Mutations from the
|
|
225
|
-
canvas (drag a node, draw a connection, delete an edge) write
|
|
226
|
-
back; mutations from the host (`setFlowData(...)`) re-render.
|
|
227
|
-
|
|
228
|
-
---
|
|
229
|
-
|
|
230
|
-
## Feature 3 - Properties panel types: Markdown, Template, Form, View
|
|
231
|
-
|
|
232
|
-
The four built-in `PropertiesPanel.PanelType` values cover most of
|
|
233
|
-
what a node-editing UI needs. The example demonstrates one of
|
|
234
|
-
each:
|
|
235
|
-
|
|
236
|
-
**Markdown** (If-Then-Else card):
|
|
237
|
-
|
|
238
|
-
```js
|
|
239
|
-
PropertiesPanel:
|
|
240
|
-
{
|
|
241
|
-
PanelType: 'Markdown',
|
|
242
|
-
DefaultWidth: 300, DefaultHeight: 200,
|
|
243
|
-
Title: 'If-Then-Else Info',
|
|
244
|
-
Configuration: { Markdown: '## Conditional Branch\n\nEvaluates a **boolean condition**...' }
|
|
245
|
-
}
|
|
246
|
-
```
|
|
247
|
-
|
|
248
|
-
Static documentation with markdown rendering. No data binding;
|
|
249
|
-
read-only.
|
|
250
|
-
|
|
251
|
-
**Template** (Log Values card):
|
|
252
|
-
|
|
253
|
-
```js
|
|
254
|
-
PropertiesPanel:
|
|
255
|
-
{
|
|
256
|
-
PanelType: 'Template',
|
|
257
|
-
DefaultWidth: 260, DefaultHeight: 140,
|
|
258
|
-
Title: 'Log Settings',
|
|
259
|
-
Configuration:
|
|
260
|
-
{
|
|
261
|
-
Templates:
|
|
262
|
-
[
|
|
263
|
-
{
|
|
264
|
-
Hash: 'flow-card-log-panel',
|
|
265
|
-
Template: '<div style="padding:4px"><label style="font-size:11px;color:#7f8c8d">Log Level</label>' +
|
|
266
|
-
'<div style="font-size:12px;padding:4px 0">{~D:Record.Data.LogLevel~}</div>' +
|
|
267
|
-
'<label style="font-size:11px;color:#7f8c8d">Format</label>' +
|
|
268
|
-
'<div style="font-size:12px;padding:4px 0">{~D:Record.Data.Format~}</div></div>'
|
|
269
|
-
}
|
|
270
|
-
],
|
|
271
|
-
TemplateHash: 'flow-card-log-panel'
|
|
272
|
-
}
|
|
273
|
-
}
|
|
274
|
-
```
|
|
275
|
-
|
|
276
|
-
`pict-template` syntax - `{~D:Record.Data.LogLevel~}` resolves
|
|
277
|
-
against the node's `Data` block. Read-only viewer surfaced from a
|
|
278
|
-
template hash; ideal for showing computed or formatted state.
|
|
279
|
-
|
|
280
|
-
**Form** (Set Value card):
|
|
281
|
-
|
|
282
|
-
```js
|
|
283
|
-
PropertiesPanel:
|
|
284
|
-
{
|
|
285
|
-
PanelType: 'Form',
|
|
286
|
-
DefaultWidth: 320, DefaultHeight: 200,
|
|
287
|
-
Title: 'Set Value Properties',
|
|
288
|
-
Configuration:
|
|
289
|
-
{
|
|
290
|
-
Manifest:
|
|
291
|
-
{
|
|
292
|
-
Scope: 'FlowCardSetValue',
|
|
293
|
-
Sections: [ { Name: 'Value Assignment', Hash: 'SetValueSection',
|
|
294
|
-
Groups: [ { Name: 'Settings', Hash: 'SetValueGroup' } ] } ],
|
|
295
|
-
Descriptors:
|
|
296
|
-
{
|
|
297
|
-
'Record.Data.VariableName':
|
|
298
|
-
{
|
|
299
|
-
Name: 'Variable Name', Hash: 'VariableName', DataType: 'String', Default: '',
|
|
300
|
-
PictForm: { Section: 'SetValueSection', Group: 'SetValueGroup', Row: 1, Width: 12 }
|
|
301
|
-
},
|
|
302
|
-
'Record.Data.Expression':
|
|
303
|
-
{
|
|
304
|
-
Name: 'Value Expression', Hash: 'Expression', DataType: 'String', Default: '',
|
|
305
|
-
PictForm: { Section: 'SetValueSection', Group: 'SetValueGroup',
|
|
306
|
-
Row: 2, Width: 12, InputType: 'TextArea' }
|
|
307
|
-
}
|
|
308
|
-
}
|
|
309
|
-
}
|
|
310
|
-
}
|
|
311
|
-
}
|
|
312
|
-
```
|
|
313
|
-
|
|
314
|
-
A full `pict-section-form` manifest. The panel renders a live form;
|
|
315
|
-
edits flow back into the node's `Data` block; the next save snapshots
|
|
316
|
-
them. The Set Value card's `VariableName` and `Expression` fields
|
|
317
|
-
are what a flow engine would later read at evaluation time.
|
|
318
|
-
|
|
319
|
-
**View** (File Write card):
|
|
320
|
-
|
|
321
|
-
```js
|
|
322
|
-
PropertiesPanel:
|
|
323
|
-
{
|
|
324
|
-
PanelType: 'View',
|
|
325
|
-
DefaultWidth: 260, DefaultHeight: 180,
|
|
326
|
-
Title: 'File Write Info',
|
|
327
|
-
Configuration: { ViewHash: 'FlowExample-FileWriteInfo' }
|
|
328
|
-
}
|
|
329
|
-
```
|
|
330
|
-
|
|
331
|
-
The application registers `FlowExample-FileWriteInfo` as a Pict
|
|
332
|
-
view (any host-defined view), and the panel renders it. This is the
|
|
333
|
-
escape hatch for "I need something none of the built-in panels
|
|
334
|
-
cover" - a third-party widget, a custom editor, an embedded
|
|
335
|
-
preview.
|
|
336
|
-
|
|
337
|
-
The four types cover the gradient from "static" (Markdown) ->
|
|
338
|
-
"templated read-only" (Template) -> "structured editing" (Form) ->
|
|
339
|
-
"anything you can build" (View).
|
|
340
|
-
|
|
341
|
-
---
|
|
342
|
-
|
|
343
|
-
## Feature 4 - BodyContent: SVG / HTML / Canvas
|
|
344
|
-
|
|
345
|
-
Every card has an optional `BodyContent` block that paints inside
|
|
346
|
-
the node's body (between the title bar and the port row). Three
|
|
347
|
-
content types cover the spectrum from static vector art to live
|
|
348
|
-
rendered visualizations:
|
|
349
|
-
|
|
350
|
-
**SVG** - declarative shapes inline in the node:
|
|
351
|
-
|
|
352
|
-
```js
|
|
353
|
-
// FlowCard-StatusMonitor.js
|
|
354
|
-
BodyContent:
|
|
355
|
-
{
|
|
356
|
-
ContentType: 'svg',
|
|
357
|
-
Template: '<circle cx="30" cy="28" r="6" fill="#27ae60" opacity="0.9"/>' +
|
|
358
|
-
'<text x="42" y="32" font-size="9" fill="#2c3e50">API</text>' +
|
|
359
|
-
'<circle cx="100" cy="28" r="6" fill="#27ae60" opacity="0.9"/>' +
|
|
360
|
-
'<text x="112" y="32" font-size="9" fill="#2c3e50">DB</text>' +
|
|
361
|
-
/* ... */
|
|
362
|
-
}
|
|
363
|
-
```
|
|
364
|
-
|
|
365
|
-
The SVG template is interpolated into the node's `<svg>` group, so
|
|
366
|
-
every primitive coordinate is in the node's local space (`0,0` is
|
|
367
|
-
the body top-left). Use this for status indicators, mini-icons,
|
|
368
|
-
glyphs.
|
|
369
|
-
|
|
370
|
-
**HTML** - `foreignObject`-wrapped markup for rich text and tables:
|
|
371
|
-
|
|
372
|
-
```js
|
|
373
|
-
// FlowCard-DataPreview.js
|
|
374
|
-
BodyContent:
|
|
375
|
-
{
|
|
376
|
-
ContentType: 'html',
|
|
377
|
-
Template:
|
|
378
|
-
'<table style="width:100%;border-collapse:collapse;font-size:9px;color:#2c3e50">' +
|
|
379
|
-
'<tr style="background:#d6eaf8">' +
|
|
380
|
-
'<td style="padding:3px 5px;font-weight:600">Field</td>' +
|
|
381
|
-
'<td style="padding:3px 5px;font-weight:600">Type</td>' +
|
|
382
|
-
'<td style="padding:3px 5px;font-weight:600">Value</td>' +
|
|
383
|
-
'</tr>' +
|
|
384
|
-
/* ... */
|
|
385
|
-
'</table>'
|
|
386
|
-
}
|
|
387
|
-
```
|
|
388
|
-
|
|
389
|
-
The HTML is wrapped in an SVG `<foreignObject>` and sized to the
|
|
390
|
-
node body. Use it for the things SVG `<text>` can't do - tables,
|
|
391
|
-
multi-line wrapping, real CSS.
|
|
392
|
-
|
|
393
|
-
**Canvas** - programmatic drawing via a render callback:
|
|
394
|
-
|
|
395
|
-
```js
|
|
396
|
-
// FlowCard-Sparkline.js
|
|
397
|
-
BodyContent:
|
|
398
|
-
{
|
|
399
|
-
ContentType: 'canvas',
|
|
400
|
-
RenderCallback: function (pCanvas, pNodeData, pNodeTypeConfig, pBounds)
|
|
401
|
-
{
|
|
402
|
-
let tmpCtx = pCanvas.getContext('2d');
|
|
403
|
-
if (!tmpCtx) return;
|
|
404
|
-
|
|
405
|
-
let tmpData = [12, 19, 8, 25, 15, 30, 22, 18, 35, 28, 14, 32, 20, 26, 10, 24, 33, 17, 29, 21];
|
|
406
|
-
let tmpMax = Math.max.apply(null, tmpData);
|
|
407
|
-
let tmpMin = Math.min.apply(null, tmpData);
|
|
408
|
-
let tmpRange = tmpMax - tmpMin || 1;
|
|
409
|
-
let tmpPadding = 6;
|
|
410
|
-
let tmpChartW = pCanvas.width - (tmpPadding * 2);
|
|
411
|
-
let tmpChartH = pCanvas.height - (tmpPadding * 2);
|
|
412
|
-
let tmpStep = tmpChartW / (tmpData.length - 1);
|
|
413
|
-
|
|
414
|
-
// Fill the area beneath the line ...
|
|
415
|
-
tmpCtx.beginPath();
|
|
416
|
-
tmpCtx.moveTo(tmpPadding, pCanvas.height - tmpPadding);
|
|
417
|
-
for (let i = 0; i < tmpData.length; i++)
|
|
418
|
-
{
|
|
419
|
-
let tmpX = tmpPadding + (i * tmpStep);
|
|
420
|
-
let tmpY = tmpPadding + tmpChartH - ((tmpData[i] - tmpMin) / tmpRange) * tmpChartH;
|
|
421
|
-
tmpCtx.lineTo(tmpX, tmpY);
|
|
422
|
-
}
|
|
423
|
-
/* ... draw line, end dot ... */
|
|
424
|
-
}
|
|
425
|
-
}
|
|
426
|
-
```
|
|
427
|
-
|
|
428
|
-
The framework calls `RenderCallback` with a sized `<canvas>` element
|
|
429
|
-
and the node's own data, so the chart redraws on every re-render
|
|
430
|
-
(node drag, zoom change, theme switch). Use this for charts,
|
|
431
|
-
visualizations of data the node carries, any non-trivial 2D rendering.
|
|
432
|
-
|
|
433
|
-
---
|
|
434
|
-
|
|
435
|
-
## Feature 5 - Host shell + multi-page routing
|
|
436
|
-
|
|
437
|
-
The application has three top-level pages - Home (the canvas),
|
|
438
|
-
About, and Documentation - wired through `pict-router`. The route
|
|
439
|
-
configuration JSON lives next to the application:
|
|
440
|
-
|
|
441
|
-
```json
|
|
442
|
-
{
|
|
443
|
-
"ProviderIdentifier": "Pict-Router",
|
|
444
|
-
"AutoInitialize": true,
|
|
445
|
-
"AutoInitializeOrdinal": 0,
|
|
446
|
-
"Routes":
|
|
447
|
-
[
|
|
448
|
-
{ "path": "/Home", "template": "{~LV:Pict.PictApplication.showView(`FlowExample-MainWorkspace`)~}" },
|
|
449
|
-
{ "path": "/About", "template": "{~LV:Pict.PictApplication.showView(`FlowExample-About`)~}" },
|
|
450
|
-
{ "path": "/Documentation", "template": "{~LV:Pict.PictApplication.showView(`FlowExample-Documentation`)~}" }
|
|
451
|
-
]
|
|
452
|
-
}
|
|
453
|
-
```
|
|
454
|
-
|
|
455
|
-
The `{~LV:...~}` is the live-value template tag - it evaluates
|
|
456
|
-
the expression every time the route matches, calling the
|
|
457
|
-
application's `showView(viewIdentifier)` method. That method
|
|
458
|
-
swaps the content container's view in place:
|
|
459
|
-
|
|
460
|
-
```js
|
|
461
|
-
showView(pViewIdentifier)
|
|
462
|
-
{
|
|
463
|
-
if (pViewIdentifier in this.pict.views)
|
|
464
|
-
{
|
|
465
|
-
this.pict.AppData.FlowExample.CurrentRoute = pViewIdentifier;
|
|
466
|
-
this.pict.views[pViewIdentifier].render();
|
|
467
|
-
}
|
|
468
|
-
else
|
|
469
|
-
{
|
|
470
|
-
this.pict.log.warn(`View [${pViewIdentifier}] not found; falling back to main workspace.`);
|
|
471
|
-
this.pict.views['FlowExample-MainWorkspace'].render();
|
|
472
|
-
}
|
|
473
|
-
}
|
|
474
|
-
```
|
|
475
|
-
|
|
476
|
-
The topbar and bottombar are siblings of the content container in
|
|
477
|
-
the layout shell - they don't re-render on route change. The
|
|
478
|
-
brand link calls `Pict.PictApplication.navigateTo('/Home')`, which
|
|
479
|
-
in turn calls the router's `navigate(...)`; the router fires the
|
|
480
|
-
template; the host calls `showView(...)`. Same path as a direct hash
|
|
481
|
-
URL - `#/Documentation` works the same way.
|
|
482
|
-
|
|
483
|
-
The flow view re-initializes its SVG primitives whenever the
|
|
484
|
-
workspace re-renders, so navigating away to About and back to Home
|
|
485
|
-
gets a fresh canvas:
|
|
486
|
-
|
|
487
|
-
```js
|
|
488
|
-
// In MainWorkspace's onAfterRender:
|
|
489
|
-
this._FlowView.initialRenderComplete = false;
|
|
490
|
-
this._FlowView.render();
|
|
491
|
-
```
|
|
492
|
-
|
|
493
|
-
---
|
|
494
|
-
|
|
495
|
-
## Feature 6 - Sample-graph catalog with layout-algorithm hints
|
|
496
|
-
|
|
497
|
-
The dropdown above the canvas surfaces a curated set of graphs
|
|
498
|
-
shaped to exercise the flow view's seven layout algorithms (the
|
|
499
|
-
"Hello World" reference, linear chains, fan-outs, grids, etc.).
|
|
500
|
-
Each catalog entry declares a `Name`, `Description`, optional
|
|
501
|
-
`Recommended` layout, and a complete `_FlowData` object:
|
|
502
|
-
|
|
503
|
-
```js
|
|
504
|
-
// sample-flows.js
|
|
505
|
-
function _flow(pNodes, pConnections, pAlgorithm, pParameters, pAutoApply)
|
|
506
|
-
{
|
|
507
|
-
return {
|
|
508
|
-
Nodes: pNodes,
|
|
509
|
-
Connections: pConnections || [],
|
|
510
|
-
OpenPanels: [],
|
|
511
|
-
SavedLayouts: [],
|
|
512
|
-
ViewState: _emptyViewState(),
|
|
513
|
-
LayoutAlgorithm: pAlgorithm || 'Custom',
|
|
514
|
-
LayoutParameters: pParameters || {},
|
|
515
|
-
LayoutAutoApply: !!pAutoApply
|
|
516
|
-
};
|
|
517
|
-
}
|
|
518
|
-
```
|
|
519
|
-
|
|
520
|
-
The workspace view's `_loadSample` callback deep-clones the sample
|
|
521
|
-
flow (so reloading does not share references with the prior load)
|
|
522
|
-
and pushes it through `setFlowData(...)`:
|
|
523
|
-
|
|
524
|
-
```js
|
|
525
|
-
_loadSample(pKey, pDescEl, pRecoEl)
|
|
526
|
-
{
|
|
527
|
-
if (!this._FlowView) return;
|
|
528
|
-
|
|
529
|
-
if (pKey === '__hello-world__')
|
|
530
|
-
{
|
|
531
|
-
this._FlowView.setFlowData(this.pict.AppData.FlowExample.SampleFlow);
|
|
532
|
-
pDescEl.innerHTML = 'The full reference flow with all card types, properties panels, and an error branch.' +
|
|
533
|
-
' Originally designed by hand - set <code>LayoutAlgorithm</code> to <em>Layered</em>' +
|
|
534
|
-
' to see how the auto-layout compares.';
|
|
535
|
-
pRecoEl.style.display = 'none';
|
|
536
|
-
return;
|
|
537
|
-
}
|
|
538
|
-
|
|
539
|
-
let tmpSample = libSampleFlows.getSample(pKey);
|
|
540
|
-
if (!tmpSample) return;
|
|
541
|
-
|
|
542
|
-
this._FlowView.setFlowData(JSON.parse(JSON.stringify(tmpSample.Flow)));
|
|
543
|
-
pDescEl.textContent = tmpSample.Description;
|
|
544
|
-
if (tmpSample.Recommended)
|
|
545
|
-
{
|
|
546
|
-
pRecoEl.style.display = '';
|
|
547
|
-
pRecoEl.textContent = `Try: ${tmpSample.Recommended}`;
|
|
548
|
-
}
|
|
549
|
-
else
|
|
550
|
-
{
|
|
551
|
-
pRecoEl.style.display = 'none';
|
|
552
|
-
}
|
|
553
|
-
}
|
|
554
|
-
```
|
|
555
|
-
|
|
556
|
-
Picking a sample swaps the canvas instantly. Opening the toolbar's
|
|
557
|
-
Algorithm popup lets you flip between layouts and watch the same
|
|
558
|
-
graph re-arrange - which is the whole point of the catalog. Some
|
|
559
|
-
shapes shine under Layered; some under Force-Directed; the
|
|
560
|
-
`Recommended` hint is the curator's pick.
|
|
561
|
-
|
|
562
|
-
---
|
|
563
|
-
|
|
564
|
-
## Feature 7 - Help overlay rendered from a CSS grid
|
|
565
|
-
|
|
566
|
-
The "?" button in the workspace header toggles a hint panel built
|
|
567
|
-
as a CSS grid. The panel itself is part of the workspace template;
|
|
568
|
-
the toggle simply adds/removes a `visible` class:
|
|
569
|
-
|
|
570
|
-
```js
|
|
571
|
-
let tmpHelpToggle = document.getElementById('FlowExample-HelpToggle');
|
|
572
|
-
let tmpHelpPanel = document.getElementById('FlowExample-HelpPanel');
|
|
573
|
-
if (tmpHelpToggle && tmpHelpPanel)
|
|
574
|
-
{
|
|
575
|
-
tmpHelpToggle.addEventListener('click', function ()
|
|
576
|
-
{
|
|
577
|
-
tmpHelpPanel.classList.toggle('visible');
|
|
578
|
-
tmpHelpToggle.classList.toggle('active');
|
|
579
|
-
});
|
|
580
|
-
}
|
|
581
|
-
```
|
|
582
|
-
|
|
583
|
-
The eight hints - Add / Connect / Move / Pan & Zoom / Delete /
|
|
584
|
-
Auto Layout / Properties / Save Layouts - are static `<div>`s in
|
|
585
|
-
the workspace template, each with a heading and short description:
|
|
586
|
-
|
|
587
|
-
```html
|
|
588
|
-
<div class="flowexample-hints">
|
|
589
|
-
<div class="flowexample-hint">
|
|
590
|
-
<h4>Add Nodes</h4>
|
|
591
|
-
<p>Select a node type from the dropdown and click <code>+ Add Node</code> in the toolbar.</p>
|
|
592
|
-
</div>
|
|
593
|
-
<div class="flowexample-hint">
|
|
594
|
-
<h4>Connect Nodes</h4>
|
|
595
|
-
<p>Drag from a green output port to a blue input port to create a connection.</p>
|
|
596
|
-
</div>
|
|
597
|
-
/* ... six more ... */
|
|
598
|
-
</div>
|
|
599
|
-
```
|
|
600
|
-
|
|
601
|
-
`grid-template-columns: repeat(auto-fill, minmax(220px, 1fr))` makes
|
|
602
|
-
the grid reflow without media queries - the hints arrange themselves
|
|
603
|
-
across whatever width the viewport gives them.
|
|
604
|
-
|
|
605
|
-
---
|
|
606
|
-
|
|
607
|
-
## Running the example
|
|
608
|
-
|
|
609
|
-
```bash
|
|
610
|
-
cd example_applications/simple_cards
|
|
611
|
-
npm install
|
|
612
|
-
npm run build
|
|
613
|
-
# serve ./dist/ over HTTP (e.g. `cd dist && python3 -m http.server 8000`)
|
|
614
|
-
```
|
|
615
|
-
|
|
616
|
-
The `prebuild` script generates `card-help/*.md` documentation
|
|
617
|
-
from the card sources into `docs/card-help/`. The build itself is
|
|
618
|
-
`npx quack build && npx quack copy` - emits the application
|
|
619
|
-
bundle and copies the html/css/pict assets into `dist/`.
|
|
620
|
-
|
|
621
|
-
## Things to try in the running app
|
|
622
|
-
|
|
623
|
-
- **Drop in the Hello World flow** - the canvas opens to it. Pan
|
|
624
|
-
around; every card type is on the page.
|
|
625
|
-
- **Open a properties panel** - double-click the Set Value node
|
|
626
|
-
for the Form panel; the Log Values node for the Template panel;
|
|
627
|
-
the If-Then-Else node for the Markdown panel; the File Write
|
|
628
|
-
node for the View panel.
|
|
629
|
-
- **Switch sample graphs** - pick "Linear Chain" or "Fan-Out". The
|
|
630
|
-
canvas swaps to the new shape. Open the toolbar's Algorithm
|
|
631
|
-
popup and try `Layered` vs `Force-Directed`.
|
|
632
|
-
- **Toggle the help overlay** - click the `?` button in the header.
|
|
633
|
-
The eight hint cards appear in a responsive grid.
|
|
634
|
-
- **Navigate** - click `About` in the topbar, then back to `Home`.
|
|
635
|
-
The flow re-renders cleanly; the topbar/bottombar stay put.
|
|
636
|
-
- **Inspect the BodyContent showcase** - at the bottom-left of the
|
|
637
|
-
Hello World graph are four cards: Status Monitor (SVG circles),
|
|
638
|
-
Data Preview (HTML table), Throughput (canvas-rendered sparkline),
|
|
639
|
-
Note (HTML text). Each demonstrates one rendering type.
|
|
640
|
-
|
|
641
|
-
## Takeaways
|
|
642
|
-
|
|
643
|
-
1. **A card is one file, ~30 lines.** Twelve cards, twelve files,
|
|
644
|
-
twelve constructors that hand declarative config to
|
|
645
|
-
`PictFlowCard`. No inheritance trees, no template files.
|
|
646
|
-
2. **Pre-register node types via `NodeTypes` in the view options.**
|
|
647
|
-
The toolbar palette is alive before its first paint, no
|
|
648
|
-
subsequent `registerNodeType` flicker.
|
|
649
|
-
3. **Pick your panel type by what you want to bind.** Markdown for
|
|
650
|
-
docs, Template for read-only display, Form for structured
|
|
651
|
-
editing, View for everything else. They share the same panel
|
|
652
|
-
chrome and tether-line behavior.
|
|
653
|
-
4. **`BodyContent` is per-card.** SVG for icons, HTML for tables,
|
|
654
|
-
Canvas for charts. The framework wires it; the card declares
|
|
655
|
-
it.
|
|
656
|
-
5. **The sample-graph catalog is the layout algorithm's test
|
|
657
|
-
harness.** Each sample is a shape; the dropdown swaps shapes;
|
|
658
|
-
the Algorithm popup swaps layouts. That is how you discover
|
|
659
|
-
which layout fits which kind of graph.
|
|
660
|
-
|
|
661
|
-
## Related documentation
|
|
662
|
-
|
|
663
|
-
- [Getting Started](../../Getting_Started.md) - minimum-viable flow
|
|
664
|
-
view; build the first card from scratch.
|
|
665
|
-
- [Architecture](../../Architecture.md) - service / provider /
|
|
666
|
-
view layering of the section.
|
|
667
|
-
- [Implementation Reference](../../Implementation_Reference.md) -
|
|
668
|
-
full API surface.
|
|
669
|
-
- [Data Model](../../Data_Model.md) - the `_FlowData` shape used
|
|
670
|
-
by the seed flow and the sample catalog.
|
|
671
|
-
- [PictFlowCard](../../api/PictFlowCard.md) - the card base class.
|
|
672
|
-
- [PictFlowCardPropertiesPanel](../../api/PictFlowCardPropertiesPanel.md)
|
|
673
|
-
- the panel base class extending to custom panel types.
|
|
674
|
-
- [registerNodeType](../../api/registerNodeType.md) - the
|
|
675
|
-
alternative to passing `NodeTypes` at construction time.
|
|
676
|
-
- [setTheme / registerTheme](../../api/setTheme.md) - the theming
|
|
677
|
-
surface every card respects.
|