@peter.prib/renderengine 0.15.0 → 0.15.2
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/dist/renderengine-workspace.umd.js +776 -229
- package/dist/renderengine.umd.js +390 -107
- package/documentation/REFERENCE.md +496 -6
- package/examples/decision-workbench.html +26 -0
- package/package.json +2 -1
- package/src/charting/ArchimateDiagramEditor.js +2 -1
- package/src/charting/Edge.js +22 -0
- package/src/charting/archimate/ArchimateCanvasEditor.js +21 -5
- package/src/charting/archimate/ViewGroupTemplate.js +5 -2
- package/src/charting/diagramModel/DiagramJsonFileFormat.js +32 -0
- package/src/charting/diagramModel/DiagramModel.js +39 -0
- package/src/charting/diagramModel/DiagramView.js +97 -61
- package/src/charting/diagramModel/index.js +11 -10
- package/src/charting/diagrams/AddGroupToViewCommand.js +35 -0
- package/src/charting/diagrams/ArchimateModel.js +53 -13
- package/src/charting/diagrams/NestInstanceCommand.js +2 -1
- package/src/charting/templates/templateRegistry.js +70 -0
- package/src/index.js +4 -3
- package/src/workspace/index.js +3 -0
- package/src/workspace/parts/ArchimateEditorPart.js +2 -2
- package/src/workspace/parts/DecisionWorkbenchPart.js +58 -0
- package/src/workspace/parts/DiagramEditorPart.js +144 -131
- package/src/workspace/parts/ViewsPart.js +196 -0
|
@@ -104,6 +104,31 @@ catalog `key` for you.
|
|
|
104
104
|
| `wordCloud` | `wordCloud(data, opts)` | `Array<{text: string, value: number}>` | spiral placement + bounding-box collision; `minFontSize`, `maxFontSize`, `padding` |
|
|
105
105
|
| `parallelCoordinates` | `parallelCoordinates(data, opts)` | `Array<{label?, category?, [dim: number]}>` | one vertical axis per numeric dimension; category-driven colors; `dimensions` |
|
|
106
106
|
| `geoMap` | `geoMap(data, opts)` | `{features: Array<{id, name, value?, color?, geometry}>, bubbles?: Array<{lat, lon, value}>}` | equirectangular projection; `center`, `scale`, `colorScale`; see note below |
|
|
107
|
+
| `polarArea` | `polarAreaChart(data, opts)` | `Array<{label, value, exploded?}>` | Nightingale rose equal-angle wedges; `scale: 'radius'|'area'`, `extrude3D`, `depth`, `innerRadiusRatio` |
|
|
108
|
+
| `pie3D` | `pieChart3D(data, opts)` | `Array<{label, value}>` | isometric 3D pie; `depth`, `tilt`, `exploded`, `colors` |
|
|
109
|
+
| `donut3D` | `donutChart3D(data, opts)` | `Array<{label, value}>` | isometric 3D donut; `innerRadiusRatio`, `depth`, `tilt` |
|
|
110
|
+
| `pareto` | `paretoChart(data, opts)` | `Array<{label, value}>` | sorted descending bars with cumulative percentage line (80/20 rule); `barColor`, `lineColor` |
|
|
111
|
+
| `lollipop` | `lollipopChart(data, opts)` | `Array<{label, value}>` | stem with circular point markers; `orientation: 'vertical'|'horizontal'`, `pointRadius` |
|
|
112
|
+
| `marimekko` | `marimekkoChart(data, opts)` | `Array<{name, values: Array<{label, value}>}>` | 2D mosaic chart where both bar width and height encode values |
|
|
113
|
+
| `icicle` | `icicleChart(data, opts)` | `Array<{label, value?, children?}>` | hierarchical partition chart laying out tree levels as rectangular blocks; `orientation` |
|
|
114
|
+
| `dumbbell` | `dumbbellChart(data, opts)` | `Array<{label, start, end}>` or multi-series `Array<{name, values}>` | connected pair of dots showing change across categories; `colorByDelta`, `showDeltas`, `orientation` |
|
|
115
|
+
| `slopegraph` | `slopegraph(data, opts)` | `Array<{label, values: number[]}>` or `Array<{label, start, end}>` | connects categories across stages with direct labels; `stageLabels`, `collisionAvoidance` |
|
|
116
|
+
| `circlePack` | `circlePackChart(data, opts)` | `Array<{label, value?, children?}>` | nested tangent circles sized by value with translucent branch containment; `padding` |
|
|
117
|
+
| `ridgeline` | `ridgelineChart(data, opts)` | `Array<{label, values: number[]}>` | vertically staggered, overlapping Gaussian-KDE density curves (Joy plot); `overlap`, `showMedian` |
|
|
118
|
+
| `beeswarm` | `beeswarmChart(data, opts)` | `Array<{label, values: number[]}>` | packed individual sample points along category slots; `mode: 'beeswarm'|'raincloud'`, `radius` |
|
|
119
|
+
| `combo` | `comboChart(data, opts)` | multi-series with type specifications | composite multi-series chart combining bars, lines, and area layers on primary/secondary axes |
|
|
120
|
+
| `hexbin` | `hexbinChart(data, opts)` | `Array<{x, y, value?}>` or `Array<[x, y]>` | 2D hexagonal density binning for large scatter clouds; `radius`, `minCount`, `colorScale` |
|
|
121
|
+
| `ecdf` | `ecdfChart(data, opts)` | `number[]` or `Array<{label, values: number[]}>` | empirical cumulative distribution step function (0..1); `showMedian`, `showQuantiles`, `step` |
|
|
122
|
+
| `splom` | `scatterMatrixChart(data, opts)` | `Array<object>` with numeric dimensions | scatter plot matrix of pairwise bivariate relationships; `dimensions`, `colorCol` |
|
|
123
|
+
| `sparklineTable` | `sparklineTableChart(data, opts)` | `Array<{label, values: number[], current?, change?}>` | data table with embedded inline trendline sparklines; `columns` |
|
|
124
|
+
| `horizon` | `horizonChart(data, opts)` | `Array<{label, values: number[]}>` | compact layered area strips folding positive and negative magnitude bands; `bands`, `posColors` |
|
|
125
|
+
| `ohlc` | `ohlcChart(data, opts)` | `Array<{label, open, high, low, close}>` | Open-High-Low-Close financial bar chart; `upColor`, `downColor` |
|
|
126
|
+
| `alluvial` | `alluvialDiagram(data, opts)` | `{dimensions: string[], rows: Array<object>}` or `Array<{steps, value}>` | multi-stage categorical flow diagram across ordered dimensions; `nodeWidth`, `curvature` |
|
|
127
|
+
| `renko` | `renkoChart(data, opts)` | `number[]` or `Array<{label, close}>` | brick-based trend-filtering chart filtering out time noise; `brickSize` |
|
|
128
|
+
| `contour` | `contourChart(data, opts)` | `number[][]` (2D scalar grid) or `Array<{x, y, value}>` | marching-squares isolines and filled isoband contours; `levels`, `filled`, `showLines` |
|
|
129
|
+
| `kagi` | `kagiChart(data, opts)` | `number[]` or `Array<{label, close}>` | trend reversal chart with alternating line thickness; `reversalAmount` |
|
|
130
|
+
| `pointAndFigure` | `pointAndFigureChart(data, opts)` | `number[]` or `Array<{label, close}>` | columns of X's (rising) and O's (falling); `boxSize`, `reversal` |
|
|
131
|
+
| `surface3D` | `surfaceChart3D(data, opts)` | `Array<{x, z, value}>` or `{xLabels, zLabels, values}` | continuous 3D surface mesh with gradient height coloring, wireframe, and orbit camera |
|
|
107
132
|
|
|
108
133
|
**Gauges.** Every gauge is a `GaugeChart` (`src/charting/charts/GaugeChart.js`) and takes the same options:
|
|
109
134
|
|
|
@@ -1340,6 +1365,278 @@ SVG each mark answers a click with `{ label, series }`.
|
|
|
1340
1365
|
engine.barChart(data, { onDatumClick: ({ label }) => openDetail(label) });
|
|
1341
1366
|
```
|
|
1342
1367
|
|
|
1368
|
+
## Advanced Statistical, Flow, Distribution & 3D Charts
|
|
1369
|
+
|
|
1370
|
+
Specialized charts designed for dense distributions, multi-stage transitions, continuous terrains, and flow modeling.
|
|
1371
|
+
|
|
1372
|
+
### Dumbbell / Gap Chart — `dumbbellChart(data, options)`
|
|
1373
|
+
|
|
1374
|
+
A connected pair of dots per category showing before/after, actual/target, or interval comparisons without the visual clutter of clustered bars.
|
|
1375
|
+
|
|
1376
|
+
- **Data shapes:**
|
|
1377
|
+
- `Array<{label: string, start: number, end: number}>`
|
|
1378
|
+
- Multi-series `Array<{name: string, values: Array<{label: string, value: number}>}>` (first two series used as start and end)
|
|
1379
|
+
- **Notable options:**
|
|
1380
|
+
- `orientation`: `'horizontal'` (default) or `'vertical'`.
|
|
1381
|
+
- `colorByDelta`: `true` to color connectors and endpoints by direction of change (green for gain, red for loss).
|
|
1382
|
+
- `startColor`, `endColor`: Custom endpoint colors when `colorByDelta` is false.
|
|
1383
|
+
- `upColor`, `downColor`, `neutralColor`: Colors used when `colorByDelta: true`.
|
|
1384
|
+
- `showDeltas`: `true` to render direct delta badges (e.g. `+12%`, `-5`) next to the endpoints.
|
|
1385
|
+
- `showValues`: `true` to render numeric value labels at dots.
|
|
1386
|
+
- `pointRadius`: Radius of endpoint circles in pixels (default `5`).
|
|
1387
|
+
- `startLabel`, `endLabel`: Custom legend labels for the start and end series.
|
|
1388
|
+
|
|
1389
|
+
```javascript
|
|
1390
|
+
engine.dumbbellChart([
|
|
1391
|
+
{ label: 'Latency', start: 240, end: 110 },
|
|
1392
|
+
{ label: 'Throughput', start: 850, end: 1420 },
|
|
1393
|
+
{ label: 'Error Rate', start: 4.2, end: 0.8 },
|
|
1394
|
+
], { colorByDelta: true, showDeltas: true, showValues: true });
|
|
1395
|
+
```
|
|
1396
|
+
|
|
1397
|
+
### Slopegraph — `slopegraph(data, options)`
|
|
1398
|
+
|
|
1399
|
+
Connects categories across two or more discrete stages or time points to highlight hierarchy shifts, rate-of-change differences, and rank reversals.
|
|
1400
|
+
|
|
1401
|
+
- **Data shapes:**
|
|
1402
|
+
- `Array<{label: string, values: number[]}>` (multi-stage trajectory)
|
|
1403
|
+
- `Array<{label: string, start: number, end: number}>` (2-stage before/after)
|
|
1404
|
+
- **Notable options:**
|
|
1405
|
+
- `stageLabels`: Array of column headings for the stages (e.g. `['2024', '2025', '2026']`).
|
|
1406
|
+
- `showDirectLabels`: `true` (default) to label line endpoints directly, avoiding an external legend.
|
|
1407
|
+
- `labelSide`: `'both'` (default), `'left'`, or `'right'`.
|
|
1408
|
+
- `collisionAvoidance`: `true` (default) to run iterative vertical relaxation preventing overlapping text labels on crowded axes.
|
|
1409
|
+
- `lineWidth`: Stroke width of trajectory lines (default `2`).
|
|
1410
|
+
- `pointRadius`: Radius of dots at each stage (default `4`).
|
|
1411
|
+
- `highlightOnHover`: `true` (default) to dim competing lines on cursor hover.
|
|
1412
|
+
|
|
1413
|
+
```javascript
|
|
1414
|
+
engine.slopegraph([
|
|
1415
|
+
{ label: 'Product Alpha', values: [12, 19, 28] },
|
|
1416
|
+
{ label: 'Product Beta', values: [24, 21, 15] },
|
|
1417
|
+
{ label: 'Product Gamma', values: [8, 14, 22] },
|
|
1418
|
+
], { stageLabels: ['Q1', 'Q2', 'Q3'], showDirectLabels: true });
|
|
1419
|
+
```
|
|
1420
|
+
|
|
1421
|
+
### Ridgeline Plot (Joy Plot) — `ridgelineChart(data, options)`
|
|
1422
|
+
|
|
1423
|
+
Vertically staggered, partially overlapping Gaussian kernel density estimates (KDE) across multiple ordered or categorical groups. Ideal for comparing distributions over time or stages in compact vertical space.
|
|
1424
|
+
|
|
1425
|
+
- **Data shape:** `Array<{label: string, values: number[]}>` (raw sample observations per group).
|
|
1426
|
+
- **Notable options:**
|
|
1427
|
+
- `overlap`: Vertical overlap ratio between adjacent ridges (default `0.65`; `0` = non-overlapping rows, `1.0` = high overlap).
|
|
1428
|
+
- `fillOpacity`: Opacity of the filled ridge area under each density curve (default `0.74`).
|
|
1429
|
+
- `showMedian`: `true` (default) to draw vertical line ticks at each group's sample median.
|
|
1430
|
+
- `medianColor`: Color of the median tick indicator (default `'#ffffff'`).
|
|
1431
|
+
- `colors`: Palette array for ridges, or auto-assigned from workspace theme.
|
|
1432
|
+
|
|
1433
|
+
```javascript
|
|
1434
|
+
engine.ridgelineChart([
|
|
1435
|
+
{ label: 'Sprint 1', values: [14, 18, 22, 25, 27, 28, 30, 35, 42] },
|
|
1436
|
+
{ label: 'Sprint 2', values: [10, 12, 15, 18, 20, 22, 24, 26, 29] },
|
|
1437
|
+
{ label: 'Sprint 3', values: [8, 9, 11, 14, 16, 17, 18, 20, 22] },
|
|
1438
|
+
], { overlap: 0.7, showMedian: true });
|
|
1439
|
+
```
|
|
1440
|
+
|
|
1441
|
+
### Beeswarm & Raincloud Plot — `beeswarmChart(data, options)`
|
|
1442
|
+
|
|
1443
|
+
Plots every individual observation as a non-overlapping circle packed tightly along a category axis without jitter noise. Raincloud mode pairs the packed dot cloud with a half-KDE density violin and a compact box plot.
|
|
1444
|
+
|
|
1445
|
+
- **Data shape:** `Array<{label: string, values: number[]}>` (raw sample numbers per group).
|
|
1446
|
+
- **Notable options:**
|
|
1447
|
+
- `mode`: `'beeswarm'` (default; centered packed point swarm) or `'raincloud'` (half-violin cloud + box plot + offset swarm).
|
|
1448
|
+
- `radius`: Radius of each observation dot (default `3.5`).
|
|
1449
|
+
- `padding`: Minimum pixel gap between adjacent packed points (default `1`).
|
|
1450
|
+
- `halfViolin`: In raincloud mode, draws upper density envelope (default `true`).
|
|
1451
|
+
- `boxPlot`: In raincloud mode, draws embedded quartiles and median bar (default `true`).
|
|
1452
|
+
- `colors`: Array of categorical colors per group.
|
|
1453
|
+
|
|
1454
|
+
```javascript
|
|
1455
|
+
engine.beeswarmChart([
|
|
1456
|
+
{ label: 'Control', values: [2.1, 2.4, 2.5, 2.7, 2.9, 3.1, 3.2, 3.6, 4.0] },
|
|
1457
|
+
{ label: 'Treatment', values: [3.2, 3.5, 3.8, 4.1, 4.2, 4.5, 4.8, 5.2, 5.9] },
|
|
1458
|
+
], { mode: 'raincloud', radius: 4 });
|
|
1459
|
+
```
|
|
1460
|
+
|
|
1461
|
+
### Empirical Cumulative Distribution Function — `ecdfChart(data, options)`
|
|
1462
|
+
|
|
1463
|
+
Draws exact empirical step CDFs \(P(X \le x)\) from 0 to 1, comparing distributions without bin-width artifacts. Includes automated Kolmogorov-Smirnov distance calculations.
|
|
1464
|
+
|
|
1465
|
+
- **Data shapes:**
|
|
1466
|
+
- `number[]` (single sample)
|
|
1467
|
+
- `Array<{label: string, values: number[]}>` (multi-group comparison)
|
|
1468
|
+
- **Notable options:**
|
|
1469
|
+
- `showMedian`: `true` (default) to project dashed 50th-percentile lines to axes.
|
|
1470
|
+
- `showQuantiles`: `true` to annotate 25th, 50th, and 75th percentile markers.
|
|
1471
|
+
- `step`: Step interpolation style (`'vh'` default: vertical-then-horizontal, or `'hv'`).
|
|
1472
|
+
- `compare`: When two series are supplied, calculates and highlights the maximum vertical distance \(D_{KS}\) (`EcdfChart.ksDistance(s1, s2)`).
|
|
1473
|
+
- `colors`: Palette array for series steps.
|
|
1474
|
+
|
|
1475
|
+
```javascript
|
|
1476
|
+
engine.ecdfChart([
|
|
1477
|
+
{ label: 'Algorithm A', values: [12, 15, 18, 22, 25, 29, 34, 40] },
|
|
1478
|
+
{ label: 'Algorithm B', values: [8, 11, 14, 16, 19, 21, 24, 28] },
|
|
1479
|
+
], { showMedian: true, compare: true });
|
|
1480
|
+
```
|
|
1481
|
+
|
|
1482
|
+
### Hexagonal 2D Density Binning — `hexbinChart(data, options)`
|
|
1483
|
+
|
|
1484
|
+
Aggregates dense 2D scatter coordinate clouds into regular hexagonal tiles, preventing visual saturation and overplotting in large point datasets.
|
|
1485
|
+
|
|
1486
|
+
- **Data shapes:**
|
|
1487
|
+
- `Array<{x: number, y: number, value?: number}>`
|
|
1488
|
+
- `Array<[x: number, y: number]>`
|
|
1489
|
+
- **Notable options:**
|
|
1490
|
+
- `radius`: Outer radius of each hexagon cell in pixels (default `14`).
|
|
1491
|
+
- `minCount`: Minimum point count threshold required to render a cell (default `1`).
|
|
1492
|
+
- `colorScale`: Sequential color palette array (e.g. `['#e0f3f8', '#67a9cf', '#02818a', '#bd0026']`).
|
|
1493
|
+
- `title`, `xAxisLabel`, `yAxisLabel`: Chart and axis labels.
|
|
1494
|
+
|
|
1495
|
+
```javascript
|
|
1496
|
+
const points = Array.from({ length: 5000 }, () => ({
|
|
1497
|
+
x: Math.random() * 100,
|
|
1498
|
+
y: Math.random() * 100,
|
|
1499
|
+
}));
|
|
1500
|
+
engine.hexbinChart(points, { radius: 12, minCount: 2 });
|
|
1501
|
+
```
|
|
1502
|
+
|
|
1503
|
+
### Horizon Chart — `horizonChart(data, options)`
|
|
1504
|
+
|
|
1505
|
+
Folds continuous time-series magnitude into 2 to 5 layered colored bands within a narrow vertical band (e.g. 30–50px), preserving high precision while displaying dozens of series simultaneously.
|
|
1506
|
+
|
|
1507
|
+
- **Data shape:** `Array<{label: string, values: number[]}>`
|
|
1508
|
+
- **Notable options:**
|
|
1509
|
+
- `bands`: Number of layered folding bands (default `3`).
|
|
1510
|
+
- `posColors`: Color gradient array for positive values (default 3-stage blues).
|
|
1511
|
+
- `negColors`: Color gradient array for negative values (default 3-stage reds).
|
|
1512
|
+
- `title`: Chart title.
|
|
1513
|
+
|
|
1514
|
+
```javascript
|
|
1515
|
+
engine.horizonChart([
|
|
1516
|
+
{ label: 'CPU Core 0', values: [10, 25, 45, 80, 95, 60, 40, 30] },
|
|
1517
|
+
{ label: 'CPU Core 1', values: [-15, 20, 50, 70, 85, 45, 20, -10] },
|
|
1518
|
+
], { bands: 3 });
|
|
1519
|
+
```
|
|
1520
|
+
|
|
1521
|
+
### Circle Packing — `circlePackChart(data, options)`
|
|
1522
|
+
|
|
1523
|
+
Represents hierarchical tree structures as nested tangent circles sized by value, with translucent ancestor boundary rings and hover elevation.
|
|
1524
|
+
|
|
1525
|
+
- **Data shape:** Hierarchical tree `Array<{label: string, value?: number, children?: Array}>`
|
|
1526
|
+
- **Notable options:**
|
|
1527
|
+
- `padding`: Pixel gap between tangent sibling circles (default `2`).
|
|
1528
|
+
- `showLabels`: `true` (default) to label circles that have sufficient interior area.
|
|
1529
|
+
- `minLabelRadius`: Minimum circle radius in pixels required to render text inside (default `14`).
|
|
1530
|
+
- `colors`: Palette array mapped across top-level tree branches.
|
|
1531
|
+
|
|
1532
|
+
```javascript
|
|
1533
|
+
engine.circlePackChart([{
|
|
1534
|
+
label: 'Architecture',
|
|
1535
|
+
children: [
|
|
1536
|
+
{ label: 'Backend', children: [{ label: 'API', value: 40 }, { label: 'DB', value: 30 }] },
|
|
1537
|
+
{ label: 'Frontend', children: [{ label: 'Web', value: 25 }, { label: 'Mobile', value: 15 }] },
|
|
1538
|
+
],
|
|
1539
|
+
}], { padding: 4 });
|
|
1540
|
+
```
|
|
1541
|
+
|
|
1542
|
+
### Alluvial Diagram — `alluvialDiagram(data, options)`
|
|
1543
|
+
|
|
1544
|
+
Visualizes categorical flows across three or more sequential dimensions using smooth cubic bezier ribbons whose widths represent flow volumes.
|
|
1545
|
+
|
|
1546
|
+
- **Data shapes:**
|
|
1547
|
+
- Multi-stage pathway list: `Array<{steps: string[], value: number}>`
|
|
1548
|
+
- Tabular rows: `{dimensions: string[], rows: Array<object>}`
|
|
1549
|
+
- Edge list: `Array<{source: string, target: string, value: number}>`
|
|
1550
|
+
- **Notable options:**
|
|
1551
|
+
- `dimensions`: Array of dimension stage names (e.g. `['Role', 'Department', 'Access Level']`).
|
|
1552
|
+
- `nodeWidth`: Width of category pillar rectangles in pixels (default `18`).
|
|
1553
|
+
- `nodePadding`: Vertical separation between category nodes (default `12`).
|
|
1554
|
+
- `curvature`: Bezier curvature ratio for flow links (default `0.5`).
|
|
1555
|
+
- `linkOpacity`: Fill opacity for flow ribbons (default `0.55`).
|
|
1556
|
+
- `colors`: Palette array for node categories.
|
|
1557
|
+
|
|
1558
|
+
```javascript
|
|
1559
|
+
engine.alluvialDiagram([
|
|
1560
|
+
{ steps: ['Engineering', 'Senior', 'Admin'], value: 12 },
|
|
1561
|
+
{ steps: ['Engineering', 'Junior', 'User'], value: 28 },
|
|
1562
|
+
{ steps: ['Product', 'Lead', 'Admin'], value: 5 },
|
|
1563
|
+
{ steps: ['Product', 'Analyst', 'User'], value: 15 },
|
|
1564
|
+
], { dimensions: ['Department', 'Seniority', 'Permission'] });
|
|
1565
|
+
```
|
|
1566
|
+
|
|
1567
|
+
### Polar Area (Nightingale Rose) — `polarAreaChart(data, options)`
|
|
1568
|
+
|
|
1569
|
+
Divides a circle into equal angular sectors where the radial distance (or area) of each sector represents its magnitude. Supports optional 3D isometric extrusion and interactive wedge pull-out.
|
|
1570
|
+
|
|
1571
|
+
- **Data shape:** `Array<{label: string, value: number, exploded?: boolean}>`
|
|
1572
|
+
- **Notable options:**
|
|
1573
|
+
- `scale`: `'radius'` (linear radial distance) or `'area'` (square-root scaling so slice area is proportional to value).
|
|
1574
|
+
- `extrude3D`: `true` to render as an isometric 3D cylindrical cylinder with depth shading.
|
|
1575
|
+
- `depth`: Extrusion height in pixels when `extrude3D: true` (default `22`).
|
|
1576
|
+
- `innerRadiusRatio`: Donut hole ratio (default `0.12`).
|
|
1577
|
+
- `padAngle`: Angular spacing between sectors in radians (default `0.02`).
|
|
1578
|
+
- `hoverExplode`: `true` to pull out wedges under the cursor.
|
|
1579
|
+
|
|
1580
|
+
```javascript
|
|
1581
|
+
engine.polarAreaChart([
|
|
1582
|
+
{ label: 'North', value: 45 },
|
|
1583
|
+
{ label: 'East', value: 80 },
|
|
1584
|
+
{ label: 'South', value: 35 },
|
|
1585
|
+
{ label: 'West', value: 60 },
|
|
1586
|
+
], { scale: 'area', extrude3D: true, depth: 25 });
|
|
1587
|
+
```
|
|
1588
|
+
|
|
1589
|
+
### 3D Surface Mesh — `surfaceChart3D(data, options)`
|
|
1590
|
+
|
|
1591
|
+
Renders continuous 3D mathematical surfaces, terrain elevations, or 2D matrix loss landscapes using true 4×4 perspective transformations and interactive orbit camera rotation.
|
|
1592
|
+
|
|
1593
|
+
- **Data shapes:**
|
|
1594
|
+
- Regular grid: `{xLabels: string[]|number[], zLabels: string[]|number[], values: number[][]}`
|
|
1595
|
+
- Coordinate tuples: `Array<{x: string|number, z: string|number, value: number}>`
|
|
1596
|
+
- **Notable options:**
|
|
1597
|
+
- `wireframe`: `true` (default) to overlay contrasting grid lines on surface polygons.
|
|
1598
|
+
- `wireframeColor`: Stroke color for wireframe lines (default `'rgba(255,255,255,0.45)'`).
|
|
1599
|
+
- `colorScale`: Array of gradient color stops for height-based surface shading.
|
|
1600
|
+
- `initialTheta`, `initialPhi`, `initialDistance`: Initial camera angles and zoom distance.
|
|
1601
|
+
- Orbit interaction: Drag to rotate camera azimuth and elevation, mouse wheel to zoom in/out.
|
|
1602
|
+
|
|
1603
|
+
```javascript
|
|
1604
|
+
const xLabels = [-2, -1, 0, 1, 2];
|
|
1605
|
+
const zLabels = [-2, -1, 0, 1, 2];
|
|
1606
|
+
const values = xLabels.map(x => zLabels.map(z => Math.sin(Math.sqrt(x * x + z * z))));
|
|
1607
|
+
|
|
1608
|
+
engine.surfaceChart3D({ xLabels, zLabels, values }, {
|
|
1609
|
+
title: 'Bivariate Ripple Surface',
|
|
1610
|
+
wireframe: true,
|
|
1611
|
+
});
|
|
1612
|
+
```
|
|
1613
|
+
|
|
1614
|
+
### Contour Plot — `contourChart(data, options)`
|
|
1615
|
+
|
|
1616
|
+
Generates smooth isoline curves and filled isoband color regions from 2D scalar fields using the marching-squares algorithm with automated numeric elevation labels.
|
|
1617
|
+
|
|
1618
|
+
- **Data shapes:**
|
|
1619
|
+
- 2D scalar matrix: `number[][]` (rows × columns)
|
|
1620
|
+
- Coordinate list: `Array<{x: number, y: number, value: number}>`
|
|
1621
|
+
- **Notable options:**
|
|
1622
|
+
- `levels`: Number of contour threshold intervals (default `8`), or an explicit array of numbers `[0.1, 0.25, 0.5, 0.75]`.
|
|
1623
|
+
- `filled`: `true` (default) to render shaded polygon bands between isolines.
|
|
1624
|
+
- `showLines`: `true` (default) to stroke isoline boundaries.
|
|
1625
|
+
- `showLabels`: `true` (default) to annotate contour lines with numeric elevation values.
|
|
1626
|
+
- `colorScale`: Array of colors interpolated across contour levels.
|
|
1627
|
+
- `lineColor`: Stroke color for isolines (default `'rgba(0,0,0,0.3)'`).
|
|
1628
|
+
|
|
1629
|
+
```javascript
|
|
1630
|
+
const grid = [
|
|
1631
|
+
[0.1, 0.2, 0.4, 0.2, 0.1],
|
|
1632
|
+
[0.2, 0.6, 0.9, 0.6, 0.2],
|
|
1633
|
+
[0.4, 0.9, 1.0, 0.9, 0.4],
|
|
1634
|
+
[0.2, 0.6, 0.9, 0.6, 0.2],
|
|
1635
|
+
[0.1, 0.2, 0.4, 0.2, 0.1],
|
|
1636
|
+
];
|
|
1637
|
+
engine.contourChart(grid, { levels: 6, filled: true, showLabels: true });
|
|
1638
|
+
```
|
|
1639
|
+
|
|
1343
1640
|
## Common options
|
|
1344
1641
|
|
|
1345
1642
|
Not every method takes every option below — the table above calls out what's notable per type —
|
|
@@ -1523,10 +1820,10 @@ data — `addDataPoint` is a **no-op** when it's `'none'`:
|
|
|
1523
1820
|
|
|
1524
1821
|
| `streamShape` | Chart types | Behavior |
|
|
1525
1822
|
|---|---|---|
|
|
1526
|
-
| `flat` | `bar`, `pie`, `scatter`, `bubble`, `candlestick`, `stackedBar`, `funnel`, `waterfall`, `histogram`, `qq`, `lag`, `treemap`, `sunburst`, `outline`, `bar3D`, `bubble3D` | one new record appended to the outer array |
|
|
1527
|
-
| `series` | `line`, `area`, `pipe` | every series' own `values` grows by one point |
|
|
1528
|
-
| `grouped-sample` | `boxPlot`, `density`, `violin` | exactly ONE randomly-chosen group's `values` grows (a new sample observation belongs to one group, unlike a shared time axis) |
|
|
1529
|
-
| `none` | `heatmap`, `radar` (fixed matrix/axis-set), `bar3DOrbit`/`stackedBar3DOrbit` (fixed grid), `gauge-dial`/`gauge-bar`/`bullet` (a value to replace, not a window) | `addDataPoint` no-ops — for gauges, just call `dialGauge(newValue)`/`barGauge(newValue)`/`bulletGauge(newValue)` again directly |
|
|
1823
|
+
| `flat` | `bar`, `pie`, `scatter`, `bubble`, `candlestick`, `stackedBar`, `funnel`, `waterfall`, `histogram`, `qq`, `lag`, `treemap`, `sunburst`, `outline`, `bar3D`, `bubble3D`, `dumbbell`, `slopegraph`, `circlePack`, `horizon`, `polarArea`, `hexbin`, `pareto`, `lollipop` | one new record appended to the outer array |
|
|
1824
|
+
| `series` | `line`, `area`, `pipe`, `combo` | every series' own `values` grows by one point |
|
|
1825
|
+
| `grouped-sample` | `boxPlot`, `density`, `violin`, `ecdf`, `beeswarm`, `ridgeline` | exactly ONE randomly-chosen group's `values` grows (a new sample observation belongs to one group, unlike a shared time axis) |
|
|
1826
|
+
| `none` | `heatmap`, `radar` (fixed matrix/axis-set), `bar3DOrbit`/`stackedBar3DOrbit`/`surface3D` (fixed grid), `gauge-dial`/`gauge-bar`/`bullet` (a value to replace, not a window), `alluvial`, `contour`, `splom` | `addDataPoint` no-ops — for gauges, just call `dialGauge(newValue)`/`barGauge(newValue)`/`bulletGauge(newValue)` again directly |
|
|
1530
1827
|
|
|
1531
1828
|
### 2. Graphs — `addGraphNode`
|
|
1532
1829
|
|
|
@@ -2640,6 +2937,8 @@ end. Waypoints and style are kept, and that end's side pin resets to automatic.
|
|
|
2640
2937
|
empty canvas, or on the shape at the other end, cancels. This is one undo step
|
|
2641
2938
|
(`ReconnectEdgeCommand`).
|
|
2642
2939
|
|
|
2940
|
+
**Container nesting and hierarchy.** Shapes such as `PackageTemplate`, `SwimlaneTemplate`, and `BoxTemplate` are containers (`isContainer = true`). When an element is dropped inside a container (`nestsOnDrop(parentId, childId)`), it is parented via `NestElementCommand` (setting `child.parentId`). Moving a container recursively moves all nested descendants (`moversFor(templateId)`). Containers can automatically expand their bounds to fit their contents via `fitNesting(changes, { padding })`. Ancestor loops are prevented (`isAncestor(childId, parentId)`).
|
|
2941
|
+
|
|
2643
2942
|
**Line style levels.** A line's style resolves through `EdgeStyleCascade`: the line itself,
|
|
2644
2943
|
then each level in `editor.edgeStyleLevels` (most specific first, `[{ key, label, style }]`),
|
|
2645
2944
|
then the schema default. A value a level doesn't set is inherited. `EDGE_STYLE_PROPERTIES` is the
|
|
@@ -3235,8 +3534,20 @@ saying why. The delivery plan's periods are put on a calendar: period 1 starts a
|
|
|
3235
3534
|
the report's as-of business time, else today), each `periodDays` long (default 14). Each view is a
|
|
3236
3535
|
`WorkbenchView` subclass (`WORKBENCH_VIEWS`); a new view is a new subclass.
|
|
3237
3536
|
|
|
3238
|
-
|
|
3239
|
-
|
|
3537
|
+
In a workspace the workbench is one part, `DecisionWorkbenchPart` (type `decision-workbench`), a
|
|
3538
|
+
`ViewsPart` that reads workbench documents: a tab per view, its charts and notes, a toolbar that opens a
|
|
3539
|
+
file and sets the calendar.
|
|
3540
|
+
|
|
3541
|
+
```js
|
|
3542
|
+
const { registerBuiltinParts, ChartPart, DecisionWorkbenchPart } = RenderEngineWorkspace;
|
|
3543
|
+
ws.registerParts([ChartPart, DecisionWorkbenchPart]);
|
|
3544
|
+
ws.addParts([{ id: 'workbench', type: 'decision-workbench', document /* optional */, start, periodDays }]);
|
|
3545
|
+
```
|
|
3546
|
+
|
|
3547
|
+
`ViewsPart` (type `views`) is the general part underneath: any `{ views: [{ id, title, charts, notes }] }`
|
|
3548
|
+
document, or views given in its spec, shown the same way — see `documentation/WORKSPACE_ARCHITECTURE.md`
|
|
3549
|
+
for why it is one part and why a new kind of document is a subclass. `examples/decision-workbench.html`
|
|
3550
|
+
is a thin host of the workbench part (it is in the package).
|
|
3240
3551
|
|
|
3241
3552
|
## Navigation menus
|
|
3242
3553
|
|
|
@@ -3349,6 +3660,185 @@ const bar = RenderEngine.askBar(document.getElementById('ask-bar'), {
|
|
|
3349
3660
|
- **For a host:** `bar.setSuggest(fn)` swaps where suggestions come from, for example when the user picks another model or ontology. `bar.setValue(text)` sets the question without suggesting. `bar.focus()` puts the cursor in the question, and `bar.destroy()` removes the bar and cancels any pending close.
|
|
3350
3661
|
- **Accessible:** the input is a WAI-ARIA combobox over a `listbox` of `option`s. `aria-expanded` follows the popup and `aria-activedescendant` follows the active item. Each bar's list has its own id, so several bars can share a page.
|
|
3351
3662
|
|
|
3663
|
+
## Navigator & Relationship Explorer (`NavigatorModel` / `NavigatorPanel`)
|
|
3664
|
+
|
|
3665
|
+
`NavigatorModel` (`src/charting/modelTree/NavigatorModel.js`) and `NavigatorPanel` (`src/charting/modelTree/NavigatorPanel.js`) provide interactive graph traversal and relationship exploration for models. It enables navigating through connected elements step-by-step to arbitrary depth with cycle detection, navigation history (back/forward), direction filters, path-finding, and transitive impact analysis.
|
|
3666
|
+
|
|
3667
|
+
```javascript
|
|
3668
|
+
import { NavigatorModel, NavigatorPanel, buildNavigatorPanel } from '@peter.prib/renderengine';
|
|
3669
|
+
|
|
3670
|
+
// 1. Create a pure, DOM-free traversal model:
|
|
3671
|
+
const nav = new NavigatorModel(archimateModel, {
|
|
3672
|
+
rootId: 'billing-app',
|
|
3673
|
+
direction: 'both', // 'both' | 'outgoing' | 'incoming'
|
|
3674
|
+
allowedKinds: ['serving-relationship', 'composition-relationship'],
|
|
3675
|
+
});
|
|
3676
|
+
|
|
3677
|
+
nav.focus('crm-app');
|
|
3678
|
+
nav.canGoBack; // true
|
|
3679
|
+
nav.back(); // returns to 'billing-app'
|
|
3680
|
+
|
|
3681
|
+
// Find all paths between two elements (up to maxDepth):
|
|
3682
|
+
const paths = nav.findPaths('billing-app', 'ledger-db', 5);
|
|
3683
|
+
|
|
3684
|
+
// Trace transitive downstream or upstream impact:
|
|
3685
|
+
const impact = nav.findImpact('billing-app', { maxDepth: 4, direction: 'outgoing' });
|
|
3686
|
+
|
|
3687
|
+
// 2. Build or render the Navigator UI panel:
|
|
3688
|
+
const panel = new NavigatorPanel({
|
|
3689
|
+
model: archimateModel,
|
|
3690
|
+
navigator: nav,
|
|
3691
|
+
onSelectElement: (elId) => editor.selectElement(elId),
|
|
3692
|
+
onOpenView: (viewId) => editor.openView(viewId),
|
|
3693
|
+
});
|
|
3694
|
+
```
|
|
3695
|
+
|
|
3696
|
+
- **DOM-free engine:** `NavigatorModel` operates completely without DOM dependencies, making it directly testable in Node.js and reusable across diverse UI shells.
|
|
3697
|
+
- **Cycle detection and path tracking:** Tracks visited nodes along active branches to prevent infinite recursion in cyclic relationship graphs, annotating cycles in tree outputs.
|
|
3698
|
+
- **Directional filters:** Traversal can follow outgoing relationships, incoming relationships, or bidirectional connections (`setDirection('outgoing' | 'incoming' | 'both')`).
|
|
3699
|
+
- **History stack:** Maintains full forward and backward navigation stacks (`focus(id)`, `back()`, `forward()`, `canGoBack`, `canGoForward`).
|
|
3700
|
+
- **Impact and path finding:** Built-in BFS/DFS algorithms find connecting pathways (`findPaths(fromId, toId, maxDepth)`) and downstream dependency cascades (`findImpact(elementId, { maxDepth, direction })`).
|
|
3701
|
+
|
|
3702
|
+
## Templated Reports (`TemplatedReport`)
|
|
3703
|
+
|
|
3704
|
+
`TemplatedReport` (`src/charting/report/TemplatedReport.js`) provides multi-format, template-driven report generation matching Archi's Jasper-style reporting capabilities. It extracts model metadata, viewpoints, diagrams (SVG/PNG), elements, properties, and relationships into document formats.
|
|
3705
|
+
|
|
3706
|
+
```javascript
|
|
3707
|
+
import { TemplatedReport, REPORT_TEMPLATES } from '@peter.prib/renderengine';
|
|
3708
|
+
|
|
3709
|
+
const report = new TemplatedReport(archimateModel, {
|
|
3710
|
+
title: 'Enterprise Architecture Overview',
|
|
3711
|
+
template: REPORT_TEMPLATES.DETAILED, // 'executive' | 'detailed' | 'tabular'
|
|
3712
|
+
pictures: { 'view-1': 'data:image/svg+xml;utf8,...' },
|
|
3713
|
+
});
|
|
3714
|
+
|
|
3715
|
+
// Generate various formats:
|
|
3716
|
+
const htmlDoc = report.toHtml({ printable: true }); // PDF-ready HTML with @media print CSS
|
|
3717
|
+
const wordDoc = report.toWord(); // Microsoft Word (.doc HTML format)
|
|
3718
|
+
const excelXml = report.toExcel(); // Excel SpreadsheetML (.xml)
|
|
3719
|
+
const csvData = report.toCsv('elements'); // RFC 4180 CSV ('elements' | 'relationships')
|
|
3720
|
+
const markdown = report.toMarkdown(); // GitHub-flavored Markdown
|
|
3721
|
+
```
|
|
3722
|
+
|
|
3723
|
+
- **Output formats:** Generates printable PDF-ready HTML with page-break controls, Word-compatible HTML documents (`.doc`), Excel SpreadsheetML workbooks (`.xml`) with styled headers and filters, RFC 4180 CSV tables, and GitHub-flavored Markdown (`.md`).
|
|
3724
|
+
- **Built-in templates:** Includes `REPORT_TEMPLATES.EXECUTIVE` (high-level summary with diagrams), `REPORT_TEMPLATES.DETAILED` (full catalog of views, elements, relationships, and user properties), and `REPORT_TEMPLATES.TABULAR` (matrix-focused presentation).
|
|
3725
|
+
- **Embedded diagram pictures:** Accepts rendered SVG data URIs or base64 raster images in the `pictures` dictionary keyed by view ID to embed high-resolution diagrams directly into generated documents.
|
|
3726
|
+
|
|
3727
|
+
## Sketch Views & Palettes (`SketchView` / `sketchBoxKinds`)
|
|
3728
|
+
|
|
3729
|
+
`SketchView` (`src/charting/diagrams/SketchView.js`) implements freeform sketching views (corresponding to Archi's `archimate:SketchModel`). It supports sticky notes, stick-figure actors, groups, freehand lines, and customizable palettes on grid or lined canvas backgrounds.
|
|
3730
|
+
|
|
3731
|
+
```javascript
|
|
3732
|
+
import { SketchView, SKETCH_BOX_KINDS, DEFAULT_SKETCH_PALETTE } from '@peter.prib/renderengine';
|
|
3733
|
+
|
|
3734
|
+
const sketch = new SketchView(model, {
|
|
3735
|
+
name: 'Brainstorming Session',
|
|
3736
|
+
background: SketchView.BACKGROUNDS.GRID, // NONE (0), GRID (1), LINES (2)
|
|
3737
|
+
palette: DEFAULT_SKETCH_PALETTE,
|
|
3738
|
+
});
|
|
3739
|
+
|
|
3740
|
+
// Custom palette management:
|
|
3741
|
+
sketch.addPaletteItem({ id: 'custom-note', name: 'Critical Note', fill: '#ffcccc' });
|
|
3742
|
+
const jsonConfig = sketch.exportPalette();
|
|
3743
|
+
sketch.importPalette(jsonConfig);
|
|
3744
|
+
```
|
|
3745
|
+
|
|
3746
|
+
- **Sketch box types:** Native support for sticky notes (`sketch-model-sticky`) and stick figures (`sketch-model-actor`) via `SKETCH_BOX_KINDS`.
|
|
3747
|
+
- **Background styles:** Configurable canvas backgrounds including plain (`NONE`), grid paper (`GRID`), and lined notebook paper (`LINES`).
|
|
3748
|
+
- **Palette customization:** Dynamically add, remove, reset, export, and import custom sticky colors and presets as JSON configurations.
|
|
3749
|
+
- **Archi XML compatibility:** Full bi-directional fidelity with `.archimate` sketch model XML representations (`archimate:SketchModel`, `archimate:Sticky`, `archimate:Actor`).
|
|
3750
|
+
|
|
3751
|
+
## Cross-Model Data Lineage & ArchiMate Linking
|
|
3752
|
+
|
|
3753
|
+
`ModelMapping` (`src/charting/datamodel/ModelMapping.js`), `DataLineage` (`src/charting/datamodel/DataLineage.js`), and `ArchimateDataLink` (`src/charting/datamodel/ArchimateDataLink.js`) extend the data modeling subsystem (`src/charting/datamodel/`) with enterprise cross-model data lineage and architectural traceability aligned with DMBOK2 and TOGAF.
|
|
3754
|
+
|
|
3755
|
+
```javascript
|
|
3756
|
+
import { DataModel, ModelMapping, DataLineage, ArchimateDataLink } from '@peter.prib/renderengine';
|
|
3757
|
+
|
|
3758
|
+
// 1. Cross-model mapping with attribute-level transformation rules:
|
|
3759
|
+
const mapping = new ModelMapping({
|
|
3760
|
+
name: 'Core Banking to EDW',
|
|
3761
|
+
sourceModel: 'OLTP-Core',
|
|
3762
|
+
targetModel: 'EDW-Analytical',
|
|
3763
|
+
entityMappings: [{ sourceEntityId: 'account', targetEntityId: 'dim_account', rule: 'SCD Type 2' }],
|
|
3764
|
+
attributeMappings: [
|
|
3765
|
+
{ sourceEntityId: 'account', sourceAttribute: 'bal', targetEntityId: 'dim_account', targetAttribute: 'current_balance', transformation: 'ROUND(bal, 2)' }
|
|
3766
|
+
],
|
|
3767
|
+
});
|
|
3768
|
+
|
|
3769
|
+
dataModel.addModelMapping(mapping);
|
|
3770
|
+
|
|
3771
|
+
// 2. Trace end-to-end lineage and downstream impact:
|
|
3772
|
+
const lineage = dataModel.crossModelLineage();
|
|
3773
|
+
const upstreamHops = lineage.traceLineage('dim_account', 'current_balance'); // Upstream provenance
|
|
3774
|
+
const downstreamImpact = lineage.traceImpact('account', 'bal'); // Downstream impact
|
|
3775
|
+
|
|
3776
|
+
// 3. Connect Data Model entities to ArchiMate enterprise architecture:
|
|
3777
|
+
const link = new ArchimateDataLink({
|
|
3778
|
+
dataModelEntityId: 'account',
|
|
3779
|
+
level: 'conceptual',
|
|
3780
|
+
archimateElementId: 'business-obj-account',
|
|
3781
|
+
archimateType: 'business-object',
|
|
3782
|
+
});
|
|
3783
|
+
dataModel.addArchimateLink(link);
|
|
3784
|
+
```
|
|
3785
|
+
|
|
3786
|
+
- **DMBOK2 integration:** Enables tracking provenance across conceptual, logical, and physical models, including disparate source and target data stores.
|
|
3787
|
+
- **Multi-hop traversal:** Traces multi-hop transformations forwards (`traceImpact`) and backwards (`traceLineage`) across complex data pipelines.
|
|
3788
|
+
- **ArchiMate alignment:** Bridges data model entities to ArchiMate Business Objects (Business Layer), Data Objects (Application Layer), and Artifacts (Technology Layer).
|
|
3789
|
+
|
|
3790
|
+
## Multi-View Chart Dashboards (`ViewsPart` / `DecisionWorkbenchPart`)
|
|
3791
|
+
|
|
3792
|
+
`ViewsPart` (`src/workspace/parts/ViewsPart.js`, type `views`) shows a set of chart **views** inside
|
|
3793
|
+
one workspace part: a tab per view, each a grid of charts with its notes underneath, and a toolbar that
|
|
3794
|
+
opens a file. A view is plain data:
|
|
3795
|
+
|
|
3796
|
+
```js
|
|
3797
|
+
{ id: 'summary', title: 'Summary',
|
|
3798
|
+
charts: [{ title, chartType, data, options? }], // chartType: a CHART_CATALOG key ('kpi-tile', 'bar', 'gantt', …)
|
|
3799
|
+
notes: ['plain lines the charts cannot show'] }
|
|
3800
|
+
```
|
|
3801
|
+
|
|
3802
|
+
Like any part it is registered, added with `addParts`, and placed in a layout by its `partId`. It uses
|
|
3803
|
+
`ChartPart`, so it is registered with it rather than being among `BUILTIN_PARTS`:
|
|
3804
|
+
|
|
3805
|
+
```js
|
|
3806
|
+
const { registerBuiltinParts, ChartPart, ViewsPart } = RenderEngineWorkspace;
|
|
3807
|
+
registerBuiltinParts(ws);
|
|
3808
|
+
ws.registerParts([ChartPart, ViewsPart]);
|
|
3809
|
+
ws.addParts([{
|
|
3810
|
+
id: 'summary', type: 'views', title: 'Summary',
|
|
3811
|
+
views: [{
|
|
3812
|
+
id: 'health', title: 'Health',
|
|
3813
|
+
charts: [
|
|
3814
|
+
{ title: 'Availability (%)', chartType: 'kpi-tile', data: { value: 99.95 } },
|
|
3815
|
+
{ title: 'Errors by service', chartType: 'bar', data: [{ label: 'api', value: 12 }, { label: 'web', value: 3 }] },
|
|
3816
|
+
],
|
|
3817
|
+
notes: ['All latency thresholds met'],
|
|
3818
|
+
}],
|
|
3819
|
+
}]);
|
|
3820
|
+
ws.registerPerspective('Summary', { type: 'part', partId: 'summary' });
|
|
3821
|
+
```
|
|
3822
|
+
|
|
3823
|
+
- **One part, any layout.** It sits in a tab, a split, a dashboard cell or a WorkArea document beside
|
|
3824
|
+
what else the host shows; it does not register perspectives of its own.
|
|
3825
|
+
- **Composed from existing parts.** Each chart is a `ChartPart`, the notes a `ListPart`. Gauge-like
|
|
3826
|
+
charts (catalog `category: 'gauge'`, e.g. `kpi-tile`, `gauge-bar`, `bullet`) share the top row as
|
|
3827
|
+
tiles; other charts take half a row, or the whole row when a view has one (`ViewsPart.layout(views)`).
|
|
3828
|
+
- **Spec:** `views`, `open` (default true: the toolbar's file opener), `empty` (the text shown with no
|
|
3829
|
+
views). `part.read(doc)` shows a `{ views: [...] }` document from code. The views shown are kept in
|
|
3830
|
+
`spec.views`, so a serialized workspace comes back showing them.
|
|
3831
|
+
- **Other kinds of document** are subclasses overriding `viewsFrom(doc)` (and `accept`, `controls()`,
|
|
3832
|
+
`controlValues()` for options their reader takes). Why a subclass and not a reader in the spec, and
|
|
3833
|
+
why one part rather than perspectives: `documentation/WORKSPACE_ARCHITECTURE.md` (Parts).
|
|
3834
|
+
|
|
3835
|
+
`DecisionWorkbenchPart` (`src/workspace/parts/DecisionWorkbenchPart.js`, type `decision-workbench`) is
|
|
3836
|
+
the first such subclass. It reads a SADIS workbench document from decisionengine
|
|
3837
|
+
(`{ kind: 'sadis-workbench', report, plan?, before? }`) through `DecisionWorkbench` and shows its
|
|
3838
|
+
**executive**, **architecture**, **delivery**, **portfolio** and **replay** views (see *Decision
|
|
3839
|
+
Workbench* above), with toolbar fields for the calendar the delivery plan is drawn on. Spec: `ViewsPart`'s
|
|
3840
|
+
plus `document`, `start`, `periodDays`. `examples/decision-workbench.html` hosts one.
|
|
3841
|
+
|
|
3352
3842
|
## Where to go next
|
|
3353
3843
|
|
|
3354
3844
|
- **`ARCHITECTURE.md`** — module layout, the chart-type catalog mechanics, how to add a new chart type.
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html>
|
|
3
|
+
<head><meta charset="utf-8"><title>Decision Workbench</title></head>
|
|
4
|
+
<body style="margin:0;height:100vh;display:flex;font:14px system-ui">
|
|
5
|
+
<!--
|
|
6
|
+
The Decision Workbench: decisionengine's SADIS recommendation, drawn. A thin host, as data-model.html is:
|
|
7
|
+
everything it does is DecisionWorkbenchPart's (reading a workbench file, the calendar) and ViewsPart's
|
|
8
|
+
(a tab per view, its charts and notes, opening a file). Open a workbench file — decisionengine's SADIS
|
|
9
|
+
Explorer downloads one ("Download for the Decision Workbench"). Runs straight off disk.
|
|
10
|
+
-->
|
|
11
|
+
<script src="../dist/renderengine-workspace.umd.js"></script>
|
|
12
|
+
<script>
|
|
13
|
+
const { el, registerBuiltinParts, ChartPart, DecisionWorkbenchPart } = window.RenderEngineWorkspace;
|
|
14
|
+
const ws = document.body.appendChild(el({
|
|
15
|
+
tag: 'ws-workspace',
|
|
16
|
+
attrs: { label: 'Decision Workbench', theme: 'light' },
|
|
17
|
+
style: { flex: '1 1 auto', minHeight: '0' },
|
|
18
|
+
}));
|
|
19
|
+
registerBuiltinParts(ws);
|
|
20
|
+
ws.registerParts([ChartPart, DecisionWorkbenchPart]);
|
|
21
|
+
ws.addParts([{ id: 'workbench', type: 'decision-workbench', title: 'Decision Workbench' }]);
|
|
22
|
+
ws.registerPerspective('Decision Workbench', { type: 'part', partId: 'workbench' });
|
|
23
|
+
ws.activatePerspective('Decision Workbench');
|
|
24
|
+
</script>
|
|
25
|
+
</body>
|
|
26
|
+
</html>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@peter.prib/renderengine",
|
|
3
|
-
"version": "0.15.
|
|
3
|
+
"version": "0.15.2",
|
|
4
4
|
"description": "ArchiMate modeller, data modeller, diagram editor, OLAP cube & pivot chart studio, and 50+ type chart library for the browser, with no runtime dependencies.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "src/index.js",
|
|
@@ -23,6 +23,7 @@
|
|
|
23
23
|
"examples/archimate.html",
|
|
24
24
|
"examples/diagram-editor.html",
|
|
25
25
|
"examples/data-model.html",
|
|
26
|
+
"examples/decision-workbench.html",
|
|
26
27
|
"README.md",
|
|
27
28
|
"documentation/REFERENCE.md",
|
|
28
29
|
"LICENSE"
|
|
@@ -33,7 +33,8 @@ import { ExchangeFileFormat } from './archimate/ExchangeFileFormat.js';
|
|
|
33
33
|
import { ArchimateCsvFileFormat } from './archimate/ArchimateCsvFileFormat.js';
|
|
34
34
|
|
|
35
35
|
/**
|
|
36
|
-
* ArchimateDiagramEditor —
|
|
36
|
+
* ArchimateDiagramEditor — legacy GraphDiagram-based ArchiMate editor extending DiagramEditor.
|
|
37
|
+
* @deprecated Use ArchimateCanvasEditor (or ArchimateCanvasPart) for ArchiMate editing. RenderEngine.archimateDiagram() remains for read-only charts.
|
|
37
38
|
*
|
|
38
39
|
* Encapsulates: ArchiMate model, tree navigator, diagram tabs, rendering, controls wiring.
|
|
39
40
|
* Inherits: common rendering, drag/drop, toolbar, tree, filtering from DiagramEditor.
|
package/src/charting/Edge.js
CHANGED
|
@@ -117,4 +117,26 @@ export class Edge {
|
|
|
117
117
|
clearWaypoints() {
|
|
118
118
|
this.waypoints = [];
|
|
119
119
|
}
|
|
120
|
+
|
|
121
|
+
/** The edge as plain JSON: its endpoints, label, waypoints, side pins and style overrides. */
|
|
122
|
+
toJSON() {
|
|
123
|
+
return {
|
|
124
|
+
id: this.id,
|
|
125
|
+
sourceId: this.sourceId,
|
|
126
|
+
targetId: this.targetId,
|
|
127
|
+
label: this.label,
|
|
128
|
+
waypoints: this.waypoints.map(w => ({ x: w.x, y: w.y })),
|
|
129
|
+
sourceSide: this.sourceSide,
|
|
130
|
+
targetSide: this.targetSide,
|
|
131
|
+
visible: this.visible,
|
|
132
|
+
...this.styleOverrides(),
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/** Reconstruct an Edge from plain JSON. */
|
|
137
|
+
static fromJSON(json) {
|
|
138
|
+
if (!json) throw new TypeError('Edge.fromJSON requires a JSON object');
|
|
139
|
+
const { id, sourceId, targetId, ...rest } = json;
|
|
140
|
+
return new Edge(id, sourceId, targetId, rest);
|
|
141
|
+
}
|
|
120
142
|
}
|