@peter.prib/renderengine 0.15.1 → 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 +525 -229
- package/dist/renderengine.umd.js +390 -107
- package/documentation/REFERENCE.md +347 -25
- package/package.json +1 -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/parts/ArchimateEditorPart.js +2 -2
- package/src/workspace/parts/DiagramEditorPart.js +144 -131
|
@@ -1,131 +1,144 @@
|
|
|
1
|
-
import { render } from '../dom.js';
|
|
2
|
-
import { EditorShell } from '../EditorShell.js';
|
|
3
|
-
import { EditorPart } from './EditorPart.js';
|
|
4
|
-
import { DiagramEditor } from '../../charting/DiagramEditor.js';
|
|
5
|
-
import { MenuBar } from '../../charting/MenuBar.js';
|
|
6
|
-
import { DiagramModel } from '../../charting/diagramModel/index.js';
|
|
7
|
-
import { LocalJsonStore } from '../../charting/storage/LocalJsonStore.js';
|
|
8
|
-
import { EdgeStyleCascade } from '../../charting/edgeStyle/index.js';
|
|
9
|
-
import { DiagramViewPropertiesDialog } from '../../charting/DiagramViewPropertiesDialog.js';
|
|
10
|
-
|
|
11
|
-
const SVG_NS = 'http://www.w3.org/2000/svg';
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* DiagramEditorPart — a complete diagram editor as a workspace part: menu bar,
|
|
15
|
-
* palette, one tab per diagram and the canvas, over a DiagramModel.
|
|
16
|
-
*
|
|
17
|
-
* Spec (JSON): `templateType` (palette category), `tabOrientation`
|
|
18
|
-
* ('horizontal'|'vertical'), `diagramTitle` (first diagram), `toolStyleKey`
|
|
19
|
-
* (localStorage key for the tool-level line style; `null` keeps it in memory).
|
|
20
|
-
*
|
|
21
|
-
* Line styles cascade line → diagram (`view.edgeStyle`) → model
|
|
22
|
-
* (`model.edgeStyle`) → tool. Each diagram keeps its own undo history, so undo
|
|
23
|
-
* survives switching tabs. The diagrams' menu (new, duplicate, rename, delete)
|
|
24
|
-
* comes from EditorPart. Like ChartPart it needs the engine, so it is not in
|
|
25
|
-
* BUILTIN_PARTS: register it explicitly.
|
|
26
|
-
*/
|
|
27
|
-
export class DiagramEditorPart extends EditorPart {
|
|
28
|
-
static type = 'diagram-editor';
|
|
29
|
-
static viewNoun = 'diagram';
|
|
30
|
-
|
|
31
|
-
constructor(spec = {}) {
|
|
32
|
-
super(spec);
|
|
33
|
-
this.tabOrientation = spec.tabOrientation ?? 'horizontal';
|
|
34
|
-
// The editor is rebuilt with the canvas on every render, which follows every model change.
|
|
35
|
-
this._unsubscribe = this.model.onChange(() => { if (this.mounted) this.render(); });
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
createModel(spec) {
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
const
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
const
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
})
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
1
|
+
import { render } from '../dom.js';
|
|
2
|
+
import { EditorShell } from '../EditorShell.js';
|
|
3
|
+
import { EditorPart } from './EditorPart.js';
|
|
4
|
+
import { DiagramEditor } from '../../charting/DiagramEditor.js';
|
|
5
|
+
import { MenuBar } from '../../charting/MenuBar.js';
|
|
6
|
+
import { DiagramModel, DiagramJsonFileFormat } from '../../charting/diagramModel/index.js';
|
|
7
|
+
import { LocalJsonStore } from '../../charting/storage/LocalJsonStore.js';
|
|
8
|
+
import { EdgeStyleCascade } from '../../charting/edgeStyle/index.js';
|
|
9
|
+
import { DiagramViewPropertiesDialog } from '../../charting/DiagramViewPropertiesDialog.js';
|
|
10
|
+
|
|
11
|
+
const SVG_NS = 'http://www.w3.org/2000/svg';
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* DiagramEditorPart — a complete diagram editor as a workspace part: menu bar,
|
|
15
|
+
* palette, one tab per diagram and the canvas, over a DiagramModel.
|
|
16
|
+
*
|
|
17
|
+
* Spec (JSON): `templateType` (palette category), `tabOrientation`
|
|
18
|
+
* ('horizontal'|'vertical'), `diagramTitle` (first diagram), `toolStyleKey`
|
|
19
|
+
* (localStorage key for the tool-level line style; `null` keeps it in memory).
|
|
20
|
+
*
|
|
21
|
+
* Line styles cascade line → diagram (`view.edgeStyle`) → model
|
|
22
|
+
* (`model.edgeStyle`) → tool. Each diagram keeps its own undo history, so undo
|
|
23
|
+
* survives switching tabs. The diagrams' menu (new, duplicate, rename, delete)
|
|
24
|
+
* comes from EditorPart. Like ChartPart it needs the engine, so it is not in
|
|
25
|
+
* BUILTIN_PARTS: register it explicitly.
|
|
26
|
+
*/
|
|
27
|
+
export class DiagramEditorPart extends EditorPart {
|
|
28
|
+
static type = 'diagram-editor';
|
|
29
|
+
static viewNoun = 'diagram';
|
|
30
|
+
|
|
31
|
+
constructor(spec = {}) {
|
|
32
|
+
super(spec);
|
|
33
|
+
this.tabOrientation = spec.tabOrientation ?? 'horizontal';
|
|
34
|
+
// The editor is rebuilt with the canvas on every render, which follows every model change.
|
|
35
|
+
this._unsubscribe = this.model.onChange(() => { if (this.mounted) this.render(); });
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
createModel(spec) {
|
|
39
|
+
if (spec.model instanceof DiagramModel) return spec.model;
|
|
40
|
+
const store = spec.toolStyleKey === null ? null
|
|
41
|
+
: new LocalJsonStore(spec.toolStyleKey ?? 'renderengine.diagramEditor.toolEdgeStyle');
|
|
42
|
+
this.toolEdgeStyle = store?.load({}) ?? {};
|
|
43
|
+
const historyOptions = { onChange: () => store?.save(this.toolEdgeStyle) };
|
|
44
|
+
if (spec.views) {
|
|
45
|
+
return DiagramModel.fromJSON(spec, historyOptions);
|
|
46
|
+
}
|
|
47
|
+
const model = new DiagramModel({
|
|
48
|
+
name: spec.name ?? '',
|
|
49
|
+
templateType: spec.templateType ?? 'generic',
|
|
50
|
+
// Tool-level style edits go through the diagram's undo history; persist whenever it moves.
|
|
51
|
+
historyOptions,
|
|
52
|
+
});
|
|
53
|
+
model.createView(spec.diagramTitle ?? 'Diagram 1');
|
|
54
|
+
return model;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
fileFormats() {
|
|
58
|
+
return this.spec.fileFormats ? [new DiagramJsonFileFormat()] : [];
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
saveFormat() {
|
|
62
|
+
return this.fileFormats()[0];
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
render() {
|
|
66
|
+
const model = this.model;
|
|
67
|
+
const view = model.currentView;
|
|
68
|
+
const doc = this.document;
|
|
69
|
+
const canvasId = `diagram-canvas-${this.id}`;
|
|
70
|
+
|
|
71
|
+
const canvas = doc.createElementNS(SVG_NS, 'svg');
|
|
72
|
+
canvas.id = canvasId;
|
|
73
|
+
canvas.setAttribute('viewBox', '0 0 800 600');
|
|
74
|
+
canvas.style.cssText = 'flex: 1; width: 100%; height: 100%; display: block; background: #fff; border: 2px solid #333; box-sizing: border-box;';
|
|
75
|
+
const elements = doc.createElementNS(SVG_NS, 'g');
|
|
76
|
+
elements.id = 'elements';
|
|
77
|
+
canvas.appendChild(elements);
|
|
78
|
+
|
|
79
|
+
const tabs = this.viewTabs({ orientation: this.tabOrientation });
|
|
80
|
+
|
|
81
|
+
// The shared workbench layout: toolbar, palette at the side, tabs + canvas in the main area.
|
|
82
|
+
const { toolbar: menuBarEl, side: palette, main } = new EditorShell({ document: doc, sideWidth: '200px', layout: this.layout, labels: { side: 'Palette' } }).mount(this.container);
|
|
83
|
+
palette.classList.add('ws-diagram-palette');
|
|
84
|
+
Object.assign(palette.style, { padding: '8px', fontSize: '12px', display: 'flex', flexDirection: 'column', overflowY: 'hidden' });
|
|
85
|
+
main.style.flexDirection = this.tabOrientation === 'vertical' ? 'row' : 'column';
|
|
86
|
+
render(main, [tabs, { style: { flex: '1', display: 'flex', flexDirection: 'column', minHeight: '0' }, children: [canvas] }], doc);
|
|
87
|
+
|
|
88
|
+
// The editor is bound to the view's own maps and history: nothing to save back on switch.
|
|
89
|
+
const previous = this.editor;
|
|
90
|
+
previous?.dispose();
|
|
91
|
+
this.editor = new DiagramEditor({
|
|
92
|
+
diagramContainerId: canvasId,
|
|
93
|
+
model,
|
|
94
|
+
templateType: model.templateType,
|
|
95
|
+
onTemplateTypeChange: (type) => model.setTemplateType(type),
|
|
96
|
+
templates: view.templates,
|
|
97
|
+
edges: view.edges,
|
|
98
|
+
history: view.history,
|
|
99
|
+
arrangement: view.arrangement,
|
|
100
|
+
edgeStyleLevels: this.edgeStyleLevels(view),
|
|
101
|
+
});
|
|
102
|
+
if (previous) {
|
|
103
|
+
this.editor.showGrid = previous.showGrid;
|
|
104
|
+
this.editor.gridSize = previous.gridSize;
|
|
105
|
+
this.editor.showExportArea = previous.showExportArea;
|
|
106
|
+
this.editor.exportOptions = previous.exportOptions;
|
|
107
|
+
}
|
|
108
|
+
this.editor.initPaletteForDiagramType(palette, model.templateType);
|
|
109
|
+
this.menuBar?.dispose();
|
|
110
|
+
this.menuBar = new MenuBar({
|
|
111
|
+
container: menuBarEl,
|
|
112
|
+
editor: this.editor,
|
|
113
|
+
items: [this.fileMenu(), this.editMenu(), ...this.hostMenus(), ...this.editor.menuBarItems()],
|
|
114
|
+
}).render();
|
|
115
|
+
this.editor.render();
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/** A diagram's line-style levels, most specific first: the diagram, the model, the tool. */
|
|
119
|
+
edgeStyleLevels(view) {
|
|
120
|
+
return [
|
|
121
|
+
{ key: 'view', label: 'Diagram', style: view.edgeStyle },
|
|
122
|
+
{ key: 'model', label: 'Model', style: this.model.edgeStyle },
|
|
123
|
+
{ key: 'tool', label: 'Tool', style: this.toolEdgeStyle },
|
|
124
|
+
];
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/** A diagram's properties: name, documentation and its line-style defaults. */
|
|
128
|
+
showViewProperties(view) {
|
|
129
|
+
return new DiagramViewPropertiesDialog({
|
|
130
|
+
model: this.model,
|
|
131
|
+
view,
|
|
132
|
+
document: this.document,
|
|
133
|
+
cascade: new EdgeStyleCascade(this.edgeStyleLevels(view)),
|
|
134
|
+
// The editor shows the current diagram; a style change there needs a redraw.
|
|
135
|
+
onStyleChange: () => { if (view === this.model.currentView) this.editor?.render(); },
|
|
136
|
+
}).open();
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
dispose() {
|
|
140
|
+
this.menuBar?.dispose();
|
|
141
|
+
this._unsubscribe();
|
|
142
|
+
super.dispose();
|
|
143
|
+
}
|
|
144
|
+
}
|