@principal-ai/subsystems-react 0.17.0 → 0.19.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 (108) hide show
  1. package/README.md +11 -85
  2. package/dist/index.d.ts +7 -44
  3. package/dist/index.d.ts.map +1 -1
  4. package/dist/index.js +6 -32
  5. package/dist/index.js.map +1 -1
  6. package/dist/subsystem/SubsystemCarousel.d.ts +36 -0
  7. package/dist/subsystem/SubsystemCarousel.d.ts.map +1 -0
  8. package/dist/subsystem/SubsystemCarousel.js +163 -0
  9. package/dist/subsystem/SubsystemCarousel.js.map +1 -0
  10. package/dist/subsystem/SubsystemComponentGraph.d.ts +25 -0
  11. package/dist/subsystem/SubsystemComponentGraph.d.ts.map +1 -1
  12. package/dist/subsystem/SubsystemComponentGraph.js +329 -68
  13. package/dist/subsystem/SubsystemComponentGraph.js.map +1 -1
  14. package/package.json +4 -4
  15. package/src/index.ts +9 -199
  16. package/src/subsystem/SubsystemComponentGraph.tsx +396 -50
  17. package/src/components/ConfigurationSelector.tsx +0 -133
  18. package/src/components/GraphRenderer.tsx +0 -3195
  19. package/src/components/MultiCanvasRenderer.tsx +0 -295
  20. package/src/components/NodeTooltip.tsx +0 -279
  21. package/src/components/PendingChanges.test.tsx +0 -375
  22. package/src/components/SelectionSidebar.tsx +0 -352
  23. package/src/components/SequenceDiagramRenderer.tsx +0 -1156
  24. package/src/components/WorkflowSequenceDiagram.tsx +0 -270
  25. package/src/components/dashboard/DashboardRenderer.tsx +0 -317
  26. package/src/components/dashboard/MetricPanel.tsx +0 -254
  27. package/src/components/dashboard/MockDataProvider.ts +0 -330
  28. package/src/components/dashboard/components/BarChart.tsx +0 -299
  29. package/src/components/dashboard/components/LineChart.tsx +0 -279
  30. package/src/components/dashboard/components/MetricCard.tsx +0 -270
  31. package/src/components/dashboard/components/SourceLink.tsx +0 -63
  32. package/src/components/dashboard/components/TimeRangeSelector.tsx +0 -280
  33. package/src/components/dashboard/components/index.ts +0 -5
  34. package/src/components/dashboard/index.ts +0 -47
  35. package/src/components/dashboard/types.ts +0 -126
  36. package/src/components/state-view/PipelineView.tsx +0 -347
  37. package/src/components/state-view/index.ts +0 -14
  38. package/src/components/state-view/types.ts +0 -261
  39. package/src/components/state-view/useStateView.ts +0 -205
  40. package/src/contexts/GraphEditContext.tsx +0 -27
  41. package/src/contexts/TooltipPortalContext.ts +0 -8
  42. package/src/edges/CustomEdge.tsx +0 -402
  43. package/src/edges/GenericEdge.tsx +0 -36
  44. package/src/hooks/usePathBasedEvents.ts +0 -192
  45. package/src/hooks/useSequenceLayout.ts +0 -543
  46. package/src/hooks/useUndoRedo.ts +0 -144
  47. package/src/nodes/CustomNode.tsx +0 -1231
  48. package/src/nodes/GenericNode.tsx +0 -55
  49. package/src/nodes/otel/OtelBoundaryNode.tsx +0 -224
  50. package/src/nodes/otel/OtelEventNode.tsx +0 -225
  51. package/src/nodes/otel/OtelResourceNode.tsx +0 -251
  52. package/src/nodes/otel/OtelScopeNode.tsx +0 -221
  53. package/src/nodes/otel/OtelSpanConventionNode.tsx +0 -295
  54. package/src/nodes/otel/index.ts +0 -23
  55. package/src/nodes/otel/shared/NodeBadges.tsx +0 -295
  56. package/src/nodes/otel/shared/NodeContent.tsx +0 -204
  57. package/src/nodes/otel/shared/index.ts +0 -8
  58. package/src/nodes/otel/shared/types.ts +0 -138
  59. package/src/nodes/otel/shared/useNodeBehavior.ts +0 -114
  60. package/src/stories/Audit/BoundaryNodes.stories.tsx +0 -385
  61. package/src/stories/Audit/CanvasEdgeTypes.stories.tsx +0 -1448
  62. package/src/stories/Audit/CanvasNodeTypes.stories.tsx +0 -1049
  63. package/src/stories/Audit/ColorPriority.stories.tsx +0 -895
  64. package/src/stories/Audit/DiamondBadges.stories.tsx +0 -629
  65. package/src/stories/Audit/NodeDimensionsTesting.stories.tsx +0 -724
  66. package/src/stories/Audit/NodeFieldsAudit.stories.tsx +0 -996
  67. package/src/stories/Audit/NodeFontSizeTesting.stories.tsx +0 -715
  68. package/src/stories/Audit/NodeShapes.stories.tsx +0 -1208
  69. package/src/stories/Audit/WideNodesTesting.stories.tsx +0 -1045
  70. package/src/stories/Components/DashboardRenderer.stories.tsx +0 -263
  71. package/src/stories/Components/GraphRenderer.stories.tsx +0 -3236
  72. package/src/stories/Components/MultiCanvasRenderer.stories.tsx +0 -370
  73. package/src/stories/Components/SequenceDiagram.stories.tsx +0 -255
  74. package/src/stories/Components/StateView.stories.tsx +0 -417
  75. package/src/stories/Components/TraceViewer.stories.tsx +0 -442
  76. package/src/stories/Components/WorkflowSequenceDiagram.stories.tsx +0 -802
  77. package/src/stories/Features/AnimationWorkshop.stories.tsx +0 -727
  78. package/src/stories/Features/ChangeTypeVisual.stories.tsx +0 -67
  79. package/src/stories/Features/EventDrivenAnimations.stories.tsx +0 -513
  80. package/src/stories/Features/MultiConfig.stories.tsx +0 -539
  81. package/src/stories/Layout/ElkEdgeRouting.stories.tsx +0 -539
  82. package/src/stories/Layout/GraphOrientation.stories.tsx +0 -500
  83. package/src/stories/Layout/MultiDirectionalConnections.stories.tsx +0 -352
  84. package/src/stories/Nodes/NodeDefinitionComparison.stories.tsx +0 -560
  85. package/src/stories/Nodes/NodeNameFallbacks.stories.tsx +0 -491
  86. package/src/stories/Nodes/NumericColors.stories.tsx +0 -440
  87. package/src/stories/OTEL/EventNameDisplay.stories.tsx +0 -694
  88. package/src/stories/OTEL/EventNameFallback.stories.tsx +0 -578
  89. package/src/stories/OTEL/OtelComponents.stories.tsx +0 -422
  90. package/src/stories/OTEL/OtelNodeTypesPrototype.stories.tsx +0 -806
  91. package/src/stories/OTEL/RawEventCards.stories.tsx +0 -57
  92. package/src/stories/OTEL/SpanBadges.stories.tsx +0 -840
  93. package/src/stories/OTEL/ValidationEventsCanvas.stories.tsx +0 -209
  94. package/src/stories/RealWorld/BacklogMdCanvases.stories.tsx +0 -721
  95. package/src/stories/RealWorld/FileCitySequence.stories.tsx +0 -516
  96. package/src/stories/RealWorld/RealCanvasFiles.stories.tsx +0 -336
  97. package/src/stories/__traces__/test-run.canvas.json +0 -241
  98. package/src/stories/data/activity-feed-analytics.dashboard.json +0 -300
  99. package/src/stories/data/file-city-images-transformed.otel.canvas.json +0 -295
  100. package/src/stories/data/file-city-workflows.json +0 -269
  101. package/src/stories/data/graph-converter-test-execution.json +0 -443
  102. package/src/stories/data/graph-converter-test.workflow.json +0 -105
  103. package/src/stories/data/graph-converter-validated-execution.json +0 -58
  104. package/src/utils/animationMapping.ts +0 -166
  105. package/src/utils/canvasBounds.ts +0 -146
  106. package/src/utils/graphConverter.ts +0 -148
  107. package/src/utils/iconResolver.tsx +0 -53
  108. package/src/utils/orientationUtils.ts +0 -73
@@ -1,724 +0,0 @@
1
- import React from 'react';
2
- import type { Meta, StoryObj } from '@storybook/react';
3
- import { GraphRenderer } from '../../components/GraphRenderer';
4
- import type { ExtendedCanvas, ExtendedCanvasNode } from '@principal-ai/subsystems-core';
5
- import { ThemeProvider, defaultEditorTheme } from '@principal-ade/industry-theme';
6
-
7
- const meta = {
8
- title: 'Audit/NodeDimensionsTesting',
9
- component: GraphRenderer,
10
- parameters: {
11
- layout: 'fullscreen',
12
- },
13
- tags: ['autodocs'],
14
- decorators: [
15
- (Story) => (
16
- <ThemeProvider theme={defaultEditorTheme}>
17
- <Story />
18
- </ThemeProvider>
19
- ),
20
- ],
21
- } satisfies Meta<typeof GraphRenderer>;
22
-
23
- export default meta;
24
- type Story = StoryObj<typeof meta>;
25
-
26
- /**
27
- * Text length variations for testing
28
- */
29
- const TEXT_SAMPLES = {
30
- veryShort: 'Init',
31
- short: 'File Parsed',
32
- medium: 'Validation Started',
33
- long: 'Canvas Validated Successfully',
34
- veryLong: 'Complete Analysis And Validation Process',
35
- extraLong: 'Comprehensive System Validation And Analysis Workflow Process',
36
- };
37
-
38
- /**
39
- * Common dimension presets
40
- */
41
- const DIMENSIONS = {
42
- tiny: { width: 100, height: 60 },
43
- small: { width: 140, height: 80 },
44
- medium: { width: 180, height: 100 },
45
- mediumWide: { width: 220, height: 100 },
46
- large: { width: 200, height: 120 },
47
- wide: { width: 260, height: 100 },
48
- tall: { width: 140, height: 140 },
49
- extraWide: { width: 300, height: 100 },
50
- square: { width: 150, height: 150 },
51
- };
52
-
53
- /**
54
- * Grid layout helper
55
- */
56
- const createGrid = (
57
- rows: { label: string; textKey: keyof typeof TEXT_SAMPLES }[],
58
- cols: { label: string; dimKey: keyof typeof DIMENSIONS }[],
59
- startX = 50,
60
- startY = 100,
61
- gapX = 40,
62
- gapY = 40
63
- ) => {
64
- const nodes: ExtendedCanvasNode[] = [];
65
-
66
- rows.forEach((row, rowIdx) => {
67
- cols.forEach((col, colIdx) => {
68
- const dim = DIMENSIONS[col.dimKey];
69
- const text = TEXT_SAMPLES[row.textKey];
70
-
71
- nodes.push({
72
- id: `${row.textKey}-${col.dimKey}`,
73
- type: 'text',
74
- x: startX + colIdx * (Math.max(...Object.values(DIMENSIONS).map(d => d.width)) + gapX),
75
- y: startY + rowIdx * (Math.max(...Object.values(DIMENSIONS).map(d => d.height)) + gapY),
76
- width: dim.width,
77
- height: dim.height,
78
- text: text,
79
- color: '#3b82f6',
80
- pv: {
81
- name: text,
82
- shape: 'roundedRect',
83
- icon: 'Circle',
84
- otel: {
85
- kind: 'event',
86
- category: 'operation',
87
- },
88
- },
89
- });
90
- });
91
- });
92
-
93
- return nodes;
94
- };
95
-
96
- /**
97
- * Shows all dimension variations with different text lengths in a comprehensive grid
98
- */
99
- export const DimensionsGrid: Story = {
100
- render: () => {
101
- const theme = defaultEditorTheme;
102
-
103
- const rows = [
104
- { label: 'Very Short', textKey: 'veryShort' as const },
105
- { label: 'Short', textKey: 'short' as const },
106
- { label: 'Medium', textKey: 'medium' as const },
107
- { label: 'Long', textKey: 'long' as const },
108
- { label: 'Very Long', textKey: 'veryLong' as const },
109
- { label: 'Extra Long', textKey: 'extraLong' as const },
110
- ];
111
-
112
- const cols = [
113
- { label: 'Tiny\n100×60', dimKey: 'tiny' as const },
114
- { label: 'Small\n140×80', dimKey: 'small' as const },
115
- { label: 'Medium\n180×100', dimKey: 'medium' as const },
116
- { label: 'Wide\n260×100', dimKey: 'wide' as const },
117
- { label: 'Tall\n140×140', dimKey: 'tall' as const },
118
- ];
119
-
120
- const canvas: ExtendedCanvas = {
121
- nodes: createGrid(rows, cols, 220, 150, 60, 60),
122
- edges: [],
123
- };
124
-
125
- return (
126
- <div style={{ padding: '32px', fontFamily: theme.fonts.body }}>
127
- <h1 style={{
128
- marginBottom: '16px',
129
- fontFamily: theme.fonts.heading,
130
- fontSize: theme.fontSizes[7],
131
- color: theme.colors.text,
132
- }}>
133
- Node Dimensions & Text Readability Grid
134
- </h1>
135
- <p style={{
136
- marginBottom: '24px',
137
- fontSize: theme.fontSizes[2],
138
- color: theme.colors.textSecondary,
139
- maxWidth: '1000px',
140
- }}>
141
- Testing various node dimensions with different text lengths. All nodes use 12px font (theme.fontSizes[0]).
142
- Find the optimal width/height combinations for your use case.
143
- </p>
144
-
145
- {/* Column headers */}
146
- <div style={{
147
- position: 'relative',
148
- marginBottom: '16px',
149
- paddingLeft: '160px',
150
- display: 'flex',
151
- gap: '60px',
152
- }}>
153
- {cols.map(col => (
154
- <div
155
- key={col.dimKey}
156
- style={{
157
- width: DIMENSIONS[col.dimKey].width,
158
- textAlign: 'center',
159
- fontSize: theme.fontSizes[0],
160
- fontWeight: theme.fontWeights.semibold,
161
- color: theme.colors.textSecondary,
162
- fontFamily: theme.fonts.monospace,
163
- whiteSpace: 'pre-line',
164
- }}
165
- >
166
- {col.label}
167
- </div>
168
- ))}
169
- </div>
170
-
171
- {/* Row labels + Canvas */}
172
- <div style={{ display: 'flex' }}>
173
- {/* Row labels */}
174
- <div style={{
175
- width: '160px',
176
- paddingTop: '150px',
177
- display: 'flex',
178
- flexDirection: 'column',
179
- gap: '60px',
180
- }}>
181
- {rows.map(row => (
182
- <div
183
- key={row.textKey}
184
- style={{
185
- height: DIMENSIONS.medium.height,
186
- display: 'flex',
187
- alignItems: 'center',
188
- fontSize: theme.fontSizes[1],
189
- fontWeight: theme.fontWeights.semibold,
190
- color: theme.colors.textSecondary,
191
- }}
192
- >
193
- <div>
194
- <div style={{ marginBottom: '4px' }}>{row.label}</div>
195
- <div style={{
196
- fontSize: theme.fontSizes[0],
197
- fontFamily: theme.fonts.monospace,
198
- color: theme.colors.textMuted,
199
- }}>
200
- "{TEXT_SAMPLES[row.textKey]}"
201
- </div>
202
- </div>
203
- </div>
204
- ))}
205
- </div>
206
-
207
- {/* Canvas */}
208
- <div style={{
209
- backgroundColor: theme.colors.background,
210
- border: `2px solid ${theme.colors.border}`,
211
- borderRadius: '8px',
212
- flex: 1,
213
- }}>
214
- <GraphRenderer
215
- canvas={canvas}
216
- height={1100}
217
- width="100%"
218
- />
219
- </div>
220
- </div>
221
-
222
- {/* Legend */}
223
- <div style={{
224
- marginTop: '32px',
225
- padding: '20px',
226
- backgroundColor: theme.colors.surface,
227
- border: `1px solid ${theme.colors.border}`,
228
- borderRadius: '8px',
229
- }}>
230
- <h3 style={{
231
- marginBottom: '12px',
232
- fontSize: theme.fontSizes[3],
233
- color: theme.colors.text,
234
- }}>
235
- Reading Guide
236
- </h3>
237
- <div style={{
238
- display: 'grid',
239
- gridTemplateColumns: '1fr 1fr',
240
- gap: '16px',
241
- fontSize: theme.fontSizes[1],
242
- color: theme.colors.textSecondary,
243
- }}>
244
- <div>
245
- <strong>✅ Good readability:</strong> Text fits comfortably, no awkward wrapping
246
- </div>
247
- <div>
248
- <strong>⚠️ Tight fit:</strong> Text fits but feels cramped
249
- </div>
250
- <div>
251
- <strong>❌ Too cramped:</strong> Text wraps awkwardly or gets cut off
252
- </div>
253
- <div>
254
- <strong>📏 Too spacious:</strong> Excessive empty space, inefficient use of canvas
255
- </div>
256
- </div>
257
- </div>
258
- </div>
259
- );
260
- },
261
- };
262
-
263
- /**
264
- * OTEL Canvas standard sizes - focused comparison
265
- */
266
- export const OtelStandardSizes: Story = {
267
- render: () => {
268
- const theme = defaultEditorTheme;
269
-
270
- const testCases = [
271
- {
272
- title: 'validation.otel.canvas Standard (200×100)',
273
- description: 'Most common size in your validation workflow',
274
- nodes: [
275
- { text: 'Analysis Started', width: 200, height: 100, x: 100 },
276
- { text: 'File Parsed', width: 200, height: 100, x: 350 },
277
- { text: 'Canvas Validated', width: 200, height: 100, x: 600 },
278
- { text: 'Validation Complete', width: 200, height: 100, x: 850 },
279
- { text: 'Very Long Event Name Here', width: 200, height: 100, x: 1100 },
280
- ],
281
- },
282
- {
283
- title: 'Wider (220×100) - More breathing room',
284
- description: 'Extra 20px width for longer event names',
285
- nodes: [
286
- { text: 'Analysis Started', width: 220, height: 100, x: 100 },
287
- { text: 'File Parsed', width: 220, height: 100, x: 370 },
288
- { text: 'Canvas Validated', width: 220, height: 100, x: 640 },
289
- { text: 'Validation Complete', width: 220, height: 100, x: 910 },
290
- { text: 'Very Long Event Name Here', width: 220, height: 100, x: 1180 },
291
- ],
292
- },
293
- {
294
- title: 'Compact (180×90) - Space efficient',
295
- description: 'Smaller footprint for dense workflows',
296
- nodes: [
297
- { text: 'Analysis Started', width: 180, height: 90, x: 100 },
298
- { text: 'File Parsed', width: 180, height: 90, x: 330 },
299
- { text: 'Canvas Validated', width: 180, height: 90, x: 560 },
300
- { text: 'Validation Complete', width: 180, height: 90, x: 790 },
301
- { text: 'Very Long Event Name Here', width: 180, height: 90, x: 1020 },
302
- ],
303
- },
304
- {
305
- title: 'Tall (200×120) - Extra vertical space',
306
- description: 'Better for nodes with state labels or badges',
307
- nodes: [
308
- { text: 'Analysis Started', width: 200, height: 120, x: 100 },
309
- { text: 'File Parsed', width: 200, height: 120, x: 350 },
310
- { text: 'Canvas Validated', width: 200, height: 120, x: 600 },
311
- { text: 'Validation Complete', width: 200, height: 120, x: 850 },
312
- { text: 'Very Long Event Name Here', width: 200, height: 120, x: 1100 },
313
- ],
314
- },
315
- ];
316
-
317
- return (
318
- <div style={{ padding: '32px' }}>
319
- <h1 style={{
320
- marginBottom: '16px',
321
- fontSize: theme.fontSizes[7],
322
- color: theme.colors.text,
323
- }}>
324
- OTEL Canvas Standard Sizes Comparison
325
- </h1>
326
- <p style={{
327
- marginBottom: '32px',
328
- fontSize: theme.fontSizes[2],
329
- color: theme.colors.textSecondary,
330
- maxWidth: '900px',
331
- }}>
332
- Comparing different standard sizes for OTEL event nodes. All use the same event names to show
333
- how text fits in each dimension.
334
- </p>
335
-
336
- {testCases.map((testCase, idx) => {
337
- const canvas: ExtendedCanvas = {
338
- nodes: testCase.nodes.map((node, nodeIdx) => ({
339
- id: `node-${idx}-${nodeIdx}`,
340
- type: 'text',
341
- x: node.x,
342
- y: 100,
343
- width: node.width,
344
- height: node.height,
345
- text: node.text,
346
- color: '#3b82f6',
347
- pv: {
348
- name: node.text,
349
- shape: 'roundedRect',
350
- icon: 'Circle',
351
- otel: {
352
- kind: 'event',
353
- category: 'operation',
354
- },
355
- },
356
- })),
357
- edges: [],
358
- };
359
-
360
- return (
361
- <div
362
- key={idx}
363
- style={{
364
- marginBottom: '40px',
365
- padding: '24px',
366
- backgroundColor: theme.colors.surface,
367
- border: `1px solid ${theme.colors.border}`,
368
- borderRadius: '8px',
369
- }}
370
- >
371
- <div style={{
372
- display: 'flex',
373
- justifyContent: 'space-between',
374
- alignItems: 'flex-start',
375
- marginBottom: '16px',
376
- }}>
377
- <div>
378
- <h3 style={{
379
- fontSize: theme.fontSizes[3],
380
- fontWeight: theme.fontWeights.semibold,
381
- color: theme.colors.text,
382
- marginBottom: '4px',
383
- }}>
384
- {testCase.title}
385
- </h3>
386
- <p style={{
387
- fontSize: theme.fontSizes[1],
388
- color: theme.colors.textSecondary,
389
- }}>
390
- {testCase.description}
391
- </p>
392
- </div>
393
- <div style={{
394
- padding: '8px 12px',
395
- backgroundColor: theme.colors.backgroundSecondary,
396
- borderRadius: '4px',
397
- fontFamily: theme.fonts.monospace,
398
- fontSize: theme.fontSizes[0],
399
- color: theme.colors.textMuted,
400
- }}>
401
- {testCase.nodes[0].width} × {testCase.nodes[0].height}
402
- </div>
403
- </div>
404
-
405
- <div style={{
406
- backgroundColor: theme.colors.background,
407
- border: `2px solid ${theme.colors.border}`,
408
- borderRadius: '6px',
409
- overflow: 'hidden',
410
- }}>
411
- <GraphRenderer
412
- canvas={canvas}
413
- height={300}
414
- width="100%"
415
- />
416
- </div>
417
- </div>
418
- );
419
- })}
420
-
421
- <div style={{
422
- marginTop: '32px',
423
- padding: '24px',
424
- backgroundColor: theme.colors.backgroundSecondary,
425
- border: `2px solid ${theme.colors.primary}`,
426
- borderRadius: '8px',
427
- }}>
428
- <h3 style={{
429
- marginBottom: '16px',
430
- fontSize: theme.fontSizes[4],
431
- color: theme.colors.text,
432
- }}>
433
- Recommendations
434
- </h3>
435
- <div style={{
436
- fontSize: theme.fontSizes[1],
437
- color: theme.colors.text,
438
- lineHeight: 1.8,
439
- }}>
440
- <div style={{ marginBottom: '12px' }}>
441
- <strong style={{ color: theme.colors.primary }}>✨ Best for most OTEL events:</strong> 200×100 (current standard)
442
- <div style={{ paddingLeft: '20px', color: theme.colors.textSecondary }}>
443
- Good balance of readability and space efficiency
444
- </div>
445
- </div>
446
- <div style={{ marginBottom: '12px' }}>
447
- <strong style={{ color: theme.colors.primary }}>📏 For longer event names:</strong> 220×100
448
- <div style={{ paddingLeft: '20px', color: theme.colors.textSecondary }}>
449
- Prevents cramped text, better for descriptive names
450
- </div>
451
- </div>
452
- <div style={{ marginBottom: '12px' }}>
453
- <strong style={{ color: theme.colors.primary }}>🎯 For compact workflows:</strong> 180×90
454
- <div style={{ paddingLeft: '20px', color: theme.colors.textSecondary }}>
455
- Saves space when you have many nodes
456
- </div>
457
- </div>
458
- <div>
459
- <strong style={{ color: theme.colors.primary }}>🏷️ With badges/states:</strong> 200×120
460
- <div style={{ paddingLeft: '20px', color: theme.colors.textSecondary }}>
461
- Extra vertical space for OTEL badges and state labels
462
- </div>
463
- </div>
464
- </div>
465
- </div>
466
- </div>
467
- );
468
- },
469
- };
470
-
471
- /**
472
- * Different shapes with same dimensions
473
- */
474
- export const ShapesWithDimensions: Story = {
475
- render: () => {
476
- const theme = defaultEditorTheme;
477
-
478
- const shapes: Array<{
479
- shape: 'rectangle' | 'roundedRect' | 'circle' | 'hexagon' | 'diamond';
480
- label: string;
481
- }> = [
482
- { shape: 'rectangle', label: 'Rectangle' },
483
- { shape: 'roundedRect', label: 'Rounded Rect' },
484
- { shape: 'circle', label: 'Circle' },
485
- { shape: 'hexagon', label: 'Hexagon' },
486
- { shape: 'diamond', label: 'Diamond' },
487
- ];
488
-
489
- const dimensions = [
490
- { label: 'Small (140×80)', width: 140, height: 80 },
491
- { label: 'Medium (180×100)', width: 180, height: 100 },
492
- { label: 'Large (220×120)', width: 220, height: 120 },
493
- ];
494
-
495
- const textSamples = [
496
- 'Init',
497
- 'File Parsed',
498
- 'Validation Complete',
499
- ];
500
-
501
- return (
502
- <div style={{ padding: '32px' }}>
503
- <h1 style={{
504
- marginBottom: '16px',
505
- fontSize: theme.fontSizes[7],
506
- color: theme.colors.text,
507
- }}>
508
- Shape & Dimension Combinations
509
- </h1>
510
- <p style={{
511
- marginBottom: '32px',
512
- fontSize: theme.fontSizes[2],
513
- color: theme.colors.textSecondary,
514
- }}>
515
- How different shapes utilize the same dimensions with varying text lengths.
516
- </p>
517
-
518
- {dimensions.map((dim, dimIdx) => {
519
- const canvas: ExtendedCanvas = {
520
- nodes: shapes.flatMap((shape, shapeIdx) =>
521
- textSamples.map((text, textIdx) => ({
522
- id: `${dimIdx}-${shapeIdx}-${textIdx}`,
523
- type: 'text',
524
- x: 100 + shapeIdx * (dim.width + 60),
525
- y: 100 + textIdx * (dim.height + 40),
526
- width: dim.width,
527
- height: dim.height,
528
- text,
529
- color: ['#22c55e', '#3b82f6', '#f59e0b', '#8b5cf6', '#ec4899'][shapeIdx],
530
- pv: {
531
- name: text,
532
- shape: shape.shape,
533
- icon: 'Circle',
534
- },
535
- }))
536
- ),
537
- edges: [],
538
- };
539
-
540
- return (
541
- <div
542
- key={dimIdx}
543
- style={{
544
- marginBottom: '40px',
545
- padding: '24px',
546
- backgroundColor: theme.colors.surface,
547
- border: `1px solid ${theme.colors.border}`,
548
- borderRadius: '8px',
549
- }}
550
- >
551
- <h3 style={{
552
- fontSize: theme.fontSizes[3],
553
- marginBottom: '16px',
554
- color: theme.colors.text,
555
- }}>
556
- {dim.label}
557
- </h3>
558
-
559
- <div style={{
560
- display: 'flex',
561
- gap: '40px',
562
- marginBottom: '16px',
563
- paddingLeft: '100px',
564
- }}>
565
- {shapes.map(shape => (
566
- <div
567
- key={shape.shape}
568
- style={{
569
- width: dim.width,
570
- textAlign: 'center',
571
- fontSize: theme.fontSizes[1],
572
- fontWeight: theme.fontWeights.semibold,
573
- color: theme.colors.textSecondary,
574
- }}
575
- >
576
- {shape.label}
577
- </div>
578
- ))}
579
- </div>
580
-
581
- <div style={{
582
- backgroundColor: theme.colors.background,
583
- border: `2px solid ${theme.colors.border}`,
584
- borderRadius: '6px',
585
- }}>
586
- <GraphRenderer
587
- canvas={canvas}
588
- height={500}
589
- width="100%"
590
- />
591
- </div>
592
- </div>
593
- );
594
- })}
595
- </div>
596
- );
597
- },
598
- };
599
-
600
- /**
601
- * Real-world OTEL workflow with consistent dimensions
602
- */
603
- export const RealWorldWorkflow: Story = {
604
- render: () => {
605
- const theme = defaultEditorTheme;
606
-
607
- const workflows = [
608
- {
609
- title: 'Current (200×100) - validation.otel.canvas style',
610
- width: 200,
611
- height: 100,
612
- },
613
- {
614
- title: 'Proposed (220×100) - More readable',
615
- width: 220,
616
- height: 100,
617
- },
618
- {
619
- title: 'Compact (180×90) - Space efficient',
620
- width: 180,
621
- height: 90,
622
- },
623
- ];
624
-
625
- const events = [
626
- { name: 'Analysis Started', color: '#22c55e', y: 50 },
627
- { name: 'FileTree Built', color: '#3b82f6', y: 200 },
628
- { name: 'Packages Discovered', color: '#f59e0b', y: 350 },
629
- { name: 'Discovery Complete', color: '#f59e0b', y: 500 },
630
- { name: 'Validation Started', color: '#22c55e', y: 650 },
631
- { name: 'Canvas Validated', color: '#8b5cf6', y: 800 },
632
- { name: 'Validation Complete', color: '#22c55e', y: 950 },
633
- ];
634
-
635
- return (
636
- <div style={{ padding: '32px' }}>
637
- <h1 style={{
638
- marginBottom: '16px',
639
- fontSize: theme.fontSizes[7],
640
- color: theme.colors.text,
641
- }}>
642
- Real Workflow Comparison
643
- </h1>
644
- <p style={{
645
- marginBottom: '32px',
646
- fontSize: theme.fontSizes[2],
647
- color: theme.colors.textSecondary,
648
- }}>
649
- Same workflow rendered with different node dimensions. Compare overall aesthetics and readability.
650
- </p>
651
-
652
- <div style={{
653
- display: 'grid',
654
- gridTemplateColumns: 'repeat(3, 1fr)',
655
- gap: '24px',
656
- }}>
657
- {workflows.map((workflow, idx) => {
658
- const canvas: ExtendedCanvas = {
659
- nodes: events.map((event, eventIdx) => ({
660
- id: `${idx}-${eventIdx}`,
661
- type: 'text',
662
- x: 100,
663
- y: event.y,
664
- width: workflow.width,
665
- height: workflow.height,
666
- text: event.name,
667
- color: event.color,
668
- pv: {
669
- name: event.name,
670
- shape: 'roundedRect',
671
- icon: 'Circle',
672
- otel: {
673
- kind: 'event',
674
- category: eventIdx === 0 || eventIdx === 4 || eventIdx === 6 ? 'lifecycle' : 'operation',
675
- },
676
- sources: eventIdx % 2 === 0 ? ['src/discovery/CanvasDiscovery.ts'] : undefined,
677
- },
678
- })),
679
- edges: events.slice(0, -1).map((_, eventIdx) => ({
680
- id: `edge-${idx}-${eventIdx}`,
681
- fromNode: `${idx}-${eventIdx}`,
682
- toNode: `${idx}-${eventIdx + 1}`,
683
- fromSide: 'bottom' as const,
684
- toSide: 'top' as const,
685
- })),
686
- };
687
-
688
- return (
689
- <div key={idx}>
690
- <h3 style={{
691
- fontSize: theme.fontSizes[2],
692
- fontWeight: theme.fontWeights.semibold,
693
- color: theme.colors.text,
694
- marginBottom: '8px',
695
- }}>
696
- {workflow.title}
697
- </h3>
698
- <div style={{
699
- fontSize: theme.fontSizes[0],
700
- fontFamily: theme.fonts.monospace,
701
- color: theme.colors.textMuted,
702
- marginBottom: '12px',
703
- }}>
704
- {workflow.width} × {workflow.height}
705
- </div>
706
- <div style={{
707
- backgroundColor: theme.colors.background,
708
- border: `2px solid ${theme.colors.border}`,
709
- borderRadius: '6px',
710
- }}>
711
- <GraphRenderer
712
- canvas={canvas}
713
- height={1200}
714
- width="100%"
715
- />
716
- </div>
717
- </div>
718
- );
719
- })}
720
- </div>
721
- </div>
722
- );
723
- },
724
- };