pict-section-flow 1.3.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.
Files changed (162) hide show
  1. package/package.json +7 -2
  2. package/source/Pict-Section-Flow.js +20 -14
  3. package/source/providers/PictProvider-Flow-Background.js +303 -0
  4. package/source/providers/PictProvider-Flow-CSS.js +99 -7
  5. package/source/providers/PictProvider-Flow-ConnectorShapes.js +8 -0
  6. package/source/providers/PictProvider-Flow-Geometry.js +11 -421
  7. package/source/providers/PictProvider-Flow-Icons.js +20 -0
  8. package/source/providers/PictProvider-Flow-Layouts.js +107 -0
  9. package/source/services/PictService-Flow-ConnectionRenderer.js +77 -5
  10. package/source/services/PictService-Flow-CursorManager.js +113 -0
  11. package/source/services/PictService-Flow-InteractionManager.js +443 -61
  12. package/source/services/PictService-Flow-Layout.js +21 -16
  13. package/source/services/PictService-Flow-PathGenerator.js +30 -417
  14. package/source/services/PictService-Flow-RenderManager.js +9 -1
  15. package/source/services/PictService-Flow-ViewportManager.js +102 -0
  16. package/source/views/PictView-Flow-FloatingToolbar.js +57 -0
  17. package/source/views/PictView-Flow-Node.js +36 -0
  18. package/source/views/PictView-Flow-PropertiesPanel.js +27 -5
  19. package/source/views/PictView-Flow-Toolbar.js +148 -13
  20. package/source/views/PictView-Flow.js +628 -3
  21. package/.claude/launch.json +0 -11
  22. package/docs/.nojekyll +0 -0
  23. package/docs/Architecture.md +0 -163
  24. package/docs/Custom-Styling.md +0 -275
  25. package/docs/Data_Model.md +0 -149
  26. package/docs/Event_System.md +0 -156
  27. package/docs/Getting_Started.md +0 -237
  28. package/docs/Implementation_Reference.md +0 -528
  29. package/docs/Layout_Persistence.md +0 -117
  30. package/docs/README.md +0 -103
  31. package/docs/Theme_Integration.md +0 -150
  32. package/docs/_brand.json +0 -18
  33. package/docs/_cover.md +0 -17
  34. package/docs/_playground.json +0 -24
  35. package/docs/_sidebar.md +0 -57
  36. package/docs/_topbar.md +0 -8
  37. package/docs/_version.json +0 -7
  38. package/docs/api/PictFlowCard.md +0 -216
  39. package/docs/api/PictFlowCardPropertiesPanel.md +0 -235
  40. package/docs/api/addConnection.md +0 -101
  41. package/docs/api/addNode.md +0 -137
  42. package/docs/api/autoLayout.md +0 -77
  43. package/docs/api/getFlowData.md +0 -112
  44. package/docs/api/marshalToView.md +0 -95
  45. package/docs/api/openPanel.md +0 -128
  46. package/docs/api/registerHandler.md +0 -174
  47. package/docs/api/registerNodeType.md +0 -142
  48. package/docs/api/removeConnection.md +0 -57
  49. package/docs/api/removeNode.md +0 -80
  50. package/docs/api/saveLayout.md +0 -152
  51. package/docs/api/screenToSVGCoords.md +0 -68
  52. package/docs/api/selectNode.md +0 -116
  53. package/docs/api/setTheme.md +0 -168
  54. package/docs/api/setZoom.md +0 -97
  55. package/docs/api/toggleFullscreen.md +0 -68
  56. package/docs/card-help/EACH.md +0 -19
  57. package/docs/card-help/FREAD.md +0 -24
  58. package/docs/card-help/FWRITE.md +0 -24
  59. package/docs/card-help/GET.md +0 -22
  60. package/docs/card-help/ITE.md +0 -23
  61. package/docs/card-help/LOG.md +0 -23
  62. package/docs/card-help/NOTE.md +0 -17
  63. package/docs/card-help/PREV.md +0 -18
  64. package/docs/card-help/SET.md +0 -27
  65. package/docs/card-help/SPKL.md +0 -22
  66. package/docs/card-help/STAT.md +0 -23
  67. package/docs/card-help/SW.md +0 -25
  68. package/docs/diagrams/architecture-at-a-glance.excalidraw +0 -4270
  69. package/docs/diagrams/architecture-at-a-glance.mmd +0 -30
  70. package/docs/diagrams/architecture-at-a-glance.svg +0 -2
  71. package/docs/diagrams/data-flow.excalidraw +0 -1451
  72. package/docs/diagrams/data-flow.mmd +0 -17
  73. package/docs/diagrams/data-flow.svg +0 -2
  74. package/docs/diagrams/high-level-design.excalidraw +0 -5767
  75. package/docs/diagrams/high-level-design.mmd +0 -86
  76. package/docs/diagrams/high-level-design.svg +0 -2
  77. package/docs/diagrams/relationships.excalidraw +0 -3852
  78. package/docs/diagrams/relationships.mmd +0 -9
  79. package/docs/diagrams/relationships.svg +0 -2
  80. package/docs/diagrams/service-initialization-sequence.excalidraw +0 -1466
  81. package/docs/diagrams/service-initialization-sequence.mmd +0 -19
  82. package/docs/diagrams/service-initialization-sequence.svg +0 -2
  83. package/docs/diagrams/svg-layer-structure.excalidraw +0 -1060
  84. package/docs/diagrams/svg-layer-structure.mmd +0 -18
  85. package/docs/diagrams/svg-layer-structure.svg +0 -2
  86. package/docs/examples/README.md +0 -9
  87. package/docs/examples/simple_cards/README.md +0 -677
  88. package/docs/examples/simple_cards/css/flowexample.css +0 -65
  89. package/docs/examples/simple_cards/index.html +0 -32
  90. package/docs/examples/simple_cards/js/pict.min.js +0 -12
  91. package/docs/examples/simple_cards/pict-section-flow-example-simple-cards.compatible.min.js +0 -1
  92. package/docs/index.html +0 -38
  93. package/docs/playground/app.json +0 -6
  94. package/docs/playground/appdata.json +0 -85
  95. package/docs/playground/application.js +0 -23
  96. package/docs/playground/pict.json +0 -17
  97. package/docs/playground/runtime/pict-application.min.js +0 -2
  98. package/docs/playground/runtime/pict-section-flow.min.js +0 -2
  99. package/docs/playground/runtime/pict-section-modal.min.js +0 -2
  100. package/docs/playground/runtime/pict.min.js +0 -12
  101. package/docs/retold-catalog.json +0 -244
  102. package/docs/retold-keyword-index.json +0 -26028
  103. package/example_applications/simple_cards/css/flowexample.css +0 -65
  104. package/example_applications/simple_cards/html/index.html +0 -32
  105. package/example_applications/simple_cards/package.json +0 -52
  106. package/example_applications/simple_cards/source/Pict-Application-FlowExample-Configuration.json +0 -15
  107. package/example_applications/simple_cards/source/Pict-Application-FlowExample.js +0 -539
  108. package/example_applications/simple_cards/source/card-help-content.js +0 -16
  109. package/example_applications/simple_cards/source/cards/FlowCard-Comment.js +0 -38
  110. package/example_applications/simple_cards/source/cards/FlowCard-DataPreview.js +0 -44
  111. package/example_applications/simple_cards/source/cards/FlowCard-Each.js +0 -38
  112. package/example_applications/simple_cards/source/cards/FlowCard-FileRead.js +0 -56
  113. package/example_applications/simple_cards/source/cards/FlowCard-FileWrite.js +0 -50
  114. package/example_applications/simple_cards/source/cards/FlowCard-GetValue.js +0 -37
  115. package/example_applications/simple_cards/source/cards/FlowCard-IfThenElse.js +0 -49
  116. package/example_applications/simple_cards/source/cards/FlowCard-LogValues.js +0 -55
  117. package/example_applications/simple_cards/source/cards/FlowCard-SetValue.js +0 -97
  118. package/example_applications/simple_cards/source/cards/FlowCard-Sparkline.js +0 -100
  119. package/example_applications/simple_cards/source/cards/FlowCard-StatusMonitor.js +0 -46
  120. package/example_applications/simple_cards/source/cards/FlowCard-Switch.js +0 -39
  121. package/example_applications/simple_cards/source/providers/PictRouter-FlowExample-Configuration.json +0 -22
  122. package/example_applications/simple_cards/source/sample-flows.js +0 -410
  123. package/example_applications/simple_cards/source/views/PictView-FlowExample-About.js +0 -184
  124. package/example_applications/simple_cards/source/views/PictView-FlowExample-BottomBar.js +0 -77
  125. package/example_applications/simple_cards/source/views/PictView-FlowExample-Documentation.js +0 -325
  126. package/example_applications/simple_cards/source/views/PictView-FlowExample-FileWriteInfo.js +0 -59
  127. package/example_applications/simple_cards/source/views/PictView-FlowExample-Layout.js +0 -90
  128. package/example_applications/simple_cards/source/views/PictView-FlowExample-MainWorkspace.js +0 -453
  129. package/example_applications/simple_cards/source/views/PictView-FlowExample-TopBar.js +0 -95
  130. package/scripts/generate-card-help.js +0 -214
  131. package/source/providers/edges/Edge-Bezier.js +0 -41
  132. package/source/providers/edges/Edge-Orthogonal.js +0 -37
  133. package/source/providers/edges/Edge-OrthogonalSnap.js +0 -72
  134. package/source/providers/edges/Edge-Perimeter-Linear.js +0 -31
  135. package/source/providers/edges/Edge-Perimeter-Orthogonal.js +0 -39
  136. package/source/providers/edges/Edge-Perimeter.js +0 -48
  137. package/source/providers/edges/Edge-PerimeterMath.js +0 -92
  138. package/source/providers/edges/Edge-Straight.js +0 -24
  139. package/source/providers/layouts/Layout-Circular.js +0 -203
  140. package/source/providers/layouts/Layout-Coerce.js +0 -40
  141. package/source/providers/layouts/Layout-Columnar.js +0 -134
  142. package/source/providers/layouts/Layout-Custom.js +0 -27
  143. package/source/providers/layouts/Layout-ForcedFromCenter.js +0 -256
  144. package/source/providers/layouts/Layout-Grid.js +0 -134
  145. package/source/providers/layouts/Layout-Layered.js +0 -155
  146. package/source/providers/layouts/Layout-Rank.js +0 -141
  147. package/source/providers/layouts/Layout-Staggered.js +0 -131
  148. package/source/providers/layouts/Layout-Tabular.js +0 -94
  149. package/test/ConnectionHandleManager_tests.js +0 -717
  150. package/test/ConnectionRenderer_tests.js +0 -591
  151. package/test/DataManager_tests.js +0 -859
  152. package/test/Geometry_tests.js +0 -767
  153. package/test/InteractionManager_tests.js +0 -279
  154. package/test/Layout_tests.js +0 -1604
  155. package/test/NodeView_tests.js +0 -66
  156. package/test/PanelManager_tests.js +0 -172
  157. package/test/PathGenerator_tests.js +0 -978
  158. package/test/PortRenderer_tests.js +0 -376
  159. package/test/RenderManager_tests.js +0 -756
  160. package/test/Renderer_tests.js +0 -133
  161. package/test/SelectionManager_tests.js +0 -185
  162. package/test/StylePresets_tests.js +0 -153
@@ -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
- };