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

Sign up to get free protection for your applications and to get access to all the features.
Files changed (73) hide show
  1. package/lib/DiagramRenderer.d.ts +1 -1
  2. package/lib/DiagramRenderer.d.ts.map +1 -1
  3. package/lib/DiagramRenderer.js +56 -54
  4. package/lib/DiagramRenderer.js.map +1 -1
  5. package/lib/components/studio/ClassDiagramPreview.d.ts +1 -0
  6. package/lib/components/studio/ClassDiagramPreview.d.ts.map +1 -1
  7. package/lib/components/studio/DiagramEditor.d.ts +1 -0
  8. package/lib/components/studio/DiagramEditor.d.ts.map +1 -1
  9. package/lib/components/studio/DiagramEditor.js +10 -9
  10. package/lib/components/studio/DiagramEditor.js.map +1 -1
  11. package/lib/helpers/DiagramHelper.d.ts.map +1 -1
  12. package/lib/helpers/DiagramHelper.js +4 -3
  13. package/lib/helpers/DiagramHelper.js.map +1 -1
  14. package/lib/index.css +1 -1
  15. package/lib/index.d.ts +2 -1
  16. package/lib/index.d.ts.map +1 -1
  17. package/lib/index.js +2 -1
  18. package/lib/index.js.map +1 -1
  19. package/lib/models/metamodels/pure/packageableElements/diagram/DSLDiagram_ClassView.d.ts +0 -3
  20. package/lib/models/metamodels/pure/packageableElements/diagram/DSLDiagram_ClassView.d.ts.map +1 -1
  21. package/lib/models/metamodels/pure/packageableElements/diagram/DSLDiagram_ClassView.js +1 -13
  22. package/lib/models/metamodels/pure/packageableElements/diagram/DSLDiagram_ClassView.js.map +1 -1
  23. package/lib/models/metamodels/pure/packageableElements/diagram/DSLDiagram_ClassViewReference.d.ts +0 -1
  24. package/lib/models/metamodels/pure/packageableElements/diagram/DSLDiagram_ClassViewReference.d.ts.map +1 -1
  25. package/lib/models/metamodels/pure/packageableElements/diagram/DSLDiagram_ClassViewReference.js +2 -7
  26. package/lib/models/metamodels/pure/packageableElements/diagram/DSLDiagram_ClassViewReference.js.map +1 -1
  27. package/lib/models/metamodels/pure/packageableElements/diagram/DSLDiagram_Diagram.d.ts +0 -11
  28. package/lib/models/metamodels/pure/packageableElements/diagram/DSLDiagram_Diagram.d.ts.map +1 -1
  29. package/lib/models/metamodels/pure/packageableElements/diagram/DSLDiagram_Diagram.js +2 -46
  30. package/lib/models/metamodels/pure/packageableElements/diagram/DSLDiagram_Diagram.js.map +1 -1
  31. package/lib/models/metamodels/pure/packageableElements/diagram/DSLDiagram_GraphModifierHelper.d.ts +35 -0
  32. package/lib/models/metamodels/pure/packageableElements/diagram/DSLDiagram_GraphModifierHelper.d.ts.map +1 -0
  33. package/lib/models/metamodels/pure/packageableElements/diagram/DSLDiagram_GraphModifierHelper.js +118 -0
  34. package/lib/models/metamodels/pure/packageableElements/diagram/DSLDiagram_GraphModifierHelper.js.map +1 -0
  35. package/lib/models/metamodels/pure/packageableElements/diagram/DSLDiagram_RelationshipEdgeView.d.ts +0 -2
  36. package/lib/models/metamodels/pure/packageableElements/diagram/DSLDiagram_RelationshipEdgeView.d.ts.map +1 -1
  37. package/lib/models/metamodels/pure/packageableElements/diagram/DSLDiagram_RelationshipEdgeView.js +1 -9
  38. package/lib/models/metamodels/pure/packageableElements/diagram/DSLDiagram_RelationshipEdgeView.js.map +1 -1
  39. package/lib/models/metamodels/pure/packageableElements/diagram/DSLDiagram_RelationshipView.d.ts +0 -17
  40. package/lib/models/metamodels/pure/packageableElements/diagram/DSLDiagram_RelationshipView.d.ts.map +1 -1
  41. package/lib/models/metamodels/pure/packageableElements/diagram/DSLDiagram_RelationshipView.js +6 -109
  42. package/lib/models/metamodels/pure/packageableElements/diagram/DSLDiagram_RelationshipView.js.map +1 -1
  43. package/lib/models/metamodels/pure/packageableElements/diagram/geometry/DSLDiagram_PositionedRectangle.d.ts +0 -8
  44. package/lib/models/metamodels/pure/packageableElements/diagram/geometry/DSLDiagram_PositionedRectangle.d.ts.map +1 -1
  45. package/lib/models/metamodels/pure/packageableElements/diagram/geometry/DSLDiagram_PositionedRectangle.js +1 -16
  46. package/lib/models/metamodels/pure/packageableElements/diagram/geometry/DSLDiagram_PositionedRectangle.js.map +1 -1
  47. package/lib/models/protocols/pure/v1/transformation/pureGraph/V1_DSLDiagram_GraphBuilderHelper.d.ts.map +1 -1
  48. package/lib/models/protocols/pure/v1/transformation/pureGraph/V1_DSLDiagram_GraphBuilderHelper.js +3 -2
  49. package/lib/models/protocols/pure/v1/transformation/pureGraph/V1_DSLDiagram_GraphBuilderHelper.js.map +1 -1
  50. package/lib/package.json +4 -4
  51. package/lib/stores/studio/DSLDiagram_ModifierHelper.d.ts +54 -0
  52. package/lib/stores/studio/DSLDiagram_ModifierHelper.d.ts.map +1 -0
  53. package/lib/stores/studio/DSLDiagram_ModifierHelper.js +87 -0
  54. package/lib/stores/studio/DSLDiagram_ModifierHelper.js.map +1 -0
  55. package/lib/stores/studio/DiagramEditorState.d.ts.map +1 -1
  56. package/lib/stores/studio/DiagramEditorState.js +3 -3
  57. package/lib/stores/studio/DiagramEditorState.js.map +1 -1
  58. package/package.json +10 -10
  59. package/src/DiagramRenderer.ts +125 -58
  60. package/src/components/studio/DiagramEditor.tsx +16 -11
  61. package/src/helpers/DiagramHelper.ts +4 -3
  62. package/src/index.ts +2 -4
  63. package/src/models/metamodels/pure/packageableElements/diagram/DSLDiagram_ClassView.ts +1 -14
  64. package/src/models/metamodels/pure/packageableElements/diagram/DSLDiagram_ClassViewReference.ts +1 -8
  65. package/src/models/metamodels/pure/packageableElements/diagram/DSLDiagram_Diagram.ts +2 -52
  66. package/src/models/metamodels/pure/packageableElements/diagram/DSLDiagram_GraphModifierHelper.ts +165 -0
  67. package/src/models/metamodels/pure/packageableElements/diagram/DSLDiagram_RelationshipEdgeView.ts +1 -10
  68. package/src/models/metamodels/pure/packageableElements/diagram/DSLDiagram_RelationshipView.ts +6 -147
  69. package/src/models/metamodels/pure/packageableElements/diagram/geometry/DSLDiagram_PositionedRectangle.ts +1 -17
  70. package/src/models/protocols/pure/v1/transformation/pureGraph/V1_DSLDiagram_GraphBuilderHelper.ts +3 -2
  71. package/src/stores/studio/DSLDiagram_ModifierHelper.ts +148 -0
  72. package/src/stores/studio/DiagramEditorState.ts +2 -2
  73. package/tsconfig.json +2 -0
@@ -84,10 +84,6 @@ import {
84
84
  isValidFullPath,
85
85
  isValidPathIdentifier,
86
86
  resolvePackagePathAndElementName,
87
- setPropertyName,
88
- setPropertyGenericType,
89
- setPropertyMultiplicity,
90
- addPackageElement,
91
87
  } from '@finos/legend-graph';
92
88
  import {
93
89
  guaranteeNonNullable,
@@ -104,10 +100,19 @@ import {
104
100
  CORE_DND_TYPE,
105
101
  ElementDragSource,
106
102
  useEditorStore,
103
+ property_setName,
104
+ property_setGenericType,
105
+ property_setMultiplicity,
106
+ package_addElement,
107
107
  } from '@finos/legend-studio';
108
108
  import { cleanUpDeadReferencesInDiagram } from '../../helpers/DiagramHelper';
109
109
  import { Point } from '../../models/metamodels/pure/packageableElements/diagram/geometry/DSLDiagram_Point';
110
110
  import type { DSLDiagram_LegendStudioPlugin_Extension } from './DSLDiagram_LegendStudioPlugin_Extension';
111
+ import {
112
+ classView_setHideProperties,
113
+ classView_setHideStereotypes,
114
+ classView_setHideTaggedValues,
115
+ } from '../../stores/studio/DSLDiagram_ModifierHelper';
111
116
 
112
117
  const DiagramEditorContextMenu = observer(
113
118
  forwardRef<
@@ -519,21 +524,21 @@ const DiagramEditorClassViewEditor = observer(
519
524
  if (isReadOnly) {
520
525
  return;
521
526
  }
522
- classView.setHideProperties(!classView.hideProperties);
527
+ classView_setHideProperties(classView, !classView.hideProperties);
523
528
  diagramEditorState.renderer.render();
524
529
  };
525
530
  const toggleHideTaggedValues = (): void => {
526
531
  if (isReadOnly) {
527
532
  return;
528
533
  }
529
- classView.setHideTaggedValues(!classView.hideTaggedValues);
534
+ classView_setHideTaggedValues(classView, !classView.hideTaggedValues);
530
535
  diagramEditorState.renderer.render();
531
536
  };
532
537
  const toggleHideStereotypes = (): void => {
533
538
  if (isReadOnly) {
534
539
  return;
535
540
  }
536
- classView.setHideStereotypes(!classView.hideStereotypes);
541
+ classView_setHideStereotypes(classView, !classView.hideStereotypes);
537
542
  diagramEditorState.renderer.render();
538
543
  };
539
544
 
@@ -857,7 +862,7 @@ const DiagramEditorInlineClassCreatorInner = observer(
857
862
  diagramEditorState.setInlineClassCreatorState(undefined);
858
863
  const [packagePath, name] = resolvePackagePathAndElementName(path);
859
864
  const _class = new Class(name);
860
- addPackageElement(
865
+ package_addElement(
861
866
  editorStore.graphManagerState.graph.getOrCreatePackage(packagePath),
862
867
  _class,
863
868
  );
@@ -1032,14 +1037,14 @@ const DiagramEditorInlinePropertyEditorInner = observer(
1032
1037
  event,
1033
1038
  ) => {
1034
1039
  if (property instanceof DerivedProperty || property instanceof Property) {
1035
- setPropertyName(property, event.target.value);
1040
+ property_setName(property, event.target.value);
1036
1041
  diagramEditorState.renderer.render();
1037
1042
  }
1038
1043
  };
1039
1044
 
1040
1045
  const changeMultiplicity = (val: Multiplicity): void => {
1041
1046
  if (property instanceof DerivedProperty || property instanceof Property) {
1042
- setPropertyMultiplicity(property, val);
1047
+ property_setMultiplicity(property, val);
1043
1048
  diagramEditorState.renderer.render();
1044
1049
  }
1045
1050
  };
@@ -1059,7 +1064,7 @@ const DiagramEditorInlinePropertyEditorInner = observer(
1059
1064
  };
1060
1065
  const changePropertyType = (val: PackageableElementOption<Type>): void => {
1061
1066
  if (property instanceof Property || property instanceof DerivedProperty) {
1062
- setPropertyGenericType(property, new GenericType(val.value));
1067
+ property_setGenericType(property, new GenericType(val.value));
1063
1068
  }
1064
1069
  };
1065
1070
 
@@ -15,6 +15,7 @@
15
15
  */
16
16
 
17
17
  import type { PureModel } from '@finos/legend-graph';
18
+ import { deleteEntry } from '@finos/legend-shared';
18
19
  import type { ClassView } from '../models/metamodels/pure/packageableElements/diagram/DSLDiagram_ClassView';
19
20
  import type { Diagram } from '../models/metamodels/pure/packageableElements/diagram/DSLDiagram_Diagram';
20
21
  import { Point } from '../models/metamodels/pure/packageableElements/diagram/geometry/DSLDiagram_Point';
@@ -51,14 +52,14 @@ export const cleanUpDeadReferencesInDiagram = (
51
52
  .includes(propertyView.property.value.name),
52
53
  );
53
54
  propertyViewsToRemove.forEach((propertyView) =>
54
- diagram.deletePropertyView(propertyView),
55
+ deleteEntry(diagram.propertyViews, propertyView),
55
56
  );
56
57
 
57
58
  // Fix orphan class views
58
59
  const classViewsToRemove = diagram.classViews.filter(
59
60
  (cv) => !graph.getNullableClass(cv.class.value.path),
60
61
  );
61
- classViewsToRemove.forEach((cw) => diagram.deleteClassView(cw));
62
+ classViewsToRemove.forEach((cw) => deleteEntry(diagram.classViews, cw));
62
63
 
63
64
  // Fix orphan gneralization views
64
65
  const generalizationViewsToRemove = diagram.generalizationViews.filter(
@@ -74,6 +75,6 @@ export const cleanUpDeadReferencesInDiagram = (
74
75
  },
75
76
  );
76
77
  generalizationViewsToRemove.forEach((g) =>
77
- diagram.deleteGeneralizationView(g),
78
+ deleteEntry(diagram.generalizationViews, g),
78
79
  );
79
80
  };
package/src/index.ts CHANGED
@@ -24,10 +24,8 @@ export { DiagramRenderer, DIAGRAM_INTERACTION_MODE } from './DiagramRenderer';
24
24
 
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
- export {
28
- RelationshipView,
29
- manageInsidePointsDynamically,
30
- } from './models/metamodels/pure/packageableElements/diagram/DSLDiagram_RelationshipView';
27
+ export { RelationshipView } from './models/metamodels/pure/packageableElements/diagram/DSLDiagram_RelationshipView';
28
+ export { _relationView_manageInsidePointsDynamically } from './models/metamodels/pure/packageableElements/diagram/DSLDiagram_GraphModifierHelper';
31
29
  export { PropertyHolderView } from './models/metamodels/pure/packageableElements/diagram/DSLDiagram_PropertyHolderView';
32
30
  export { PropertyView } from './models/metamodels/pure/packageableElements/diagram/DSLDiagram_PropertyView';
33
31
  export { AssociationView } from './models/metamodels/pure/packageableElements/diagram/DSLDiagram_AssociationView';
@@ -14,7 +14,7 @@
14
14
  * limitations under the License.
15
15
  */
16
16
 
17
- import { computed, observable, action, makeObservable } from 'mobx';
17
+ import { computed, observable, makeObservable } from 'mobx';
18
18
  import { hashArray, type Hashable } from '@finos/legend-shared';
19
19
  import { PositionedRectangle } from './geometry/DSLDiagram_PositionedRectangle';
20
20
  import { Rectangle } from './geometry/DSLDiagram_Rectangle';
@@ -43,9 +43,6 @@ export class ClassView extends PositionedRectangle implements Hashable {
43
43
  hideProperties: observable,
44
44
  hideTaggedValues: observable,
45
45
  hideStereotypes: observable,
46
- setHideProperties: action,
47
- setHideStereotypes: action,
48
- setHideTaggedValues: action,
49
46
  hashCode: computed,
50
47
  });
51
48
 
@@ -54,16 +51,6 @@ export class ClassView extends PositionedRectangle implements Hashable {
54
51
  this.class = _class;
55
52
  }
56
53
 
57
- setHideProperties(val: boolean): void {
58
- this.hideProperties = val;
59
- }
60
- setHideStereotypes(val: boolean): void {
61
- this.hideStereotypes = val;
62
- }
63
- setHideTaggedValues(val: boolean): void {
64
- this.hideTaggedValues = val;
65
- }
66
-
67
54
  override get hashCode(): string {
68
55
  return hashArray([
69
56
  DIAGRAM_HASH_STRUCTURE.CLASS_VIEW,
@@ -14,13 +14,12 @@
14
14
  * limitations under the License.
15
15
  */
16
16
 
17
- import { observable, action, makeObservable } from 'mobx';
17
+ import { observable, makeObservable } from 'mobx';
18
18
  import type { Diagram } from './DSLDiagram_Diagram';
19
19
  import type { ClassView } from './DSLDiagram_ClassView';
20
20
  import {
21
21
  PackageableElementExplicitReference,
22
22
  ReferenceWithOwner,
23
- setPackageableElementReferenceValue,
24
23
  type PackageableElementImplicitReference,
25
24
  type PackageableElementReference,
26
25
  } from '@finos/legend-graph';
@@ -37,17 +36,11 @@ export abstract class ClassViewReference extends ReferenceWithOwner {
37
36
 
38
37
  makeObservable(this, {
39
38
  value: observable,
40
- setValue: action,
41
39
  });
42
40
 
43
41
  this.ownerReference = ownerReference;
44
42
  this.value = value;
45
43
  }
46
-
47
- setValue(value: ClassView): void {
48
- this.value = value;
49
- setPackageableElementReferenceValue(this.ownerReference, value.owner);
50
- }
51
44
  }
52
45
 
53
46
  export class ClassViewExplicitReference extends ClassViewReference {
@@ -14,13 +14,8 @@
14
14
  * limitations under the License.
15
15
  */
16
16
 
17
- import { observable, action, makeObservable, override } from 'mobx';
18
- import {
19
- hashArray,
20
- addUniqueEntry,
21
- deleteEntry,
22
- type Hashable,
23
- } from '@finos/legend-shared';
17
+ import { observable, makeObservable, override } from 'mobx';
18
+ import { hashArray, type Hashable } from '@finos/legend-shared';
24
19
  import type { ClassView } from './DSLDiagram_ClassView';
25
20
  import type { PropertyView } from './DSLDiagram_PropertyView';
26
21
  import type { GeneralizationView } from './DSLDiagram_GeneralizationView';
@@ -45,55 +40,10 @@ export class Diagram extends PackageableElement implements Hashable {
45
40
  associationViews: observable,
46
41
  generalizationViews: observable,
47
42
  propertyViews: observable,
48
- setClassViews: action,
49
- addClassView: action,
50
- deleteClassView: action,
51
- setAssociationViews: action,
52
- deleteAssociationView: action,
53
- setGeneralizationViews: action,
54
- addGeneralizationView: action,
55
- deleteGeneralizationView: action,
56
- setPropertyViews: action,
57
- addPropertyView: action,
58
- deletePropertyView: action,
59
43
  _elementHashCode: override,
60
44
  });
61
45
  }
62
46
 
63
- setClassViews(val: ClassView[]): void {
64
- this.classViews = val;
65
- }
66
- addClassView(val: ClassView): void {
67
- addUniqueEntry(this.classViews, val);
68
- }
69
- deleteClassView(val: ClassView): void {
70
- deleteEntry(this.classViews, val);
71
- }
72
- setAssociationViews(val: AssociationView[]): void {
73
- this.associationViews = val;
74
- }
75
- deleteAssociationView(val: AssociationView): void {
76
- deleteEntry(this.associationViews, val);
77
- }
78
- setGeneralizationViews(val: GeneralizationView[]): void {
79
- this.generalizationViews = val;
80
- }
81
- addGeneralizationView(val: GeneralizationView): void {
82
- addUniqueEntry(this.generalizationViews, val);
83
- }
84
- deleteGeneralizationView(val: GeneralizationView): void {
85
- deleteEntry(this.generalizationViews, val);
86
- }
87
- setPropertyViews(val: PropertyView[]): void {
88
- this.propertyViews = val;
89
- }
90
- addPropertyView(val: PropertyView): void {
91
- addUniqueEntry(this.propertyViews, val);
92
- }
93
- deletePropertyView(val: PropertyView): void {
94
- deleteEntry(this.propertyViews, val);
95
- }
96
-
97
47
  protected override get _elementHashCode(): string {
98
48
  return hashArray([
99
49
  DIAGRAM_HASH_STRUCTURE.DIAGRAM,
@@ -0,0 +1,165 @@
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 type { ClassView } from './DSLDiagram_ClassView';
18
+ import type { RelationshipView } from './DSLDiagram_RelationshipView';
19
+ import { Point } from './geometry/DSLDiagram_Point';
20
+ import { Vector } from './geometry/DSLDiagram_Vector';
21
+
22
+ export const _relationView_setPath = (
23
+ relationView: RelationshipView,
24
+ val: Point[],
25
+ ): void => {
26
+ relationView.path = val;
27
+ };
28
+
29
+ /**
30
+ * For a path, only counts the points which lie outside of the 2 class views
31
+ */
32
+ export const _relationView_manageInsidePointsDynamically = (
33
+ path: Point[],
34
+ from: ClassView,
35
+ to: ClassView,
36
+ ): Point[] => {
37
+ if (!path.length) {
38
+ return [];
39
+ }
40
+
41
+ let start = 0;
42
+ let startPoint = path[start] as Point;
43
+
44
+ while (start < path.length - 1 && from.contains(startPoint.x, startPoint.y)) {
45
+ start++;
46
+ startPoint = path[start] as Point;
47
+ }
48
+
49
+ let end = path.length - 1;
50
+ let endPoint = path[end] as Point;
51
+
52
+ while (end > 0 && to.contains(endPoint.x, endPoint.y)) {
53
+ end--;
54
+ endPoint = path[end] as Point;
55
+ }
56
+
57
+ return path.slice(start - 1, end + 2);
58
+ };
59
+
60
+ /**
61
+ * Flatten the path if the angle is wide enough
62
+ * Also `swallow` points in path which lie inside of the rectangle of a view
63
+ */
64
+ export const _relationView_possiblyFlattenPath = (
65
+ relationView: RelationshipView,
66
+ ): void => {
67
+ const fullPath = relationView.buildFullPath();
68
+ // NOTE: this method here will `swallow` up points inside of the boxes
69
+ const newPath = _relationView_manageInsidePointsDynamically(
70
+ fullPath,
71
+ relationView.from.classView.value,
72
+ relationView.to.classView.value,
73
+ );
74
+
75
+ // recompute the offset point from center inside of `from` and `to` classviews.
76
+ // for each, we first check if `manageInsidePointsDynamically` removes any points from the full path
77
+ // if it does we will update the offset
78
+ if (newPath[0] !== fullPath[0]) {
79
+ const center = relationView.from.classView.value.center();
80
+
81
+ relationView.from.offsetX = (newPath[0] as Point).x - center.x;
82
+ relationView.from.offsetY = (newPath[0] as Point).y - center.y;
83
+ }
84
+
85
+ if (newPath[newPath.length - 1] !== fullPath[fullPath.length - 1]) {
86
+ const center = relationView.to.classView.value.center();
87
+ relationView.to.offsetX =
88
+ (newPath[newPath.length - 1] as Point).x - center.x;
89
+ relationView.to.offsetY =
90
+ (newPath[newPath.length - 1] as Point).y - center.y;
91
+ }
92
+
93
+ // find the point which can be flattened due to its wide angle
94
+ const result = [];
95
+ for (let i = 0; i < newPath.length - 2; i++) {
96
+ const v1 = Vector.fromPoints(
97
+ newPath[i + 1] as Point,
98
+ newPath[i] as Point,
99
+ ).norm();
100
+ const v2 = Vector.fromPoints(
101
+ newPath[i + 1] as Point,
102
+ newPath[i + 2] as Point,
103
+ ).norm();
104
+ const dot = v1.dotProduct(v2);
105
+ const angle = (Math.acos(dot) * 180) / Math.PI;
106
+ if (Math.abs(angle - 180) > 5) {
107
+ result.push(newPath[i + 1] as Point);
108
+ }
109
+ }
110
+ // here's where we will modify the path, i.e. swallow inside points if we have to
111
+ _relationView_setPath(relationView, result);
112
+ };
113
+
114
+ /**
115
+ * Based on the location, find the point on the path that matches or create new point
116
+ * (within a threshold of proximity) from the coordinate and put this in the path array
117
+ * so it doesn't look too weird
118
+ */
119
+ export const _findOrBuildPoint = (
120
+ relationView: RelationshipView,
121
+ x: number,
122
+ y: number,
123
+ zoom: number,
124
+ allowChange = true,
125
+ ): Point | undefined => {
126
+ for (const pt of relationView.path) {
127
+ if (
128
+ Math.sqrt((x - pt.x) * (x - pt.x) + (y - pt.y) * (y - pt.y)) <
129
+ 10 / zoom
130
+ ) {
131
+ return pt;
132
+ }
133
+ }
134
+
135
+ const fullPath = relationView.buildFullPath(allowChange);
136
+ const newPath = [];
137
+ let point;
138
+
139
+ for (let i = 0; i < fullPath.length - 1; i++) {
140
+ const a = fullPath[i] as Point;
141
+ const b = fullPath[i + 1] as Point;
142
+ const n = new Vector(a.x, a.y).normal(new Vector(b.x, b.y)).norm();
143
+ const v = Vector.fromPoints(a, new Point(x, y));
144
+
145
+ if (Math.abs(n.dotProduct(v)) < 5 / zoom) {
146
+ const lx = (a.x < b.x ? a.x : b.x) - 5 / zoom;
147
+ const hx = (a.x < b.x ? b.x : a.x) + 5 / zoom;
148
+ const ly = (a.y < b.y ? a.y : b.y) - 5 / zoom;
149
+ const hy = (a.y < b.y ? b.y : a.y) + 5 / zoom;
150
+
151
+ if (lx <= x && x <= hx && ly <= y && y <= hy) {
152
+ point = new Point(x, y);
153
+ newPath.push(point);
154
+ }
155
+ }
156
+
157
+ if (i < fullPath.length - 2) {
158
+ newPath.push(fullPath[i + 1] as Point);
159
+ }
160
+ }
161
+ if (point && allowChange) {
162
+ _relationView_setPath(relationView, newPath);
163
+ }
164
+ return point;
165
+ };
@@ -14,7 +14,7 @@
14
14
  * limitations under the License.
15
15
  */
16
16
 
17
- import { observable, action, makeObservable } from 'mobx';
17
+ import { observable, makeObservable } from 'mobx';
18
18
  import type { ClassViewReference } from './DSLDiagram_ClassViewReference';
19
19
 
20
20
  export class RelationShipEdgeView {
@@ -26,17 +26,8 @@ export class RelationShipEdgeView {
26
26
  makeObservable(this, {
27
27
  offsetX: observable,
28
28
  offsetY: observable,
29
- setOffsetX: action,
30
- setOffsetY: action,
31
29
  });
32
30
 
33
31
  this.classView = classView;
34
32
  }
35
-
36
- setOffsetX(val: number): void {
37
- this.offsetX = val;
38
- }
39
- setOffsetY(val: number): void {
40
- this.offsetY = val;
41
- }
42
33
  }
@@ -14,46 +14,15 @@
14
14
  * limitations under the License.
15
15
  */
16
16
 
17
- import { observable, action, computed, makeObservable } from 'mobx';
18
- import { hashArray, changeEntry, type Hashable } from '@finos/legend-shared';
17
+ import { observable, computed, makeObservable } from 'mobx';
18
+ import { hashArray, type Hashable } from '@finos/legend-shared';
19
19
  import { RelationShipEdgeView as RelationshipEdgeView } from './DSLDiagram_RelationshipEdgeView';
20
20
  import { Point } from './geometry/DSLDiagram_Point';
21
21
  import type { ClassView } from './DSLDiagram_ClassView';
22
- import { Vector } from './geometry/DSLDiagram_Vector';
23
22
  import type { Diagram } from './DSLDiagram_Diagram';
24
23
  import { ClassViewExplicitReference } from './DSLDiagram_ClassViewReference';
25
24
  import { DIAGRAM_HASH_STRUCTURE } from '../../../../DSLDiagram_ModelUtils';
26
-
27
- /**
28
- * For a path, only counts the points which lie outside of the 2 class views
29
- */
30
- export const manageInsidePointsDynamically = (
31
- path: Point[],
32
- from: ClassView,
33
- to: ClassView,
34
- ): Point[] => {
35
- if (!path.length) {
36
- return [];
37
- }
38
-
39
- let start = 0;
40
- let startPoint = path[start] as Point;
41
-
42
- while (start < path.length - 1 && from.contains(startPoint.x, startPoint.y)) {
43
- start++;
44
- startPoint = path[start] as Point;
45
- }
46
-
47
- let end = path.length - 1;
48
- let endPoint = path[end] as Point;
49
-
50
- while (end > 0 && to.contains(endPoint.x, endPoint.y)) {
51
- end--;
52
- endPoint = path[end] as Point;
53
- }
54
-
55
- return path.slice(start - 1, end + 2);
56
- };
25
+ import { _relationView_manageInsidePointsDynamically } from './DSLDiagram_GraphModifierHelper';
57
26
 
58
27
  export class RelationshipView implements Hashable {
59
28
  owner: Diagram;
@@ -66,8 +35,6 @@ export class RelationshipView implements Hashable {
66
35
  constructor(owner: Diagram, from: ClassView, to: ClassView) {
67
36
  makeObservable(this, {
68
37
  path: observable,
69
- setPath: action,
70
- changePoint: action,
71
38
  fullPath: computed,
72
39
  });
73
40
 
@@ -78,13 +45,6 @@ export class RelationshipView implements Hashable {
78
45
  this.to = new RelationshipEdgeView(ClassViewExplicitReference.create(to));
79
46
  }
80
47
 
81
- setPath(val: Point[]): void {
82
- this.path = val;
83
- }
84
- changePoint(val: Point, newVal: Point): void {
85
- changeEntry(this.path, val, newVal);
86
- }
87
-
88
48
  /**
89
49
  * Compute the full path for an edge, but notice here that the end points are recomputed every time, as such
90
50
  * `path` only stores point that matters to the edge but are not end points
@@ -101,114 +61,13 @@ export class RelationshipView implements Hashable {
101
61
  * This method will compute the full path from the offset within class view for persistence purpose
102
62
  */
103
63
  get fullPath(): Point[] {
104
- return manageInsidePointsDynamically(
64
+ return _relationView_manageInsidePointsDynamically(
105
65
  this.buildFullPath(),
106
66
  this.from.classView.value,
107
67
  this.to.classView.value,
108
68
  );
109
69
  }
110
70
 
111
- /**
112
- * Flatten the path if the angle is wide enough
113
- * Also `swallow` points in path which lie inside of the rectangle of a view
114
- */
115
- possiblyFlattenPath(): void {
116
- const fullPath = this.buildFullPath();
117
- // NOTE: this method here will `swallow` up points inside of the boxes
118
- const newPath = manageInsidePointsDynamically(
119
- fullPath,
120
- this.from.classView.value,
121
- this.to.classView.value,
122
- );
123
-
124
- // recompute the offset point from center inside of `from` and `to` classviews.
125
- // for each, we first check if `manageInsidePointsDynamically` removes any points from the full path
126
- // if it does we will update the offset
127
- if (newPath[0] !== fullPath[0]) {
128
- const center = this.from.classView.value.center();
129
- this.from.setOffsetX((newPath[0] as Point).x - center.x);
130
- this.from.setOffsetY((newPath[0] as Point).y - center.y);
131
- }
132
-
133
- if (newPath[newPath.length - 1] !== fullPath[fullPath.length - 1]) {
134
- const center = this.to.classView.value.center();
135
- this.to.setOffsetX((newPath[newPath.length - 1] as Point).x - center.x);
136
- this.to.setOffsetY((newPath[newPath.length - 1] as Point).y - center.y);
137
- }
138
-
139
- // find the point which can be flattened due to its wide angle
140
- const result = [];
141
- for (let i = 0; i < newPath.length - 2; i++) {
142
- const v1 = Vector.fromPoints(
143
- newPath[i + 1] as Point,
144
- newPath[i] as Point,
145
- ).norm();
146
- const v2 = Vector.fromPoints(
147
- newPath[i + 1] as Point,
148
- newPath[i + 2] as Point,
149
- ).norm();
150
- const dot = v1.dotProduct(v2);
151
- const angle = (Math.acos(dot) * 180) / Math.PI;
152
- if (Math.abs(angle - 180) > 5) {
153
- result.push(newPath[i + 1] as Point);
154
- }
155
- }
156
- // here's where we will modify the path, i.e. swallow inside points if we have to
157
- this.setPath(result);
158
- }
159
-
160
- /**
161
- * Based on the location, find the point on the path that matches or create new point
162
- * (within a threshold of proximity) from the coordinate and put this in the path array
163
- * so it doesn't look too weird
164
- */
165
- findOrBuildPoint(
166
- x: number,
167
- y: number,
168
- zoom: number,
169
- allowChange = true,
170
- ): Point | undefined {
171
- for (const pt of this.path) {
172
- if (
173
- Math.sqrt((x - pt.x) * (x - pt.x) + (y - pt.y) * (y - pt.y)) <
174
- 10 / zoom
175
- ) {
176
- return pt;
177
- }
178
- }
179
-
180
- const fullPath = this.buildFullPath(allowChange);
181
- const newPath = [];
182
- let point;
183
-
184
- for (let i = 0; i < fullPath.length - 1; i++) {
185
- const a = fullPath[i] as Point;
186
- const b = fullPath[i + 1] as Point;
187
- const n = new Vector(a.x, a.y).normal(new Vector(b.x, b.y)).norm();
188
- const v = Vector.fromPoints(a, new Point(x, y));
189
-
190
- if (Math.abs(n.dotProduct(v)) < 5 / zoom) {
191
- const lx = (a.x < b.x ? a.x : b.x) - 5 / zoom;
192
- const hx = (a.x < b.x ? b.x : a.x) + 5 / zoom;
193
- const ly = (a.y < b.y ? a.y : b.y) - 5 / zoom;
194
- const hy = (a.y < b.y ? b.y : a.y) + 5 / zoom;
195
-
196
- if (lx <= x && x <= hx && ly <= y && y <= hy) {
197
- point = new Point(x, y);
198
- newPath.push(point);
199
- }
200
- }
201
-
202
- if (i < fullPath.length - 2) {
203
- newPath.push(fullPath[i + 1] as Point);
204
- }
205
- }
206
- if (point && allowChange) {
207
- this.setPath(newPath);
208
- }
209
- return point;
210
- }
211
-
212
71
  /**
213
72
  * Calculate the end points of the edge using offset, otherwise, use the center
214
73
  */
@@ -224,8 +83,8 @@ export class RelationshipView implements Hashable {
224
83
  return new Point(newX, newY);
225
84
  }
226
85
  if (allowChange) {
227
- edgeView.setOffsetX(0);
228
- edgeView.setOffsetY(0);
86
+ edgeView.offsetX = 0;
87
+ edgeView.offsetY = 0;
229
88
  }
230
89
  return new Point(center.x, center.y);
231
90
  }