@peter.prib/renderengine 0.2.4 → 0.2.6

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 (35) hide show
  1. package/README.md +215 -213
  2. package/REFERENCE.md +99 -7
  3. package/dist/renderengine-workspace.umd.js +13168 -11966
  4. package/dist/renderengine.umd.js +7439 -6472
  5. package/examples/data-model.html +324 -0
  6. package/package.json +70 -68
  7. package/src/charting/CheckboxTreeSelector.js +373 -304
  8. package/src/charting/DiagramEditor.js +3372 -3330
  9. package/src/charting/DiagramTypeRegistry.js +365 -326
  10. package/src/charting/Palette.js +119 -119
  11. package/src/charting/TemplateCatalog.js +61 -59
  12. package/src/charting/archimate/ArchimateCanvasEditor.js +825 -815
  13. package/src/charting/archimate/ArchimateElementTemplate.js +208 -195
  14. package/src/charting/datamodel/DataModel.js +299 -0
  15. package/src/charting/datamodel/DataModelContext.js +108 -0
  16. package/src/charting/datamodel/DataModelPerspective.js +84 -0
  17. package/src/charting/datamodel/LevelMapping.js +38 -0
  18. package/src/charting/datamodel/LevelSchema.js +41 -0
  19. package/src/charting/datamodel/index.js +5 -0
  20. package/src/charting/diagrams/DataModelDiagram.js +160 -86
  21. package/src/charting/diagrams/DataModelRelationshipStrategy.js +86 -38
  22. package/src/charting/diagrams/nesting.js +31 -0
  23. package/src/charting/modelTree/ModelTree.js +202 -164
  24. package/src/charting/modelTree/ModelTreePanel.js +36 -3
  25. package/src/charting/modelTree/TreeViewMode.js +131 -110
  26. package/src/charting/modelTree/modes/FlatTreeMode.js +32 -46
  27. package/src/charting/modelTree/modes/LayerGroupedTreeMode.js +47 -62
  28. package/src/charting/modelTree/modes/TypeGroupedTreeMode.js +46 -60
  29. package/src/datamodel.js +132 -122
  30. package/src/diagramCatalog.js +35 -30
  31. package/src/index.js +6 -1
  32. package/src/workspace/index.js +1 -0
  33. package/src/workspace/parts/ArchimateCanvasPart.js +5 -2
  34. package/src/workspace/parts/ChartPart.js +6 -1
  35. package/src/workspace/parts/DataModelPart.js +234 -0
package/README.md CHANGED
@@ -1,213 +1,215 @@
1
- # RenderEngine
2
-
3
- **An ArchiMate modeller, a diagram editor and a chart library that run in any browser tab, with no install and no
4
- runtime dependencies.**
5
-
6
- Open an Archi model, edit it the way you would in Archi, and save it back to the same `.archimate` file, without
7
- installing anything. Or put the same editor in your own app: it's a JavaScript library and a set of workbench parts,
8
- not a desktop application.
9
-
10
- ![The ArchiMate modeller: a layered view of an online shop, the model tree by layer with each type's picture, and the palette](https://gitlab.com/peter.prib/renderengine/-/raw/master/docs/images/archimate-modeller.png)
11
-
12
- ---
13
-
14
- ## Try it
15
-
16
- ```bash
17
- git clone https://gitlab.com/peter.prib/renderengine.git
18
- cd renderengine
19
- npm start # the ArchiMate modeller
20
- npm run diagram # the diagram editor (flowcharts, UML and more)
21
- ```
22
-
23
- No server is needed, and nothing needs installing first, because the built bundles are in `dist/`. You can also
24
- open the pages directly:
25
-
26
- - `examples/archimate.html`: the ArchiMate modeller
27
- - `examples/diagram-editor.html`: the diagram editor
28
-
29
- Both work in current Chrome, Edge, Firefox and Safari. Save writes back to the file you opened in Chrome and Edge;
30
- other browsers download the file instead.
31
-
32
- ---
33
-
34
- ## The ArchiMate modeller
35
-
36
- ### Works with Archi
37
-
38
- - **Open and save Archi files** (`.archimate`, and archives that include pictures). Save writes back to the file you
39
- opened; Save As picks a new one. Unsaved changes are marked (•), and the page asks before you leave or close them.
40
- - **Import a spreadsheet** into the open model: choose the name, type, id, documentation, property and "related
41
- to" columns; existing elements are updated, not duplicated (Archi's elements.csv imports as it is).
42
- - **draw.io export**: every view a page, in draw.io's ArchiMate shapes, with the elements' properties.
43
- - **Open Group Exchange Format** import and export, the standard way into Sparx, BiZZdesign and other tools.
44
- Checked with Archi 5.8, which validates and opens the files.
45
- - **Every element Archi receives is a valid ArchiMate 3.2 class.** A type Archi lacks is written as its nearest
46
- 3.2 type, and its own type is kept so it comes back on the next import.
47
- - **Canvases, sketches, notes, groups and Archi's canvas templates** come through import and export.
48
-
49
- ### Modelling
50
-
51
- - A **palette** of every element type, grouped by layer and limited by the view's viewpoint.
52
- - **Connecting two elements offers only the relationship kinds the ArchiMate rules allow** between them.
53
- - **Nesting**: drop an element inside another and choose what the nesting stands for (composition, aggregation,
54
- assignment, realization or specialization). It goes into the model, and the nesting shows it.
55
- - **Add from text**: paste a list of names, from a document or a spreadsheet's columns, and get an element for
56
- each.
57
- - **Copy and paste** within a model and between models, **Duplicate**, and **Generate View For** an element and
58
- what it relates to.
59
- - **Several models open at once**, a tab each. Each has its own file and its own undo history.
60
- - **Undo for everything**, one history per model as in Archi: edits on any view, and adding, renaming and deleting
61
- views. Undoing an edit made on another view takes you to that view.
62
- - **Specializations**, custom viewpoints, label expressions (`${name}` and `{name}`), and properties with types.
63
-
64
- ### Editing
65
-
66
- - **Align, distribute and match size**, to the shape you selected last, as in Archi; **automatic layouts** (grid,
67
- circle, tree, force-directed, by layer) and **Nest its parts inside**, following composition and aggregation.
68
- - **Properties of several shapes at once**: colours and text style, the elements' type and specialization, and a
69
- property to set on all of them.
70
- - **Format painter**: copy one shape's look onto others.
71
- - **Colour by** layer, type, specialization or any property (a heat map, e.g. by lifecycle: invest, maintain,
72
- retire), with a legend; or a legend of the element types on the view.
73
- - **Find and replace** across names, documentation and property values, with match case, whole words and
74
- regular expressions; **transform names** (Title Case, split camelCase, ...) and **rename a property** across the
75
- model; **fit a shape to its text**.
76
- - **Groups and locks on any view**, multi-select, a marquee, Archi's tabbed groups, bendpoints, pinned line ends,
77
- and orthogonal, curved or straight routing.
78
-
79
- ### Understanding and sharing a model
80
-
81
- - A **model tree** by layer, by type or flat, each element with its type's picture, with search and filters (type, specialization, property) that dim the
82
- diagram too.
83
- - An **analysis panel** for the selected element: which views it's on, and its incoming and outgoing relationships.
84
- - **Check model** finds relationships the rules don't allow, likely duplicates (by their words, so "System of
85
- Order Management" matches "order-management system"), unused elements and relationships, empty views, nested
86
- elements with no relationship, and unprintable characters. **Merge…** makes duplicates one element, keeping
87
- every relationship and appearance on a view.
88
- - **Derived relationships**, worked out and shown as dotted lines.
89
- - **Roadmaps**: generate a view of work packages, plateaus or anything with start and end dates, as bars under
90
- the months.
91
- - An **HTML report** in one self-contained file: a tree, search, a page per element, relationship and view, and
92
- diagrams whose elements link to their pages.
93
- - **Images**: export PNG or SVG, or copy to the clipboard.
94
-
95
- ### Beyond Archi
96
-
97
- It runs in the browser and embeds in other apps. It also has:
98
-
99
- - ArchiMate 4 types alongside 3.2;
100
- - derived relationships without scripts;
101
- - invalid relationships shown as you choose (highlight, tooltip or hidden), per view, per model or for the tool;
102
- - groups and locks on every view, not just canvases;
103
- - a canvas template library shared across models;
104
- - two drawing backends, SVG and Canvas.
105
-
106
- ---
107
-
108
- ## The diagram editor
109
-
110
- The ArchiMate modeller is built on a general diagram editor, and every editing feature above is part of that
111
- editor rather than of ArchiMate: align, format painter, properties of several shapes, find and replace, copy and
112
- paste, groups and locks, undo, HTML report, image export, several models at once. The diagram editor gives you all
113
- of them for its own palettes:
114
-
115
- - basic shapes
116
- - flowchart and BPMN
117
- - swimlanes
118
- - UML: class, sequence, activity, state machine, use case, component, deployment
119
- - entity-relationship
120
- - data flow
121
- - network
122
- - org chart
123
-
124
- Each model can hold several diagrams, with line styles inherited from the diagram, then the model, then the tool.
125
-
126
- ![The diagram editor: an order flowchart with a decision, labelled lines and the flowchart palette](https://gitlab.com/peter.prib/renderengine/-/raw/master/docs/images/diagram-editor.png)
127
-
128
- ## The chart library
129
-
130
- The engine underneath draws 24 chart types: bar, line, area, pie, scatter, bubble, heatmap, candlestick,
131
- waterfall, histogram, box plot, violin, radar, funnel, treemap, sunburst, gauges (dial, arc, ring, rings, bar, bullet, thermometer, KPI tiles; with bands, targets, LED segments and animation), 3D bars and others. It also
132
- draws graph and railroad diagrams, all to SVG or Canvas. `test/charts.html` is the full gallery, and
133
- `examples/csv-chart-builder.html` builds a chart from a CSV file without code.
134
-
135
- ![Gauges: a dial with bands, ticks and a target; arc, ring and nested rings; a two-needle dial; LED segments; a thermometer; KPI tiles with sparklines](https://gitlab.com/peter.prib/renderengine/-/raw/master/docs/images/gauges.png)
136
-
137
- ![Charts from the gallery: bar, grouped bar, line and line with error bars](https://gitlab.com/peter.prib/renderengine/-/raw/master/docs/images/charts.png)
138
-
139
- ---
140
-
141
- ## Put it in your own page
142
-
143
- ```bash
144
- npm install @peter.prib/renderengine
145
- ```
146
-
147
- The package is the ES module source and the built bundles:
148
-
149
- - `import { ArchimateModel, RenderEngine } from '@peter.prib/renderengine'`: the engine and the models (this also
150
- imports under Node).
151
- - `import '@peter.prib/renderengine/workspace'`: the workbench shell and its parts (browser only).
152
- - `@peter.prib/renderengine/dist/renderengine-workspace.umd.js`: the same as one classic script.
153
-
154
- The modeller is a part in the `<ws-workspace>` workbench shell. One script tag and a JSON spec is the whole host
155
- page:
156
-
157
- ```html
158
- <script src="dist/renderengine-workspace.umd.js"></script>
159
- <script>
160
- const { el, registerBuiltinParts, ArchimateCanvasPart } = RenderEngineWorkspace;
161
- const ws = document.body.appendChild(el({ tag: 'ws-workspace', attrs: { label: 'Modeller' } }));
162
- registerBuiltinParts(ws);
163
- ws.registerPart(ArchimateCanvasPart);
164
- ws.addParts([{
165
- id: 'models', type: 'models', editorType: 'archimate-canvas', // several models, a tab each
166
- models: [{
167
- id: 'shop', name: 'Shop',
168
- elements: [{ id: 'c', name: 'Customer', type: 'business-actor' }, { id: 'o', name: 'Order', type: 'business-process' }],
169
- relationships: [{ source: 'c', target: 'o', kind: 'assignment' }],
170
- views: [{ id: 'v', name: 'Main', elementIds: ['c', 'o'], layout: { c: { x: 100, y: 100 }, o: { x: 320, y: 100 } } }],
171
- }],
172
- }]);
173
- ws.registerPerspective('Modelling', { type: 'part', partId: 'models' });
174
- ws.activatePerspective('Modelling');
175
- </script>
176
- ```
177
-
178
- Use `editorType: 'diagram-editor'` with `DiagramEditorPart` for the diagram editor. The model is a plain JavaScript
179
- API (`ArchimateModel`, `DiagramModel`), so you can also build, check, search, report on and export models with no
180
- UI at all.
181
-
182
- ---
183
-
184
- ## Documentation
185
-
186
- | Document | What it covers |
187
- |---|---|
188
- | `REFERENCE.md` | The API: chart methods and options, the editors, models, commands, file formats |
189
- | `WORKSPACE_ARCHITECTURE.md` | The `<ws-workspace>` shell: parts, layout, context bus, work area |
190
- | `ARCHITECTURE.md` | Module layout and the chart-type catalog |
191
- | `LLM_ARCHIMATE_GUIDE.md` | Generating valid ArchiMate model data, with a prompt template |
192
- | `tasks.md` | What's still to come |
193
-
194
- ## Build and test
195
-
196
- ```bash
197
- npm install # dev tools only: Rollup
198
- npm run build # dist/renderengine.umd.js and dist/renderengine-workspace.umd.js
199
- npm test # Node's built-in test runner, no browser needed
200
- npm run screenshots # this README's pictures, from the example pages (headless Chrome)
201
- ```
202
-
203
- There are two bundles:
204
-
205
- - `renderengine.umd.js` (global `RenderEngine`): the engine.
206
- - `renderengine-workspace.umd.js` (global `RenderEngineWorkspace`): the workbench shell and its parts, plus the
207
- whole engine API, so one script tag is enough.
208
-
209
- The source is plain ES modules. `src/index.js` imports under Node, which is how the tests run.
210
-
211
- ## Licence
212
-
213
- MIT. Contributions welcome.
1
+ # RenderEngine
2
+
3
+ **An ArchiMate modeller, a diagram editor and a chart library that run in any browser tab, with no install and no
4
+ runtime dependencies.**
5
+
6
+ Open an Archi model, edit it the way you would in Archi, and save it back to the same `.archimate` file, without
7
+ installing anything. Or put the same editor in your own app: it's a JavaScript library and a set of workbench parts,
8
+ not a desktop application.
9
+
10
+ ![The ArchiMate modeller: a layered view of an online shop, the model tree by layer with each type's picture, and the palette](https://gitlab.com/peter.prib/renderengine/-/raw/master/docs/images/archimate-modeller.png)
11
+
12
+ ---
13
+
14
+ ## Try it
15
+
16
+ ```bash
17
+ git clone https://gitlab.com/peter.prib/renderengine.git
18
+ cd renderengine
19
+ npm start # the ArchiMate modeller
20
+ npm run diagram # the diagram editor (flowcharts, UML and more)
21
+ npm run datamodel # a data model at each level, in each notation
22
+ ```
23
+
24
+ No server is needed, and nothing needs installing first, because the built bundles are in `dist/`. You can also
25
+ open the pages directly:
26
+
27
+ - `examples/archimate.html`: the ArchiMate modeller
28
+ - `examples/diagram-editor.html`: the diagram editor
29
+ - `examples/data-model.html`: a data model (conceptual, logical, physical; Chen, Crow's Foot, UML)
30
+
31
+ All work in current Chrome, Edge, Firefox and Safari. Save writes back to the file you opened in Chrome and Edge;
32
+ other browsers download the file instead.
33
+
34
+ ---
35
+
36
+ ## The ArchiMate modeller
37
+
38
+ ### Works with Archi
39
+
40
+ - **Open and save Archi files** (`.archimate`, and archives that include pictures). Save writes back to the file you
41
+ opened; Save As picks a new one. Unsaved changes are marked (•), and the page asks before you leave or close them.
42
+ - **Import a spreadsheet** into the open model: choose the name, type, id, documentation, property and "related
43
+ to" columns; existing elements are updated, not duplicated (Archi's elements.csv imports as it is).
44
+ - **draw.io export**: every view a page, in draw.io's ArchiMate shapes, with the elements' properties.
45
+ - **Open Group Exchange Format** import and export, the standard way into Sparx, BiZZdesign and other tools.
46
+ Checked with Archi 5.8, which validates and opens the files.
47
+ - **Every element Archi receives is a valid ArchiMate 3.2 class.** A type Archi lacks is written as its nearest
48
+ 3.2 type, and its own type is kept so it comes back on the next import.
49
+ - **Canvases, sketches, notes, groups and Archi's canvas templates** come through import and export.
50
+
51
+ ### Modelling
52
+
53
+ - A **palette** of every element type, grouped by layer and limited by the view's viewpoint.
54
+ - **Connecting two elements offers only the relationship kinds the ArchiMate rules allow** between them.
55
+ - **Nesting**: drop an element inside another and choose what the nesting stands for (composition, aggregation,
56
+ assignment, realization or specialization). It goes into the model, and the nesting shows it.
57
+ - **Add from text**: paste a list of names, from a document or a spreadsheet's columns, and get an element for
58
+ each.
59
+ - **Copy and paste** within a model and between models, **Duplicate**, and **Generate View For** an element and
60
+ what it relates to.
61
+ - **Several models open at once**, a tab each. Each has its own file and its own undo history.
62
+ - **Undo for everything**, one history per model as in Archi: edits on any view, and adding, renaming and deleting
63
+ views. Undoing an edit made on another view takes you to that view.
64
+ - **Specializations**, custom viewpoints, label expressions (`${name}` and `{name}`), and properties with types.
65
+
66
+ ### Editing
67
+
68
+ - **Align, distribute and match size**, to the shape you selected last, as in Archi; **automatic layouts** (grid,
69
+ circle, tree, force-directed, by layer) and **Nest its parts inside**, following composition and aggregation.
70
+ - **Properties of several shapes at once**: colours and text style, the elements' type and specialization, and a
71
+ property to set on all of them.
72
+ - **Format painter**: copy one shape's look onto others.
73
+ - **Colour by** layer, type, specialization or any property (a heat map, e.g. by lifecycle: invest, maintain,
74
+ retire), with a legend; or a legend of the element types on the view.
75
+ - **Find and replace** across names, documentation and property values, with match case, whole words and
76
+ regular expressions; **transform names** (Title Case, split camelCase, ...) and **rename a property** across the
77
+ model; **fit a shape to its text**.
78
+ - **Groups and locks on any view**, multi-select, a marquee, Archi's tabbed groups, bendpoints, pinned line ends,
79
+ and orthogonal, curved or straight routing.
80
+
81
+ ### Understanding and sharing a model
82
+
83
+ - A **model tree** by layer, by type or flat, each element with its type's picture, with search and filters (type, specialization, property) that dim the
84
+ diagram too.
85
+ - An **analysis panel** for the selected element: which views it's on, and its incoming and outgoing relationships.
86
+ - **Check model** finds relationships the rules don't allow, likely duplicates (by their words, so "System of
87
+ Order Management" matches "order-management system"), unused elements and relationships, empty views, nested
88
+ elements with no relationship, and unprintable characters. **Merge…** makes duplicates one element, keeping
89
+ every relationship and appearance on a view.
90
+ - **Derived relationships**, worked out and shown as dotted lines.
91
+ - **Roadmaps**: generate a view of work packages, plateaus or anything with start and end dates, as bars under
92
+ the months.
93
+ - An **HTML report** in one self-contained file: a tree, search, a page per element, relationship and view, and
94
+ diagrams whose elements link to their pages.
95
+ - **Images**: export PNG or SVG, or copy to the clipboard.
96
+
97
+ ### Beyond Archi
98
+
99
+ It runs in the browser and embeds in other apps. It also has:
100
+
101
+ - ArchiMate 4 types alongside 3.2;
102
+ - derived relationships without scripts;
103
+ - invalid relationships shown as you choose (highlight, tooltip or hidden), per view, per model or for the tool;
104
+ - groups and locks on every view, not just canvases;
105
+ - a canvas template library shared across models;
106
+ - two drawing backends, SVG and Canvas.
107
+
108
+ ---
109
+
110
+ ## The diagram editor
111
+
112
+ The ArchiMate modeller is built on a general diagram editor, and every editing feature above is part of that
113
+ editor rather than of ArchiMate: align, format painter, properties of several shapes, find and replace, copy and
114
+ paste, groups and locks, undo, HTML report, image export, several models at once. The diagram editor gives you all
115
+ of them for its own palettes:
116
+
117
+ - basic shapes
118
+ - flowchart and BPMN
119
+ - swimlanes
120
+ - UML: class, sequence, activity, state machine, use case, component, deployment
121
+ - entity-relationship
122
+ - data flow
123
+ - network
124
+ - org chart
125
+
126
+ Each model can hold several diagrams, with line styles inherited from the diagram, then the model, then the tool.
127
+
128
+ ![The diagram editor: an order flowchart with a decision, labelled lines and the flowchart palette](https://gitlab.com/peter.prib/renderengine/-/raw/master/docs/images/diagram-editor.png)
129
+
130
+ ## The chart library
131
+
132
+ The engine underneath draws 24 chart types: bar, line, area, pie, scatter, bubble, heatmap, candlestick,
133
+ waterfall, histogram, box plot, violin, radar, funnel, treemap, sunburst, gauges (dial, arc, ring, rings, bar, bullet, thermometer, KPI tiles; with bands, targets, LED segments and animation), 3D bars and others. It also
134
+ draws graph and railroad diagrams, all to SVG or Canvas. `test/charts.html` is the full gallery, and
135
+ `examples/csv-chart-builder.html` builds a chart from a CSV file without code.
136
+
137
+ ![Gauges: a dial with bands, ticks and a target; arc, ring and nested rings; a two-needle dial; LED segments; a thermometer; KPI tiles with sparklines](https://gitlab.com/peter.prib/renderengine/-/raw/master/docs/images/gauges.png)
138
+
139
+ ![Charts from the gallery: bar, grouped bar, line and line with error bars](https://gitlab.com/peter.prib/renderengine/-/raw/master/docs/images/charts.png)
140
+
141
+ ---
142
+
143
+ ## Put it in your own page
144
+
145
+ ```bash
146
+ npm install @peter.prib/renderengine
147
+ ```
148
+
149
+ The package is the ES module source and the built bundles:
150
+
151
+ - `import { ArchimateModel, RenderEngine } from '@peter.prib/renderengine'`: the engine and the models (this also
152
+ imports under Node).
153
+ - `import '@peter.prib/renderengine/workspace'`: the workbench shell and its parts (browser only).
154
+ - `@peter.prib/renderengine/dist/renderengine-workspace.umd.js`: the same as one classic script.
155
+
156
+ The modeller is a part in the `<ws-workspace>` workbench shell. One script tag and a JSON spec is the whole host
157
+ page:
158
+
159
+ ```html
160
+ <script src="dist/renderengine-workspace.umd.js"></script>
161
+ <script>
162
+ const { el, registerBuiltinParts, ArchimateCanvasPart } = RenderEngineWorkspace;
163
+ const ws = document.body.appendChild(el({ tag: 'ws-workspace', attrs: { label: 'Modeller' } }));
164
+ registerBuiltinParts(ws);
165
+ ws.registerPart(ArchimateCanvasPart);
166
+ ws.addParts([{
167
+ id: 'models', type: 'models', editorType: 'archimate-canvas', // several models, a tab each
168
+ models: [{
169
+ id: 'shop', name: 'Shop',
170
+ elements: [{ id: 'c', name: 'Customer', type: 'business-actor' }, { id: 'o', name: 'Order', type: 'business-process' }],
171
+ relationships: [{ source: 'c', target: 'o', kind: 'assignment' }],
172
+ views: [{ id: 'v', name: 'Main', elementIds: ['c', 'o'], layout: { c: { x: 100, y: 100 }, o: { x: 320, y: 100 } } }],
173
+ }],
174
+ }]);
175
+ ws.registerPerspective('Modelling', { type: 'part', partId: 'models' });
176
+ ws.activatePerspective('Modelling');
177
+ </script>
178
+ ```
179
+
180
+ Use `editorType: 'diagram-editor'` with `DiagramEditorPart` for the diagram editor. The model is a plain JavaScript
181
+ API (`ArchimateModel`, `DiagramModel`), so you can also build, check, search, report on and export models with no
182
+ UI at all.
183
+
184
+ ---
185
+
186
+ ## Documentation
187
+
188
+ | Document | What it covers |
189
+ |---|---|
190
+ | `REFERENCE.md` | The API: chart methods and options, the editors, models, commands, file formats |
191
+ | `WORKSPACE_ARCHITECTURE.md` | The `<ws-workspace>` shell: parts, layout, context bus, work area |
192
+ | `ARCHITECTURE.md` | Module layout and the chart-type catalog |
193
+ | `LLM_ARCHIMATE_GUIDE.md` | Generating valid ArchiMate model data, with a prompt template |
194
+ | `tasks.md` | What's still to come |
195
+
196
+ ## Build and test
197
+
198
+ ```bash
199
+ npm install # dev tools only: Rollup
200
+ npm run build # dist/renderengine.umd.js and dist/renderengine-workspace.umd.js
201
+ npm test # Node's built-in test runner, no browser needed
202
+ npm run screenshots # this README's pictures, from the example pages (headless Chrome)
203
+ ```
204
+
205
+ There are two bundles:
206
+
207
+ - `renderengine.umd.js` (global `RenderEngine`): the engine.
208
+ - `renderengine-workspace.umd.js` (global `RenderEngineWorkspace`): the workbench shell and its parts, plus the
209
+ whole engine API, so one script tag is enough.
210
+
211
+ The source is plain ES modules. `src/index.js` imports under Node, which is how the tests run.
212
+
213
+ ## Licence
214
+
215
+ MIT. Contributions welcome.
package/REFERENCE.md CHANGED
@@ -718,6 +718,78 @@ types — see `ARCHITECTURE.md`):
718
718
  renders a dashed line (a non-identifying relationship, in real ERD terms) regardless of notation;
719
719
  unset/`true` stays solid. None of the three notations are pixel-perfect renditions of the real, full
720
720
  notations (same calibration as `archimateDiagram`'s own icons) — see `src/datamodel.js`'s own doc comment.
721
+ An entity drawn as a box with its name inside (the conceptual level, and Chen) is `DataModelDiagram.ENTITY_BOX`
722
+ (140 × 56) unless it gives `width`/`height`; one with its own `shape` (any glyph: `'person'`, `'cube'`,
723
+ `'cylinder'`, ...) and `labelPosition: 'below'` keeps the shape's size. In Chen a relationship's diamond holds
724
+ its name and sits midway between its two entities when both have `x`/`y`, or when something is drawn there (an entity, a
725
+ note, another diamond) the nearest clear spot across the line (`RelationshipAsNodeStrategy.spotFor`,
726
+ `DataModelDiagram.boxOf`); its lines have no arrowheads.
727
+ Each level and notation has a `label` for menus (`'Conceptual'`, `"Crow's Foot"`).
728
+ **Levels of their own, and how they map.** A `DataModel` (`src/charting/datamodel/`, exported from the package
729
+ root) keeps each level as its own schema, a `LevelSchema` (`model.level('conceptual' | 'logical' | 'physical')`):
730
+ its entities (`{id, name, description?, attributes?, x?, y?, color?, shape?, labelPosition?}`; `attributes`
731
+ `[{name, type?, isPK?, isFK?}]`, none for a concept, a physical entity's name its table's) and its relationships.
732
+ The levels are not one to one: a `LevelMapping` from each level to the next (`model.mapping('conceptual',
733
+ 'logical')`) is pairs of ids, any number either way (a concept realised by several logical entities, several by
734
+ one table, or many many). `model.realising(level, conceptIds)` gives what realises some concepts at a level;
735
+ `model.conceptsOf(level, id)` what an entity or table realises. The older form, one entity carrying each level's
736
+ detail (`{ entities, relationships }`, as `dataModelDiagram` takes them), is read as three levels mapped one to one
737
+ (`DataModel.levelsFromCombined`).
738
+
739
+ **Schema, perspective, context.** On that structure, a `DataModelPerspective` is a stakeholder's viewpoint on the
740
+ concepts: the concepts it shows (`entities`, all when unset) under its names (`names`, and `relationshipNames` by
741
+ relationship id), and the context it is read in (`context`); a `DataModelContext` is the meaning, scope and
742
+ constraints: what concepts mean there (`meanings`), the rules that hold (`constraints: [{id?, text, applies:
743
+ [concept ids], x?, y?}]`) and where and when (`jurisdiction`, `validFrom`, `validTo`; `context.scope` reads
744
+ 'AU · from 2024-07-01'). `model.view({ perspective, context, level })` (ids, either may be null) gives
745
+ `{entities, relationships, annotations, links}` for `dataModelDiagram`, the schema itself unchanged: at a level,
746
+ what realises the concepts shown (the concepts themselves under the perspective's names), each with its level's
747
+ detail, its `description` the context's meaning of its concepts, and `details` (shown on hover) naming the schema
748
+ entity behind a renamed concept, the concepts an entity or table realises, the context and the rules on them; the
749
+ level's relationships between shown entities; and each rule as a note on what realises the concepts it applies
750
+ to, placed per level (`model.notePlace(level, rule)`: the rule's own `x`, `y` on the concepts, `model.noteLayout`
751
+ on the others, else in a row below every box). With `level: 'mapping'` (`DataModel.MAPPING`, `model.mappingView()`)
752
+ it gives the levels side by side, a column each (ids `'level:id'`, each box drawn at its own `level`, where
753
+ `model.mappingLayout` left it), and a `link` per mapping between shown ones. `dataModelDiagram` draws an entity at
754
+ its own `level` when it has one; its `annotations` option (`[{id, text, attachTo: [entity ids], x?, y?}]`) draws
755
+ notes, and its `links` option (`[{source, target, label?}]`) plain lines, both dotted in every notation
756
+ (`DataModelDiagram.buildLink`); an entity's `details` show on hover, boxes and tables alike.
757
+
758
+ ```js
759
+ const model = new DataModel({
760
+ levels: {
761
+ conceptual: { entities: [{ id: 'party', name: 'Party' }], relationships: [] },
762
+ logical: { entities: [{ id: 'person', name: 'Person', attributes: [{ name: 'id', isPK: true }] },
763
+ { id: 'org', name: 'Organisation', attributes: [{ name: 'id', isPK: true }] }], relationships: [] },
764
+ physical: { entities: [{ id: 'party_t', name: 'party', attributes: [{ name: 'party_id', type: 'BIGINT', isPK: true }] }], relationships: [] },
765
+ },
766
+ mappings: [
767
+ { from: 'conceptual', to: 'logical', pairs: [['party', 'person'], ['party', 'org']] }, // one to many
768
+ { from: 'logical', to: 'physical', pairs: [['person', 'party_t'], ['org', 'party_t']] }, // many to one
769
+ ],
770
+ perspectives: [{ id: 'customer', context: 'retail', names: { party: 'Customer' } }],
771
+ contexts: [{ id: 'retail', jurisdiction: 'AU', meanings: { party: 'Someone who buys from us.' },
772
+ constraints: [{ text: 'Prices include GST', applies: ['party'] }] }],
773
+ });
774
+ const { entities, relationships, annotations, links } = model.view({ perspective: 'customer', context: 'retail', level: 'mapping' });
775
+ engine.dataModelDiagram(entities, relationships, { annotations, links, level: 'conceptual' });
776
+ ```
777
+
778
+ **Perspectives and contexts of one's own.** `model.addPerspective(spec)` / `updatePerspective(id, spec)` /
779
+ `removePerspective(id)`, and the same for contexts (an id is made from the name when none is given; a context
780
+ removed leaves its perspectives in none). Each class defines its own dialog: `DataModelPerspective.fields(model,
781
+ perspective?)` and `DataModelPerspective.specFrom(values, model)` (what it shows, what it calls each concept);
782
+ `DataModelContext.fields(model, context?)` and `DataModelContext.specFrom(values, model, context?)` (meanings, dates,
783
+ and rules a line each, `the rule | the concepts, by name`).
784
+
785
+ **In the workbench:** `DataModelPart` (type `data-model`, `RenderEngineWorkspace.DataModelPart`) shows one
786
+ model: Model ▸ New / Edit / Delete perspective and context (those dialogs), Perspective and Context selects (when
787
+ it has some; a perspective brings its context, and the context's scope shows beside them), Level (Conceptual,
788
+ Logical, Physical, and Mapping), Notation, and Export ▸ PNG / SVG. A box or note dragged stays on the level it
789
+ was dragged on (the mapping view's in its own layout). `examples/data-model.html` (`npm run datamodel`) uses every
790
+ feature above. A data model can also be registered like a chart:
791
+ `engine.register(id, 'dataModel', { entities, relationships, level })` then `engine.refreshChart(id)` (each
792
+ diagram catalog entry names its data options, `args`).
721
793
  - `railroadDiagram(diagramString)` — renders an EBNF grammar string as a railroad diagram. No node/edge
722
794
  data at all.
723
795
 
@@ -1029,15 +1101,22 @@ do, and a folder of one type in the Layers tree too (`typeGlyph(typeName, { size
1029
1101
  `TreeBuilder`'s `iconFor(node)` gives a node a picture in place of its `icon` text.
1030
1102
 
1031
1103
  **Nesting.** In the ArchiMate canvas editor, dropping a box wholly inside an element's box nests it there (Archi's
1032
- nested elements): it moves with its parent, is raised above it, and an Archi file writes it inside it (whatever order
1104
+ nested elements); so does dropping an element with its centre on another element's box when a relationship a
1105
+ nesting stands for is allowed between them (`nestsOnDrop`), and the parent then grows to show it whole, with its
1106
+ own parents in turn (`DiagramEditor#fitNesting`, `DiagramEditor.NEST_MARGIN`: room around it, more at the top for
1107
+ the parent's name), all in the move's undo step. A nested box moves with its parent, is raised above it, and an Archi file writes it inside it (whatever order
1033
1108
  they were added in). Dragged out again, it is taken out. The move and the nesting are one undo step. On a canvas, a
1034
1109
  block holds boxes the same way. Nesting one element in another then asks which relationship it stands for, among
1035
1110
  Archi's nesting kinds (`NESTING_KINDS`: composition, aggregation, assignment, realization, specialization) that the
1036
1111
  rules allow from parent to child, and none when the two already have one; **Add** puts it in the model, drawn as no
1037
1112
  line (the nesting shows it), as its own undo step; **No relationship** adds none. The shared editor does the
1038
1113
  finding: after a move, `DiagramEditor#nestingChanges(ids)` gives each moved shape's new parent (the innermost shape
1039
- that wholly holds it and `canHold` it), and a subclass supplies `parentOf`, `canHold`, `nestCommand`
1040
- (`NestInstanceCommand`) and `nested(changes)`; the template editor has no nesting. Model checks: **Check model…**
1114
+ that wholly holds it and `canHold` it, else the innermost its centre lies on that `nestsOnDrop` it), and a subclass
1115
+ supplies `parentOf`, `canHold`, `nestsOnDrop`, `nestCommand` (`NestInstanceCommand`) and `nested(changes)`; the
1116
+ template editor has no nesting. As in Archi, a line a nesting stands for (one of `NESTING_KINDS`) from a box to one
1117
+ nested in it is not drawn, at any depth (to a box nested in a box nested in it too: `hiddenByNesting`,
1118
+ `holdsNested` in `diagrams/nesting.js`); an Archi file's such lines are read in, kept and written back, just not
1119
+ drawn. ⚙ Settings ▸ **Lines to nested boxes** (`nodeOptions.showNestedLines`) shows them. Model checks: **Check model…**
1041
1120
  warns of an element drawn inside another with no such relationship (`nested-without-relationship`), and a
1042
1121
  relationship a nesting shows is not reported as unused (`viewNestings(view)`, `nestingRelationships` in
1043
1122
  `diagrams/nesting.js`).
@@ -1103,7 +1182,14 @@ there (`editor.addImage(dataURL, point)`, one undo step, selected; the base edit
1103
1182
  relationships) under the palette, for an element chosen on the canvas or in the tree. The tree's own filters (its
1104
1183
  "Filters…" dialog: text, types, specializations, properties) dim what they leave out on the canvas too:
1105
1184
  `modelTree.matchingElementIds()` (null with no filter on) and `modelTree.onFilterChange(fn)` feed
1106
- `editor.setElementFilter`. The analysis names an element's layer as the tree files it (`treeLayerOf`).
1185
+ `editor.setElementFilter`. Under the search box, **In:** chooses what the search covers, the whole model or only
1186
+ the diagram in front (`modelTree.setSearchScope('model' | 'view')`, `ModelTree.SEARCH_SCOPES`), and
1187
+ **Descriptions** looks for the text in elements' and relationships' documentation too
1188
+ (`modelTree.setSearchInDescriptions(true)`). The Filters… dialog opens showing the filters on now
1189
+ (`getTypeFilter()`, `getSpecializationFilter()`, `getPropertyFilter()`). Its properties start unticked (no property
1190
+ filter; `OptInCheckboxTreeSelector`: a value is ticked to keep what has it), and a property with more than 10
1191
+ values starts folded, with a box that narrows its values to those containing what is typed; ticking the property
1192
+ then ticks only the values shown (`CheckboxTreeSelector`'s `searchAbove`, `search(id, text)`). The analysis names an element's layer as the tree files it (`treeLayerOf`).
1107
1193
 
1108
1194
  **Groups on the canvas.** An Archi group (a model folder with bounds on the view, `view.placedFolders`) is a
1109
1195
  `ViewGroupTemplate`: Archi's box with a name tab (`TabbedBoxGlyph`), placed by its centre while its layout entry
@@ -1671,6 +1757,7 @@ the shared `MenuBar` (see "Toolbars and dialogs" below):
1671
1757
  - **`viewpoint`** — Settings ▸ Viewpoint (every built-in and custom viewpoint) and ▸ Viewpoint mode (fade/hide)
1672
1758
  - **`distinctShapes`** — Settings ▸ Distinct shapes: on/off
1673
1759
  - **`showDerived`** — Settings ▸ Show derived: on/off
1760
+ - **`showNestedLines`** — Settings ▸ Lines to nested boxes: hidden (default, Archi's way) / shown
1674
1761
  - **`exportCSV`**, **`importCSV`**, **`exportArchimate`**, **`importArchimate`** — entries in the **File** menu,
1675
1762
  after the view items (New view…, Properties…, Duplicate, Delete)
1676
1763
 
@@ -1940,8 +2027,12 @@ Each ArchiMate relationship type gives its notation as line style values:
1940
2027
  `{ lineStyle: 'solid', startMarker: 'diamond', endMarker: 'none' }`; arrowheads come back as marker keys
1941
2028
  (`realization` ends in `'trianglehollow'`).
1942
2029
 
1943
- `DIAGRAM_TYPES` (19 categories in the groups General, Process, UML, Data, Infrastructure,
1944
- Business, Ideas) decides which templates the palette offers. `editor.initPaletteForDiagramType(container, key)`
2030
+ `DIAGRAM_TYPES` (20 categories in the groups General, Process, UML, Data, Infrastructure,
2031
+ Business, Ideas) decides which templates the palette offers. An entry may say what it is (`description`), shown
2032
+ when the pointer rests on its tile. **Enterprise Ontology** (`'enterprise-ontology'`, in Data) offers the
2033
+ universal concepts enterprise data models are built from (after IBM IFW's data concepts), each described: Party,
2034
+ Role, Arrangement, Product, Resource, Event, Account / Ledger, Classification, Place, Time, Measure, Business
2035
+ Direction and Rule. `editor.initPaletteForDiagramType(container, key)`
1945
2036
  renders a grouped category picker above a grid of draggable tiles. `editor.setPaletteCategory(key)`
1946
2037
  switches category, and `onTemplateTypeChange(key)` (a constructor option) reports the switch.
1947
2038
  Unknown keys fall back to `'generic'` (Basic Shapes).
@@ -1962,7 +2053,8 @@ class ChevronTemplate extends PolygonTemplate {
1962
2053
 
1963
2054
  DIAGRAM_TYPES['value-chain'] = {
1964
2055
  name: 'Value Chain', group: 'Business', description: 'Primary activities in sequence',
1965
- templates: [{ id: 'activity', name: 'Activity', factory: (id, x, y) => new ChevronTemplate(id, 'Activity', { x, y }) }],
2056
+ templates: [{ id: 'activity', name: 'Activity', description: 'A step that adds value',
2057
+ factory: (id, x, y) => new ChevronTemplate(id, 'Activity', { x, y }) }],
1966
2058
  };
1967
2059
 
1968
2060
  console.log(DIAGRAM_TYPES['value-chain'].templates[0].factory('a1', 100, 50).points().length); // 6