From 79a7105356a7536b154fa46c7f6fd05c48f1706a Mon Sep 17 00:00:00 2001 From: Ryan Johnson Date: Wed, 28 Jul 2021 11:14:36 -0400 Subject: [PATCH 1/9] remove extraneous calls to layoutDiagram in Palette and Diagram Components --- projects/gojs-angular/src/lib/diagram.component.ts | 1 - projects/gojs-angular/src/lib/palette.component.ts | 1 - 2 files changed, 2 deletions(-) diff --git a/projects/gojs-angular/src/lib/diagram.component.ts b/projects/gojs-angular/src/lib/diagram.component.ts index 3f87c43..95f2e90 100644 --- a/projects/gojs-angular/src/lib/diagram.component.ts +++ b/projects/gojs-angular/src/lib/diagram.component.ts @@ -90,7 +90,6 @@ export class DiagramComponent { if (this.modelData) { m.assignAllDataProperties(m.modelData, this.modelData); } - this.diagram.layoutDiagram(true); }, null); }); diff --git a/projects/gojs-angular/src/lib/palette.component.ts b/projects/gojs-angular/src/lib/palette.component.ts index 8b634be..267e85b 100644 --- a/projects/gojs-angular/src/lib/palette.component.ts +++ b/projects/gojs-angular/src/lib/palette.component.ts @@ -94,7 +94,6 @@ export class PaletteComponent { if (this.modelData) { m.assignAllDataProperties(m.modelData, this.modelData); } - this.palette.layoutDiagram(true); }, null); }); From 60a24acda95a488dfa1bb3a6c5098007f49c8e37 Mon Sep 17 00:00:00 2001 From: Ryan Johnson Date: Wed, 28 Jul 2021 11:27:31 -0400 Subject: [PATCH 2/9] Update package.json --- projects/gojs-angular/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/projects/gojs-angular/package.json b/projects/gojs-angular/package.json index 6b170f5..932dc07 100644 --- a/projects/gojs-angular/package.json +++ b/projects/gojs-angular/package.json @@ -1,6 +1,6 @@ { "name": "gojs-angular", - "version": "1.0.17", + "version": "1.0.18", "peerDependencies": { "@angular/common": ">=11.0.0", "@angular/core": ">=11.0.0" From a94c64b691afb9ead747f6cd340802f7de758402 Mon Sep 17 00:00:00 2001 From: Ryan Johnson Date: Thu, 5 Aug 2021 12:41:43 -0400 Subject: [PATCH 3/9] 1.x clearModel beta --- .gitignore | 1 + .../gojs-angular/src/lib/diagram.component.ts | 56 ++++++++++++++----- .../gojs-angular/src/lib/palette.component.ts | 2 +- 3 files changed, 45 insertions(+), 14 deletions(-) diff --git a/.gitignore b/.gitignore index 037afdf..20fb034 100644 --- a/.gitignore +++ b/.gitignore @@ -10,6 +10,7 @@ # dependencies /node_modules /src/app +/src # profiling files chrome-profiler-events.json diff --git a/projects/gojs-angular/src/lib/diagram.component.ts b/projects/gojs-angular/src/lib/diagram.component.ts index 95f2e90..eae745b 100644 --- a/projects/gojs-angular/src/lib/diagram.component.ts +++ b/projects/gojs-angular/src/lib/diagram.component.ts @@ -39,9 +39,11 @@ export class DiagramComponent { // differs for array inputs (node / link data arrays) private _ndaDiffer: KeyValueDiffer; private _ldaDiffer: KeyValueDiffer; - private _mdaDiffer: KeyValueDiffer; + /** An internal flag used to tell ngOnChanges to treat the next sync operation as a Diagram initialization */ + private wasCleared: boolean = false; + constructor(private _kvdiffers: KeyValueDiffers, public zone: NgZone) { // differs used to check if there have been changed to the array @Inputs // without them, changes to the input arrays won't register in ngOnChanges, @@ -105,7 +107,6 @@ export class DiagramComponent { }; this.diagram.addModelChangedListener(this.modelChangedListener); - } // end ngAfterViewInit /** @@ -235,7 +236,7 @@ export class DiagramComponent { }); } - } + } // end mergeChanges function /** * Always be checking if array Input data has changed (node and link data arrays) @@ -259,23 +260,52 @@ export class DiagramComponent { if (this.skipsDiagramUpdate) return; + if (this.wasCleared) { + this.diagram.delayInitialization(() => { + this.mergeAppDataWithModel(this, nodeDiffs, linkDiffs, true); + }); + this.wasCleared = false; + } else { + this.mergeAppDataWithModel(this, nodeDiffs, linkDiffs, false); + } + + } // end ngDoCheck + + private mergeAppDataWithModel(component: DiagramComponent, nodeDiffs, linkDiffs, isInit?: boolean) { // don't need model change listener while performing known data updates - if (this.modelChangedListener !== null) this.diagram.model.removeChangedListener(this.modelChangedListener); + if (component.modelChangedListener !== null) this.diagram.model.removeChangedListener(this.modelChangedListener); - this.diagram.model.startTransaction('update data'); + component.diagram.model.startTransaction('update data'); + if (isInit) component.diagram.model.modelData = {}; // update modelData first, in case bindings on nodes / links depend on model data - this.diagram.model.assignAllDataProperties(this.diagram.model.modelData, this.modelData); + component.diagram.model.assignAllDataProperties(this.diagram.model.modelData, this.modelData); // merge node / link data - DiagramComponent.mergeChanges(this, nodeDiffs, "n"); - DiagramComponent.mergeChanges(this, linkDiffs, "l"); - this.diagram.model.commitTransaction('update data'); + if (isInit) component.diagram.model.nodeDataArray = []; + // DiagramComponent.mergeChanges(component, nodeDiffs, "n"); + this.diagram.model.mergeNodeDataArray(this.nodeDataArray); + if (component.linkDataArray && component.diagram.model instanceof go.GraphLinksModel) { + if (isInit) component.diagram.model.linkDataArray = []; + component.diagram.model.mergeLinkDataArray(this.linkDataArray); + // DiagramComponent.mergeChanges(component, linkDiffs, "l"); + } + component.diagram.model.commitTransaction('update data'); // reset the model change listener - if (this.modelChangedListener !== null) this.diagram.model.addChangedListener(this.modelChangedListener); + if (component.modelChangedListener !== null) component.diagram.model.addChangedListener(this.modelChangedListener); + } // end mergeAppDataWithModel function - } // end ngDoCheck + /** + * Allows the next update to be treated as an initial load of the model. + */ + public clearModel(): void { + const diagram = this.diagram; + if (diagram !== null) { + this.wasCleared = true; + } + } // end clearModel function public ngOnDestroy() { this.diagram.div = null; // removes event listeners - } -} + } // end ngOnDestroy function + +} // end DiagramComponent class diff --git a/projects/gojs-angular/src/lib/palette.component.ts b/projects/gojs-angular/src/lib/palette.component.ts index 267e85b..61ae912 100644 --- a/projects/gojs-angular/src/lib/palette.component.ts +++ b/projects/gojs-angular/src/lib/palette.component.ts @@ -149,6 +149,6 @@ export class PaletteComponent { public ngOnDestroy() { this.palette.div = null; // removes event listeners - } + } // end ngOnDestroy } From 5a07a0cc89aed4cdd6d21937007c29ef6fe70372 Mon Sep 17 00:00:00 2001 From: Ryan Johnson Date: Thu, 5 Aug 2021 13:53:05 -0400 Subject: [PATCH 4/9] Update diagram.component.ts --- projects/gojs-angular/src/lib/diagram.component.ts | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/projects/gojs-angular/src/lib/diagram.component.ts b/projects/gojs-angular/src/lib/diagram.component.ts index eae745b..6da7929 100644 --- a/projects/gojs-angular/src/lib/diagram.component.ts +++ b/projects/gojs-angular/src/lib/diagram.component.ts @@ -276,15 +276,15 @@ export class DiagramComponent { if (component.modelChangedListener !== null) this.diagram.model.removeChangedListener(this.modelChangedListener); component.diagram.model.startTransaction('update data'); - if (isInit) component.diagram.model.modelData = {}; + // if (isInit) component.diagram.model.modelData = {}; // update modelData first, in case bindings on nodes / links depend on model data component.diagram.model.assignAllDataProperties(this.diagram.model.modelData, this.modelData); // merge node / link data - if (isInit) component.diagram.model.nodeDataArray = []; + // if (isInit) component.diagram.model.nodeDataArray = []; // DiagramComponent.mergeChanges(component, nodeDiffs, "n"); this.diagram.model.mergeNodeDataArray(this.nodeDataArray); if (component.linkDataArray && component.diagram.model instanceof go.GraphLinksModel) { - if (isInit) component.diagram.model.linkDataArray = []; + // if (isInit) component.diagram.model.linkDataArray = []; component.diagram.model.mergeLinkDataArray(this.linkDataArray); // DiagramComponent.mergeChanges(component, linkDiffs, "l"); } @@ -300,6 +300,11 @@ export class DiagramComponent { public clearModel(): void { const diagram = this.diagram; if (diagram !== null) { + diagram.model.modelData = {}; + diagram.model.nodeDataArray = []; + if (diagram.model instanceof go.GraphLinksModel) { + diagram.model.linkDataArray = []; + } this.wasCleared = true; } } // end clearModel function From 579d83d28915155c803e2be0628acb434c0ef32b Mon Sep 17 00:00:00 2001 From: Ryan Johnson Date: Thu, 5 Aug 2021 16:10:53 -0400 Subject: [PATCH 5/9] Update diagram.component.ts --- .../gojs-angular/src/lib/diagram.component.ts | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/projects/gojs-angular/src/lib/diagram.component.ts b/projects/gojs-angular/src/lib/diagram.component.ts index 6da7929..5d3aab7 100644 --- a/projects/gojs-angular/src/lib/diagram.component.ts +++ b/projects/gojs-angular/src/lib/diagram.component.ts @@ -263,8 +263,8 @@ export class DiagramComponent { if (this.wasCleared) { this.diagram.delayInitialization(() => { this.mergeAppDataWithModel(this, nodeDiffs, linkDiffs, true); - }); - this.wasCleared = false; + this.wasCleared = false; + }); } else { this.mergeAppDataWithModel(this, nodeDiffs, linkDiffs, false); } @@ -295,19 +295,17 @@ export class DiagramComponent { } // end mergeAppDataWithModel function /** - * Allows the next update to be treated as an initial load of the model. + * Clears the diagram of all nodes, links, and model data. + * Also clears the UndoManager history and clipboard. + * The next state update will be treated as diagram initialization. */ - public clearModel(): void { + public clear(): void { const diagram = this.diagram; if (diagram !== null) { - diagram.model.modelData = {}; - diagram.model.nodeDataArray = []; - if (diagram.model instanceof go.GraphLinksModel) { - diagram.model.linkDataArray = []; - } + diagram.clear(); this.wasCleared = true; } - } // end clearModel function + } // end clear function public ngOnDestroy() { this.diagram.div = null; // removes event listeners From 5ccd8c40c8b601bbe8334d0a029e6ed281a81bf0 Mon Sep 17 00:00:00 2001 From: Ryan Johnson Date: Wed, 18 Aug 2021 10:43:13 -0400 Subject: [PATCH 6/9] Update diagram.component.ts --- .../gojs-angular/src/lib/diagram.component.ts | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/projects/gojs-angular/src/lib/diagram.component.ts b/projects/gojs-angular/src/lib/diagram.component.ts index 5d3aab7..28be1ba 100644 --- a/projects/gojs-angular/src/lib/diagram.component.ts +++ b/projects/gojs-angular/src/lib/diagram.component.ts @@ -110,12 +110,12 @@ export class DiagramComponent { } // end ngAfterViewInit /** - * Merges changes from app data into GoJS model data, + * Merges changes from app data into GoJS model data, * making sure only actual changes (and not falsely flagged no-ops on array / obj data props) are logged * @param component an instance of DiagramComponent or PaletteComponent * @param kvchanges The kvchanges object produced by either a node or link Angular differ object * @param str "n" for node data changes, "l" for link data changes - * */ + * */ public static mergeChanges(component, kvchanges, str): boolean { // helper function @@ -193,7 +193,7 @@ export class DiagramComponent { // handle changed data for nodes / links kvchanges.forEachChangedItem((r: KeyValueChangeRecord) => { - + // ensure "changes" to array / object / enumerable data properties are legit const sameVals = compareObjs(r.currentValue, r.previousValue); @@ -232,10 +232,10 @@ export class DiagramComponent { } } } - + }); } - + } // end mergeChanges function /** @@ -248,7 +248,7 @@ export class DiagramComponent { // these need to be run each check, even if no merging happens // otherwise, they will detect all diffs that happened since last time skipsDiagram was false, - // such as remove ops that happened in GoJS when skipsDiagram = true, + // such as remove ops that happened in GoJS when skipsDiagram = true, // and then realllllly bad stuff happens (deleting random nodes, updating the wrong Parts) // Angular differs are a lot of fun var nodeDiffs = this._ndaDiffer.diff(this.nodeDataArray); @@ -264,7 +264,7 @@ export class DiagramComponent { this.diagram.delayInitialization(() => { this.mergeAppDataWithModel(this, nodeDiffs, linkDiffs, true); this.wasCleared = false; - }); + }); } else { this.mergeAppDataWithModel(this, nodeDiffs, linkDiffs, false); } @@ -276,17 +276,12 @@ export class DiagramComponent { if (component.modelChangedListener !== null) this.diagram.model.removeChangedListener(this.modelChangedListener); component.diagram.model.startTransaction('update data'); - // if (isInit) component.diagram.model.modelData = {}; // update modelData first, in case bindings on nodes / links depend on model data component.diagram.model.assignAllDataProperties(this.diagram.model.modelData, this.modelData); // merge node / link data - // if (isInit) component.diagram.model.nodeDataArray = []; - // DiagramComponent.mergeChanges(component, nodeDiffs, "n"); this.diagram.model.mergeNodeDataArray(this.nodeDataArray); if (component.linkDataArray && component.diagram.model instanceof go.GraphLinksModel) { - // if (isInit) component.diagram.model.linkDataArray = []; component.diagram.model.mergeLinkDataArray(this.linkDataArray); - // DiagramComponent.mergeChanges(component, linkDiffs, "l"); } component.diagram.model.commitTransaction('update data'); From cee59bdc906438c0cb53436751bf4fc5f0210d13 Mon Sep 17 00:00:00 2001 From: Ryan Johnson Date: Wed, 18 Aug 2021 11:03:26 -0400 Subject: [PATCH 7/9] Update diagram.component.ts --- .../gojs-angular/src/lib/diagram.component.ts | 25 ++++++++++--------- 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/projects/gojs-angular/src/lib/diagram.component.ts b/projects/gojs-angular/src/lib/diagram.component.ts index 28be1ba..3bcd5a3 100644 --- a/projects/gojs-angular/src/lib/diagram.component.ts +++ b/projects/gojs-angular/src/lib/diagram.component.ts @@ -262,28 +262,29 @@ export class DiagramComponent { if (this.wasCleared) { this.diagram.delayInitialization(() => { - this.mergeAppDataWithModel(this, nodeDiffs, linkDiffs, true); + this.mergeAppDataWithModel(this, true); this.wasCleared = false; }); } else { - this.mergeAppDataWithModel(this, nodeDiffs, linkDiffs, false); + this.mergeAppDataWithModel(this, false); } } // end ngDoCheck - private mergeAppDataWithModel(component: DiagramComponent, nodeDiffs, linkDiffs, isInit?: boolean) { + private mergeAppDataWithModel(component: DiagramComponent, isInit?: boolean) { + // don't need model change listener while performing known data updates if (component.modelChangedListener !== null) this.diagram.model.removeChangedListener(this.modelChangedListener); - component.diagram.model.startTransaction('update data'); - // update modelData first, in case bindings on nodes / links depend on model data - component.diagram.model.assignAllDataProperties(this.diagram.model.modelData, this.modelData); - // merge node / link data - this.diagram.model.mergeNodeDataArray(this.nodeDataArray); - if (component.linkDataArray && component.diagram.model instanceof go.GraphLinksModel) { - component.diagram.model.mergeLinkDataArray(this.linkDataArray); - } - component.diagram.model.commitTransaction('update data'); + component.diagram.model.commit((m: go.Model) => { + // update modelData first, in case bindings on nodes / links depend on model data + component.diagram.model.assignAllDataProperties(this.diagram.model.modelData, this.modelData); + // merge node / link data + this.diagram.model.mergeNodeDataArray(this.nodeDataArray); + if (component.linkDataArray && component.diagram.model instanceof go.GraphLinksModel) { + component.diagram.model.mergeLinkDataArray(this.linkDataArray); + } + }, isInit ? null : 'merge data'); // reset the model change listener if (component.modelChangedListener !== null) component.diagram.model.addChangedListener(this.modelChangedListener); From a63c7e1317505173d3a4d671a572c041df28a57e Mon Sep 17 00:00:00 2001 From: Ryan Johnson Date: Wed, 18 Aug 2021 11:40:50 -0400 Subject: [PATCH 8/9] Update package.json --- projects/gojs-angular/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/projects/gojs-angular/package.json b/projects/gojs-angular/package.json index 932dc07..0909f7d 100644 --- a/projects/gojs-angular/package.json +++ b/projects/gojs-angular/package.json @@ -1,6 +1,6 @@ { "name": "gojs-angular", - "version": "1.0.18", + "version": "1.0.19", "peerDependencies": { "@angular/common": ">=11.0.0", "@angular/core": ">=11.0.0" From 3bc8ef804aaba8e4e4138ca7b690d0852e612739 Mon Sep 17 00:00:00 2001 From: Ryan Johnson Date: Thu, 21 Oct 2021 09:13:29 -0400 Subject: [PATCH 9/9] update modelData before node / link data in Diagram/Palette init --- projects/gojs-angular/package.json | 2 +- projects/gojs-angular/src/lib/diagram.component.ts | 6 +++--- projects/gojs-angular/src/lib/palette.component.ts | 8 ++++---- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/projects/gojs-angular/package.json b/projects/gojs-angular/package.json index 0909f7d..fd723aa 100644 --- a/projects/gojs-angular/package.json +++ b/projects/gojs-angular/package.json @@ -1,6 +1,6 @@ { "name": "gojs-angular", - "version": "1.0.19", + "version": "1.0.20", "peerDependencies": { "@angular/common": ">=11.0.0", "@angular/core": ">=11.0.0" diff --git a/projects/gojs-angular/src/lib/diagram.component.ts b/projects/gojs-angular/src/lib/diagram.component.ts index 3bcd5a3..e70616c 100644 --- a/projects/gojs-angular/src/lib/diagram.component.ts +++ b/projects/gojs-angular/src/lib/diagram.component.ts @@ -85,13 +85,13 @@ export class DiagramComponent { this.diagram.delayInitialization(() => { const model = this.diagram.model; model.commit((m: go.Model) => { + if (this.modelData) { + m.assignAllDataProperties(m.modelData, this.modelData); + } m.mergeNodeDataArray(m.cloneDeep(this.nodeDataArray)); if (this.linkDataArray && m instanceof go.GraphLinksModel) { m.mergeLinkDataArray(m.cloneDeep(this.linkDataArray)); } - if (this.modelData) { - m.assignAllDataProperties(m.modelData, this.modelData); - } }, null); }); diff --git a/projects/gojs-angular/src/lib/palette.component.ts b/projects/gojs-angular/src/lib/palette.component.ts index 61ae912..1ff0c94 100644 --- a/projects/gojs-angular/src/lib/palette.component.ts +++ b/projects/gojs-angular/src/lib/palette.component.ts @@ -87,13 +87,13 @@ export class PaletteComponent { this.palette.delayInitialization(() => { const model = this.palette.model; model.commit((m: go.Model) => { + if (this.modelData) { + m.assignAllDataProperties(m.modelData, this.modelData); + } m.mergeNodeDataArray(m.cloneDeep(this.nodeDataArray)); if (this.linkDataArray && m instanceof go.GraphLinksModel) { m.mergeLinkDataArray(m.cloneDeep(this.linkDataArray)); } - if (this.modelData) { - m.assignAllDataProperties(m.modelData, this.modelData); - } }, null); }); @@ -121,7 +121,7 @@ export class PaletteComponent { // these need to be run each check, even if no merging happens // otherwise, they will detect all diffs that happened since last time skipsPaletteUpdate was false, - // such as remove ops that happened in GoJS when skipsPaletteUpdate = true, + // such as remove ops that happened in GoJS when skipsPaletteUpdate = true, // and then realllllly bad stuff happens (deleting random nodes, updating the wrong Parts) // Angular differs are a lot of fun var nodeDiffs = this._ndaDiffer.diff(this.nodeDataArray);