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,214 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
/**
|
|
3
|
-
* generate-card-help.js
|
|
4
|
-
*
|
|
5
|
-
* Reads markdown files from docs/card-help/ and generates a CommonJS module
|
|
6
|
-
* that exports an object mapping card codes to rendered HTML strings.
|
|
7
|
-
*
|
|
8
|
-
* Each markdown file is named by its card code (e.g. ITE.md, SET.md).
|
|
9
|
-
* The file content is converted from markdown to HTML and embedded as a
|
|
10
|
-
* string in the generated module.
|
|
11
|
-
*
|
|
12
|
-
* Usage:
|
|
13
|
-
* node scripts/generate-card-help.js [source_dir] [output_file]
|
|
14
|
-
*
|
|
15
|
-
* Defaults:
|
|
16
|
-
* source_dir = docs/card-help
|
|
17
|
-
* output_file = example_applications/simple_cards/source/card-help-content.js
|
|
18
|
-
*
|
|
19
|
-
* If the source directory does not exist or contains no markdown files the
|
|
20
|
-
* script writes an empty map and exits cleanly — the build never fails due
|
|
21
|
-
* to missing documentation.
|
|
22
|
-
*/
|
|
23
|
-
|
|
24
|
-
const libFS = require('fs');
|
|
25
|
-
const libPath = require('path');
|
|
26
|
-
|
|
27
|
-
// ---------------------------------------------------------------------------
|
|
28
|
-
// Minimal markdown-to-HTML converter
|
|
29
|
-
// ---------------------------------------------------------------------------
|
|
30
|
-
// Handles the subset of markdown used in card help documentation:
|
|
31
|
-
// headings (#, ##, ###), bold (**), italic (*), inline code (`),
|
|
32
|
-
// unordered lists (- or *), ordered lists (1.), paragraphs, line breaks,
|
|
33
|
-
// and horizontal rules (---).
|
|
34
|
-
// ---------------------------------------------------------------------------
|
|
35
|
-
|
|
36
|
-
function convertMarkdownToHTML(pMarkdown)
|
|
37
|
-
{
|
|
38
|
-
let tmpLines = pMarkdown.split('\n');
|
|
39
|
-
let tmpHTML = [];
|
|
40
|
-
let tmpInList = false;
|
|
41
|
-
let tmpListType = '';
|
|
42
|
-
let tmpParagraph = [];
|
|
43
|
-
|
|
44
|
-
function flushParagraph()
|
|
45
|
-
{
|
|
46
|
-
if (tmpParagraph.length > 0)
|
|
47
|
-
{
|
|
48
|
-
tmpHTML.push('<p>' + tmpParagraph.join(' ') + '</p>');
|
|
49
|
-
tmpParagraph = [];
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
function closeList()
|
|
54
|
-
{
|
|
55
|
-
if (tmpInList)
|
|
56
|
-
{
|
|
57
|
-
tmpHTML.push(tmpListType === 'ul' ? '</ul>' : '</ol>');
|
|
58
|
-
tmpInList = false;
|
|
59
|
-
tmpListType = '';
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
function inlineFormat(pText)
|
|
64
|
-
{
|
|
65
|
-
// Inline code
|
|
66
|
-
pText = pText.replace(/`([^`]+)`/g, '<code>$1</code>');
|
|
67
|
-
// Bold (** or __)
|
|
68
|
-
pText = pText.replace(/\*\*([^*]+)\*\*/g, '<b>$1</b>');
|
|
69
|
-
pText = pText.replace(/__([^_]+)__/g, '<b>$1</b>');
|
|
70
|
-
// Italic (* or _)
|
|
71
|
-
pText = pText.replace(/\*([^*]+)\*/g, '<i>$1</i>');
|
|
72
|
-
pText = pText.replace(/(?<!\w)_([^_]+)_(?!\w)/g, '<i>$1</i>');
|
|
73
|
-
// Links
|
|
74
|
-
pText = pText.replace(/\[([^\]]+)\]\(([^)]+)\)/g, '<a href="$2">$1</a>');
|
|
75
|
-
return pText;
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
for (let i = 0; i < tmpLines.length; i++)
|
|
79
|
-
{
|
|
80
|
-
let tmpLine = tmpLines[i];
|
|
81
|
-
let tmpTrimmed = tmpLine.trim();
|
|
82
|
-
|
|
83
|
-
// Empty line — flush paragraph
|
|
84
|
-
if (tmpTrimmed === '')
|
|
85
|
-
{
|
|
86
|
-
flushParagraph();
|
|
87
|
-
continue;
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
// Horizontal rule
|
|
91
|
-
if (/^-{3,}$/.test(tmpTrimmed) || /^\*{3,}$/.test(tmpTrimmed))
|
|
92
|
-
{
|
|
93
|
-
flushParagraph();
|
|
94
|
-
closeList();
|
|
95
|
-
tmpHTML.push('<hr>');
|
|
96
|
-
continue;
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
// Headings
|
|
100
|
-
let tmpHeadingMatch = tmpTrimmed.match(/^(#{1,6})\s+(.*)$/);
|
|
101
|
-
if (tmpHeadingMatch)
|
|
102
|
-
{
|
|
103
|
-
flushParagraph();
|
|
104
|
-
closeList();
|
|
105
|
-
let tmpLevel = tmpHeadingMatch[1].length;
|
|
106
|
-
tmpHTML.push('<h' + tmpLevel + '>' + inlineFormat(tmpHeadingMatch[2]) + '</h' + tmpLevel + '>');
|
|
107
|
-
continue;
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
// Unordered list item (- or *)
|
|
111
|
-
let tmpULMatch = tmpTrimmed.match(/^[-*]\s+(.*)$/);
|
|
112
|
-
if (tmpULMatch)
|
|
113
|
-
{
|
|
114
|
-
flushParagraph();
|
|
115
|
-
if (!tmpInList || tmpListType !== 'ul')
|
|
116
|
-
{
|
|
117
|
-
closeList();
|
|
118
|
-
tmpHTML.push('<ul>');
|
|
119
|
-
tmpInList = true;
|
|
120
|
-
tmpListType = 'ul';
|
|
121
|
-
}
|
|
122
|
-
tmpHTML.push('<li>' + inlineFormat(tmpULMatch[1]) + '</li>');
|
|
123
|
-
continue;
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
// Ordered list item (1. 2. etc)
|
|
127
|
-
let tmpOLMatch = tmpTrimmed.match(/^\d+\.\s+(.*)$/);
|
|
128
|
-
if (tmpOLMatch)
|
|
129
|
-
{
|
|
130
|
-
flushParagraph();
|
|
131
|
-
if (!tmpInList || tmpListType !== 'ol')
|
|
132
|
-
{
|
|
133
|
-
closeList();
|
|
134
|
-
tmpHTML.push('<ol>');
|
|
135
|
-
tmpInList = true;
|
|
136
|
-
tmpListType = 'ol';
|
|
137
|
-
}
|
|
138
|
-
tmpHTML.push('<li>' + inlineFormat(tmpOLMatch[1]) + '</li>');
|
|
139
|
-
continue;
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
// Regular text — accumulate into paragraph
|
|
143
|
-
closeList();
|
|
144
|
-
tmpParagraph.push(inlineFormat(tmpTrimmed));
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
flushParagraph();
|
|
148
|
-
closeList();
|
|
149
|
-
|
|
150
|
-
return tmpHTML.join('');
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
// ---------------------------------------------------------------------------
|
|
154
|
-
// Main
|
|
155
|
-
// ---------------------------------------------------------------------------
|
|
156
|
-
|
|
157
|
-
let tmpModuleRoot = libPath.resolve(__dirname, '..');
|
|
158
|
-
let tmpSourceDir = process.argv[2]
|
|
159
|
-
? libPath.resolve(process.argv[2])
|
|
160
|
-
: libPath.join(tmpModuleRoot, 'docs', 'card-help');
|
|
161
|
-
let tmpOutputFile = process.argv[3]
|
|
162
|
-
? libPath.resolve(process.argv[3])
|
|
163
|
-
: libPath.join(tmpModuleRoot, 'example_applications', 'simple_cards', 'source', 'card-help-content.js');
|
|
164
|
-
|
|
165
|
-
let tmpHelpMap = {};
|
|
166
|
-
|
|
167
|
-
// Gracefully handle missing source directory
|
|
168
|
-
if (libFS.existsSync(tmpSourceDir))
|
|
169
|
-
{
|
|
170
|
-
let tmpFiles = libFS.readdirSync(tmpSourceDir).filter(
|
|
171
|
-
(pFile) => { return pFile.endsWith('.md'); }
|
|
172
|
-
);
|
|
173
|
-
|
|
174
|
-
for (let i = 0; i < tmpFiles.length; i++)
|
|
175
|
-
{
|
|
176
|
-
let tmpFile = tmpFiles[i];
|
|
177
|
-
let tmpCode = libPath.basename(tmpFile, '.md');
|
|
178
|
-
try
|
|
179
|
-
{
|
|
180
|
-
let tmpContent = libFS.readFileSync(libPath.join(tmpSourceDir, tmpFile), 'utf8');
|
|
181
|
-
let tmpHTML = convertMarkdownToHTML(tmpContent);
|
|
182
|
-
if (tmpHTML.length > 0)
|
|
183
|
-
{
|
|
184
|
-
tmpHelpMap[tmpCode] = tmpHTML;
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
catch (pError)
|
|
188
|
-
{
|
|
189
|
-
// Skip files that cannot be read — never fail the build
|
|
190
|
-
console.warn('generate-card-help: skipping ' + tmpFile + ' (' + pError.message + ')');
|
|
191
|
-
}
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
console.log('generate-card-help: processed ' + Object.keys(tmpHelpMap).length + ' card help files from ' + tmpSourceDir);
|
|
195
|
-
}
|
|
196
|
-
else
|
|
197
|
-
{
|
|
198
|
-
console.log('generate-card-help: no docs/card-help directory found — generating empty map');
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
// Ensure output directory exists
|
|
202
|
-
let tmpOutputDir = libPath.dirname(tmpOutputFile);
|
|
203
|
-
if (!libFS.existsSync(tmpOutputDir))
|
|
204
|
-
{
|
|
205
|
-
libFS.mkdirSync(tmpOutputDir, { recursive: true });
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
// Write the generated module
|
|
209
|
-
let tmpOutput = '// Auto-generated by scripts/generate-card-help.js — do not edit manually.\n';
|
|
210
|
-
tmpOutput += '// Source markdown files are in docs/card-help/\n';
|
|
211
|
-
tmpOutput += 'module.exports = ' + JSON.stringify(tmpHelpMap, null, '\t') + ';\n';
|
|
212
|
-
|
|
213
|
-
libFS.writeFileSync(tmpOutputFile, tmpOutput, 'utf8');
|
|
214
|
-
console.log('generate-card-help: wrote ' + tmpOutputFile);
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Edge-Bezier
|
|
3
|
-
*
|
|
4
|
-
* Default edge theme: smooth cubic bezier between source and target ports,
|
|
5
|
-
* with departure/approach geometry derived from each port's `Side`. This
|
|
6
|
-
* is a thin wrapper around the renderer's pre-existing bezier path
|
|
7
|
-
* generator — selecting it is equivalent to the historical default.
|
|
8
|
-
*
|
|
9
|
-
* Honors per-connection multi-handle waypoints (BezierHandles) when
|
|
10
|
-
* present so user-edited curves still survive.
|
|
11
|
-
*/
|
|
12
|
-
module.exports =
|
|
13
|
-
{
|
|
14
|
-
Name: 'Bezier',
|
|
15
|
-
Label: 'Bezier (smooth)',
|
|
16
|
-
Description: 'Smooth cubic curves with side-aware departures.',
|
|
17
|
-
|
|
18
|
-
GeneratePath: function (pContext)
|
|
19
|
-
{
|
|
20
|
-
let tmpHelpers = pContext.Helpers;
|
|
21
|
-
let tmpSrc = pContext.Source;
|
|
22
|
-
let tmpTgt = pContext.Target;
|
|
23
|
-
let tmpData = (pContext.Connection && pContext.Connection.Data) || {};
|
|
24
|
-
|
|
25
|
-
// Preserve user-customized multi-handle bezier waypoints.
|
|
26
|
-
if (tmpData.HandleCustomized)
|
|
27
|
-
{
|
|
28
|
-
let tmpHandles = tmpHelpers.getBezierHandles(tmpData);
|
|
29
|
-
if (tmpHandles.length > 0)
|
|
30
|
-
{
|
|
31
|
-
return tmpHelpers.generateMultiBezier(tmpSrc, tmpTgt, tmpHandles);
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
return tmpHelpers.generateBezier(tmpSrc, tmpTgt);
|
|
36
|
-
},
|
|
37
|
-
|
|
38
|
-
DefaultParameters: {},
|
|
39
|
-
|
|
40
|
-
ParameterSchema: {}
|
|
41
|
-
};
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Edge-Orthogonal
|
|
3
|
-
*
|
|
4
|
-
* Right-angle (Manhattan) routing between source and target. Reads
|
|
5
|
-
* cleanly for layered DAGs and grid-shaped layouts. Per-connection
|
|
6
|
-
* `OrthoMidOffset` and customized corner overrides are preserved.
|
|
7
|
-
*/
|
|
8
|
-
module.exports =
|
|
9
|
-
{
|
|
10
|
-
Name: 'Orthogonal',
|
|
11
|
-
Label: 'Orthogonal (right-angle)',
|
|
12
|
-
Description: 'Right-angle routing — reads well for DAGs and grids.',
|
|
13
|
-
|
|
14
|
-
GeneratePath: function (pContext)
|
|
15
|
-
{
|
|
16
|
-
let tmpHelpers = pContext.Helpers;
|
|
17
|
-
let tmpSrc = pContext.Source;
|
|
18
|
-
let tmpTgt = pContext.Target;
|
|
19
|
-
let tmpData = (pContext.Connection && pContext.Connection.Data) || {};
|
|
20
|
-
|
|
21
|
-
let tmpCorners = null;
|
|
22
|
-
if (tmpData.HandleCustomized && tmpData.OrthoCorner1X != null)
|
|
23
|
-
{
|
|
24
|
-
tmpCorners =
|
|
25
|
-
{
|
|
26
|
-
corner1: { x: tmpData.OrthoCorner1X, y: tmpData.OrthoCorner1Y },
|
|
27
|
-
corner2: { x: tmpData.OrthoCorner2X, y: tmpData.OrthoCorner2Y }
|
|
28
|
-
};
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
return tmpHelpers.generateOrthogonal(tmpSrc, tmpTgt, tmpCorners, tmpData.OrthoMidOffset || 0);
|
|
32
|
-
},
|
|
33
|
-
|
|
34
|
-
DefaultParameters: {},
|
|
35
|
-
|
|
36
|
-
ParameterSchema: {}
|
|
37
|
-
};
|
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
const libCoerce = require('../layouts/Layout-Coerce.js');
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Edge-OrthogonalSnap
|
|
5
|
-
*
|
|
6
|
-
* Demonstrates the "edge theme can affect node placement" axis. Same
|
|
7
|
-
* right-angle routing as Edge-Orthogonal, but with an `AdjustLayout`
|
|
8
|
-
* pass that snaps every node's X/Y to a grid so corner segments line
|
|
9
|
-
* up cleanly across the diagram.
|
|
10
|
-
*
|
|
11
|
-
* Trade-off: nodes shift slightly from the layout's natural positions
|
|
12
|
-
* to gain visual alignment. The user opts into this by picking the
|
|
13
|
-
* theme — the layout algorithm itself is unaware.
|
|
14
|
-
*/
|
|
15
|
-
module.exports =
|
|
16
|
-
{
|
|
17
|
-
Name: 'OrthogonalSnap',
|
|
18
|
-
Label: 'Orthogonal (snap to grid)',
|
|
19
|
-
Description: 'Right-angle routing; snaps node positions to a grid for cleaner corner alignment. Demonstrates an edge theme that adjusts node placement.',
|
|
20
|
-
|
|
21
|
-
GeneratePath: function (pContext)
|
|
22
|
-
{
|
|
23
|
-
let tmpHelpers = pContext.Helpers;
|
|
24
|
-
let tmpSrc = pContext.Source;
|
|
25
|
-
let tmpTgt = pContext.Target;
|
|
26
|
-
let tmpData = (pContext.Connection && pContext.Connection.Data) || {};
|
|
27
|
-
|
|
28
|
-
let tmpCorners = null;
|
|
29
|
-
if (tmpData.HandleCustomized && tmpData.OrthoCorner1X != null)
|
|
30
|
-
{
|
|
31
|
-
tmpCorners =
|
|
32
|
-
{
|
|
33
|
-
corner1: { x: tmpData.OrthoCorner1X, y: tmpData.OrthoCorner1Y },
|
|
34
|
-
corner2: { x: tmpData.OrthoCorner2X, y: tmpData.OrthoCorner2Y }
|
|
35
|
-
};
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
return tmpHelpers.generateOrthogonal(tmpSrc, tmpTgt, tmpCorners, tmpData.OrthoMidOffset || 0);
|
|
39
|
-
},
|
|
40
|
-
|
|
41
|
-
/**
|
|
42
|
-
* Snap each node's (X, Y) to the configured grid after the layout
|
|
43
|
-
* has run. Mutates pNodes in place.
|
|
44
|
-
*
|
|
45
|
-
* @param {Array} pNodes
|
|
46
|
-
* @param {Array} pConnections
|
|
47
|
-
* @param {Object} pParameters
|
|
48
|
-
*/
|
|
49
|
-
AdjustLayout: function (pNodes, pConnections, pParameters)
|
|
50
|
-
{
|
|
51
|
-
let tmpGridSize = libCoerce.toFloat((pParameters || {}).GridSize, 20);
|
|
52
|
-
if (tmpGridSize <= 0) return;
|
|
53
|
-
|
|
54
|
-
for (let i = 0; i < pNodes.length; i++)
|
|
55
|
-
{
|
|
56
|
-
let tmpNode = pNodes[i];
|
|
57
|
-
if (typeof tmpNode.X !== 'number' || typeof tmpNode.Y !== 'number') continue;
|
|
58
|
-
tmpNode.X = Math.round(tmpNode.X / tmpGridSize) * tmpGridSize;
|
|
59
|
-
tmpNode.Y = Math.round(tmpNode.Y / tmpGridSize) * tmpGridSize;
|
|
60
|
-
}
|
|
61
|
-
},
|
|
62
|
-
|
|
63
|
-
DefaultParameters:
|
|
64
|
-
{
|
|
65
|
-
GridSize: 20
|
|
66
|
-
},
|
|
67
|
-
|
|
68
|
-
ParameterSchema:
|
|
69
|
-
{
|
|
70
|
-
GridSize: { Type: 'PreciseNumber', Label: 'Grid size', Default: 20, Min: 1, Max: 200 }
|
|
71
|
-
}
|
|
72
|
-
};
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
const libPerimeterMath = require('./Edge-PerimeterMath.js');
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Edge-Perimeter-Linear
|
|
5
|
-
*
|
|
6
|
-
* Perimeter attachment + literal straight line between the two
|
|
7
|
-
* resolved exit points. Reads cleanly for force-directed and circular
|
|
8
|
-
* layouts where the topology already determines edge angles, and the
|
|
9
|
-
* curves of bezier add visual noise.
|
|
10
|
-
*/
|
|
11
|
-
module.exports =
|
|
12
|
-
{
|
|
13
|
-
Name: 'Perimeter-Linear',
|
|
14
|
-
Label: 'Perimeter (linear)',
|
|
15
|
-
Description: 'Each connection exits the node at the perimeter, then runs as a straight line to the other end.',
|
|
16
|
-
|
|
17
|
-
GeneratePath: function (pContext)
|
|
18
|
-
{
|
|
19
|
-
let tmpS = pContext.Source;
|
|
20
|
-
let tmpT = pContext.Target;
|
|
21
|
-
return `M ${tmpS.x} ${tmpS.y} L ${tmpT.x} ${tmpT.y}`;
|
|
22
|
-
},
|
|
23
|
-
|
|
24
|
-
ResolveAttachment: function (pContext)
|
|
25
|
-
{
|
|
26
|
-
return libPerimeterMath.resolvePerimeterAttachment(pContext);
|
|
27
|
-
},
|
|
28
|
-
|
|
29
|
-
DefaultParameters: {},
|
|
30
|
-
ParameterSchema: {}
|
|
31
|
-
};
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
const libPerimeterMath = require('./Edge-PerimeterMath.js');
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Edge-Perimeter-Orthogonal
|
|
5
|
-
*
|
|
6
|
-
* Perimeter attachment + right-angle (Manhattan) routing between
|
|
7
|
-
* the two resolved exit points. Best when the layout already has
|
|
8
|
-
* grid-like structure (Grid, Mesh) and you want connections to
|
|
9
|
-
* leave from whichever side faces the partner.
|
|
10
|
-
*/
|
|
11
|
-
module.exports =
|
|
12
|
-
{
|
|
13
|
-
Name: 'Perimeter-Orthogonal',
|
|
14
|
-
Label: 'Perimeter (orthogonal)',
|
|
15
|
-
Description: 'Each connection exits the node at the perimeter, then routes via right-angle segments to the other end.',
|
|
16
|
-
|
|
17
|
-
GeneratePath: function (pContext)
|
|
18
|
-
{
|
|
19
|
-
let tmpData = (pContext.Connection && pContext.Connection.Data) || {};
|
|
20
|
-
let tmpCorners = null;
|
|
21
|
-
if (tmpData.HandleCustomized && tmpData.OrthoCorner1X != null)
|
|
22
|
-
{
|
|
23
|
-
tmpCorners =
|
|
24
|
-
{
|
|
25
|
-
corner1: { x: tmpData.OrthoCorner1X, y: tmpData.OrthoCorner1Y },
|
|
26
|
-
corner2: { x: tmpData.OrthoCorner2X, y: tmpData.OrthoCorner2Y }
|
|
27
|
-
};
|
|
28
|
-
}
|
|
29
|
-
return pContext.Helpers.generateOrthogonal(pContext.Source, pContext.Target, tmpCorners, tmpData.OrthoMidOffset || 0);
|
|
30
|
-
},
|
|
31
|
-
|
|
32
|
-
ResolveAttachment: function (pContext)
|
|
33
|
-
{
|
|
34
|
-
return libPerimeterMath.resolvePerimeterAttachment(pContext);
|
|
35
|
-
},
|
|
36
|
-
|
|
37
|
-
DefaultParameters: {},
|
|
38
|
-
ParameterSchema: {}
|
|
39
|
-
};
|
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
const libPerimeterMath = require('./Edge-PerimeterMath.js');
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Edge-Perimeter (Bezier)
|
|
5
|
-
*
|
|
6
|
-
* "Smart exit" routing with smooth bezier curves. Each connection
|
|
7
|
-
* exits the node at the perimeter point closest to its target —
|
|
8
|
-
* solves star/hub topologies where many connections share one port.
|
|
9
|
-
*
|
|
10
|
-
* Renders the path as a side-aware bezier (uses the side returned by
|
|
11
|
-
* `ResolveAttachment` so the curve departs in the right direction).
|
|
12
|
-
*
|
|
13
|
-
* See `Edge-Perimeter-Linear` and `Edge-Perimeter-Orthogonal` for the
|
|
14
|
-
* straight-line and right-angle variants.
|
|
15
|
-
*/
|
|
16
|
-
module.exports =
|
|
17
|
-
{
|
|
18
|
-
Name: 'Perimeter',
|
|
19
|
-
Label: 'Perimeter (bezier)',
|
|
20
|
-
Description: 'Each connection exits the node at the perimeter point closest to its target, with smooth bezier curves. Fixes star/hub topologies where many lines share one port.',
|
|
21
|
-
|
|
22
|
-
GeneratePath: function (pContext)
|
|
23
|
-
{
|
|
24
|
-
// Honor user-edited bezier handles when the connection is selected
|
|
25
|
-
// and dragged. Without this, the drag handles render but moving
|
|
26
|
-
// them does nothing because Perimeter would always re-emit a
|
|
27
|
-
// fresh side-aware bezier.
|
|
28
|
-
let tmpHelpers = pContext.Helpers;
|
|
29
|
-
let tmpData = (pContext.Connection && pContext.Connection.Data) || {};
|
|
30
|
-
if (tmpData.HandleCustomized)
|
|
31
|
-
{
|
|
32
|
-
let tmpHandles = tmpHelpers.getBezierHandles(tmpData);
|
|
33
|
-
if (tmpHandles.length > 0)
|
|
34
|
-
{
|
|
35
|
-
return tmpHelpers.generateMultiBezier(pContext.Source, pContext.Target, tmpHandles);
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
return tmpHelpers.generateBezier(pContext.Source, pContext.Target);
|
|
39
|
-
},
|
|
40
|
-
|
|
41
|
-
ResolveAttachment: function (pContext)
|
|
42
|
-
{
|
|
43
|
-
return libPerimeterMath.resolvePerimeterAttachment(pContext);
|
|
44
|
-
},
|
|
45
|
-
|
|
46
|
-
DefaultParameters: {},
|
|
47
|
-
ParameterSchema: {}
|
|
48
|
-
};
|
|
@@ -1,92 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Edge-PerimeterMath
|
|
3
|
-
*
|
|
4
|
-
* Shared geometry helper for the Perimeter family of edge themes
|
|
5
|
-
* (Perimeter, Perimeter-Linear, Perimeter-Orthogonal). Solves the
|
|
6
|
-
* "where on this node's bounding box should the line attach so it
|
|
7
|
-
* points at the other end" question.
|
|
8
|
-
*
|
|
9
|
-
* The themes themselves only differ in how they render the path
|
|
10
|
-
* between the two attachment points; the attachment math is identical.
|
|
11
|
-
*/
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* Resolve a perimeter attachment point for one end of a connection.
|
|
15
|
-
* Traces a line from the node's center toward the other end and returns
|
|
16
|
-
* the first crossing of the node's bounding-box perimeter, plus the
|
|
17
|
-
* `side` of that crossing (so the bezier helper departs in the right
|
|
18
|
-
* direction).
|
|
19
|
-
*
|
|
20
|
-
* @param {Object} pContext - the same shape the renderer passes into
|
|
21
|
-
* ResolveAttachment (Node, OtherNode, OtherDefaultPosition,
|
|
22
|
-
* DefaultPosition, …).
|
|
23
|
-
* @returns {{x: number, y: number, side: string}|Object|null}
|
|
24
|
-
* Returns null when node geometry is missing; returns
|
|
25
|
-
* DefaultPosition (verbatim) for degenerate same-center cases.
|
|
26
|
-
*/
|
|
27
|
-
function _resolvePerimeterAttachment(pContext)
|
|
28
|
-
{
|
|
29
|
-
let tmpNode = pContext.Node;
|
|
30
|
-
if (!tmpNode || typeof tmpNode.X !== 'number' || typeof tmpNode.Y !== 'number') return null;
|
|
31
|
-
|
|
32
|
-
let tmpW = tmpNode.Width || 180;
|
|
33
|
-
let tmpH = tmpNode.Height || 80;
|
|
34
|
-
let tmpCx = tmpNode.X + tmpW / 2;
|
|
35
|
-
let tmpCy = tmpNode.Y + tmpH / 2;
|
|
36
|
-
|
|
37
|
-
let tmpAimX, tmpAimY;
|
|
38
|
-
if (pContext.OtherNode && typeof pContext.OtherNode.X === 'number')
|
|
39
|
-
{
|
|
40
|
-
let tmpOW = pContext.OtherNode.Width || 180;
|
|
41
|
-
let tmpOH = pContext.OtherNode.Height || 80;
|
|
42
|
-
tmpAimX = pContext.OtherNode.X + tmpOW / 2;
|
|
43
|
-
tmpAimY = pContext.OtherNode.Y + tmpOH / 2;
|
|
44
|
-
}
|
|
45
|
-
else if (pContext.OtherDefaultPosition)
|
|
46
|
-
{
|
|
47
|
-
tmpAimX = pContext.OtherDefaultPosition.x;
|
|
48
|
-
tmpAimY = pContext.OtherDefaultPosition.y;
|
|
49
|
-
}
|
|
50
|
-
else
|
|
51
|
-
{
|
|
52
|
-
return null;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
let tmpDX = tmpAimX - tmpCx;
|
|
56
|
-
let tmpDY = tmpAimY - tmpCy;
|
|
57
|
-
|
|
58
|
-
if (tmpDX === 0 && tmpDY === 0) return pContext.DefaultPosition || null;
|
|
59
|
-
|
|
60
|
-
let tmpHalfW = tmpW / 2;
|
|
61
|
-
let tmpHalfH = tmpH / 2;
|
|
62
|
-
|
|
63
|
-
let tmpTX = (tmpDX > 0) ? tmpHalfW / tmpDX
|
|
64
|
-
: (tmpDX < 0) ? -tmpHalfW / tmpDX
|
|
65
|
-
: Infinity;
|
|
66
|
-
let tmpTY = (tmpDY > 0) ? tmpHalfH / tmpDY
|
|
67
|
-
: (tmpDY < 0) ? -tmpHalfH / tmpDY
|
|
68
|
-
: Infinity;
|
|
69
|
-
|
|
70
|
-
let tmpT, tmpSide;
|
|
71
|
-
if (tmpTX < tmpTY)
|
|
72
|
-
{
|
|
73
|
-
tmpT = tmpTX;
|
|
74
|
-
tmpSide = (tmpDX > 0) ? 'right' : 'left';
|
|
75
|
-
}
|
|
76
|
-
else
|
|
77
|
-
{
|
|
78
|
-
tmpT = tmpTY;
|
|
79
|
-
tmpSide = (tmpDY > 0) ? 'bottom' : 'top';
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
return {
|
|
83
|
-
x: tmpCx + tmpT * tmpDX,
|
|
84
|
-
y: tmpCy + tmpT * tmpDY,
|
|
85
|
-
side: tmpSide
|
|
86
|
-
};
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
module.exports =
|
|
90
|
-
{
|
|
91
|
-
resolvePerimeterAttachment: _resolvePerimeterAttachment
|
|
92
|
-
};
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Edge-Straight
|
|
3
|
-
*
|
|
4
|
-
* Literal straight line from source port to target port. Useful for
|
|
5
|
-
* dense clusters where curves add visual noise, and for force-directed
|
|
6
|
-
* layouts where the topology already determines edge angles.
|
|
7
|
-
*/
|
|
8
|
-
module.exports =
|
|
9
|
-
{
|
|
10
|
-
Name: 'Straight',
|
|
11
|
-
Label: 'Straight line',
|
|
12
|
-
Description: 'Plain straight line between ports.',
|
|
13
|
-
|
|
14
|
-
GeneratePath: function (pContext)
|
|
15
|
-
{
|
|
16
|
-
let tmpSrc = pContext.Source;
|
|
17
|
-
let tmpTgt = pContext.Target;
|
|
18
|
-
return `M ${tmpSrc.x} ${tmpSrc.y} L ${tmpTgt.x} ${tmpTgt.y}`;
|
|
19
|
-
},
|
|
20
|
-
|
|
21
|
-
DefaultParameters: {},
|
|
22
|
-
|
|
23
|
-
ParameterSchema: {}
|
|
24
|
-
};
|