@peter.prib/renderengine 0.2.5 → 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.
- package/README.md +215 -213
- package/REFERENCE.md +94 -6
- package/dist/renderengine-workspace.umd.js +3254 -2089
- package/dist/renderengine.umd.js +3016 -2086
- package/examples/data-model.html +324 -0
- package/package.json +70 -68
- package/src/charting/CheckboxTreeSelector.js +373 -304
- package/src/charting/DiagramEditor.js +48 -6
- package/src/charting/DiagramTypeRegistry.js +5 -1
- package/src/charting/archimate/ArchimateCanvasEditor.js +825 -815
- package/src/charting/archimate/ArchimateElementTemplate.js +208 -195
- package/src/charting/datamodel/DataModel.js +299 -0
- package/src/charting/datamodel/DataModelContext.js +108 -0
- package/src/charting/datamodel/DataModelPerspective.js +84 -0
- package/src/charting/datamodel/LevelMapping.js +38 -0
- package/src/charting/datamodel/LevelSchema.js +41 -0
- package/src/charting/datamodel/index.js +5 -0
- package/src/charting/diagrams/DataModelDiagram.js +160 -86
- package/src/charting/diagrams/DataModelRelationshipStrategy.js +86 -38
- package/src/charting/diagrams/nesting.js +31 -0
- package/src/charting/modelTree/ModelTree.js +202 -164
- package/src/charting/modelTree/ModelTreePanel.js +36 -3
- package/src/charting/modelTree/TreeViewMode.js +131 -110
- package/src/charting/modelTree/modes/FlatTreeMode.js +32 -46
- package/src/charting/modelTree/modes/LayerGroupedTreeMode.js +47 -62
- package/src/charting/modelTree/modes/TypeGroupedTreeMode.js +46 -60
- package/src/datamodel.js +132 -122
- package/src/diagramCatalog.js +35 -30
- package/src/index.js +6 -1
- package/src/workspace/index.js +1 -0
- package/src/workspace/parts/ArchimateCanvasPart.js +5 -2
- package/src/workspace/parts/ChartPart.js +6 -1
- package/src/workspace/parts/DataModelPart.js +234 -0
|
@@ -3244,8 +3244,10 @@ export class DiagramEditor {
|
|
|
3244
3244
|
// Try template-based first (template diagram pattern)
|
|
3245
3245
|
const ids = (this._dragState?.movers ?? [elementId]).filter(id => this.getTemplate(id));
|
|
3246
3246
|
if (!ids.length || !this.history) return;
|
|
3247
|
-
// Where they were dropped: into a shape that holds them, or out of their parent
|
|
3247
|
+
// Where they were dropped: into a shape that holds them, or out of their parent;
|
|
3248
|
+
// a parent they stick out of grows to show them (worked out where they lie now).
|
|
3248
3249
|
const nesting = this.nestingChanges(ids);
|
|
3250
|
+
const fits = this.fitNesting(nesting);
|
|
3249
3251
|
// Put them back, then move them all (and nest them) as one undo step.
|
|
3250
3252
|
for (const id of ids) {
|
|
3251
3253
|
const t = this.getTemplate(id);
|
|
@@ -3255,6 +3257,7 @@ export class DiagramEditor {
|
|
|
3255
3257
|
const steps = [
|
|
3256
3258
|
...ids.map(id => new MoveElementCommand(this, id, deltaX, deltaY)),
|
|
3257
3259
|
...nesting.map(({ childId, parentId }) => this.nestCommand(childId, parentId)).filter(Boolean),
|
|
3260
|
+
...fits.map(({ id, bounds }) => new SetPropertiesCommand(this.getTemplate(id), bounds, 'Fit around nested')),
|
|
3258
3261
|
];
|
|
3259
3262
|
this.history.execute(steps.length === 1 ? steps[0] : new CompositeCommand('Move', steps));
|
|
3260
3263
|
this.render();
|
|
@@ -3264,11 +3267,15 @@ export class DiagramEditor {
|
|
|
3264
3267
|
|
|
3265
3268
|
// ===== Nesting (a shape drawn inside another) =====
|
|
3266
3269
|
|
|
3270
|
+
/** The room kept around a nested shape when its parent grows to show it: the top leaves room for the parent's name. */
|
|
3271
|
+
static NEST_MARGIN = Object.freeze({ side: 12, top: 28 });
|
|
3272
|
+
|
|
3267
3273
|
/**
|
|
3268
3274
|
* After a move, as the shapes lie now: each moved shape that is not moving
|
|
3269
3275
|
* with its parent, whose parent changes. Its new parent is the innermost
|
|
3270
|
-
* shape not moved that wholly holds its box and `canHold` it
|
|
3271
|
-
*
|
|
3276
|
+
* shape not moved that wholly holds its box and `canHold` it, else the
|
|
3277
|
+
* innermost one its centre was dropped on that `nestsOnDrop` it (fitNesting
|
|
3278
|
+
* then grows it); none (null) takes it out of the one it was in.
|
|
3272
3279
|
* @param {Array<string>} movedIds
|
|
3273
3280
|
* @returns {Array<{childId: string, parentId: (string|null), previousId: (string|null)}>}
|
|
3274
3281
|
*/
|
|
@@ -3283,15 +3290,50 @@ export class DiagramEditor {
|
|
|
3283
3290
|
const child = this.getTemplate(childId);
|
|
3284
3291
|
if (!child) continue;
|
|
3285
3292
|
const inner = box(child);
|
|
3286
|
-
const
|
|
3287
|
-
|
|
3288
|
-
|
|
3293
|
+
const candidates = [...this.templates.values()].filter(t => !moved.has(t.id) && t.visible !== false && this.canHold(t.id, childId));
|
|
3294
|
+
const smallest = (list) => list.sort((a, b) => a.width * a.height - b.width * b.height)[0];
|
|
3295
|
+
const onCentre = (t) => { const b = box(t); return b.left <= child.x && child.x <= b.right && b.top <= child.y && child.y <= b.bottom; };
|
|
3296
|
+
const parent = smallest(candidates.filter(t => holds(box(t), inner)))
|
|
3297
|
+
?? smallest(candidates.filter(t => onCentre(t) && this.nestsOnDrop(t.id, childId)));
|
|
3289
3298
|
const parentId = parent?.id ?? null;
|
|
3290
3299
|
if (parentId !== previousId) changes.push({ childId, parentId, previousId });
|
|
3291
3300
|
}
|
|
3292
3301
|
return changes;
|
|
3293
3302
|
}
|
|
3294
3303
|
|
|
3304
|
+
/**
|
|
3305
|
+
* What has to grow for some nesting changes (nestingChanges') to show each
|
|
3306
|
+
* child whole, as the shapes lie now: each new parent the child sticks out
|
|
3307
|
+
* of, then that parent's own parents in turn, each to hold the one inside
|
|
3308
|
+
* with NEST_MARGIN around it.
|
|
3309
|
+
* @returns {Array<{id: string, bounds: {x, y, width, height}}>} new centre and size, outermost last
|
|
3310
|
+
*/
|
|
3311
|
+
fitNesting(changes) {
|
|
3312
|
+
const { side, top } = DiagramEditor.NEST_MARGIN;
|
|
3313
|
+
const bounds = new Map();
|
|
3314
|
+
const at = (id) => bounds.get(id) ?? (({ x, y, width, height }) => ({ x, y, width, height }))(this.getTemplate(id));
|
|
3315
|
+
for (const { childId, parentId } of changes) {
|
|
3316
|
+
let inner = at(childId);
|
|
3317
|
+
for (let outerId = parentId; outerId; outerId = this.parentOf(outerId)) {
|
|
3318
|
+
const outer = at(outerId);
|
|
3319
|
+
const left = Math.min(outer.x - outer.width / 2, inner.x - inner.width / 2 - side);
|
|
3320
|
+
const right = Math.max(outer.x + outer.width / 2, inner.x + inner.width / 2 + side);
|
|
3321
|
+
const upper = Math.min(outer.y - outer.height / 2, inner.y - inner.height / 2 - top);
|
|
3322
|
+
const lower = Math.max(outer.y + outer.height / 2, inner.y + inner.height / 2 + side);
|
|
3323
|
+
const grown = { x: (left + right) / 2, y: (upper + lower) / 2, width: right - left, height: lower - upper };
|
|
3324
|
+
if (grown.width === outer.width && grown.height === outer.height) break; // it already shows it
|
|
3325
|
+
bounds.set(outerId, grown);
|
|
3326
|
+
inner = grown;
|
|
3327
|
+
}
|
|
3328
|
+
}
|
|
3329
|
+
return [...bounds].map(([id, b]) => ({ id, bounds: b }));
|
|
3330
|
+
}
|
|
3331
|
+
|
|
3332
|
+
/** Whether a shape dropped on another (its centre on it, sticking out) nests there. Never here; a subclass says when. */
|
|
3333
|
+
nestsOnDrop(parentId, childId) {
|
|
3334
|
+
return false;
|
|
3335
|
+
}
|
|
3336
|
+
|
|
3295
3337
|
/** The shape this one is drawn inside (nested in), or null. None here: a subclass with nesting says. */
|
|
3296
3338
|
parentOf(templateId) {
|
|
3297
3339
|
return null;
|
|
@@ -218,7 +218,7 @@ export const DIAGRAM_TYPES = {
|
|
|
218
218
|
'enterprise-ontology': {
|
|
219
219
|
name: 'Enterprise Ontology',
|
|
220
220
|
group: 'Data',
|
|
221
|
-
description: 'The universal concepts enterprise data models are built from: parties in roles enter arrangements
|
|
221
|
+
description: 'The universal concepts enterprise data models are built from (after IBM IFW\'s data concepts): parties in roles enter arrangements for products and resources; events change them, ledgers record their value; business direction steers them; classification, place, time, measure and rule describe them',
|
|
222
222
|
templates: [
|
|
223
223
|
shape('party', 'Party', ActorTemplate, {},
|
|
224
224
|
'A person or legal actor that can act or hold rights: person, organisation, government body. Every business process involves actors.'),
|
|
@@ -226,6 +226,8 @@ export const DIAGRAM_TYPES = {
|
|
|
226
226
|
'The part a party (or resource) plays in a context: customer, supplier, employee, owner, custodian. A party has many roles, and they change over time.'),
|
|
227
227
|
shape('arrangement', 'Arrangement', DocumentTemplate, { width: 130, height: 70, fillColor: C.yellow },
|
|
228
228
|
'A formalised relationship between parties, or parties and resources: contract, agreement, subscription, membership, policy, lease. Business interactions are structured by agreements.'),
|
|
229
|
+
shape('product', 'Product', PackageTemplate, { width: 120, height: 70, fillColor: C.green },
|
|
230
|
+
'What the business offers and sells, under terms: a plan, a policy, a loan, a service bundle. Not the things it holds (resources), but the offer made of them.'),
|
|
229
231
|
shape('resource', 'Resource', BoxTemplate, { width: 110, height: 80, fillColor: C.blue },
|
|
230
232
|
'A physical or digital thing of value or use: product, asset, document, file, device. Businesses manage things.'),
|
|
231
233
|
shape('event', 'Event', EllipseTemplate, { width: 120, height: 60, fillColor: C.green },
|
|
@@ -240,6 +242,8 @@ export const DIAGRAM_TYPES = {
|
|
|
240
242
|
'A point or interval in time: effective date, validity period, contract term, timestamp, posting date.'),
|
|
241
243
|
shape('measure', 'Measure', RectangleTemplate, { width: 110, height: 40, fillColor: C.white },
|
|
242
244
|
'A quantity with its unit: weight, price, balance, temperature, risk score, count. The basis of metrics, KPIs and ledgers.'),
|
|
245
|
+
shape('direction', 'Business Direction', StarTemplate, { width: 100, height: 90, fillColor: C.yellow },
|
|
246
|
+
'Where the business means to go: goal, objective, strategy, plan, policy, and the targets that measure them. It shapes products, arrangements and rules.'),
|
|
243
247
|
shape('rule', 'Rule', DiamondTemplate, { width: 100, height: 70, fillColor: C.red },
|
|
244
248
|
'A condition that governs arrangements, events or resources: business rule, policy, validation, regulatory requirement, eligibility.'),
|
|
245
249
|
note,
|