@finos/legend-extension-dsl-diagram 1.0.29 → 1.0.30

Sign up to get free protection for your applications and to get access to all the features.
Files changed (106) hide show
  1. package/lib/DiagramRenderer.d.ts +4 -1
  2. package/lib/DiagramRenderer.d.ts.map +1 -1
  3. package/lib/DiagramRenderer.js +21 -23
  4. package/lib/DiagramRenderer.js.map +1 -1
  5. package/lib/components/studio/ClassDiagramPreview.d.ts.map +1 -1
  6. package/lib/components/studio/ClassDiagramPreview.js +3 -1
  7. package/lib/components/studio/ClassDiagramPreview.js.map +1 -1
  8. package/lib/components/studio/DiagramEditor.d.ts.map +1 -1
  9. package/lib/components/studio/DiagramEditor.js +2 -2
  10. package/lib/components/studio/DiagramEditor.js.map +1 -1
  11. package/lib/graphManager/DSLDiagram_PureGraphManagerPlugin.d.ts +2 -1
  12. package/lib/graphManager/DSLDiagram_PureGraphManagerPlugin.d.ts.map +1 -1
  13. package/lib/graphManager/DSLDiagram_PureGraphManagerPlugin.js +11 -0
  14. package/lib/graphManager/DSLDiagram_PureGraphManagerPlugin.js.map +1 -1
  15. package/lib/graphManager/action/changeDetection/DSLDiagram_ObserverHelper.d.ts +34 -0
  16. package/lib/graphManager/action/changeDetection/DSLDiagram_ObserverHelper.d.ts.map +1 -0
  17. package/lib/graphManager/action/changeDetection/DSLDiagram_ObserverHelper.js +94 -0
  18. package/lib/graphManager/action/changeDetection/DSLDiagram_ObserverHelper.js.map +1 -0
  19. package/lib/helpers/DiagramHelper.d.ts +16 -1
  20. package/lib/helpers/DiagramHelper.d.ts.map +1 -1
  21. package/lib/helpers/DiagramHelper.js +87 -1
  22. package/lib/helpers/DiagramHelper.js.map +1 -1
  23. package/lib/index.css +1 -1
  24. package/lib/index.d.ts +0 -1
  25. package/lib/index.d.ts.map +1 -1
  26. package/lib/index.js +0 -1
  27. package/lib/index.js.map +1 -1
  28. package/lib/models/metamodels/pure/packageableElements/diagram/DSLDiagram_AssociationView.d.ts.map +1 -1
  29. package/lib/models/metamodels/pure/packageableElements/diagram/DSLDiagram_AssociationView.js +0 -4
  30. package/lib/models/metamodels/pure/packageableElements/diagram/DSLDiagram_AssociationView.js.map +1 -1
  31. package/lib/models/metamodels/pure/packageableElements/diagram/DSLDiagram_ClassView.d.ts.map +1 -1
  32. package/lib/models/metamodels/pure/packageableElements/diagram/DSLDiagram_ClassView.js +0 -8
  33. package/lib/models/metamodels/pure/packageableElements/diagram/DSLDiagram_ClassView.js.map +1 -1
  34. package/lib/models/metamodels/pure/packageableElements/diagram/DSLDiagram_ClassViewReference.d.ts.map +1 -1
  35. package/lib/models/metamodels/pure/packageableElements/diagram/DSLDiagram_ClassViewReference.js +0 -4
  36. package/lib/models/metamodels/pure/packageableElements/diagram/DSLDiagram_ClassViewReference.js.map +1 -1
  37. package/lib/models/metamodels/pure/packageableElements/diagram/DSLDiagram_Diagram.d.ts +0 -1
  38. package/lib/models/metamodels/pure/packageableElements/diagram/DSLDiagram_Diagram.d.ts.map +1 -1
  39. package/lib/models/metamodels/pure/packageableElements/diagram/DSLDiagram_Diagram.js +0 -11
  40. package/lib/models/metamodels/pure/packageableElements/diagram/DSLDiagram_Diagram.js.map +1 -1
  41. package/lib/models/metamodels/pure/packageableElements/diagram/DSLDiagram_GeneralizationView.d.ts +0 -3
  42. package/lib/models/metamodels/pure/packageableElements/diagram/DSLDiagram_GeneralizationView.d.ts.map +1 -1
  43. package/lib/models/metamodels/pure/packageableElements/diagram/DSLDiagram_GeneralizationView.js +0 -7
  44. package/lib/models/metamodels/pure/packageableElements/diagram/DSLDiagram_GeneralizationView.js.map +1 -1
  45. package/lib/models/metamodels/pure/packageableElements/diagram/DSLDiagram_PropertyView.d.ts +0 -4
  46. package/lib/models/metamodels/pure/packageableElements/diagram/DSLDiagram_PropertyView.d.ts.map +1 -1
  47. package/lib/models/metamodels/pure/packageableElements/diagram/DSLDiagram_PropertyView.js +0 -7
  48. package/lib/models/metamodels/pure/packageableElements/diagram/DSLDiagram_PropertyView.js.map +1 -1
  49. package/lib/models/metamodels/pure/packageableElements/diagram/DSLDiagram_RelationshipEdgeView.d.ts +6 -1
  50. package/lib/models/metamodels/pure/packageableElements/diagram/DSLDiagram_RelationshipEdgeView.d.ts.map +1 -1
  51. package/lib/models/metamodels/pure/packageableElements/diagram/DSLDiagram_RelationshipEdgeView.js +6 -6
  52. package/lib/models/metamodels/pure/packageableElements/diagram/DSLDiagram_RelationshipEdgeView.js.map +1 -1
  53. package/lib/models/metamodels/pure/packageableElements/diagram/DSLDiagram_RelationshipView.d.ts +24 -6
  54. package/lib/models/metamodels/pure/packageableElements/diagram/DSLDiagram_RelationshipView.d.ts.map +1 -1
  55. package/lib/models/metamodels/pure/packageableElements/diagram/DSLDiagram_RelationshipView.js +58 -27
  56. package/lib/models/metamodels/pure/packageableElements/diagram/DSLDiagram_RelationshipView.js.map +1 -1
  57. package/lib/models/metamodels/pure/packageableElements/diagram/geometry/DSLDiagram_PositionedRectangle.d.ts.map +1 -1
  58. package/lib/models/metamodels/pure/packageableElements/diagram/geometry/DSLDiagram_PositionedRectangle.js +0 -4
  59. package/lib/models/metamodels/pure/packageableElements/diagram/geometry/DSLDiagram_PositionedRectangle.js.map +1 -1
  60. package/lib/models/metamodels/pure/packageableElements/diagram/geometry/DSLDiagram_Vector.d.ts +3 -3
  61. package/lib/models/metamodels/pure/packageableElements/diagram/geometry/DSLDiagram_Vector.d.ts.map +1 -1
  62. package/lib/models/metamodels/pure/packageableElements/diagram/geometry/DSLDiagram_Vector.js +1 -1
  63. package/lib/models/metamodels/pure/packageableElements/diagram/geometry/DSLDiagram_Vector.js.map +1 -1
  64. package/lib/models/protocols/pure/v1/transformation/pureGraph/V1_DSLDiagram_GraphBuilderHelper.d.ts.map +1 -1
  65. package/lib/models/protocols/pure/v1/transformation/pureGraph/V1_DSLDiagram_GraphBuilderHelper.js +3 -4
  66. package/lib/models/protocols/pure/v1/transformation/pureGraph/V1_DSLDiagram_GraphBuilderHelper.js.map +1 -1
  67. package/lib/models/protocols/pure/v1/transformation/pureGraph/V1_DSLDiagram_TransformerHelper.js +2 -2
  68. package/lib/models/protocols/pure/v1/transformation/pureGraph/V1_DSLDiagram_TransformerHelper.js.map +1 -1
  69. package/lib/package.json +2 -2
  70. package/lib/stores/studio/{DSLDiagram_ModifierHelper.d.ts → DSLDiagram_GraphModifierHelper.d.ts} +10 -7
  71. package/lib/stores/studio/DSLDiagram_GraphModifierHelper.d.ts.map +1 -0
  72. package/lib/stores/studio/{DSLDiagram_ModifierHelper.js → DSLDiagram_GraphModifierHelper.js} +20 -13
  73. package/lib/stores/studio/DSLDiagram_GraphModifierHelper.js.map +1 -0
  74. package/lib/stores/studio/DiagramEditorState.d.ts.map +1 -1
  75. package/lib/stores/studio/DiagramEditorState.js +10 -7
  76. package/lib/stores/studio/DiagramEditorState.js.map +1 -1
  77. package/package.json +9 -9
  78. package/src/DiagramRenderer.ts +31 -34
  79. package/src/components/studio/ClassDiagramPreview.tsx +3 -1
  80. package/src/components/studio/DiagramEditor.tsx +2 -1
  81. package/src/graphManager/DSLDiagram_PureGraphManagerPlugin.ts +17 -0
  82. package/src/graphManager/action/changeDetection/DSLDiagram_ObserverHelper.ts +153 -0
  83. package/src/helpers/DiagramHelper.ts +122 -1
  84. package/src/index.ts +0 -1
  85. package/src/models/metamodels/pure/packageableElements/diagram/DSLDiagram_AssociationView.ts +0 -6
  86. package/src/models/metamodels/pure/packageableElements/diagram/DSLDiagram_ClassView.ts +0 -10
  87. package/src/models/metamodels/pure/packageableElements/diagram/DSLDiagram_ClassViewReference.ts +0 -6
  88. package/src/models/metamodels/pure/packageableElements/diagram/DSLDiagram_Diagram.ts +0 -13
  89. package/src/models/metamodels/pure/packageableElements/diagram/DSLDiagram_GeneralizationView.ts +0 -11
  90. package/src/models/metamodels/pure/packageableElements/diagram/DSLDiagram_PropertyView.ts +0 -17
  91. package/src/models/metamodels/pure/packageableElements/diagram/DSLDiagram_RelationshipEdgeView.ts +6 -7
  92. package/src/models/metamodels/pure/packageableElements/diagram/DSLDiagram_RelationshipView.ts +77 -34
  93. package/src/models/metamodels/pure/packageableElements/diagram/geometry/DSLDiagram_PositionedRectangle.ts +0 -5
  94. package/src/models/metamodels/pure/packageableElements/diagram/geometry/DSLDiagram_Vector.ts +3 -3
  95. package/src/models/protocols/pure/v1/transformation/pureGraph/V1_DSLDiagram_GraphBuilderHelper.ts +6 -4
  96. package/src/models/protocols/pure/v1/transformation/pureGraph/V1_DSLDiagram_TransformerHelper.ts +4 -4
  97. package/src/stores/studio/{DSLDiagram_ModifierHelper.ts → DSLDiagram_GraphModifierHelper.ts} +34 -18
  98. package/src/stores/studio/DiagramEditorState.ts +26 -7
  99. package/tsconfig.json +2 -2
  100. package/lib/models/metamodels/pure/packageableElements/diagram/DSLDiagram_GraphModifierHelper.d.ts +0 -35
  101. package/lib/models/metamodels/pure/packageableElements/diagram/DSLDiagram_GraphModifierHelper.d.ts.map +0 -1
  102. package/lib/models/metamodels/pure/packageableElements/diagram/DSLDiagram_GraphModifierHelper.js +0 -118
  103. package/lib/models/metamodels/pure/packageableElements/diagram/DSLDiagram_GraphModifierHelper.js.map +0 -1
  104. package/lib/stores/studio/DSLDiagram_ModifierHelper.d.ts.map +0 -1
  105. package/lib/stores/studio/DSLDiagram_ModifierHelper.js.map +0 -1
  106. package/src/models/metamodels/pure/packageableElements/diagram/DSLDiagram_GraphModifierHelper.ts +0 -165
@@ -17,10 +17,13 @@
17
17
  import packageJson from '../../package.json';
18
18
  import {
19
19
  PureGraphManagerPlugin,
20
+ type ObserverContext,
21
+ type ElementObserver,
20
22
  type PackageableElement,
21
23
  type PureGrammarElementLabeler,
22
24
  } from '@finos/legend-graph';
23
25
  import { Diagram } from '../models/metamodels/pure/packageableElements/diagram/DSLDiagram_Diagram';
26
+ import { observe_Diagram } from './action/changeDetection/DSLDiagram_ObserverHelper';
24
27
 
25
28
  const PURE_GRAMMAR_DIAGRAM_PARSER_NAME = 'Diagram';
26
29
  const PURE_GRAMMAR_DIAGRAM_ELEMENT_TYPE_LABEL = 'Diagram';
@@ -48,4 +51,18 @@ export class DSLDiagram_PureGraphManagerPlugin extends PureGraphManagerPlugin {
48
51
  },
49
52
  ];
50
53
  }
54
+
55
+ override getExtraElementObservers(): ElementObserver[] {
56
+ return [
57
+ (
58
+ element: PackageableElement,
59
+ context: ObserverContext,
60
+ ): PackageableElement | undefined => {
61
+ if (element instanceof Diagram) {
62
+ return observe_Diagram(element);
63
+ }
64
+ return undefined;
65
+ },
66
+ ];
67
+ }
51
68
  }
@@ -0,0 +1,153 @@
1
+ /**
2
+ * Copyright (c) 2020-present, Goldman Sachs
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+
17
+ import {
18
+ observe_Abstract_PackageableElement,
19
+ observe_PackageableElementReference,
20
+ observe_PropertyReference,
21
+ skipObserved,
22
+ } from '@finos/legend-graph';
23
+ import { computed, makeObservable, observable, override } from 'mobx';
24
+ import type { AssociationView } from '../../../models/metamodels/pure/packageableElements/diagram/DSLDiagram_AssociationView';
25
+ import type { ClassView } from '../../../models/metamodels/pure/packageableElements/diagram/DSLDiagram_ClassView';
26
+ import type { ClassViewReference } from '../../../models/metamodels/pure/packageableElements/diagram/DSLDiagram_ClassViewReference';
27
+ import type { Diagram } from '../../../models/metamodels/pure/packageableElements/diagram/DSLDiagram_Diagram';
28
+ import type { GeneralizationView } from '../../../models/metamodels/pure/packageableElements/diagram/DSLDiagram_GeneralizationView';
29
+ import type { PropertyView } from '../../../models/metamodels/pure/packageableElements/diagram/DSLDiagram_PropertyView';
30
+ import type { RelationshipEdgeView } from '../../../models/metamodels/pure/packageableElements/diagram/DSLDiagram_RelationshipEdgeView';
31
+ import type { RelationshipView } from '../../../models/metamodels/pure/packageableElements/diagram/DSLDiagram_RelationshipView';
32
+ import type { PositionedRectangle } from '../../../models/metamodels/pure/packageableElements/diagram/geometry/DSLDiagram_PositionedRectangle';
33
+
34
+ export const observe_PositionedRectangle = skipObserved(
35
+ (metamodel: PositionedRectangle): PositionedRectangle =>
36
+ makeObservable(metamodel, {
37
+ dummyObservable: observable,
38
+ }),
39
+ );
40
+
41
+ export const observe_ClassViewReference = skipObserved(
42
+ (metamodel: ClassViewReference): ClassViewReference => {
43
+ makeObservable(metamodel, {
44
+ value: observable,
45
+ });
46
+
47
+ observe_PackageableElementReference(metamodel.ownerReference);
48
+
49
+ return metamodel;
50
+ },
51
+ );
52
+
53
+ export const observe_ClassView = skipObserved(
54
+ (metamodel: ClassView): ClassView => {
55
+ observe_PositionedRectangle(metamodel);
56
+
57
+ makeObservable(metamodel, {
58
+ id: observable,
59
+ hideProperties: observable,
60
+ hideTaggedValues: observable,
61
+ hideStereotypes: observable,
62
+ hashCode: computed,
63
+ });
64
+
65
+ observe_PackageableElementReference(metamodel.class);
66
+
67
+ return metamodel;
68
+ },
69
+ );
70
+
71
+ export const observe_RelationShipEdgeView = skipObserved(
72
+ (metamodel: RelationshipEdgeView): RelationshipEdgeView => {
73
+ observe_ClassViewReference(metamodel.classView);
74
+
75
+ return metamodel;
76
+ },
77
+ );
78
+
79
+ export const observe_RelationshipView = skipObserved(
80
+ (metamodel: RelationshipView): RelationshipView => {
81
+ makeObservable(metamodel, {
82
+ // NOTE: to optimize performance for diagram, we have made classview's position and rectangle non-observable
83
+ // if we want to further optimize, perhaps we can also remove observability from path
84
+ path: observable,
85
+ pathForSerialization: computed,
86
+ });
87
+
88
+ observe_RelationShipEdgeView(metamodel.from);
89
+ observe_RelationShipEdgeView(metamodel.to);
90
+
91
+ return metamodel;
92
+ },
93
+ );
94
+
95
+ export const observe_GeneralizationView = skipObserved(
96
+ (metamodel: GeneralizationView): GeneralizationView => {
97
+ observe_RelationshipView(metamodel);
98
+
99
+ makeObservable(metamodel, {
100
+ hashCode: computed,
101
+ });
102
+
103
+ return metamodel;
104
+ },
105
+ );
106
+
107
+ export const observe_AssociationView = skipObserved(
108
+ (metamodel: AssociationView): AssociationView => {
109
+ observe_RelationshipView(metamodel);
110
+
111
+ makeObservable(metamodel, {
112
+ hashCode: computed,
113
+ });
114
+
115
+ observe_PropertyReference(metamodel.property);
116
+ observe_PackageableElementReference(metamodel.association);
117
+
118
+ return metamodel;
119
+ },
120
+ );
121
+
122
+ export const observe_PropertyView = skipObserved(
123
+ (metamodel: PropertyView): PropertyView => {
124
+ observe_RelationshipView(metamodel);
125
+
126
+ makeObservable(metamodel, {
127
+ hashCode: computed,
128
+ });
129
+
130
+ observe_PropertyReference(metamodel.property);
131
+
132
+ return metamodel;
133
+ },
134
+ );
135
+
136
+ export const observe_Diagram = skipObserved((metamodel: Diagram): Diagram => {
137
+ observe_Abstract_PackageableElement(metamodel);
138
+
139
+ makeObservable<Diagram, '_elementHashCode'>(metamodel, {
140
+ classViews: observable,
141
+ associationViews: observable,
142
+ generalizationViews: observable,
143
+ propertyViews: observable,
144
+ _elementHashCode: override,
145
+ });
146
+
147
+ metamodel.classViews.forEach(observe_ClassView);
148
+ metamodel.associationViews.forEach(observe_AssociationView);
149
+ metamodel.generalizationViews.forEach(observe_GeneralizationView);
150
+ metamodel.propertyViews.forEach(observe_PropertyView);
151
+
152
+ return metamodel;
153
+ });
@@ -14,11 +14,13 @@
14
14
  * limitations under the License.
15
15
  */
16
16
 
17
+ import { RelationshipView } from '../models/metamodels/pure/packageableElements/diagram/DSLDiagram_RelationshipView';
18
+ import { Point } from '../models/metamodels/pure/packageableElements/diagram/geometry/DSLDiagram_Point';
19
+ import { Vector } from '../models/metamodels/pure/packageableElements/diagram/geometry/DSLDiagram_Vector';
17
20
  import type { PureModel } from '@finos/legend-graph';
18
21
  import { deleteEntry } from '@finos/legend-shared';
19
22
  import type { ClassView } from '../models/metamodels/pure/packageableElements/diagram/DSLDiagram_ClassView';
20
23
  import type { Diagram } from '../models/metamodels/pure/packageableElements/diagram/DSLDiagram_Diagram';
21
- import { Point } from '../models/metamodels/pure/packageableElements/diagram/geometry/DSLDiagram_Point';
22
24
 
23
25
  /**
24
26
  * Get absolute position of element on the screen by recursively walking up element tree
@@ -78,3 +80,122 @@ export const cleanUpDeadReferencesInDiagram = (
78
80
  deleteEntry(diagram.generalizationViews, g),
79
81
  );
80
82
  };
83
+
84
+ export const _relationshipView_setPath = (
85
+ relationshipView: RelationshipView,
86
+ val: Point[],
87
+ ): void => {
88
+ relationshipView.path = val;
89
+ };
90
+
91
+ /**
92
+ * Simplify the path.
93
+ *
94
+ * Flatten the path if the angle is wide enough between 3 consecutive points
95
+ * Also remove unnecessary inside points
96
+ */
97
+ export const _relationshipView_simplifyPath = (
98
+ relationshipView: RelationshipView,
99
+ ): void => {
100
+ const fullPath = relationshipView.buildFullPath();
101
+ // NOTE: this method here will `swallow` up points inside of the boxes
102
+ const newPath = RelationshipView.pruneUnnecessaryInsidePoints(
103
+ fullPath,
104
+ relationshipView.from.classView.value,
105
+ relationshipView.to.classView.value,
106
+ );
107
+
108
+ // recompute the offset point from center inside of `from` and `to` classviews.
109
+ // for each, we first check if `manageInsidePointsDynamically` removes any points from the full path
110
+ // if it does we will update the offset
111
+ if (newPath[0] !== fullPath[0]) {
112
+ const center = relationshipView.from.classView.value.center();
113
+ relationshipView.from.offsetX = (newPath[0] as Point).x - center.x;
114
+ relationshipView.from.offsetY = (newPath[0] as Point).y - center.y;
115
+ }
116
+
117
+ if (newPath[newPath.length - 1] !== fullPath[fullPath.length - 1]) {
118
+ const center = relationshipView.to.classView.value.center();
119
+ relationshipView.to.offsetX =
120
+ (newPath[newPath.length - 1] as Point).x - center.x;
121
+ relationshipView.to.offsetY =
122
+ (newPath[newPath.length - 1] as Point).y - center.y;
123
+ }
124
+
125
+ // find the point which can be flattened due to its wide angle
126
+ const result = [];
127
+ for (let i = 0; i < newPath.length - 2; i++) {
128
+ const v1 = Vector.fromPoints(
129
+ newPath[i + 1] as Point,
130
+ newPath[i] as Point,
131
+ ).unit();
132
+ const v2 = Vector.fromPoints(
133
+ newPath[i + 1] as Point,
134
+ newPath[i + 2] as Point,
135
+ ).unit();
136
+ const dot = v1.dotProduct(v2);
137
+ const angle = (Math.acos(dot) * 180) / Math.PI;
138
+ if (Math.abs(angle - 180) > 5) {
139
+ result.push(newPath[i + 1] as Point);
140
+ }
141
+ }
142
+
143
+ // NOTE: this new path does not contain the 2 end points
144
+ _relationshipView_setPath(relationshipView, result);
145
+ };
146
+
147
+ /**
148
+ * Based on the location, find the point on the path that matches or create new point
149
+ * (within a threshold of proximity) from the coordinate and put this in the path array
150
+ * so it doesn't look too weird
151
+ */
152
+ export const _findOrBuildPoint = (
153
+ relationshipView: RelationshipView,
154
+ x: number,
155
+ y: number,
156
+ zoom: number,
157
+ allowChange: boolean,
158
+ ): Point | undefined => {
159
+ for (const pt of relationshipView.path) {
160
+ if (
161
+ Math.sqrt((x - pt.x) * (x - pt.x) + (y - pt.y) * (y - pt.y)) <
162
+ 10 / zoom
163
+ ) {
164
+ return pt;
165
+ }
166
+ }
167
+
168
+ const fullPath = relationshipView.buildFullPath(allowChange);
169
+ const newPath = [];
170
+ let point;
171
+
172
+ for (let i = 0; i < fullPath.length - 1; i++) {
173
+ const a = fullPath[i] as Point;
174
+ const b = fullPath[i + 1] as Point;
175
+ const u = new Vector(a.x, a.y).normal(new Vector(b.x, b.y)).unit();
176
+ const v = Vector.fromPoints(a, new Point(x, y));
177
+
178
+ // if the selection point is not too far from the segment
179
+ // of the path, create a new point and make it part of the path
180
+ if (Math.abs(u.dotProduct(v)) < 5 / zoom) {
181
+ const lx = (a.x < b.x ? a.x : b.x) - 5 / zoom;
182
+ const hx = (a.x < b.x ? b.x : a.x) + 5 / zoom;
183
+ const ly = (a.y < b.y ? a.y : b.y) - 5 / zoom;
184
+ const hy = (a.y < b.y ? b.y : a.y) + 5 / zoom;
185
+
186
+ if (lx <= x && x <= hx && ly <= y && y <= hy) {
187
+ point = new Point(x, y);
188
+ newPath.push(point);
189
+ }
190
+ }
191
+
192
+ if (i < fullPath.length - 2) {
193
+ newPath.push(fullPath[i + 1] as Point);
194
+ }
195
+ }
196
+ if (point && allowChange) {
197
+ // NOTE: this new path does not contain the 2 end points
198
+ _relationshipView_setPath(relationshipView, newPath);
199
+ }
200
+ return point;
201
+ };
package/src/index.ts CHANGED
@@ -25,7 +25,6 @@ export { DiagramRenderer, DIAGRAM_INTERACTION_MODE } from './DiagramRenderer';
25
25
  export { Diagram } from './models/metamodels/pure/packageableElements/diagram/DSLDiagram_Diagram';
26
26
  export { ClassView } from './models/metamodels/pure/packageableElements/diagram/DSLDiagram_ClassView';
27
27
  export { RelationshipView } from './models/metamodels/pure/packageableElements/diagram/DSLDiagram_RelationshipView';
28
- export { _relationView_manageInsidePointsDynamically } from './models/metamodels/pure/packageableElements/diagram/DSLDiagram_GraphModifierHelper';
29
28
  export { PropertyHolderView } from './models/metamodels/pure/packageableElements/diagram/DSLDiagram_PropertyHolderView';
30
29
  export { PropertyView } from './models/metamodels/pure/packageableElements/diagram/DSLDiagram_PropertyView';
31
30
  export { AssociationView } from './models/metamodels/pure/packageableElements/diagram/DSLDiagram_AssociationView';
@@ -14,7 +14,6 @@
14
14
  * limitations under the License.
15
15
  */
16
16
 
17
- import { computed, makeObservable } from 'mobx';
18
17
  import { hashArray, type Hashable } from '@finos/legend-shared';
19
18
  import { PropertyHolderView } from './DSLDiagram_PropertyHolderView';
20
19
  import type { ClassView } from './DSLDiagram_ClassView';
@@ -37,11 +36,6 @@ export class AssociationView extends PropertyHolderView implements Hashable {
37
36
  to: ClassView,
38
37
  ) {
39
38
  super(owner, property, from, to);
40
-
41
- makeObservable(this, {
42
- hashCode: computed,
43
- });
44
-
45
39
  this.association = association;
46
40
  }
47
41
 
@@ -14,7 +14,6 @@
14
14
  * limitations under the License.
15
15
  */
16
16
 
17
- import { computed, observable, makeObservable } from 'mobx';
18
17
  import { hashArray, type Hashable } from '@finos/legend-shared';
19
18
  import { PositionedRectangle } from './geometry/DSLDiagram_PositionedRectangle';
20
19
  import { Rectangle } from './geometry/DSLDiagram_Rectangle';
@@ -37,15 +36,6 @@ export class ClassView extends PositionedRectangle implements Hashable {
37
36
  _class: PackageableElementReference<Class>,
38
37
  ) {
39
38
  super(new Point(0, 0), new Rectangle(0, 0));
40
-
41
- makeObservable(this, {
42
- id: observable,
43
- hideProperties: observable,
44
- hideTaggedValues: observable,
45
- hideStereotypes: observable,
46
- hashCode: computed,
47
- });
48
-
49
39
  this.owner = owner;
50
40
  this.id = id;
51
41
  this.class = _class;
@@ -14,7 +14,6 @@
14
14
  * limitations under the License.
15
15
  */
16
16
 
17
- import { observable, makeObservable } from 'mobx';
18
17
  import type { Diagram } from './DSLDiagram_Diagram';
19
18
  import type { ClassView } from './DSLDiagram_ClassView';
20
19
  import {
@@ -33,11 +32,6 @@ export abstract class ClassViewReference extends ReferenceWithOwner {
33
32
  value: ClassView,
34
33
  ) {
35
34
  super(ownerReference);
36
-
37
- makeObservable(this, {
38
- value: observable,
39
- });
40
-
41
35
  this.ownerReference = ownerReference;
42
36
  this.value = value;
43
37
  }
@@ -14,7 +14,6 @@
14
14
  * limitations under the License.
15
15
  */
16
16
 
17
- import { observable, makeObservable, override } from 'mobx';
18
17
  import { hashArray, type Hashable } from '@finos/legend-shared';
19
18
  import type { ClassView } from './DSLDiagram_ClassView';
20
19
  import type { PropertyView } from './DSLDiagram_PropertyView';
@@ -32,18 +31,6 @@ export class Diagram extends PackageableElement implements Hashable {
32
31
  generalizationViews: GeneralizationView[] = [];
33
32
  propertyViews: PropertyView[] = [];
34
33
 
35
- constructor(name: string) {
36
- super(name);
37
-
38
- makeObservable<Diagram, '_elementHashCode'>(this, {
39
- classViews: observable,
40
- associationViews: observable,
41
- generalizationViews: observable,
42
- propertyViews: observable,
43
- _elementHashCode: override,
44
- });
45
- }
46
-
47
34
  protected override get _elementHashCode(): string {
48
35
  return hashArray([
49
36
  DIAGRAM_HASH_STRUCTURE.DIAGRAM,
@@ -14,22 +14,11 @@
14
14
  * limitations under the License.
15
15
  */
16
16
 
17
- import { computed, makeObservable } from 'mobx';
18
17
  import { hashArray, type Hashable } from '@finos/legend-shared';
19
18
  import { RelationshipView } from './DSLDiagram_RelationshipView';
20
- import type { Diagram } from './DSLDiagram_Diagram';
21
- import type { ClassView } from './DSLDiagram_ClassView';
22
19
  import { DIAGRAM_HASH_STRUCTURE } from '../../../../DSLDiagram_ModelUtils';
23
20
 
24
21
  export class GeneralizationView extends RelationshipView implements Hashable {
25
- constructor(owner: Diagram, from: ClassView, to: ClassView) {
26
- super(owner, from, to);
27
-
28
- makeObservable(this, {
29
- hashCode: computed,
30
- });
31
- }
32
-
33
22
  override get hashCode(): string {
34
23
  return hashArray([
35
24
  DIAGRAM_HASH_STRUCTURE.GENERALIZATION_VIEW,
@@ -14,28 +14,11 @@
14
14
  * limitations under the License.
15
15
  */
16
16
 
17
- import { computed, makeObservable } from 'mobx';
18
17
  import { hashArray, type Hashable } from '@finos/legend-shared';
19
18
  import { PropertyHolderView } from './DSLDiagram_PropertyHolderView';
20
- import type { Diagram } from './DSLDiagram_Diagram';
21
- import type { ClassView } from './DSLDiagram_ClassView';
22
- import type { PropertyReference } from '@finos/legend-graph';
23
19
  import { DIAGRAM_HASH_STRUCTURE } from '../../../../DSLDiagram_ModelUtils';
24
20
 
25
21
  export class PropertyView extends PropertyHolderView implements Hashable {
26
- constructor(
27
- owner: Diagram,
28
- property: PropertyReference,
29
- from: ClassView,
30
- to: ClassView,
31
- ) {
32
- super(owner, property, from, to);
33
-
34
- makeObservable(this, {
35
- hashCode: computed,
36
- });
37
- }
38
-
39
22
  override get hashCode(): string {
40
23
  return hashArray([DIAGRAM_HASH_STRUCTURE.PROPERTY_VIEW, super.hashCode]);
41
24
  }
@@ -14,20 +14,19 @@
14
14
  * limitations under the License.
15
15
  */
16
16
 
17
- import { observable, makeObservable } from 'mobx';
18
17
  import type { ClassViewReference } from './DSLDiagram_ClassViewReference';
19
18
 
20
- export class RelationShipEdgeView {
19
+ export class RelationshipEdgeView {
21
20
  classView: ClassViewReference;
21
+ /**
22
+ * Offsets from the center of the class view.
23
+ *
24
+ * These offsets can be used to compute the end points of relationship views.
25
+ */
22
26
  offsetX?: number | undefined;
23
27
  offsetY?: number | undefined;
24
28
 
25
29
  constructor(classView: ClassViewReference) {
26
- makeObservable(this, {
27
- offsetX: observable,
28
- offsetY: observable,
29
- });
30
-
31
30
  this.classView = classView;
32
31
  }
33
32
  }
@@ -14,30 +14,31 @@
14
14
  * limitations under the License.
15
15
  */
16
16
 
17
- import { observable, computed, makeObservable } from 'mobx';
18
17
  import { hashArray, type Hashable } from '@finos/legend-shared';
19
- import { RelationShipEdgeView as RelationshipEdgeView } from './DSLDiagram_RelationshipEdgeView';
18
+ import { RelationshipEdgeView } from './DSLDiagram_RelationshipEdgeView';
20
19
  import { Point } from './geometry/DSLDiagram_Point';
21
20
  import type { ClassView } from './DSLDiagram_ClassView';
22
21
  import type { Diagram } from './DSLDiagram_Diagram';
23
22
  import { ClassViewExplicitReference } from './DSLDiagram_ClassViewReference';
24
23
  import { DIAGRAM_HASH_STRUCTURE } from '../../../../DSLDiagram_ModelUtils';
25
- import { _relationView_manageInsidePointsDynamically } from './DSLDiagram_GraphModifierHelper';
26
24
 
27
25
  export class RelationshipView implements Hashable {
28
26
  owner: Diagram;
29
27
  from: RelationshipEdgeView;
30
28
  to: RelationshipEdgeView;
31
- // NOTE: to optimize performance for diagram, we have made classview's position and rectangle non-observable
32
- // if we want to further optimize, perhaps we can also remove observability from path
29
+ /**
30
+ * NOTE: Unlike in the protocol model, we don't store the end points in the path but only store the
31
+ * offsets of that point from the center of the end/start classviews. The main purpose here is to
32
+ * make less error. We don't need to bother maintaining these points in the path. They are
33
+ * auto-managed. Even if an erroneous path is set (e.g. an empty list of points), this logic
34
+ * that we have will rectify that and create a sensible path.
35
+ *
36
+ * In exchange, this logic is a little complicated, we have tried to document as much about it as we could
37
+ * but the logic is not straight forward. Perhaps, we could simplify this in the future.
38
+ */
33
39
  path: Point[] = [];
34
40
 
35
41
  constructor(owner: Diagram, from: ClassView, to: ClassView) {
36
- makeObservable(this, {
37
- path: observable,
38
- fullPath: computed,
39
- });
40
-
41
42
  this.owner = owner;
42
43
  this.from = new RelationshipEdgeView(
43
44
  ClassViewExplicitReference.create(from),
@@ -45,29 +46,6 @@ export class RelationshipView implements Hashable {
45
46
  this.to = new RelationshipEdgeView(ClassViewExplicitReference.create(to));
46
47
  }
47
48
 
48
- /**
49
- * Compute the full path for an edge, but notice here that the end points are recomputed every time, as such
50
- * `path` only stores point that matters to the edge but are not end points
51
- */
52
- buildFullPath(allowChange = true): Point[] {
53
- return [
54
- this.computeEdgeEndpoint(this.from, allowChange),
55
- ...this.path,
56
- this.computeEdgeEndpoint(this.to, allowChange),
57
- ];
58
- }
59
-
60
- /**
61
- * This method will compute the full path from the offset within class view for persistence purpose
62
- */
63
- get fullPath(): Point[] {
64
- return _relationView_manageInsidePointsDynamically(
65
- this.buildFullPath(),
66
- this.from.classView.value,
67
- this.to.classView.value,
68
- );
69
- }
70
-
71
49
  /**
72
50
  * Calculate the end points of the edge using offset, otherwise, use the center
73
51
  */
@@ -89,12 +67,77 @@ export class RelationshipView implements Hashable {
89
67
  return new Point(center.x, center.y);
90
68
  }
91
69
 
70
+ /**
71
+ * Compute the full path for the relationship view (including the ends even if these
72
+ * ends lie inside of the classviews)
73
+ *
74
+ * Notice here that the end points are recomputed every time, as such
75
+ * `path` only stores point that matters to the edge but are not end points
76
+ */
77
+ buildFullPath(allowChange = true): Point[] {
78
+ return [
79
+ this.computeEdgeEndpoint(this.from, allowChange),
80
+ ...this.path,
81
+ this.computeEdgeEndpoint(this.to, allowChange),
82
+ ];
83
+ }
84
+
85
+ /**
86
+ * For a path, only keep **at most** 1 point at each end that lies inside the class view.
87
+ * If there is no inside points, none of kept, so the path only contains outside points.
88
+ */
89
+ static pruneUnnecessaryInsidePoints = (
90
+ path: Point[],
91
+ from: ClassView,
92
+ to: ClassView,
93
+ ): Point[] => {
94
+ if (!path.length) {
95
+ return [];
96
+ }
97
+
98
+ let start = 0;
99
+ let startPoint = path[start] as Point;
100
+
101
+ while (
102
+ start < path.length - 1 &&
103
+ from.contains(startPoint.x, startPoint.y)
104
+ ) {
105
+ start++;
106
+ startPoint = path[start] as Point;
107
+ }
108
+
109
+ // NOTE: due to the usage path, we could make sure `end > start`, but maybe this
110
+ // is an improvement to be done
111
+
112
+ let end = path.length - 1;
113
+ let endPoint = path[end] as Point;
114
+
115
+ while (end > 0 && to.contains(endPoint.x, endPoint.y)) {
116
+ end--;
117
+ endPoint = path[end] as Point;
118
+ }
119
+
120
+ // NOTE: slice upper bound is exclusive, hence the +2 instead of +1
121
+ return path.slice(start - 1, end + 2);
122
+ };
123
+
124
+ /**
125
+ * This method will compute the full path from the offset within class view for serialization and persistence purpose
126
+ */
127
+ get pathForSerialization(): Point[] {
128
+ return RelationshipView.pruneUnnecessaryInsidePoints(
129
+ this.buildFullPath(),
130
+ this.from.classView.value,
131
+ this.to.classView.value,
132
+ );
133
+ }
134
+
92
135
  get hashCode(): string {
93
136
  return hashArray([
94
137
  DIAGRAM_HASH_STRUCTURE.RELATIONSHIP_VIEW,
95
138
  this.from.classView.value.id,
96
139
  this.to.classView.value.id,
97
- hashArray(this.fullPath),
140
+ hashArray(this.pathForSerialization),
98
141
  ]);
99
142
  }
100
143
  }
@@ -14,7 +14,6 @@
14
14
  * limitations under the License.
15
15
  */
16
16
 
17
- import { observable, makeObservable } from 'mobx';
18
17
  import { hashArray, type Hashable } from '@finos/legend-shared';
19
18
  import { Point } from './DSLDiagram_Point';
20
19
  import { Rectangle } from './DSLDiagram_Rectangle';
@@ -26,10 +25,6 @@ export class PositionedRectangle implements Hashable {
26
25
  dummyObservable = {};
27
26
 
28
27
  constructor(position: Point, rectangle: Rectangle) {
29
- makeObservable(this, {
30
- dummyObservable: observable,
31
- });
32
-
33
28
  this.position = position;
34
29
  this.rectangle = rectangle;
35
30
  }