@memberjunction/ng-graph-view 6.1.0-edge.5 → 6.1.0-edge.7

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.
@@ -11,63 +11,63 @@ const _c1 = ["svgCanvas"];
11
11
  const _forTrack0 = ($index, $item) => $item.ID;
12
12
  const _forTrack1 = ($index, $item) => $item.Category;
13
13
  function GraphViewComponent_Conditional_2_Conditional_20_Template(rf, ctx) { if (rf & 1) {
14
- const _r4 = i0.ɵɵgetCurrentView();
14
+ const _r3 = i0.ɵɵgetCurrentView();
15
15
  i0.ɵɵelement(0, "div", 10);
16
16
  i0.ɵɵelementStart(1, "div", 23);
17
17
  i0.ɵɵelement(2, "i", 24);
18
18
  i0.ɵɵelementStart(3, "input", 25);
19
- i0.ɵɵtwoWayListener("ngModelChange", function GraphViewComponent_Conditional_2_Conditional_20_Template_input_ngModelChange_3_listener($event) { i0.ɵɵrestoreView(_r4); const ctx_r2 = i0.ɵɵnextContext(2); i0.ɵɵtwoWayBindingSet(ctx_r2.SearchQuery, $event) || (ctx_r2.SearchQuery = $event); return i0.ɵɵresetView($event); });
20
- i0.ɵɵlistener("ngModelChange", function GraphViewComponent_Conditional_2_Conditional_20_Template_input_ngModelChange_3_listener($event) { i0.ɵɵrestoreView(_r4); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.SearchNodes($event)); });
19
+ i0.ɵɵtwoWayListener("ngModelChange", function GraphViewComponent_Conditional_2_Conditional_20_Template_input_ngModelChange_3_listener($event) { i0.ɵɵrestoreView(_r3); const ctx_r1 = i0.ɵɵnextContext(2); i0.ɵɵtwoWayBindingSet(ctx_r1.SearchQuery, $event) || (ctx_r1.SearchQuery = $event); return i0.ɵɵresetView($event); });
20
+ i0.ɵɵlistener("ngModelChange", function GraphViewComponent_Conditional_2_Conditional_20_Template_input_ngModelChange_3_listener($event) { i0.ɵɵrestoreView(_r3); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.SearchNodes($event)); });
21
21
  i0.ɵɵelementEnd()();
22
22
  } if (rf & 2) {
23
- const ctx_r2 = i0.ɵɵnextContext(2);
23
+ const ctx_r1 = i0.ɵɵnextContext(2);
24
24
  i0.ɵɵadvance(3);
25
- i0.ɵɵtwoWayProperty("ngModel", ctx_r2.SearchQuery);
25
+ i0.ɵɵtwoWayProperty("ngModel", ctx_r1.SearchQuery);
26
26
  } }
27
27
  function GraphViewComponent_Conditional_2_Template(rf, ctx) { if (rf & 1) {
28
- const _r2 = i0.ɵɵgetCurrentView();
28
+ const _r1 = i0.ɵɵgetCurrentView();
29
29
  i0.ɵɵelementStart(0, "div", 3)(1, "span", 8);
30
30
  i0.ɵɵelement(2, "i", 9);
31
31
  i0.ɵɵtext(3, " Network Graph ");
32
32
  i0.ɵɵelementEnd();
33
33
  i0.ɵɵelement(4, "div", 10);
34
34
  i0.ɵɵelementStart(5, "button", 11);
35
- i0.ɵɵlistener("click", function GraphViewComponent_Conditional_2_Template_button_click_5_listener() { i0.ɵɵrestoreView(_r2); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.SetLayoutMode("force")); });
35
+ i0.ɵɵlistener("click", function GraphViewComponent_Conditional_2_Template_button_click_5_listener() { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.SetLayoutMode("force")); });
36
36
  i0.ɵɵelement(6, "i", 12);
37
37
  i0.ɵɵtext(7, " Force ");
38
38
  i0.ɵɵelementEnd();
39
39
  i0.ɵɵelementStart(8, "button", 13);
40
- i0.ɵɵlistener("click", function GraphViewComponent_Conditional_2_Template_button_click_8_listener() { i0.ɵɵrestoreView(_r2); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.SetLayoutMode("circular")); });
40
+ i0.ɵɵlistener("click", function GraphViewComponent_Conditional_2_Template_button_click_8_listener() { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.SetLayoutMode("circular")); });
41
41
  i0.ɵɵelement(9, "i", 14);
42
42
  i0.ɵɵtext(10, " Circular ");
43
43
  i0.ɵɵelementEnd();
44
44
  i0.ɵɵelement(11, "div", 10);
45
45
  i0.ɵɵelementStart(12, "button", 15);
46
- i0.ɵɵlistener("click", function GraphViewComponent_Conditional_2_Template_button_click_12_listener() { i0.ɵɵrestoreView(_r2); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.ZoomIn()); });
46
+ i0.ɵɵlistener("click", function GraphViewComponent_Conditional_2_Template_button_click_12_listener() { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.ZoomIn()); });
47
47
  i0.ɵɵelement(13, "i", 16);
48
48
  i0.ɵɵelementEnd();
49
49
  i0.ɵɵelementStart(14, "button", 17);
50
- i0.ɵɵlistener("click", function GraphViewComponent_Conditional_2_Template_button_click_14_listener() { i0.ɵɵrestoreView(_r2); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.ZoomOut()); });
50
+ i0.ɵɵlistener("click", function GraphViewComponent_Conditional_2_Template_button_click_14_listener() { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.ZoomOut()); });
51
51
  i0.ɵɵelement(15, "i", 18);
52
52
  i0.ɵɵelementEnd();
53
53
  i0.ɵɵelementStart(16, "button", 19);
54
- i0.ɵɵlistener("click", function GraphViewComponent_Conditional_2_Template_button_click_16_listener() { i0.ɵɵrestoreView(_r2); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.FitToView()); });
54
+ i0.ɵɵlistener("click", function GraphViewComponent_Conditional_2_Template_button_click_16_listener() { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.FitToView()); });
55
55
  i0.ɵɵelement(17, "i", 20);
56
56
  i0.ɵɵelementEnd();
57
57
  i0.ɵɵelementStart(18, "button", 21);
58
- i0.ɵɵlistener("click", function GraphViewComponent_Conditional_2_Template_button_click_18_listener() { i0.ɵɵrestoreView(_r2); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.Rearrange()); });
58
+ i0.ɵɵlistener("click", function GraphViewComponent_Conditional_2_Template_button_click_18_listener() { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.Rearrange()); });
59
59
  i0.ɵɵelement(19, "i", 22);
60
60
  i0.ɵɵelementEnd();
61
61
  i0.ɵɵconditionalCreate(20, GraphViewComponent_Conditional_2_Conditional_20_Template, 4, 1);
62
62
  i0.ɵɵelementEnd();
63
63
  } if (rf & 2) {
64
- const ctx_r2 = i0.ɵɵnextContext();
64
+ const ctx_r1 = i0.ɵɵnextContext();
65
65
  i0.ɵɵadvance(5);
66
- i0.ɵɵclassProp("active", ctx_r2.LayoutMode === "force");
66
+ i0.ɵɵclassProp("active", ctx_r1.LayoutMode === "force");
67
67
  i0.ɵɵadvance(3);
68
- i0.ɵɵclassProp("active", ctx_r2.LayoutMode === "circular");
68
+ i0.ɵɵclassProp("active", ctx_r1.LayoutMode === "circular");
69
69
  i0.ɵɵadvance(12);
70
- i0.ɵɵconditional(ctx_r2.Searchable ? 20 : -1);
70
+ i0.ɵɵconditional(ctx_r1.Searchable ? 20 : -1);
71
71
  } }
72
72
  function GraphViewComponent_Conditional_3_For_2_Template(rf, ctx) { if (rf & 1) {
73
73
  i0.ɵɵelementStart(0, "div", 26);
@@ -75,20 +75,20 @@ function GraphViewComponent_Conditional_3_For_2_Template(rf, ctx) { if (rf & 1)
75
75
  i0.ɵɵtext(2);
76
76
  i0.ɵɵelementEnd();
77
77
  } if (rf & 2) {
78
- const cat_r5 = ctx.$implicit;
78
+ const cat_r4 = ctx.$implicit;
79
79
  i0.ɵɵadvance();
80
- i0.ɵɵstyleProp("background", cat_r5.Color);
80
+ i0.ɵɵstyleProp("background", cat_r4.Color);
81
81
  i0.ɵɵadvance();
82
- i0.ɵɵtextInterpolate1(" ", cat_r5.Label, " ");
82
+ i0.ɵɵtextInterpolate1(" ", cat_r4.Label, " ");
83
83
  } }
84
84
  function GraphViewComponent_Conditional_3_Template(rf, ctx) { if (rf & 1) {
85
85
  i0.ɵɵelementStart(0, "div", 4);
86
86
  i0.ɵɵrepeaterCreate(1, GraphViewComponent_Conditional_3_For_2_Template, 3, 3, "div", 26, _forTrack1);
87
87
  i0.ɵɵelementEnd();
88
88
  } if (rf & 2) {
89
- const ctx_r2 = i0.ɵɵnextContext();
89
+ const ctx_r1 = i0.ɵɵnextContext();
90
90
  i0.ɵɵadvance();
91
- i0.ɵɵrepeater(ctx_r2.ActiveCategories);
91
+ i0.ɵɵrepeater(ctx_r1.ActiveCategories);
92
92
  } }
93
93
  function GraphViewComponent_Conditional_4_Conditional_15_Template(rf, ctx) { if (rf & 1) {
94
94
  i0.ɵɵelementStart(0, "span", 38);
@@ -96,20 +96,20 @@ function GraphViewComponent_Conditional_4_Conditional_15_Template(rf, ctx) { if
96
96
  i0.ɵɵelementEnd();
97
97
  } }
98
98
  function GraphViewComponent_Conditional_4_Conditional_21_Template(rf, ctx) { if (rf & 1) {
99
- const _r7 = i0.ɵɵgetCurrentView();
99
+ const _r6 = i0.ɵɵgetCurrentView();
100
100
  i0.ɵɵelementStart(0, "button", 44);
101
- i0.ɵɵlistener("click", function GraphViewComponent_Conditional_4_Conditional_21_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r7); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.NavigateToEntity(ctx_r2.SelectedNode)); });
101
+ i0.ɵɵlistener("click", function GraphViewComponent_Conditional_4_Conditional_21_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r6); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.NavigateToEntity(ctx_r1.SelectedNode)); });
102
102
  i0.ɵɵelement(1, "i", 45);
103
103
  i0.ɵɵtext(2, " Open Entity Form ");
104
104
  i0.ɵɵelementEnd();
105
105
  } }
106
106
  function GraphViewComponent_Conditional_4_Template(rf, ctx) { if (rf & 1) {
107
- const _r6 = i0.ɵɵgetCurrentView();
107
+ const _r5 = i0.ɵɵgetCurrentView();
108
108
  i0.ɵɵelementStart(0, "div", 5)(1, "div", 28)(2, "span", 29);
109
109
  i0.ɵɵtext(3, "Node Inspector");
110
110
  i0.ɵɵelementEnd();
111
111
  i0.ɵɵelementStart(4, "button", 30);
112
- i0.ɵɵlistener("click", function GraphViewComponent_Conditional_4_Template_button_click_4_listener() { i0.ɵɵrestoreView(_r6); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.ClearSelection()); });
112
+ i0.ɵɵlistener("click", function GraphViewComponent_Conditional_4_Template_button_click_4_listener() { i0.ɵɵrestoreView(_r5); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.ClearSelection()); });
113
113
  i0.ɵɵelement(5, "i", 31);
114
114
  i0.ɵɵelementEnd()();
115
115
  i0.ɵɵelementStart(6, "div", 32)(7, "div", 33);
@@ -131,46 +131,46 @@ function GraphViewComponent_Conditional_4_Template(rf, ctx) { if (rf & 1) {
131
131
  i0.ɵɵelementStart(20, "div", 40);
132
132
  i0.ɵɵconditionalCreate(21, GraphViewComponent_Conditional_4_Conditional_21_Template, 3, 0, "button", 41);
133
133
  i0.ɵɵelementStart(22, "button", 42);
134
- i0.ɵɵlistener("click", function GraphViewComponent_Conditional_4_Template_button_click_22_listener() { i0.ɵɵrestoreView(_r6); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.ExpandHops(ctx_r2.SelectedNode.ID, 1)); });
134
+ i0.ɵɵlistener("click", function GraphViewComponent_Conditional_4_Template_button_click_22_listener() { i0.ɵɵrestoreView(_r5); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.ExpandHops(ctx_r1.SelectedNode.ID, 1)); });
135
135
  i0.ɵɵelement(23, "i", 43);
136
136
  i0.ɵɵtext(24, " Expand 1-Hop Neighbors ");
137
137
  i0.ɵɵelementEnd()()();
138
138
  } if (rf & 2) {
139
- const ctx_r2 = i0.ɵɵnextContext();
139
+ const ctx_r1 = i0.ɵɵnextContext();
140
140
  i0.ɵɵadvance(7);
141
- i0.ɵɵstyleProp("background", ctx_r2.GetNodeColor(ctx_r2.SelectedNode));
141
+ i0.ɵɵstyleProp("background", ctx_r1.GetNodeColor(ctx_r1.SelectedNode));
142
142
  i0.ɵɵadvance();
143
- i0.ɵɵclassMap(ctx_r2.GetNodeIcon(ctx_r2.SelectedNode));
143
+ i0.ɵɵclassMap(ctx_r1.GetNodeIcon(ctx_r1.SelectedNode));
144
144
  i0.ɵɵadvance(3);
145
- i0.ɵɵtextInterpolate1(" ", ctx_r2.SelectedNode.Label, " ");
145
+ i0.ɵɵtextInterpolate1(" ", ctx_r1.SelectedNode.Label, " ");
146
146
  i0.ɵɵadvance(3);
147
- i0.ɵɵtextInterpolate1(" ", ctx_r2.SelectedNode.Sublabel || ctx_r2.SelectedNode.Category, " ");
147
+ i0.ɵɵtextInterpolate1(" ", ctx_r1.SelectedNode.Sublabel || ctx_r1.SelectedNode.Category, " ");
148
148
  i0.ɵɵadvance();
149
- i0.ɵɵconditional(ctx_r2.IsFocalNode(ctx_r2.SelectedNode) ? 15 : -1);
149
+ i0.ɵɵconditional(ctx_r1.IsFocalNode(ctx_r1.SelectedNode) ? 15 : -1);
150
150
  i0.ɵɵadvance(4);
151
- i0.ɵɵtextInterpolate(ctx_r2.GetNodeEdgeCount(ctx_r2.SelectedNode.ID));
151
+ i0.ɵɵtextInterpolate(ctx_r1.GetNodeEdgeCount(ctx_r1.SelectedNode.ID));
152
152
  i0.ɵɵadvance(2);
153
- i0.ɵɵconditional(!ctx_r2.IsFocalNode(ctx_r2.SelectedNode) ? 21 : -1);
153
+ i0.ɵɵconditional(!ctx_r1.IsFocalNode(ctx_r1.SelectedNode) ? 21 : -1);
154
154
  } }
155
155
  function GraphViewComponent_For_9_Template(rf, ctx) { if (rf & 1) {
156
- const _r8 = i0.ɵɵgetCurrentView();
156
+ const _r7 = i0.ɵɵgetCurrentView();
157
157
  i0.ɵɵnamespaceSVG();
158
158
  i0.ɵɵelementStart(0, "g")(1, "line", 46);
159
- i0.ɵɵlistener("click", function GraphViewComponent_For_9_Template_line_click_1_listener($event) { const edge_r9 = i0.ɵɵrestoreView(_r8).$implicit; const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.OnEdgeClick(edge_r9, $event)); });
159
+ i0.ɵɵlistener("click", function GraphViewComponent_For_9_Template_line_click_1_listener($event) { const edge_r8 = i0.ɵɵrestoreView(_r7).$implicit; const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnEdgeClick(edge_r8, $event)); });
160
160
  i0.ɵɵelementEnd();
161
161
  i0.ɵɵelementStart(2, "text", 47);
162
162
  i0.ɵɵtext(3);
163
163
  i0.ɵɵelementEnd()();
164
164
  } if (rf & 2) {
165
- const edge_r9 = ctx.$implicit;
166
- const ctx_r2 = i0.ɵɵnextContext();
165
+ const edge_r8 = ctx.$implicit;
166
+ const ctx_r1 = i0.ɵɵnextContext();
167
167
  i0.ɵɵadvance();
168
- i0.ɵɵclassProp("is-highlighted", ctx_r2.IsEdgeHighlighted(edge_r9));
169
- i0.ɵɵattribute("x1", ctx_r2.GetNodeX(edge_r9.SourceID))("y1", ctx_r2.GetNodeY(edge_r9.SourceID))("x2", ctx_r2.GetNodeX(edge_r9.TargetID))("y2", ctx_r2.GetNodeY(edge_r9.TargetID));
168
+ i0.ɵɵclassProp("is-highlighted", ctx_r1.IsEdgeHighlighted(edge_r8));
169
+ i0.ɵɵattribute("x1", ctx_r1.GetNodeX(edge_r8.SourceID))("y1", ctx_r1.GetNodeY(edge_r8.SourceID))("x2", ctx_r1.GetNodeX(edge_r8.TargetID))("y2", ctx_r1.GetNodeY(edge_r8.TargetID));
170
170
  i0.ɵɵadvance();
171
- i0.ɵɵattribute("x", (ctx_r2.GetNodeX(edge_r9.SourceID) + ctx_r2.GetNodeX(edge_r9.TargetID)) / 2)("y", (ctx_r2.GetNodeY(edge_r9.SourceID) + ctx_r2.GetNodeY(edge_r9.TargetID)) / 2 - 4);
171
+ i0.ɵɵattribute("x", (ctx_r1.GetNodeX(edge_r8.SourceID) + ctx_r1.GetNodeX(edge_r8.TargetID)) / 2)("y", (ctx_r1.GetNodeY(edge_r8.SourceID) + ctx_r1.GetNodeY(edge_r8.TargetID)) / 2 - 4);
172
172
  i0.ɵɵadvance();
173
- i0.ɵɵtextInterpolate1(" ", edge_r9.Label, " ");
173
+ i0.ɵɵtextInterpolate1(" ", edge_r8.Label, " ");
174
174
  } }
175
175
  function GraphViewComponent_For_11_Conditional_1_Template(rf, ctx) { if (rf & 1) {
176
176
  i0.ɵɵnamespaceSVG();
@@ -186,17 +186,17 @@ function GraphViewComponent_For_11_Conditional_7_Template(rf, ctx) { if (rf & 1)
186
186
  i0.ɵɵtext(1);
187
187
  i0.ɵɵelementEnd();
188
188
  } if (rf & 2) {
189
- const node_r11 = i0.ɵɵnextContext().$implicit;
190
- const ctx_r2 = i0.ɵɵnextContext();
191
- i0.ɵɵattribute("y", (node_r11.Radius || 26) + 28);
189
+ const node_r10 = i0.ɵɵnextContext().$implicit;
190
+ const ctx_r1 = i0.ɵɵnextContext();
191
+ i0.ɵɵattribute("y", (node_r10.Radius || 26) + 28);
192
192
  i0.ɵɵadvance();
193
- i0.ɵɵtextInterpolate1(" ", ctx_r2.TruncateLabel(node_r11.Sublabel, 20), " ");
193
+ i0.ɵɵtextInterpolate1(" ", ctx_r1.TruncateLabel(node_r10.Sublabel, 20), " ");
194
194
  } }
195
195
  function GraphViewComponent_For_11_Template(rf, ctx) { if (rf & 1) {
196
- const _r10 = i0.ɵɵgetCurrentView();
196
+ const _r9 = i0.ɵɵgetCurrentView();
197
197
  i0.ɵɵnamespaceSVG();
198
198
  i0.ɵɵelementStart(0, "g", 48);
199
- i0.ɵɵlistener("mousedown", function GraphViewComponent_For_11_Template_g_mousedown_0_listener($event) { const node_r11 = i0.ɵɵrestoreView(_r10).$implicit; const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.OnNodeMouseDown(node_r11, $event)); })("click", function GraphViewComponent_For_11_Template_g_click_0_listener($event) { const node_r11 = i0.ɵɵrestoreView(_r10).$implicit; const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.OnNodeClick(node_r11, $event)); })("dblclick", function GraphViewComponent_For_11_Template_g_dblclick_0_listener() { const node_r11 = i0.ɵɵrestoreView(_r10).$implicit; const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.NavigateToEntity(node_r11)); });
199
+ i0.ɵɵlistener("mousedown", function GraphViewComponent_For_11_Template_g_mousedown_0_listener($event) { const node_r10 = i0.ɵɵrestoreView(_r9).$implicit; const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnNodeMouseDown(node_r10, $event)); })("click", function GraphViewComponent_For_11_Template_g_click_0_listener($event) { const node_r10 = i0.ɵɵrestoreView(_r9).$implicit; const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnNodeClick(node_r10, $event)); })("dblclick", function GraphViewComponent_For_11_Template_g_dblclick_0_listener() { const node_r10 = i0.ɵɵrestoreView(_r9).$implicit; const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.NavigateToEntity(node_r10)); });
200
200
  i0.ɵɵconditionalCreate(1, GraphViewComponent_For_11_Conditional_1_Template, 1, 0, ":svg:circle", 49)(2, GraphViewComponent_For_11_Conditional_2_Template, 1, 0, ":svg:circle", 50);
201
201
  i0.ɵɵelement(3, "circle", 51)(4, "circle");
202
202
  i0.ɵɵelementStart(5, "text", 52);
@@ -205,21 +205,21 @@ function GraphViewComponent_For_11_Template(rf, ctx) { if (rf & 1) {
205
205
  i0.ɵɵconditionalCreate(7, GraphViewComponent_For_11_Conditional_7_Template, 2, 2, ":svg:text", 53);
206
206
  i0.ɵɵelementEnd();
207
207
  } if (rf & 2) {
208
- const node_r11 = ctx.$implicit;
209
- const ctx_r2 = i0.ɵɵnextContext();
210
- i0.ɵɵattribute("transform", "translate(" + (node_r11.X || 0) + "," + (node_r11.Y || 0) + ")");
208
+ const node_r10 = ctx.$implicit;
209
+ const ctx_r1 = i0.ɵɵnextContext();
210
+ i0.ɵɵattribute("transform", "translate(" + (node_r10.X || 0) + "," + (node_r10.Y || 0) + ")");
211
211
  i0.ɵɵadvance();
212
- i0.ɵɵconditional(ctx_r2.IsNodeSelected(node_r11) ? 1 : ctx_r2.IsFocalNode(node_r11) ? 2 : -1);
212
+ i0.ɵɵconditional(ctx_r1.IsNodeSelected(node_r10) ? 1 : ctx_r1.IsFocalNode(node_r10) ? 2 : -1);
213
213
  i0.ɵɵadvance(2);
214
- i0.ɵɵattribute("r", node_r11.Radius || 26)("stroke", ctx_r2.GetNodeColor(node_r11));
214
+ i0.ɵɵattribute("r", node_r10.Radius || 26)("stroke", ctx_r1.GetNodeColor(node_r10));
215
215
  i0.ɵɵadvance();
216
- i0.ɵɵattribute("r", (node_r11.Radius || 26) - 8)("fill", ctx_r2.GetNodeColor(node_r11));
216
+ i0.ɵɵattribute("r", (node_r10.Radius || 26) - 8)("fill", ctx_r1.GetNodeColor(node_r10));
217
217
  i0.ɵɵadvance();
218
- i0.ɵɵattribute("y", (node_r11.Radius || 26) + 16);
218
+ i0.ɵɵattribute("y", (node_r10.Radius || 26) + 16);
219
219
  i0.ɵɵadvance();
220
- i0.ɵɵtextInterpolate1(" ", ctx_r2.TruncateLabel(node_r11.Label, 18), " ");
220
+ i0.ɵɵtextInterpolate1(" ", ctx_r1.TruncateLabel(node_r10.Label, 18), " ");
221
221
  i0.ɵɵadvance();
222
- i0.ɵɵconditional(node_r11.Sublabel ? 7 : -1);
222
+ i0.ɵɵconditional(node_r10.Sublabel ? 7 : -1);
223
223
  } }
224
224
  export const DEFAULT_GRAPH_CATEGORIES = [
225
225
  { Category: 'person', Label: 'Person', Color: '#10b981', IconClass: 'fa-solid fa-user' },
@@ -991,14 +991,13 @@ export class GraphViewComponent {
991
991
  i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.WrapperRef = _t.first);
992
992
  i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.CanvasRef = _t.first);
993
993
  } }, inputs: { Nodes: "Nodes", Edges: "Edges", Categories: "Categories", LayoutMode: "LayoutMode", MaxHopDistance: "MaxHopDistance", SelectedNodeId: "SelectedNodeId", FocalNodeId: "FocalNodeId", AutoOpenInspector: "AutoOpenInspector", ShowToolbar: "ShowToolbar", ShowLegend: "ShowLegend", ShowInspector: "ShowInspector", Searchable: "Searchable", AutoFitOnLoad: "AutoFitOnLoad", Physics: "Physics" }, outputs: { BeforeNodeSelect: "BeforeNodeSelect", NodeSelected: "NodeSelected", BeforeEdgeSelect: "BeforeEdgeSelect", EdgeSelected: "EdgeSelected", BeforeHopExpand: "BeforeHopExpand", HopExpanded: "HopExpanded", BeforeLayoutChange: "BeforeLayoutChange", LayoutChanged: "LayoutChanged", BeforeNodeNavigate: "BeforeNodeNavigate", NodeNavigated: "NodeNavigated", ViewportTransform: "ViewportTransform" }, features: [i0.ɵɵNgOnChangesFeature], decls: 12, vars: 6, consts: [["wrapper", ""], ["svgCanvas", ""], [1, "mj-graph-wrapper"], [1, "mj-graph-toolbar"], [1, "mj-graph-legend"], [1, "mj-graph-inspector"], [1, "mj-graph-svg-canvas", 3, "mousedown", "mousemove", "mouseup", "mouseleave", "wheel"], [1, "mj-node-group"], [2, "font-size", "12px", "font-weight", "700", "color", "#fff", "display", "flex", "align-items", "center", "gap", "6px"], [1, "fa-solid", "fa-circle-nodes", 2, "color", "var(--mj-brand-primary)"], [1, "mj-graph-separator"], ["type", "button", "title", "Force-Directed Physics", 1, "mj-graph-tool-btn", 3, "click"], [1, "fa-solid", "fa-atom"], ["type", "button", "title", "Circular Layout", 1, "mj-graph-tool-btn", 3, "click"], [1, "fa-solid", "fa-circle-notch"], ["type", "button", "title", "Zoom In", 1, "mj-graph-tool-btn", 3, "click"], [1, "fa-solid", "fa-magnifying-glass-plus"], ["type", "button", "title", "Zoom Out", 1, "mj-graph-tool-btn", 3, "click"], [1, "fa-solid", "fa-magnifying-glass-minus"], ["type", "button", "title", "Fit View", 1, "mj-graph-tool-btn", 3, "click"], [1, "fa-solid", "fa-expand"], ["type", "button", "title", "Re-simulate Physics", 1, "mj-graph-tool-btn", 3, "click"], [1, "fa-solid", "fa-arrows-rotate"], [2, "position", "relative"], [1, "fa-solid", "fa-magnifying-glass", 2, "position", "absolute", "left", "8px", "top", "50%", "transform", "translateY(-50%)", "font-size", "10px", "color", "var(--mj-text-muted)"], ["placeholder", "Search graph nodes...", 1, "mj-graph-search-input", 3, "ngModelChange", "ngModel"], [1, "mj-graph-legend-item"], [1, "mj-graph-legend-dot"], [1, "mj-graph-inspector-header"], [1, "mj-graph-inspector-title"], ["type", "button", 1, "mj-graph-inspector-close", 3, "click"], [1, "fa-solid", "fa-xmark"], [1, "mj-graph-inspector-card"], [1, "mj-graph-inspector-avatar"], [2, "overflow", "hidden", "flex", "1"], [2, "font-size", "13px", "font-weight", "700", "color", "#fff", "text-overflow", "ellipsis", "overflow", "hidden", "white-space", "nowrap"], [2, "display", "flex", "align-items", "center", "gap", "6px", "margin-top", "3px"], [2, "font-size", "11px", "color", "var(--mj-text-secondary)"], [2, "font-size", "10px", "padding", "1px 6px", "border-radius", "9999px", "background", "rgba(56, 189, 248, 0.15)", "color", "#38bdf8", "font-weight", "600", "border", "1px solid rgba(56, 189, 248, 0.3)"], [2, "font-size", "11.5px", "color", "var(--mj-text-secondary)", "line-height", "1.45"], [1, "mj-graph-inspector-actions"], ["type", "button", 1, "mj-graph-tool-btn", "active", 2, "justify-content", "center", "width", "100%"], ["type", "button", 1, "mj-graph-tool-btn", 2, "justify-content", "center", "width", "100%", 3, "click"], [1, "fa-solid", "fa-circle-nodes"], ["type", "button", 1, "mj-graph-tool-btn", "active", 2, "justify-content", "center", "width", "100%", 3, "click"], [1, "fa-solid", "fa-arrow-up-right-from-square"], [1, "mj-edge-path", 3, "click"], [1, "mj-edge-text"], [1, "mj-node-group", 3, "mousedown", "click", "dblclick"], ["r", "36", "fill", "rgba(56, 189, 248, 0.2)", "stroke", "#38bdf8", "stroke-width", "2"], ["r", "34", "fill", "none", "stroke", "rgba(56, 189, 248, 0.45)", "stroke-width", "2", "stroke-dasharray", "4 3"], ["fill", "#141f36", "stroke-width", "3", 1, "mj-node-circle"], [1, "mj-node-label"], [1, "mj-node-sublabel"]], template: function GraphViewComponent_Template(rf, ctx) { if (rf & 1) {
994
- const _r1 = i0.ɵɵgetCurrentView();
995
994
  i0.ɵɵelementStart(0, "div", 2, 0);
996
995
  i0.ɵɵconditionalCreate(2, GraphViewComponent_Conditional_2_Template, 21, 5, "div", 3);
997
996
  i0.ɵɵconditionalCreate(3, GraphViewComponent_Conditional_3_Template, 3, 0, "div", 4);
998
997
  i0.ɵɵconditionalCreate(4, GraphViewComponent_Conditional_4_Template, 25, 9, "div", 5);
999
998
  i0.ɵɵnamespaceSVG();
1000
999
  i0.ɵɵelementStart(5, "svg", 6, 1);
1001
- i0.ɵɵlistener("mousedown", function GraphViewComponent_Template_svg_mousedown_5_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.OnCanvasMouseDown($event)); })("mousemove", function GraphViewComponent_Template_svg_mousemove_5_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.OnCanvasMouseMove($event)); })("mouseup", function GraphViewComponent_Template_svg_mouseup_5_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.OnCanvasMouseUp($event)); })("mouseleave", function GraphViewComponent_Template_svg_mouseleave_5_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.OnCanvasMouseUp($event)); })("wheel", function GraphViewComponent_Template_svg_wheel_5_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.OnCanvasWheel($event)); });
1000
+ i0.ɵɵlistener("mousedown", function GraphViewComponent_Template_svg_mousedown_5_listener($event) { return ctx.OnCanvasMouseDown($event); })("mousemove", function GraphViewComponent_Template_svg_mousemove_5_listener($event) { return ctx.OnCanvasMouseMove($event); })("mouseup", function GraphViewComponent_Template_svg_mouseup_5_listener($event) { return ctx.OnCanvasMouseUp($event); })("mouseleave", function GraphViewComponent_Template_svg_mouseleave_5_listener($event) { return ctx.OnCanvasMouseUp($event); })("wheel", function GraphViewComponent_Template_svg_wheel_5_listener($event) { return ctx.OnCanvasWheel($event); });
1002
1001
  i0.ɵɵelementStart(7, "g");
1003
1002
  i0.ɵɵrepeaterCreate(8, GraphViewComponent_For_9_Template, 4, 9, ":svg:g", null, _forTrack0);
1004
1003
  i0.ɵɵrepeaterCreate(10, GraphViewComponent_For_11_Template, 8, 9, ":svg:g", 7, _forTrack0);
@@ -1018,7 +1017,7 @@ export class GraphViewComponent {
1018
1017
  i0.ɵɵrepeater(ctx.Edges);
1019
1018
  i0.ɵɵadvance(2);
1020
1019
  i0.ɵɵrepeater(ctx.FilteredNodes);
1021
- } }, dependencies: [CommonModule, FormsModule, i1.DefaultValueAccessor, i1.NgControlStatus, i1.NgModel], styles: ["[_nghost-%COMP%] {\n display: block;\n width: 100%;\n height: 100%;\n position: relative;\n overflow: hidden;\n background: var(--mj-bg-surface-sunken, #0b1220);\n border-radius: var(--mj-radius-lg, 12px);\n border: 1px solid var(--mj-border-default, #223254);\n user-select: none;\n}\n\n.mj-graph-wrapper[_ngcontent-%COMP%] {\n width: 100%;\n height: 100%;\n position: relative;\n overflow: hidden;\n display: flex;\n flex-direction: column;\n}\n\n.mj-graph-svg-canvas[_ngcontent-%COMP%] {\n width: 100%;\n height: 100%;\n cursor: grab;\n}\n\n.mj-graph-svg-canvas.is-panning[_ngcontent-%COMP%] {\n cursor: grabbing;\n}\n\n\n\n.mj-graph-toolbar[_ngcontent-%COMP%] {\n position: absolute;\n top: 14px;\n left: 14px;\n z-index: 20;\n display: flex;\n align-items: center;\n gap: 8px;\n background: rgba(20, 31, 54, 0.88);\n backdrop-filter: blur(10px);\n border: 1px solid var(--mj-border-default, #223254);\n padding: 6px 12px;\n border-radius: var(--mj-radius-lg, 10px);\n box-shadow: 0 8px 24px rgba(0, 0, 0, 0.4);\n}\n\n.mj-graph-tool-btn[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-elevated, #1a2744);\n border: 1px solid var(--mj-border-default, #223254);\n color: var(--mj-text-primary, #f8fafc);\n border-radius: 6px;\n padding: 5px 10px;\n font-size: 11.5px;\n font-weight: 600;\n cursor: pointer;\n display: flex;\n align-items: center;\n gap: 6px;\n transition: all 0.15s ease;\n}\n\n.mj-graph-tool-btn[_ngcontent-%COMP%]:hover {\n border-color: var(--mj-brand-primary, #38bdf8);\n background: var(--mj-border-hover, #334876);\n}\n\n.mj-graph-tool-btn.active[_ngcontent-%COMP%] {\n background: var(--mj-brand-primary, #38bdf8);\n color: #090e1a;\n border-color: var(--mj-brand-primary, #38bdf8);\n}\n\n.mj-graph-separator[_ngcontent-%COMP%] {\n width: 1px;\n height: 18px;\n background: var(--mj-border-default, #223254);\n}\n\n.mj-graph-search-input[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-sunken, #090e1a);\n border: 1px solid var(--mj-border-default, #223254);\n border-radius: 6px;\n color: var(--mj-text-primary, #f8fafc);\n padding: 4px 8px 4px 24px;\n font-size: 11.5px;\n width: 150px;\n}\n\n.mj-graph-search-input[_ngcontent-%COMP%]:focus {\n outline: none;\n border-color: var(--mj-brand-primary, #38bdf8);\n width: 190px;\n}\n\n\n\n.mj-graph-legend[_ngcontent-%COMP%] {\n position: absolute;\n bottom: 14px;\n left: 14px;\n z-index: 20;\n display: flex;\n align-items: center;\n gap: 12px;\n background: rgba(20, 31, 54, 0.88);\n backdrop-filter: blur(10px);\n border: 1px solid var(--mj-border-default, #223254);\n padding: 6px 14px;\n border-radius: var(--mj-radius-lg, 10px);\n font-size: 11.5px;\n color: var(--mj-text-secondary, #94a3b8);\n}\n\n.mj-graph-legend-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n.mj-graph-legend-dot[_ngcontent-%COMP%] {\n width: 10px;\n height: 10px;\n border-radius: 50%;\n}\n\n\n\n.mj-graph-inspector[_ngcontent-%COMP%] {\n position: absolute;\n top: 14px;\n right: 14px;\n width: 300px;\n max-height: calc(100% - 28px);\n background: rgba(20, 31, 54, 0.95);\n backdrop-filter: blur(14px);\n border: 1px solid var(--mj-border-default, #223254);\n border-radius: var(--mj-radius-lg, 12px);\n padding: 16px;\n display: flex;\n flex-direction: column;\n gap: 12px;\n z-index: 25;\n box-shadow: 0 10px 30px rgba(0, 0, 0, 0.5);\n overflow-y: auto;\n scrollbar-width: thin;\n animation: _ngcontent-%COMP%_mjGraphSlide 0.2s ease;\n}\n\n.mj-graph-inspector-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n}\n\n.mj-graph-inspector-title[_ngcontent-%COMP%] {\n font-size: 11px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.05em;\n color: var(--mj-text-muted, #64748b);\n}\n\n.mj-graph-inspector-close[_ngcontent-%COMP%] {\n background: none;\n border: none;\n color: var(--mj-text-muted, #64748b);\n cursor: pointer;\n font-size: 14px;\n}\n\n.mj-graph-inspector-card[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n background: var(--mj-bg-surface, #111a2e);\n border: 1px solid var(--mj-border-default, #223254);\n border-radius: 8px;\n padding: 10px 12px;\n}\n\n.mj-graph-inspector-avatar[_ngcontent-%COMP%] {\n width: 40px;\n height: 40px;\n border-radius: 8px;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 16px;\n color: #fff;\n flex-shrink: 0;\n}\n\n.mj-graph-inspector-actions[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 6px;\n margin-top: 4px;\n}\n\n\n\n.mj-edge-path[_ngcontent-%COMP%] {\n stroke: var(--mj-border-hover, #2d416b);\n stroke-width: 2;\n fill: none;\n transition: stroke 0.2s ease;\n}\n\n.mj-edge-path.is-highlighted[_ngcontent-%COMP%] {\n stroke: var(--mj-brand-primary, #38bdf8);\n stroke-width: 3;\n}\n\n.mj-edge-text[_ngcontent-%COMP%] {\n font-size: 10px;\n font-weight: 500;\n fill: var(--mj-text-muted, #64748b);\n text-anchor: middle;\n pointer-events: none;\n paint-order: stroke;\n stroke: var(--mj-bg-surface-sunken, #0b1220);\n stroke-width: 3px;\n stroke-linecap: butt;\n stroke-linejoin: miter;\n}\n\n.mj-node-group[_ngcontent-%COMP%] {\n cursor: pointer;\n transition: transform 0.1s ease;\n}\n\n.mj-node-group[_ngcontent-%COMP%]:hover .mj-node-circle[_ngcontent-%COMP%] {\n filter: drop-shadow(0 0 10px var(--mj-brand-primary, #38bdf8));\n}\n\n.mj-node-circle[_ngcontent-%COMP%] {\n transition: all 0.2s ease;\n}\n\n.mj-node-label[_ngcontent-%COMP%] {\n font-size: 11px;\n font-weight: 700;\n fill: var(--mj-text-primary, #f8fafc);\n text-anchor: middle;\n pointer-events: none;\n}\n\n.mj-node-sublabel[_ngcontent-%COMP%] {\n font-size: 9.5px;\n font-weight: 500;\n fill: var(--mj-text-secondary, #94a3b8);\n text-anchor: middle;\n pointer-events: none;\n}\n\n@keyframes _ngcontent-%COMP%_mjGraphSlide {\n from { opacity: 0; transform: translateX(20px); }\n to { opacity: 1; transform: translateX(0); }\n}"], changeDetection: 0 });
1020
+ } }, dependencies: [CommonModule, FormsModule, i1.DefaultValueAccessor, i1.NgControlStatus, i1.NgModel], styles: ["[_nghost-%COMP%] {\n display: block;\n width: 100%;\n height: 100%;\n position: relative;\n overflow: hidden;\n background: var(--mj-bg-surface-sunken, #0b1220);\n border-radius: var(--mj-radius-lg, 12px);\n border: 1px solid var(--mj-border-default, #223254);\n user-select: none;\n}\n\n.mj-graph-wrapper[_ngcontent-%COMP%] {\n width: 100%;\n height: 100%;\n position: relative;\n overflow: hidden;\n display: flex;\n flex-direction: column;\n}\n\n.mj-graph-svg-canvas[_ngcontent-%COMP%] {\n width: 100%;\n height: 100%;\n cursor: grab;\n}\n\n.mj-graph-svg-canvas.is-panning[_ngcontent-%COMP%] {\n cursor: grabbing;\n}\n\n\n.mj-graph-toolbar[_ngcontent-%COMP%] {\n position: absolute;\n top: 14px;\n left: 14px;\n z-index: 20;\n display: flex;\n align-items: center;\n gap: 8px;\n background: rgba(20, 31, 54, 0.88);\n backdrop-filter: blur(10px);\n border: 1px solid var(--mj-border-default, #223254);\n padding: 6px 12px;\n border-radius: var(--mj-radius-lg, 10px);\n box-shadow: 0 8px 24px rgba(0, 0, 0, 0.4);\n}\n\n.mj-graph-tool-btn[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-elevated, #1a2744);\n border: 1px solid var(--mj-border-default, #223254);\n color: var(--mj-text-primary, #f8fafc);\n border-radius: 6px;\n padding: 5px 10px;\n font-size: 11.5px;\n font-weight: 600;\n cursor: pointer;\n display: flex;\n align-items: center;\n gap: 6px;\n transition: all 0.15s ease;\n}\n\n.mj-graph-tool-btn[_ngcontent-%COMP%]:hover {\n border-color: var(--mj-brand-primary, #38bdf8);\n background: var(--mj-border-hover, #334876);\n}\n\n.mj-graph-tool-btn.active[_ngcontent-%COMP%] {\n background: var(--mj-brand-primary, #38bdf8);\n color: #090e1a;\n border-color: var(--mj-brand-primary, #38bdf8);\n}\n\n.mj-graph-separator[_ngcontent-%COMP%] {\n width: 1px;\n height: 18px;\n background: var(--mj-border-default, #223254);\n}\n\n.mj-graph-search-input[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-sunken, #090e1a);\n border: 1px solid var(--mj-border-default, #223254);\n border-radius: 6px;\n color: var(--mj-text-primary, #f8fafc);\n padding: 4px 8px 4px 24px;\n font-size: 11.5px;\n width: 150px;\n}\n\n.mj-graph-search-input[_ngcontent-%COMP%]:focus {\n outline: none;\n border-color: var(--mj-brand-primary, #38bdf8);\n width: 190px;\n}\n\n\n.mj-graph-legend[_ngcontent-%COMP%] {\n position: absolute;\n bottom: 14px;\n left: 14px;\n z-index: 20;\n display: flex;\n align-items: center;\n gap: 12px;\n background: rgba(20, 31, 54, 0.88);\n backdrop-filter: blur(10px);\n border: 1px solid var(--mj-border-default, #223254);\n padding: 6px 14px;\n border-radius: var(--mj-radius-lg, 10px);\n font-size: 11.5px;\n color: var(--mj-text-secondary, #94a3b8);\n}\n\n.mj-graph-legend-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n.mj-graph-legend-dot[_ngcontent-%COMP%] {\n width: 10px;\n height: 10px;\n border-radius: 50%;\n}\n\n\n.mj-graph-inspector[_ngcontent-%COMP%] {\n position: absolute;\n top: 14px;\n right: 14px;\n width: 300px;\n max-height: calc(100% - 28px);\n background: rgba(20, 31, 54, 0.95);\n backdrop-filter: blur(14px);\n border: 1px solid var(--mj-border-default, #223254);\n border-radius: var(--mj-radius-lg, 12px);\n padding: 16px;\n display: flex;\n flex-direction: column;\n gap: 12px;\n z-index: 25;\n box-shadow: 0 10px 30px rgba(0, 0, 0, 0.5);\n overflow-y: auto;\n scrollbar-width: thin;\n animation: _ngcontent-%COMP%_mjGraphSlide 0.2s ease;\n}\n\n.mj-graph-inspector-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n}\n\n.mj-graph-inspector-title[_ngcontent-%COMP%] {\n font-size: 11px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.05em;\n color: var(--mj-text-muted, #64748b);\n}\n\n.mj-graph-inspector-close[_ngcontent-%COMP%] {\n background: none;\n border: none;\n color: var(--mj-text-muted, #64748b);\n cursor: pointer;\n font-size: 14px;\n}\n\n.mj-graph-inspector-card[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n background: var(--mj-bg-surface, #111a2e);\n border: 1px solid var(--mj-border-default, #223254);\n border-radius: 8px;\n padding: 10px 12px;\n}\n\n.mj-graph-inspector-avatar[_ngcontent-%COMP%] {\n width: 40px;\n height: 40px;\n border-radius: 8px;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 16px;\n color: #fff;\n flex-shrink: 0;\n}\n\n.mj-graph-inspector-actions[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 6px;\n margin-top: 4px;\n}\n\n\n.mj-edge-path[_ngcontent-%COMP%] {\n stroke: var(--mj-border-hover, #2d416b);\n stroke-width: 2;\n fill: none;\n transition: stroke 0.2s ease;\n}\n\n.mj-edge-path.is-highlighted[_ngcontent-%COMP%] {\n stroke: var(--mj-brand-primary, #38bdf8);\n stroke-width: 3;\n}\n\n.mj-edge-text[_ngcontent-%COMP%] {\n font-size: 10px;\n font-weight: 500;\n fill: var(--mj-text-muted, #64748b);\n text-anchor: middle;\n pointer-events: none;\n paint-order: stroke;\n stroke: var(--mj-bg-surface-sunken, #0b1220);\n stroke-width: 3px;\n stroke-linecap: butt;\n stroke-linejoin: miter;\n}\n\n.mj-node-group[_ngcontent-%COMP%] {\n cursor: pointer;\n transition: transform 0.1s ease;\n}\n\n.mj-node-group[_ngcontent-%COMP%]:hover .mj-node-circle[_ngcontent-%COMP%] {\n filter: drop-shadow(0 0 10px var(--mj-brand-primary, #38bdf8));\n}\n\n.mj-node-circle[_ngcontent-%COMP%] {\n transition: all 0.2s ease;\n}\n\n.mj-node-label[_ngcontent-%COMP%] {\n font-size: 11px;\n font-weight: 700;\n fill: var(--mj-text-primary, #f8fafc);\n text-anchor: middle;\n pointer-events: none;\n}\n\n.mj-node-sublabel[_ngcontent-%COMP%] {\n font-size: 9.5px;\n font-weight: 500;\n fill: var(--mj-text-secondary, #94a3b8);\n text-anchor: middle;\n pointer-events: none;\n}\n\n@keyframes _ngcontent-%COMP%_mjGraphSlide {\n from { opacity: 0; transform: translateX(20px); }\n to { opacity: 1; transform: translateX(0); }\n}"], changeDetection: 0 });
1022
1021
  }
1023
1022
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(GraphViewComponent, [{
1024
1023
  type: Component,
@@ -1 +1 @@
1
- {"version":3,"file":"graph-view.component.js","sourceRoot":"","sources":["../../../src/lib/components/graph-view.component.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n Component,\n Input,\n Output,\n EventEmitter,\n OnInit,\n OnChanges,\n OnDestroy,\n SimpleChanges,\n ChangeDetectionStrategy,\n ChangeDetectorRef,\n ElementRef,\n ViewChild,\n inject\n} from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { FormsModule } from '@angular/forms';\nimport { NormalizeUUID, UUIDsEqual } from '@memberjunction/global';\nimport * as d3 from 'd3';\nimport type {\n GraphNode,\n GraphEdge,\n GraphLayoutMode,\n GraphNodeCategory,\n GraphCategoryConfig,\n GraphViewportTransform,\n GraphPhysicsConfig\n} from '../models/graph-models';\nimport {\n BeforeNodeSelectEventArgs,\n NodeSelectedEventArgs,\n BeforeEdgeSelectEventArgs,\n EdgeSelectedEventArgs,\n BeforeHopExpandEventArgs,\n HopExpandedEventArgs,\n BeforeLayoutChangeEventArgs,\n LayoutChangedEventArgs,\n BeforeNodeNavigateEventArgs,\n NodeNavigatedEventArgs,\n ViewportTransformEventArgs\n} from '../events/graph-events';\n\nexport const DEFAULT_GRAPH_CATEGORIES: GraphCategoryConfig[] = [\n { Category: 'person', Label: 'Person', Color: '#10b981', IconClass: 'fa-solid fa-user' },\n { Category: 'organization', Label: 'Organization', Color: '#38bdf8', IconClass: 'fa-solid fa-building' },\n { Category: 'committee', Label: 'Committee', Color: '#8b5cf6', IconClass: 'fa-solid fa-landmark' },\n { Category: 'account', Label: 'Holding / Account', Color: '#f59e0b', IconClass: 'fa-solid fa-building-flag' },\n { Category: 'asset', Label: 'Asset', Color: '#ec4899', IconClass: 'fa-solid fa-gem' },\n { Category: 'group', Label: 'Group', Color: '#06b6d4', IconClass: 'fa-solid fa-users' },\n { Category: 'custom', Label: 'Custom', Color: '#64748b', IconClass: 'fa-solid fa-circle-nodes' }\n];\n\nconst DYNAMIC_CATEGORY_PALETTE = [\n '#10b981', '#38bdf8', '#8b5cf6', '#f59e0b', '#ec4899',\n '#06b6d4', '#84cc16', '#f43f5e', '#a855f7', '#14b8a6'\n];\n\nconst GRAPH_VIEW_CSS = `\n:host {\n display: block;\n width: 100%;\n height: 100%;\n position: relative;\n overflow: hidden;\n background: var(--mj-bg-surface-sunken, #0b1220);\n border-radius: var(--mj-radius-lg, 12px);\n border: 1px solid var(--mj-border-default, #223254);\n user-select: none;\n}\n\n.mj-graph-wrapper {\n width: 100%;\n height: 100%;\n position: relative;\n overflow: hidden;\n display: flex;\n flex-direction: column;\n}\n\n.mj-graph-svg-canvas {\n width: 100%;\n height: 100%;\n cursor: grab;\n}\n\n.mj-graph-svg-canvas.is-panning {\n cursor: grabbing;\n}\n\n/* Floating Toolbar */\n.mj-graph-toolbar {\n position: absolute;\n top: 14px;\n left: 14px;\n z-index: 20;\n display: flex;\n align-items: center;\n gap: 8px;\n background: rgba(20, 31, 54, 0.88);\n backdrop-filter: blur(10px);\n border: 1px solid var(--mj-border-default, #223254);\n padding: 6px 12px;\n border-radius: var(--mj-radius-lg, 10px);\n box-shadow: 0 8px 24px rgba(0, 0, 0, 0.4);\n}\n\n.mj-graph-tool-btn {\n background: var(--mj-bg-surface-elevated, #1a2744);\n border: 1px solid var(--mj-border-default, #223254);\n color: var(--mj-text-primary, #f8fafc);\n border-radius: 6px;\n padding: 5px 10px;\n font-size: 11.5px;\n font-weight: 600;\n cursor: pointer;\n display: flex;\n align-items: center;\n gap: 6px;\n transition: all 0.15s ease;\n}\n\n.mj-graph-tool-btn:hover {\n border-color: var(--mj-brand-primary, #38bdf8);\n background: var(--mj-border-hover, #334876);\n}\n\n.mj-graph-tool-btn.active {\n background: var(--mj-brand-primary, #38bdf8);\n color: #090e1a;\n border-color: var(--mj-brand-primary, #38bdf8);\n}\n\n.mj-graph-separator {\n width: 1px;\n height: 18px;\n background: var(--mj-border-default, #223254);\n}\n\n.mj-graph-search-input {\n background: var(--mj-bg-surface-sunken, #090e1a);\n border: 1px solid var(--mj-border-default, #223254);\n border-radius: 6px;\n color: var(--mj-text-primary, #f8fafc);\n padding: 4px 8px 4px 24px;\n font-size: 11.5px;\n width: 150px;\n}\n\n.mj-graph-search-input:focus {\n outline: none;\n border-color: var(--mj-brand-primary, #38bdf8);\n width: 190px;\n}\n\n/* Floating Legend */\n.mj-graph-legend {\n position: absolute;\n bottom: 14px;\n left: 14px;\n z-index: 20;\n display: flex;\n align-items: center;\n gap: 12px;\n background: rgba(20, 31, 54, 0.88);\n backdrop-filter: blur(10px);\n border: 1px solid var(--mj-border-default, #223254);\n padding: 6px 14px;\n border-radius: var(--mj-radius-lg, 10px);\n font-size: 11.5px;\n color: var(--mj-text-secondary, #94a3b8);\n}\n\n.mj-graph-legend-item {\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n.mj-graph-legend-dot {\n width: 10px;\n height: 10px;\n border-radius: 50%;\n}\n\n/* Inspector Drawer */\n.mj-graph-inspector {\n position: absolute;\n top: 14px;\n right: 14px;\n width: 300px;\n max-height: calc(100% - 28px);\n background: rgba(20, 31, 54, 0.95);\n backdrop-filter: blur(14px);\n border: 1px solid var(--mj-border-default, #223254);\n border-radius: var(--mj-radius-lg, 12px);\n padding: 16px;\n display: flex;\n flex-direction: column;\n gap: 12px;\n z-index: 25;\n box-shadow: 0 10px 30px rgba(0, 0, 0, 0.5);\n overflow-y: auto;\n scrollbar-width: thin;\n animation: mjGraphSlide 0.2s ease;\n}\n\n.mj-graph-inspector-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n}\n\n.mj-graph-inspector-title {\n font-size: 11px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.05em;\n color: var(--mj-text-muted, #64748b);\n}\n\n.mj-graph-inspector-close {\n background: none;\n border: none;\n color: var(--mj-text-muted, #64748b);\n cursor: pointer;\n font-size: 14px;\n}\n\n.mj-graph-inspector-card {\n display: flex;\n align-items: center;\n gap: 12px;\n background: var(--mj-bg-surface, #111a2e);\n border: 1px solid var(--mj-border-default, #223254);\n border-radius: 8px;\n padding: 10px 12px;\n}\n\n.mj-graph-inspector-avatar {\n width: 40px;\n height: 40px;\n border-radius: 8px;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 16px;\n color: #fff;\n flex-shrink: 0;\n}\n\n.mj-graph-inspector-actions {\n display: flex;\n flex-direction: column;\n gap: 6px;\n margin-top: 4px;\n}\n\n/* SVG Rendering Elements */\n.mj-edge-path {\n stroke: var(--mj-border-hover, #2d416b);\n stroke-width: 2;\n fill: none;\n transition: stroke 0.2s ease;\n}\n\n.mj-edge-path.is-highlighted {\n stroke: var(--mj-brand-primary, #38bdf8);\n stroke-width: 3;\n}\n\n.mj-edge-text {\n font-size: 10px;\n font-weight: 500;\n fill: var(--mj-text-muted, #64748b);\n text-anchor: middle;\n pointer-events: none;\n paint-order: stroke;\n stroke: var(--mj-bg-surface-sunken, #0b1220);\n stroke-width: 3px;\n stroke-linecap: butt;\n stroke-linejoin: miter;\n}\n\n.mj-node-group {\n cursor: pointer;\n transition: transform 0.1s ease;\n}\n\n.mj-node-group:hover .mj-node-circle {\n filter: drop-shadow(0 0 10px var(--mj-brand-primary, #38bdf8));\n}\n\n.mj-node-circle {\n transition: all 0.2s ease;\n}\n\n.mj-node-label {\n font-size: 11px;\n font-weight: 700;\n fill: var(--mj-text-primary, #f8fafc);\n text-anchor: middle;\n pointer-events: none;\n}\n\n.mj-node-sublabel {\n font-size: 9.5px;\n font-weight: 500;\n fill: var(--mj-text-secondary, #94a3b8);\n text-anchor: middle;\n pointer-events: none;\n}\n\n@keyframes mjGraphSlide {\n from { opacity: 0; transform: translateX(20px); }\n to { opacity: 1; transform: translateX(0); }\n}\n`;\n\n/**\n * `<mj-graph-view>` — Interactive network and entity relationship graph visualization.\n *\n * Supports force-directed dynamic layout, multi-category entity badges, hop-expansion,\n * zoom/pan controls, inspector drawer, search filters, and cancelable Before/After event pairs.\n */\n@Component({\n selector: 'mj-graph-view',\n standalone: true,\n imports: [CommonModule, FormsModule],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <div class=\"mj-graph-wrapper\" #wrapper>\n <!-- 1. Floating Action Toolbar -->\n @if (ShowToolbar) {\n <div class=\"mj-graph-toolbar\">\n <span style=\"font-size: 12px; font-weight: 700; color: #fff; display: flex; align-items: center; gap: 6px;\">\n <i class=\"fa-solid fa-circle-nodes\" style=\"color: var(--mj-brand-primary);\"></i>\n Network Graph\n </span>\n\n <div class=\"mj-graph-separator\"></div>\n\n <!-- Layout Mode Selector -->\n <button\n type=\"button\"\n class=\"mj-graph-tool-btn\"\n [class.active]=\"LayoutMode === 'force'\"\n (click)=\"SetLayoutMode('force')\"\n title=\"Force-Directed Physics\">\n <i class=\"fa-solid fa-atom\"></i> Force\n </button>\n <button\n type=\"button\"\n class=\"mj-graph-tool-btn\"\n [class.active]=\"LayoutMode === 'circular'\"\n (click)=\"SetLayoutMode('circular')\"\n title=\"Circular Layout\">\n <i class=\"fa-solid fa-circle-notch\"></i> Circular\n </button>\n\n <div class=\"mj-graph-separator\"></div>\n\n <!-- Zoom Controls -->\n <button type=\"button\" class=\"mj-graph-tool-btn\" (click)=\"ZoomIn()\" title=\"Zoom In\">\n <i class=\"fa-solid fa-magnifying-glass-plus\"></i>\n </button>\n <button type=\"button\" class=\"mj-graph-tool-btn\" (click)=\"ZoomOut()\" title=\"Zoom Out\">\n <i class=\"fa-solid fa-magnifying-glass-minus\"></i>\n </button>\n <button type=\"button\" class=\"mj-graph-tool-btn\" (click)=\"FitToView()\" title=\"Fit View\">\n <i class=\"fa-solid fa-expand\"></i>\n </button>\n <button type=\"button\" class=\"mj-graph-tool-btn\" (click)=\"Rearrange()\" title=\"Re-simulate Physics\">\n <i class=\"fa-solid fa-arrows-rotate\"></i>\n </button>\n\n @if (Searchable) {\n <div class=\"mj-graph-separator\"></div>\n <div style=\"position: relative;\">\n <i class=\"fa-solid fa-magnifying-glass\" style=\"position: absolute; left: 8px; top: 50%; transform: translateY(-50%); font-size: 10px; color: var(--mj-text-muted);\"></i>\n <input\n class=\"mj-graph-search-input\"\n [(ngModel)]=\"SearchQuery\"\n (ngModelChange)=\"SearchNodes($event)\"\n placeholder=\"Search graph nodes...\" />\n </div>\n }\n </div>\n }\n\n <!-- 2. Floating Dynamic Category Legend -->\n @if (ShowLegend && ActiveCategories.length > 0) {\n <div class=\"mj-graph-legend\">\n @for (cat of ActiveCategories; track cat.Category) {\n <div class=\"mj-graph-legend-item\">\n <div class=\"mj-graph-legend-dot\" [style.background]=\"cat.Color\"></div>\n {{ cat.Label }}\n </div>\n }\n </div>\n }\n\n <!-- 3. Selected Node Inspector Drawer -->\n @if (ShowInspector && SelectedNode) {\n <div class=\"mj-graph-inspector\">\n <div class=\"mj-graph-inspector-header\">\n <span class=\"mj-graph-inspector-title\">Node Inspector</span>\n <button class=\"mj-graph-inspector-close\" type=\"button\" (click)=\"ClearSelection()\">\n <i class=\"fa-solid fa-xmark\"></i>\n </button>\n </div>\n\n <div class=\"mj-graph-inspector-card\">\n <div class=\"mj-graph-inspector-avatar\" [style.background]=\"GetNodeColor(SelectedNode)\">\n <i [class]=\"GetNodeIcon(SelectedNode)\"></i>\n </div>\n <div style=\"overflow: hidden; flex: 1;\">\n <div style=\"font-size: 13px; font-weight: 700; color: #fff; text-overflow: ellipsis; overflow: hidden; white-space: nowrap;\">\n {{ SelectedNode.Label }}\n </div>\n <div style=\"display: flex; align-items: center; gap: 6px; margin-top: 3px;\">\n <span style=\"font-size: 11px; color: var(--mj-text-secondary);\">\n {{ SelectedNode.Sublabel || SelectedNode.Category }}\n </span>\n @if (IsFocalNode(SelectedNode)) {\n <span style=\"font-size: 10px; padding: 1px 6px; border-radius: 9999px; background: rgba(56, 189, 248, 0.15); color: #38bdf8; font-weight: 600; border: 1px solid rgba(56, 189, 248, 0.3);\">Current Record</span>\n }\n </div>\n </div>\n </div>\n\n <div style=\"font-size: 11.5px; color: var(--mj-text-secondary); line-height: 1.45;\">\n Direct Connected Edges: <strong>{{ GetNodeEdgeCount(SelectedNode.ID) }}</strong>\n </div>\n\n <div class=\"mj-graph-inspector-actions\">\n @if (!IsFocalNode(SelectedNode)) {\n <button\n type=\"button\"\n class=\"mj-graph-tool-btn active\"\n style=\"justify-content: center; width: 100%;\"\n (click)=\"NavigateToEntity(SelectedNode)\">\n <i class=\"fa-solid fa-arrow-up-right-from-square\"></i> Open Entity Form\n </button>\n }\n <button\n type=\"button\"\n class=\"mj-graph-tool-btn\"\n style=\"justify-content: center; width: 100%;\"\n (click)=\"ExpandHops(SelectedNode.ID, 1)\">\n <i class=\"fa-solid fa-circle-nodes\"></i> Expand 1-Hop Neighbors\n </button>\n </div>\n </div>\n }\n\n <!-- 4. Interactive SVG Graph Canvas -->\n <svg\n #svgCanvas\n class=\"mj-graph-svg-canvas\"\n [class.is-panning]=\"IsPanning\"\n (mousedown)=\"OnCanvasMouseDown($event)\"\n (mousemove)=\"OnCanvasMouseMove($event)\"\n (mouseup)=\"OnCanvasMouseUp($event)\"\n (mouseleave)=\"OnCanvasMouseUp($event)\"\n (wheel)=\"OnCanvasWheel($event)\">\n\n <g [attr.transform]=\"'translate(' + PanX + ',' + PanY + ') scale(' + Scale + ')'\">\n <!-- Edges Layer -->\n @for (edge of Edges; track edge.ID) {\n <g>\n <line\n class=\"mj-edge-path\"\n [class.is-highlighted]=\"IsEdgeHighlighted(edge)\"\n [attr.x1]=\"GetNodeX(edge.SourceID)\"\n [attr.y1]=\"GetNodeY(edge.SourceID)\"\n [attr.x2]=\"GetNodeX(edge.TargetID)\"\n [attr.y2]=\"GetNodeY(edge.TargetID)\"\n (click)=\"OnEdgeClick(edge, $event)\">\n </line>\n <text\n class=\"mj-edge-text\"\n [attr.x]=\"(GetNodeX(edge.SourceID) + GetNodeX(edge.TargetID)) / 2\"\n [attr.y]=\"(GetNodeY(edge.SourceID) + GetNodeY(edge.TargetID)) / 2 - 4\">\n {{ edge.Label }}\n </text>\n </g>\n }\n\n <!-- Nodes Layer -->\n @for (node of FilteredNodes; track node.ID) {\n <g\n class=\"mj-node-group\"\n [attr.transform]=\"'translate(' + (node.X || 0) + ',' + (node.Y || 0) + ')'\"\n (mousedown)=\"OnNodeMouseDown(node, $event)\"\n (click)=\"OnNodeClick(node, $event)\"\n (dblclick)=\"NavigateToEntity(node)\">\n\n <!-- Outer Selection / Focal Halo -->\n @if (IsNodeSelected(node)) {\n <circle r=\"36\" fill=\"rgba(56, 189, 248, 0.2)\" stroke=\"#38bdf8\" stroke-width=\"2\"></circle>\n } @else if (IsFocalNode(node)) {\n <circle r=\"34\" fill=\"none\" stroke=\"rgba(56, 189, 248, 0.45)\" stroke-width=\"2\" stroke-dasharray=\"4 3\"></circle>\n }\n\n <!-- Node Body Circle -->\n <circle\n class=\"mj-node-circle\"\n [attr.r]=\"node.Radius || 26\"\n fill=\"#141f36\"\n [attr.stroke]=\"GetNodeColor(node)\"\n stroke-width=\"3\">\n </circle>\n\n <!-- Node Icon Center -->\n <circle [attr.r]=\"(node.Radius || 26) - 8\" [attr.fill]=\"GetNodeColor(node)\"></circle>\n\n <!-- Labels -->\n <text class=\"mj-node-label\" [attr.y]=\"(node.Radius || 26) + 16\">\n {{ TruncateLabel(node.Label, 18) }}\n </text>\n @if (node.Sublabel) {\n <text class=\"mj-node-sublabel\" [attr.y]=\"(node.Radius || 26) + 28\">\n {{ TruncateLabel(node.Sublabel, 20) }}\n </text>\n }\n </g>\n }\n </g>\n </svg>\n </div>\n `,\n styles: [GRAPH_VIEW_CSS]\n})\nexport class GraphViewComponent implements OnInit, OnChanges, OnDestroy {\n private cdr = inject(ChangeDetectorRef);\n\n @ViewChild('wrapper', { static: true }) public WrapperRef!: ElementRef<HTMLDivElement>;\n @ViewChild('svgCanvas', { static: true }) public CanvasRef!: ElementRef<SVGSVGElement>;\n\n // ── Inputs ────────────────────────────────────────────────────────\n @Input() public Nodes: GraphNode[] = [];\n @Input() public Edges: GraphEdge[] = [];\n @Input() public Categories: GraphCategoryConfig[] = DEFAULT_GRAPH_CATEGORIES;\n @Input() public LayoutMode: GraphLayoutMode = 'force';\n @Input() public MaxHopDistance = 2;\n @Input() public SelectedNodeId?: string;\n @Input() public FocalNodeId?: string;\n @Input() public AutoOpenInspector = false;\n @Input() public ShowToolbar = true;\n @Input() public ShowLegend = true;\n @Input() public ShowInspector = true;\n @Input() public Searchable = true;\n @Input() public AutoFitOnLoad = true;\n @Input() public Physics: GraphPhysicsConfig = {\n Repulsion: -500,\n LinkDistance: 130,\n Gravity: 0.05,\n Damping: 0.88,\n MaxIterations: 200\n };\n\n // ── Cancelable Before/After Outputs ────────────────────────────────\n @Output() public BeforeNodeSelect = new EventEmitter<BeforeNodeSelectEventArgs>();\n @Output() public NodeSelected = new EventEmitter<NodeSelectedEventArgs>();\n\n @Output() public BeforeEdgeSelect = new EventEmitter<BeforeEdgeSelectEventArgs>();\n @Output() public EdgeSelected = new EventEmitter<EdgeSelectedEventArgs>();\n\n @Output() public BeforeHopExpand = new EventEmitter<BeforeHopExpandEventArgs>();\n @Output() public HopExpanded = new EventEmitter<HopExpandedEventArgs>();\n\n @Output() public BeforeLayoutChange = new EventEmitter<BeforeLayoutChangeEventArgs>();\n @Output() public LayoutChanged = new EventEmitter<LayoutChangedEventArgs>();\n\n @Output() public BeforeNodeNavigate = new EventEmitter<BeforeNodeNavigateEventArgs>();\n @Output() public NodeNavigated = new EventEmitter<NodeNavigatedEventArgs>();\n\n @Output() public ViewportTransform = new EventEmitter<ViewportTransformEventArgs>();\n\n // ── Internal State ────────────────────────────────────────────────\n public FilteredNodes: GraphNode[] = [];\n public SelectedNode: GraphNode | null = null;\n public SelectedEdge: GraphEdge | null = null;\n public SearchQuery = '';\n\n public Scale = 1.0;\n public PanX = 200;\n public PanY = 150;\n public IsPanning = false;\n private panStartX = 0;\n private panStartY = 0;\n\n private draggedNode: GraphNode | null = null;\n private simulation: d3.Simulation<GraphNode, d3.SimulationLinkDatum<GraphNode>> | null = null;\n\n public ngOnInit(): void {\n this.InitializePositions();\n this.ApplyFilters();\n this.SimulatePhysics();\n }\n\n public ngOnChanges(changes: SimpleChanges): void {\n if (changes['Nodes'] || changes['Edges']) {\n this.InitializePositions();\n this.ApplyFilters();\n this.SimulatePhysics();\n }\n if (changes['SelectedNodeId'] && this.SelectedNodeId) {\n const found = this.Nodes.find(n => UUIDsEqual(n.ID, this.SelectedNodeId));\n if (found && this.AutoOpenInspector) {\n this.SelectedNode = found;\n }\n }\n }\n\n public ngOnDestroy(): void {\n if (this.simulation) {\n this.simulation.stop();\n this.simulation = null;\n }\n }\n\n // ── Positioning & D3 Physics Engine ──────────────────────────────────\n private InitializePositions(): void {\n const cx = this.GetContainerWidth() / 2 || 400;\n const cy = this.GetContainerHeight() / 2 || 250;\n const count = this.Nodes.length || 1;\n\n this.Nodes.forEach((node, idx) => {\n if (node.x === undefined || node.y === undefined) {\n if (node.X !== undefined && node.Y !== undefined) {\n node.x = node.X;\n node.y = node.Y;\n } else {\n const angle = (idx / count) * 2 * Math.PI;\n const r = 100 + Math.random() * 60;\n node.x = cx + r * Math.cos(angle);\n node.y = cy + r * Math.sin(angle);\n node.X = node.x;\n node.Y = node.y;\n }\n node.vx = 0;\n node.vy = 0;\n node.VX = 0;\n node.VY = 0;\n }\n });\n }\n\n public SimulatePhysics(): void {\n if (this.LayoutMode === 'circular') {\n this.ApplyCircularLayout();\n if (this.AutoFitOnLoad) {\n this.AutoFitToView();\n }\n this.cdr.markForCheck();\n return;\n }\n\n if (this.simulation) {\n this.simulation.stop();\n this.simulation = null;\n }\n\n const cx = this.GetContainerWidth() / 2 || 400;\n const cy = this.GetContainerHeight() / 2 || 250;\n\n // Resolve endpoints to node objects so a case-skewed UUID or dangling\n // edge cannot throw \"node not found\" out of ngOnInit. Raw-string\n // .id(d => d.ID) compared with ===, which UUIDsEqual elsewhere\n // deliberately does not.\n const nodeById = new Map<string, GraphNode>();\n for (const node of this.Nodes) {\n const key = NormalizeUUID(node.ID);\n if (key) {\n nodeById.set(key, node);\n }\n }\n const links: d3.SimulationLinkDatum<GraphNode>[] = [];\n for (const edge of this.Edges) {\n const source = nodeById.get(NormalizeUUID(edge.SourceID));\n const target = nodeById.get(NormalizeUUID(edge.TargetID));\n if (source && target) {\n links.push({ source, target });\n }\n }\n\n this.simulation = d3.forceSimulation<GraphNode>(this.Nodes)\n .force('link', d3.forceLink<GraphNode, d3.SimulationLinkDatum<GraphNode>>(links)\n .distance(this.Physics.LinkDistance || 120))\n .force('charge', d3.forceManyBody<GraphNode>()\n .strength(this.Physics.Repulsion || -450)\n .distanceMax(700))\n .force('collide', d3.forceCollide<GraphNode>((d: GraphNode) => (d.Radius || 26) + 16).iterations(2))\n .force('center', d3.forceCenter<GraphNode>(cx, cy));\n\n // Headless Pre-Warming: run 80 ticks synchronously in memory so the SVG renders resting immediately\n this.simulation.stop();\n for (let i = 0; i < 90; ++i) {\n this.simulation.tick();\n }\n\n this.SyncCoordinates();\n\n // Auto-center & fit into view\n if (this.AutoFitOnLoad) {\n this.AutoFitToView();\n }\n\n // Attach live tick handler for interactive drag & drop\n this.simulation.on('tick', () => {\n this.SyncCoordinates();\n this.cdr.markForCheck();\n });\n\n this.cdr.markForCheck();\n }\n\n private SyncCoordinates(): void {\n for (const n of this.Nodes) {\n n.X = n.x;\n n.Y = n.y;\n n.VX = n.vx;\n n.VY = n.vy;\n }\n }\n\n private ApplyCircularLayout(): void {\n const cx = this.GetContainerWidth() / 2 || 400;\n const cy = this.GetContainerHeight() / 2 || 250;\n const r = Math.min(cx, cy) * 0.7 || 160;\n const count = this.Nodes.length || 1;\n\n this.Nodes.forEach((node, idx) => {\n const angle = (idx / count) * 2 * Math.PI;\n node.x = cx + r * Math.cos(angle);\n node.y = cy + r * Math.sin(angle);\n node.X = node.x;\n node.Y = node.y;\n });\n }\n\n // ── Public Programmatic Methods ───────────────────────────────────\n public ZoomIn(): void {\n this.Scale = Math.min(this.Scale * 1.2, 3.0);\n this.EmitViewport();\n }\n\n public ZoomOut(): void {\n this.Scale = Math.max(this.Scale / 1.2, 0.3);\n this.EmitViewport();\n }\n\n public FitToView(): void {\n this.AutoFitToView(40);\n }\n\n public AutoFitToView(padding = 40): void {\n if (!this.Nodes || this.Nodes.length === 0) return;\n\n const width = this.GetContainerWidth() || 800;\n const height = this.GetContainerHeight() || 420;\n\n let minX = Infinity, maxX = -Infinity, minY = Infinity, maxY = -Infinity;\n for (const n of this.Nodes) {\n const nx = n.x ?? n.X ?? 0;\n const ny = n.y ?? n.Y ?? 0;\n const r = (n.Radius || 26) + 20; // include badge & labels\n if (nx - r < minX) minX = nx - r;\n if (nx + r > maxX) maxX = nx + r;\n if (ny - r < minY) minY = ny - r;\n if (ny + r > maxY) maxY = ny + r;\n }\n\n if (!isFinite(minX) || !isFinite(maxX) || !isFinite(minY) || !isFinite(maxY)) return;\n\n const bboxW = Math.max(maxX - minX, 100);\n const bboxH = Math.max(maxY - minY, 100);\n\n const scaleX = (width - padding * 2) / bboxW;\n const scaleY = (height - padding * 2) / bboxH;\n const targetScale = Math.min(Math.max(Math.min(scaleX, scaleY), 0.4), 1.25);\n\n this.Scale = targetScale;\n this.PanX = (width - (minX + maxX) * this.Scale) / 2;\n this.PanY = (height - (minY + maxY) * this.Scale) / 2;\n\n this.EmitViewport();\n this.cdr.markForCheck();\n }\n\n public Rearrange(): void {\n this.InitializePositions();\n this.SimulatePhysics();\n }\n\n public SetLayoutMode(mode: GraphLayoutMode): void {\n const beforeEvent = new BeforeLayoutChangeEventArgs(mode, this.LayoutMode);\n this.BeforeLayoutChange.emit(beforeEvent);\n if (beforeEvent.Cancel) return;\n\n const prev = this.LayoutMode;\n this.LayoutMode = mode;\n this.SimulatePhysics();\n this.LayoutChanged.emit(new LayoutChangedEventArgs(mode, prev));\n }\n\n public SelectNode(id: string): void {\n const node = this.Nodes.find(n => UUIDsEqual(n.ID, id));\n if (node) this.OnNodeClick(node, new MouseEvent('click'));\n }\n\n public ClearSelection(): void {\n this.SelectedNode = null;\n this.SelectedEdge = null;\n this.cdr.markForCheck();\n }\n\n public SearchNodes(query: string): void {\n this.SearchQuery = query;\n this.ApplyFilters();\n }\n\n public ExpandHops(nodeId: string, depth: number): void {\n const node = this.Nodes.find(n => UUIDsEqual(n.ID, nodeId));\n if (!node) return;\n\n const beforeEvent = new BeforeHopExpandEventArgs(node, (node.HopDistance || 0) + depth, node.HopDistance || 0);\n this.BeforeHopExpand.emit(beforeEvent);\n if (beforeEvent.Cancel) return;\n\n // Fire after event for host listener to fetch incremental relations\n this.HopExpanded.emit(new HopExpandedEventArgs(node, [], [], (node.HopDistance || 0) + depth));\n }\n\n // ── Event Handlers ────────────────────────────────────────────────\n public OnNodeClick(node: GraphNode, event: MouseEvent): void {\n event.stopPropagation();\n const beforeEvent = new BeforeNodeSelectEventArgs(node, this.SelectedNode);\n this.BeforeNodeSelect.emit(beforeEvent);\n if (beforeEvent.Cancel) return;\n\n const prev = this.SelectedNode;\n this.SelectedNode = node;\n this.SelectedEdge = null;\n this.NodeSelected.emit(new NodeSelectedEventArgs(node, prev));\n this.cdr.markForCheck();\n }\n\n public OnEdgeClick(edge: GraphEdge, event: MouseEvent): void {\n event.stopPropagation();\n const src = this.Nodes.find(n => UUIDsEqual(n.ID, edge.SourceID)) || null;\n const tgt = this.Nodes.find(n => UUIDsEqual(n.ID, edge.TargetID)) || null;\n\n const beforeEvent = new BeforeEdgeSelectEventArgs(edge, src, tgt);\n this.BeforeEdgeSelect.emit(beforeEvent);\n if (beforeEvent.Cancel) return;\n\n this.SelectedEdge = edge;\n this.EdgeSelected.emit(new EdgeSelectedEventArgs(edge, src, tgt));\n this.cdr.markForCheck();\n }\n\n public NavigateToEntity(node: GraphNode): void {\n // Focal-node dblclick must not navigate away from the record this\n // graph is illustrating — the inspector already hides the navigate\n // button for the same reason.\n if (this.IsFocalNode(node)) {\n return;\n }\n const rawId = this.stripCategoryPrefix(String(node.Data?.['ID'] || node.ID));\n const entityName = String(node.Data?.['EntityName'] || (node.Category === 'person' ? 'MJ_BizApps_Common: People' : 'MJ_BizApps_Common: Organizations'));\n const beforeEvent = new BeforeNodeNavigateEventArgs(node, entityName, rawId);\n this.BeforeNodeNavigate.emit(beforeEvent);\n if (beforeEvent.Cancel) return;\n\n // Hosts navigate. This widget is L1 and must not import Explorer's\n // NavigationService — emit the intent and let the surface open the record.\n this.NodeNavigated.emit(new NodeNavigatedEventArgs(node, entityName, rawId));\n }\n\n // ── Mouse Drag & Pan Handlers ─────────────────────────────────────\n public OnCanvasMouseDown(event: MouseEvent): void {\n if (event.target === this.CanvasRef.nativeElement || (event.target as HTMLElement).tagName === 'svg') {\n this.IsPanning = true;\n this.panStartX = event.clientX - this.PanX;\n this.panStartY = event.clientY - this.PanY;\n }\n }\n\n public OnCanvasMouseMove(event: MouseEvent): void {\n if (this.IsPanning) {\n this.PanX = event.clientX - this.panStartX;\n this.PanY = event.clientY - this.panStartY;\n this.EmitViewport();\n this.cdr.markForCheck();\n } else if (this.draggedNode) {\n const coords = this.GetCanvasRelativeCoords(event);\n this.draggedNode.fx = coords.x;\n this.draggedNode.fy = coords.y;\n this.draggedNode.x = coords.x;\n this.draggedNode.y = coords.y;\n this.draggedNode.X = coords.x;\n this.draggedNode.Y = coords.y;\n this.cdr.markForCheck();\n }\n }\n\n public OnCanvasMouseUp(_event: MouseEvent): void {\n this.IsPanning = false;\n if (this.draggedNode) {\n this.draggedNode.fx = null;\n this.draggedNode.fy = null;\n this.draggedNode = null;\n if (this.simulation) {\n this.simulation.alphaTarget(0);\n }\n }\n }\n\n public OnCanvasWheel(event: WheelEvent): void {\n event.preventDefault();\n const delta = event.deltaY > 0 ? 0.9 : 1.1;\n this.Scale = Math.min(Math.max(this.Scale * delta, 0.3), 3.0);\n this.EmitViewport();\n this.cdr.markForCheck();\n }\n\n public OnNodeMouseDown(node: GraphNode, event: MouseEvent): void {\n event.stopPropagation();\n this.draggedNode = node;\n node.fx = node.x ?? node.X;\n node.fy = node.y ?? node.Y;\n if (this.simulation) {\n this.simulation.alphaTarget(0.3).restart();\n }\n }\n\n private EmitViewport(): void {\n this.ViewportTransform.emit(new ViewportTransformEventArgs({ Scale: this.Scale, PanX: this.PanX, PanY: this.PanY }));\n this.cdr.markForCheck();\n }\n\n private GetCanvasRelativeCoords(event: MouseEvent): { x: number; y: number } {\n const canvas = this.CanvasRef?.nativeElement;\n if (!canvas) {\n return {\n x: (event.clientX - this.PanX) / this.Scale,\n y: (event.clientY - this.PanY) / this.Scale\n };\n }\n const rect = canvas.getBoundingClientRect();\n const mouseX = event.clientX - rect.left;\n const mouseY = event.clientY - rect.top;\n return {\n x: (mouseX - this.PanX) / this.Scale,\n y: (mouseY - this.PanY) / this.Scale\n };\n }\n\n private GetContainerWidth(): number {\n return this.CanvasRef?.nativeElement?.clientWidth || this.WrapperRef?.nativeElement?.clientWidth || 800;\n }\n\n private GetContainerHeight(): number {\n return this.CanvasRef?.nativeElement?.clientHeight || this.WrapperRef?.nativeElement?.clientHeight || 420;\n }\n\n // ── Helpers ───────────────────────────────────────────────────────\n public ApplyFilters(): void {\n const q = this.SearchQuery.trim().toLowerCase();\n this.FilteredNodes = this.Nodes.filter(n => {\n return !q || n.Label.toLowerCase().includes(q) || (n.Sublabel && n.Sublabel.toLowerCase().includes(q));\n });\n this.cdr.markForCheck();\n }\n\n public GetNodeX(id: string): number {\n const node = this.Nodes.find(n => UUIDsEqual(n.ID, id));\n return node ? (node.X ?? node.x ?? 0) : 0;\n }\n\n public GetNodeY(id: string): number {\n const node = this.Nodes.find(n => UUIDsEqual(n.ID, id));\n return node ? (node.Y ?? node.y ?? 0) : 0;\n }\n\n public GetCategoryConfig(category?: string): GraphCategoryConfig {\n const key = String(category || '').toLowerCase();\n const found = this.Categories?.find(c => c.Category.toLowerCase() === key);\n if (found) return found;\n\n const builtin = DEFAULT_GRAPH_CATEGORIES.find(c => c.Category.toLowerCase() === key);\n if (builtin) return builtin;\n\n // Deterministic palette hash for arbitrary consumer-defined categories\n const hash = Math.abs(key.split('').reduce((acc, ch) => ((acc << 5) - acc) + ch.charCodeAt(0), 0));\n const fallbackColor = DYNAMIC_CATEGORY_PALETTE[hash % DYNAMIC_CATEGORY_PALETTE.length];\n const formattedLabel = category ? category.charAt(0).toUpperCase() + category.slice(1) : 'Item';\n return {\n Category: category || 'custom',\n Label: formattedLabel,\n Color: fallbackColor,\n IconClass: 'fa-solid fa-circle-dot'\n };\n }\n\n public get ActiveCategories(): GraphCategoryConfig[] {\n const present = new Set<string>();\n for (const n of this.Nodes) {\n if (n.Category) present.add(n.Category.toLowerCase());\n }\n const result: GraphCategoryConfig[] = [];\n for (const catKey of present) {\n result.push(this.GetCategoryConfig(catKey));\n }\n return result;\n }\n\n public GetCategoryLabel(category?: string): string {\n return this.GetCategoryConfig(category).Label;\n }\n\n public GetNodeColor(node: GraphNode): string {\n return node.Color ?? this.GetCategoryConfig(node.Category).Color;\n }\n\n public GetNodeIcon(node: GraphNode): string {\n return node.IconClass ?? this.GetCategoryConfig(node.Category).IconClass ?? 'fa-solid fa-circle-dot';\n }\n\n public GetNodeEdgeCount(id: string): number {\n return this.Edges.filter(e => UUIDsEqual(e.SourceID, id) || UUIDsEqual(e.TargetID, id)).length;\n }\n\n public IsEdgeHighlighted(edge: GraphEdge): boolean {\n return UUIDsEqual(this.SelectedEdge?.ID, edge.ID) ||\n UUIDsEqual(this.SelectedNode?.ID, edge.SourceID) ||\n UUIDsEqual(this.SelectedNode?.ID, edge.TargetID);\n }\n\n /**\n * Whether this node is the selected one. Exists as a method because the template cannot call\n * an imported function directly, and the comparison must go through UUIDsEqual rather than ===.\n */\n public IsNodeSelected(node: GraphNode): boolean {\n return UUIDsEqual(this.SelectedNode?.ID, node.ID);\n }\n\n public TruncateLabel(text: string, maxLen: number): string {\n if (!text) return '';\n return text.length > maxLen ? text.substring(0, maxLen - 1) + '…' : text;\n }\n\n public IsFocalNode(node: GraphNode): boolean {\n if (!node || !this.FocalNodeId) return false;\n const focalClean = this.stripCategoryPrefix(this.FocalNodeId).toLowerCase();\n const nodeClean = this.stripCategoryPrefix(node.ID).toLowerCase();\n const dataClean = node.Data?.['ID'] ? String(node.Data['ID']).toLowerCase() : '';\n return UUIDsEqual(node.ID, this.FocalNodeId) || nodeClean === focalClean || dataClean === focalClean;\n }\n\n /**\n * Hosts prefix node IDs with `{category}:`. Categories are dynamic\n * (`organization`, `asset`, `group`, plus caller keys), so strip any\n * known-category prefix rather than a hardcoded subset.\n */\n private stripCategoryPrefix(id: string): string {\n const idx = id.indexOf(':');\n if (idx <= 0) {\n return id;\n }\n const prefix = id.slice(0, idx).toLowerCase();\n const known =\n this.Categories?.some(c => c.Category.toLowerCase() === prefix) ||\n DEFAULT_GRAPH_CATEGORIES.some(c => c.Category.toLowerCase() === prefix);\n return known ? id.slice(idx + 1) : id;\n }\n}\n"]}
1
+ {"version":3,"file":"graph-view.component.js","sourceRoot":"","sources":["../../../src/lib/components/graph-view.component.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n Component,\n Input,\n Output,\n EventEmitter,\n OnInit,\n OnChanges,\n OnDestroy,\n SimpleChanges,\n ChangeDetectionStrategy,\n ChangeDetectorRef,\n ElementRef,\n ViewChild,\n inject\n} from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { FormsModule } from '@angular/forms';\nimport { NormalizeUUID, UUIDsEqual } from '@memberjunction/global';\nimport * as d3 from 'd3';\nimport type {\n GraphNode,\n GraphEdge,\n GraphLayoutMode,\n GraphNodeCategory,\n GraphCategoryConfig,\n GraphViewportTransform,\n GraphPhysicsConfig\n} from '../models/graph-models';\nimport {\n BeforeNodeSelectEventArgs,\n NodeSelectedEventArgs,\n BeforeEdgeSelectEventArgs,\n EdgeSelectedEventArgs,\n BeforeHopExpandEventArgs,\n HopExpandedEventArgs,\n BeforeLayoutChangeEventArgs,\n LayoutChangedEventArgs,\n BeforeNodeNavigateEventArgs,\n NodeNavigatedEventArgs,\n ViewportTransformEventArgs\n} from '../events/graph-events';\n\nexport const DEFAULT_GRAPH_CATEGORIES: GraphCategoryConfig[] = [\n { Category: 'person', Label: 'Person', Color: '#10b981', IconClass: 'fa-solid fa-user' },\n { Category: 'organization', Label: 'Organization', Color: '#38bdf8', IconClass: 'fa-solid fa-building' },\n { Category: 'committee', Label: 'Committee', Color: '#8b5cf6', IconClass: 'fa-solid fa-landmark' },\n { Category: 'account', Label: 'Holding / Account', Color: '#f59e0b', IconClass: 'fa-solid fa-building-flag' },\n { Category: 'asset', Label: 'Asset', Color: '#ec4899', IconClass: 'fa-solid fa-gem' },\n { Category: 'group', Label: 'Group', Color: '#06b6d4', IconClass: 'fa-solid fa-users' },\n { Category: 'custom', Label: 'Custom', Color: '#64748b', IconClass: 'fa-solid fa-circle-nodes' }\n];\n\nconst DYNAMIC_CATEGORY_PALETTE = [\n '#10b981', '#38bdf8', '#8b5cf6', '#f59e0b', '#ec4899',\n '#06b6d4', '#84cc16', '#f43f5e', '#a855f7', '#14b8a6'\n];\n\nconst GRAPH_VIEW_CSS = `\n:host {\n display: block;\n width: 100%;\n height: 100%;\n position: relative;\n overflow: hidden;\n background: var(--mj-bg-surface-sunken, #0b1220);\n border-radius: var(--mj-radius-lg, 12px);\n border: 1px solid var(--mj-border-default, #223254);\n user-select: none;\n}\n\n.mj-graph-wrapper {\n width: 100%;\n height: 100%;\n position: relative;\n overflow: hidden;\n display: flex;\n flex-direction: column;\n}\n\n.mj-graph-svg-canvas {\n width: 100%;\n height: 100%;\n cursor: grab;\n}\n\n.mj-graph-svg-canvas.is-panning {\n cursor: grabbing;\n}\n\n/* Floating Toolbar */\n.mj-graph-toolbar {\n position: absolute;\n top: 14px;\n left: 14px;\n z-index: 20;\n display: flex;\n align-items: center;\n gap: 8px;\n background: rgba(20, 31, 54, 0.88);\n backdrop-filter: blur(10px);\n border: 1px solid var(--mj-border-default, #223254);\n padding: 6px 12px;\n border-radius: var(--mj-radius-lg, 10px);\n box-shadow: 0 8px 24px rgba(0, 0, 0, 0.4);\n}\n\n.mj-graph-tool-btn {\n background: var(--mj-bg-surface-elevated, #1a2744);\n border: 1px solid var(--mj-border-default, #223254);\n color: var(--mj-text-primary, #f8fafc);\n border-radius: 6px;\n padding: 5px 10px;\n font-size: 11.5px;\n font-weight: 600;\n cursor: pointer;\n display: flex;\n align-items: center;\n gap: 6px;\n transition: all 0.15s ease;\n}\n\n.mj-graph-tool-btn:hover {\n border-color: var(--mj-brand-primary, #38bdf8);\n background: var(--mj-border-hover, #334876);\n}\n\n.mj-graph-tool-btn.active {\n background: var(--mj-brand-primary, #38bdf8);\n color: #090e1a;\n border-color: var(--mj-brand-primary, #38bdf8);\n}\n\n.mj-graph-separator {\n width: 1px;\n height: 18px;\n background: var(--mj-border-default, #223254);\n}\n\n.mj-graph-search-input {\n background: var(--mj-bg-surface-sunken, #090e1a);\n border: 1px solid var(--mj-border-default, #223254);\n border-radius: 6px;\n color: var(--mj-text-primary, #f8fafc);\n padding: 4px 8px 4px 24px;\n font-size: 11.5px;\n width: 150px;\n}\n\n.mj-graph-search-input:focus {\n outline: none;\n border-color: var(--mj-brand-primary, #38bdf8);\n width: 190px;\n}\n\n/* Floating Legend */\n.mj-graph-legend {\n position: absolute;\n bottom: 14px;\n left: 14px;\n z-index: 20;\n display: flex;\n align-items: center;\n gap: 12px;\n background: rgba(20, 31, 54, 0.88);\n backdrop-filter: blur(10px);\n border: 1px solid var(--mj-border-default, #223254);\n padding: 6px 14px;\n border-radius: var(--mj-radius-lg, 10px);\n font-size: 11.5px;\n color: var(--mj-text-secondary, #94a3b8);\n}\n\n.mj-graph-legend-item {\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n.mj-graph-legend-dot {\n width: 10px;\n height: 10px;\n border-radius: 50%;\n}\n\n/* Inspector Drawer */\n.mj-graph-inspector {\n position: absolute;\n top: 14px;\n right: 14px;\n width: 300px;\n max-height: calc(100% - 28px);\n background: rgba(20, 31, 54, 0.95);\n backdrop-filter: blur(14px);\n border: 1px solid var(--mj-border-default, #223254);\n border-radius: var(--mj-radius-lg, 12px);\n padding: 16px;\n display: flex;\n flex-direction: column;\n gap: 12px;\n z-index: 25;\n box-shadow: 0 10px 30px rgba(0, 0, 0, 0.5);\n overflow-y: auto;\n scrollbar-width: thin;\n animation: mjGraphSlide 0.2s ease;\n}\n\n.mj-graph-inspector-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n}\n\n.mj-graph-inspector-title {\n font-size: 11px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.05em;\n color: var(--mj-text-muted, #64748b);\n}\n\n.mj-graph-inspector-close {\n background: none;\n border: none;\n color: var(--mj-text-muted, #64748b);\n cursor: pointer;\n font-size: 14px;\n}\n\n.mj-graph-inspector-card {\n display: flex;\n align-items: center;\n gap: 12px;\n background: var(--mj-bg-surface, #111a2e);\n border: 1px solid var(--mj-border-default, #223254);\n border-radius: 8px;\n padding: 10px 12px;\n}\n\n.mj-graph-inspector-avatar {\n width: 40px;\n height: 40px;\n border-radius: 8px;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 16px;\n color: #fff;\n flex-shrink: 0;\n}\n\n.mj-graph-inspector-actions {\n display: flex;\n flex-direction: column;\n gap: 6px;\n margin-top: 4px;\n}\n\n/* SVG Rendering Elements */\n.mj-edge-path {\n stroke: var(--mj-border-hover, #2d416b);\n stroke-width: 2;\n fill: none;\n transition: stroke 0.2s ease;\n}\n\n.mj-edge-path.is-highlighted {\n stroke: var(--mj-brand-primary, #38bdf8);\n stroke-width: 3;\n}\n\n.mj-edge-text {\n font-size: 10px;\n font-weight: 500;\n fill: var(--mj-text-muted, #64748b);\n text-anchor: middle;\n pointer-events: none;\n paint-order: stroke;\n stroke: var(--mj-bg-surface-sunken, #0b1220);\n stroke-width: 3px;\n stroke-linecap: butt;\n stroke-linejoin: miter;\n}\n\n.mj-node-group {\n cursor: pointer;\n transition: transform 0.1s ease;\n}\n\n.mj-node-group:hover .mj-node-circle {\n filter: drop-shadow(0 0 10px var(--mj-brand-primary, #38bdf8));\n}\n\n.mj-node-circle {\n transition: all 0.2s ease;\n}\n\n.mj-node-label {\n font-size: 11px;\n font-weight: 700;\n fill: var(--mj-text-primary, #f8fafc);\n text-anchor: middle;\n pointer-events: none;\n}\n\n.mj-node-sublabel {\n font-size: 9.5px;\n font-weight: 500;\n fill: var(--mj-text-secondary, #94a3b8);\n text-anchor: middle;\n pointer-events: none;\n}\n\n@keyframes mjGraphSlide {\n from { opacity: 0; transform: translateX(20px); }\n to { opacity: 1; transform: translateX(0); }\n}\n`;\n\n/**\n * `<mj-graph-view>` — Interactive network and entity relationship graph visualization.\n *\n * Supports force-directed dynamic layout, multi-category entity badges, hop-expansion,\n * zoom/pan controls, inspector drawer, search filters, and cancelable Before/After event pairs.\n */\n@Component({\n selector: 'mj-graph-view',\n standalone: true,\n imports: [CommonModule, FormsModule],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <div class=\"mj-graph-wrapper\" #wrapper>\n <!-- 1. Floating Action Toolbar -->\n @if (ShowToolbar) {\n <div class=\"mj-graph-toolbar\">\n <span style=\"font-size: 12px; font-weight: 700; color: #fff; display: flex; align-items: center; gap: 6px;\">\n <i class=\"fa-solid fa-circle-nodes\" style=\"color: var(--mj-brand-primary);\"></i>\n Network Graph\n </span>\n\n <div class=\"mj-graph-separator\"></div>\n\n <!-- Layout Mode Selector -->\n <button\n type=\"button\"\n class=\"mj-graph-tool-btn\"\n [class.active]=\"LayoutMode === 'force'\"\n (click)=\"SetLayoutMode('force')\"\n title=\"Force-Directed Physics\">\n <i class=\"fa-solid fa-atom\"></i> Force\n </button>\n <button\n type=\"button\"\n class=\"mj-graph-tool-btn\"\n [class.active]=\"LayoutMode === 'circular'\"\n (click)=\"SetLayoutMode('circular')\"\n title=\"Circular Layout\">\n <i class=\"fa-solid fa-circle-notch\"></i> Circular\n </button>\n\n <div class=\"mj-graph-separator\"></div>\n\n <!-- Zoom Controls -->\n <button type=\"button\" class=\"mj-graph-tool-btn\" (click)=\"ZoomIn()\" title=\"Zoom In\">\n <i class=\"fa-solid fa-magnifying-glass-plus\"></i>\n </button>\n <button type=\"button\" class=\"mj-graph-tool-btn\" (click)=\"ZoomOut()\" title=\"Zoom Out\">\n <i class=\"fa-solid fa-magnifying-glass-minus\"></i>\n </button>\n <button type=\"button\" class=\"mj-graph-tool-btn\" (click)=\"FitToView()\" title=\"Fit View\">\n <i class=\"fa-solid fa-expand\"></i>\n </button>\n <button type=\"button\" class=\"mj-graph-tool-btn\" (click)=\"Rearrange()\" title=\"Re-simulate Physics\">\n <i class=\"fa-solid fa-arrows-rotate\"></i>\n </button>\n\n @if (Searchable) {\n <div class=\"mj-graph-separator\"></div>\n <div style=\"position: relative;\">\n <i class=\"fa-solid fa-magnifying-glass\" style=\"position: absolute; left: 8px; top: 50%; transform: translateY(-50%); font-size: 10px; color: var(--mj-text-muted);\"></i>\n <input\n class=\"mj-graph-search-input\"\n [(ngModel)]=\"SearchQuery\"\n (ngModelChange)=\"SearchNodes($event)\"\n placeholder=\"Search graph nodes...\" />\n </div>\n }\n </div>\n }\n\n <!-- 2. Floating Dynamic Category Legend -->\n @if (ShowLegend && ActiveCategories.length > 0) {\n <div class=\"mj-graph-legend\">\n @for (cat of ActiveCategories; track cat.Category) {\n <div class=\"mj-graph-legend-item\">\n <div class=\"mj-graph-legend-dot\" [style.background]=\"cat.Color\"></div>\n {{ cat.Label }}\n </div>\n }\n </div>\n }\n\n <!-- 3. Selected Node Inspector Drawer -->\n @if (ShowInspector && SelectedNode) {\n <div class=\"mj-graph-inspector\">\n <div class=\"mj-graph-inspector-header\">\n <span class=\"mj-graph-inspector-title\">Node Inspector</span>\n <button class=\"mj-graph-inspector-close\" type=\"button\" (click)=\"ClearSelection()\">\n <i class=\"fa-solid fa-xmark\"></i>\n </button>\n </div>\n\n <div class=\"mj-graph-inspector-card\">\n <div class=\"mj-graph-inspector-avatar\" [style.background]=\"GetNodeColor(SelectedNode)\">\n <i [class]=\"GetNodeIcon(SelectedNode)\"></i>\n </div>\n <div style=\"overflow: hidden; flex: 1;\">\n <div style=\"font-size: 13px; font-weight: 700; color: #fff; text-overflow: ellipsis; overflow: hidden; white-space: nowrap;\">\n {{ SelectedNode.Label }}\n </div>\n <div style=\"display: flex; align-items: center; gap: 6px; margin-top: 3px;\">\n <span style=\"font-size: 11px; color: var(--mj-text-secondary);\">\n {{ SelectedNode.Sublabel || SelectedNode.Category }}\n </span>\n @if (IsFocalNode(SelectedNode)) {\n <span style=\"font-size: 10px; padding: 1px 6px; border-radius: 9999px; background: rgba(56, 189, 248, 0.15); color: #38bdf8; font-weight: 600; border: 1px solid rgba(56, 189, 248, 0.3);\">Current Record</span>\n }\n </div>\n </div>\n </div>\n\n <div style=\"font-size: 11.5px; color: var(--mj-text-secondary); line-height: 1.45;\">\n Direct Connected Edges: <strong>{{ GetNodeEdgeCount(SelectedNode.ID) }}</strong>\n </div>\n\n <div class=\"mj-graph-inspector-actions\">\n @if (!IsFocalNode(SelectedNode)) {\n <button\n type=\"button\"\n class=\"mj-graph-tool-btn active\"\n style=\"justify-content: center; width: 100%;\"\n (click)=\"NavigateToEntity(SelectedNode)\">\n <i class=\"fa-solid fa-arrow-up-right-from-square\"></i> Open Entity Form\n </button>\n }\n <button\n type=\"button\"\n class=\"mj-graph-tool-btn\"\n style=\"justify-content: center; width: 100%;\"\n (click)=\"ExpandHops(SelectedNode.ID, 1)\">\n <i class=\"fa-solid fa-circle-nodes\"></i> Expand 1-Hop Neighbors\n </button>\n </div>\n </div>\n }\n\n <!-- 4. Interactive SVG Graph Canvas -->\n <svg\n #svgCanvas\n class=\"mj-graph-svg-canvas\"\n [class.is-panning]=\"IsPanning\"\n (mousedown)=\"OnCanvasMouseDown($event)\"\n (mousemove)=\"OnCanvasMouseMove($event)\"\n (mouseup)=\"OnCanvasMouseUp($event)\"\n (mouseleave)=\"OnCanvasMouseUp($event)\"\n (wheel)=\"OnCanvasWheel($event)\">\n\n <g [attr.transform]=\"'translate(' + PanX + ',' + PanY + ') scale(' + Scale + ')'\">\n <!-- Edges Layer -->\n @for (edge of Edges; track edge.ID) {\n <g>\n <line\n class=\"mj-edge-path\"\n [class.is-highlighted]=\"IsEdgeHighlighted(edge)\"\n [attr.x1]=\"GetNodeX(edge.SourceID)\"\n [attr.y1]=\"GetNodeY(edge.SourceID)\"\n [attr.x2]=\"GetNodeX(edge.TargetID)\"\n [attr.y2]=\"GetNodeY(edge.TargetID)\"\n (click)=\"OnEdgeClick(edge, $event)\">\n </line>\n <text\n class=\"mj-edge-text\"\n [attr.x]=\"(GetNodeX(edge.SourceID) + GetNodeX(edge.TargetID)) / 2\"\n [attr.y]=\"(GetNodeY(edge.SourceID) + GetNodeY(edge.TargetID)) / 2 - 4\">\n {{ edge.Label }}\n </text>\n </g>\n }\n\n <!-- Nodes Layer -->\n @for (node of FilteredNodes; track node.ID) {\n <g\n class=\"mj-node-group\"\n [attr.transform]=\"'translate(' + (node.X || 0) + ',' + (node.Y || 0) + ')'\"\n (mousedown)=\"OnNodeMouseDown(node, $event)\"\n (click)=\"OnNodeClick(node, $event)\"\n (dblclick)=\"NavigateToEntity(node)\">\n\n <!-- Outer Selection / Focal Halo -->\n @if (IsNodeSelected(node)) {\n <circle r=\"36\" fill=\"rgba(56, 189, 248, 0.2)\" stroke=\"#38bdf8\" stroke-width=\"2\"></circle>\n } @else if (IsFocalNode(node)) {\n <circle r=\"34\" fill=\"none\" stroke=\"rgba(56, 189, 248, 0.45)\" stroke-width=\"2\" stroke-dasharray=\"4 3\"></circle>\n }\n\n <!-- Node Body Circle -->\n <circle\n class=\"mj-node-circle\"\n [attr.r]=\"node.Radius || 26\"\n fill=\"#141f36\"\n [attr.stroke]=\"GetNodeColor(node)\"\n stroke-width=\"3\">\n </circle>\n\n <!-- Node Icon Center -->\n <circle [attr.r]=\"(node.Radius || 26) - 8\" [attr.fill]=\"GetNodeColor(node)\"></circle>\n\n <!-- Labels -->\n <text class=\"mj-node-label\" [attr.y]=\"(node.Radius || 26) + 16\">\n {{ TruncateLabel(node.Label, 18) }}\n </text>\n @if (node.Sublabel) {\n <text class=\"mj-node-sublabel\" [attr.y]=\"(node.Radius || 26) + 28\">\n {{ TruncateLabel(node.Sublabel, 20) }}\n </text>\n }\n </g>\n }\n </g>\n </svg>\n </div>\n `,\n styles: [GRAPH_VIEW_CSS]\n})\nexport class GraphViewComponent implements OnInit, OnChanges, OnDestroy {\n private cdr = inject(ChangeDetectorRef);\n\n @ViewChild('wrapper', { static: true }) public WrapperRef!: ElementRef<HTMLDivElement>;\n @ViewChild('svgCanvas', { static: true }) public CanvasRef!: ElementRef<SVGSVGElement>;\n\n // ── Inputs ────────────────────────────────────────────────────────\n @Input() public Nodes: GraphNode[] = [];\n @Input() public Edges: GraphEdge[] = [];\n @Input() public Categories: GraphCategoryConfig[] = DEFAULT_GRAPH_CATEGORIES;\n @Input() public LayoutMode: GraphLayoutMode = 'force';\n @Input() public MaxHopDistance = 2;\n @Input() public SelectedNodeId?: string;\n @Input() public FocalNodeId?: string;\n @Input() public AutoOpenInspector = false;\n @Input() public ShowToolbar = true;\n @Input() public ShowLegend = true;\n @Input() public ShowInspector = true;\n @Input() public Searchable = true;\n @Input() public AutoFitOnLoad = true;\n @Input() public Physics: GraphPhysicsConfig = {\n Repulsion: -500,\n LinkDistance: 130,\n Gravity: 0.05,\n Damping: 0.88,\n MaxIterations: 200\n };\n\n // ── Cancelable Before/After Outputs ────────────────────────────────\n @Output() public BeforeNodeSelect = new EventEmitter<BeforeNodeSelectEventArgs>();\n @Output() public NodeSelected = new EventEmitter<NodeSelectedEventArgs>();\n\n @Output() public BeforeEdgeSelect = new EventEmitter<BeforeEdgeSelectEventArgs>();\n @Output() public EdgeSelected = new EventEmitter<EdgeSelectedEventArgs>();\n\n @Output() public BeforeHopExpand = new EventEmitter<BeforeHopExpandEventArgs>();\n @Output() public HopExpanded = new EventEmitter<HopExpandedEventArgs>();\n\n @Output() public BeforeLayoutChange = new EventEmitter<BeforeLayoutChangeEventArgs>();\n @Output() public LayoutChanged = new EventEmitter<LayoutChangedEventArgs>();\n\n @Output() public BeforeNodeNavigate = new EventEmitter<BeforeNodeNavigateEventArgs>();\n @Output() public NodeNavigated = new EventEmitter<NodeNavigatedEventArgs>();\n\n @Output() public ViewportTransform = new EventEmitter<ViewportTransformEventArgs>();\n\n // ── Internal State ────────────────────────────────────────────────\n public FilteredNodes: GraphNode[] = [];\n public SelectedNode: GraphNode | null = null;\n public SelectedEdge: GraphEdge | null = null;\n public SearchQuery = '';\n\n public Scale = 1.0;\n public PanX = 200;\n public PanY = 150;\n public IsPanning = false;\n private panStartX = 0;\n private panStartY = 0;\n\n private draggedNode: GraphNode | null = null;\n private simulation: d3.Simulation<GraphNode, d3.SimulationLinkDatum<GraphNode>> | null = null;\n\n public ngOnInit(): void {\n this.InitializePositions();\n this.ApplyFilters();\n this.SimulatePhysics();\n }\n\n public ngOnChanges(changes: SimpleChanges): void {\n if (changes['Nodes'] || changes['Edges']) {\n this.InitializePositions();\n this.ApplyFilters();\n this.SimulatePhysics();\n }\n if (changes['SelectedNodeId'] && this.SelectedNodeId) {\n const found = this.Nodes.find(n => UUIDsEqual(n.ID, this.SelectedNodeId));\n if (found && this.AutoOpenInspector) {\n this.SelectedNode = found;\n }\n }\n }\n\n public ngOnDestroy(): void {\n if (this.simulation) {\n this.simulation.stop();\n this.simulation = null;\n }\n }\n\n // ── Positioning & D3 Physics Engine ──────────────────────────────────\n private InitializePositions(): void {\n const cx = this.GetContainerWidth() / 2 || 400;\n const cy = this.GetContainerHeight() / 2 || 250;\n const count = this.Nodes.length || 1;\n\n this.Nodes.forEach((node, idx) => {\n if (node.x === undefined || node.y === undefined) {\n if (node.X !== undefined && node.Y !== undefined) {\n node.x = node.X;\n node.y = node.Y;\n } else {\n const angle = (idx / count) * 2 * Math.PI;\n const r = 100 + Math.random() * 60;\n node.x = cx + r * Math.cos(angle);\n node.y = cy + r * Math.sin(angle);\n node.X = node.x;\n node.Y = node.y;\n }\n node.vx = 0;\n node.vy = 0;\n node.VX = 0;\n node.VY = 0;\n }\n });\n }\n\n public SimulatePhysics(): void {\n if (this.LayoutMode === 'circular') {\n this.ApplyCircularLayout();\n if (this.AutoFitOnLoad) {\n this.AutoFitToView();\n }\n this.cdr.markForCheck();\n return;\n }\n\n if (this.simulation) {\n this.simulation.stop();\n this.simulation = null;\n }\n\n const cx = this.GetContainerWidth() / 2 || 400;\n const cy = this.GetContainerHeight() / 2 || 250;\n\n // Resolve endpoints to node objects so a case-skewed UUID or dangling\n // edge cannot throw \"node not found\" out of ngOnInit. Raw-string\n // .id(d => d.ID) compared with ===, which UUIDsEqual elsewhere\n // deliberately does not.\n const nodeById = new Map<string, GraphNode>();\n for (const node of this.Nodes) {\n const key = NormalizeUUID(node.ID);\n if (key) {\n nodeById.set(key, node);\n }\n }\n const links: d3.SimulationLinkDatum<GraphNode>[] = [];\n for (const edge of this.Edges) {\n const source = nodeById.get(NormalizeUUID(edge.SourceID));\n const target = nodeById.get(NormalizeUUID(edge.TargetID));\n if (source && target) {\n links.push({ source, target });\n }\n }\n\n this.simulation = d3.forceSimulation<GraphNode>(this.Nodes)\n .force('link', d3.forceLink<GraphNode, d3.SimulationLinkDatum<GraphNode>>(links)\n .distance(this.Physics.LinkDistance || 120))\n .force('charge', d3.forceManyBody<GraphNode>()\n .strength(this.Physics.Repulsion || -450)\n .distanceMax(700))\n .force('collide', d3.forceCollide<GraphNode>((d: GraphNode) => (d.Radius || 26) + 16).iterations(2))\n .force('center', d3.forceCenter<GraphNode>(cx, cy));\n\n // Headless Pre-Warming: run 80 ticks synchronously in memory so the SVG renders resting immediately\n this.simulation.stop();\n for (let i = 0; i < 90; ++i) {\n this.simulation.tick();\n }\n\n this.SyncCoordinates();\n\n // Auto-center & fit into view\n if (this.AutoFitOnLoad) {\n this.AutoFitToView();\n }\n\n // Attach live tick handler for interactive drag & drop\n this.simulation.on('tick', () => {\n this.SyncCoordinates();\n this.cdr.markForCheck();\n });\n\n this.cdr.markForCheck();\n }\n\n private SyncCoordinates(): void {\n for (const n of this.Nodes) {\n n.X = n.x;\n n.Y = n.y;\n n.VX = n.vx;\n n.VY = n.vy;\n }\n }\n\n private ApplyCircularLayout(): void {\n const cx = this.GetContainerWidth() / 2 || 400;\n const cy = this.GetContainerHeight() / 2 || 250;\n const r = Math.min(cx, cy) * 0.7 || 160;\n const count = this.Nodes.length || 1;\n\n this.Nodes.forEach((node, idx) => {\n const angle = (idx / count) * 2 * Math.PI;\n node.x = cx + r * Math.cos(angle);\n node.y = cy + r * Math.sin(angle);\n node.X = node.x;\n node.Y = node.y;\n });\n }\n\n // ── Public Programmatic Methods ───────────────────────────────────\n public ZoomIn(): void {\n this.Scale = Math.min(this.Scale * 1.2, 3.0);\n this.EmitViewport();\n }\n\n public ZoomOut(): void {\n this.Scale = Math.max(this.Scale / 1.2, 0.3);\n this.EmitViewport();\n }\n\n public FitToView(): void {\n this.AutoFitToView(40);\n }\n\n public AutoFitToView(padding = 40): void {\n if (!this.Nodes || this.Nodes.length === 0) return;\n\n const width = this.GetContainerWidth() || 800;\n const height = this.GetContainerHeight() || 420;\n\n let minX = Infinity, maxX = -Infinity, minY = Infinity, maxY = -Infinity;\n for (const n of this.Nodes) {\n const nx = n.x ?? n.X ?? 0;\n const ny = n.y ?? n.Y ?? 0;\n const r = (n.Radius || 26) + 20; // include badge & labels\n if (nx - r < minX) minX = nx - r;\n if (nx + r > maxX) maxX = nx + r;\n if (ny - r < minY) minY = ny - r;\n if (ny + r > maxY) maxY = ny + r;\n }\n\n if (!isFinite(minX) || !isFinite(maxX) || !isFinite(minY) || !isFinite(maxY)) return;\n\n const bboxW = Math.max(maxX - minX, 100);\n const bboxH = Math.max(maxY - minY, 100);\n\n const scaleX = (width - padding * 2) / bboxW;\n const scaleY = (height - padding * 2) / bboxH;\n const targetScale = Math.min(Math.max(Math.min(scaleX, scaleY), 0.4), 1.25);\n\n this.Scale = targetScale;\n this.PanX = (width - (minX + maxX) * this.Scale) / 2;\n this.PanY = (height - (minY + maxY) * this.Scale) / 2;\n\n this.EmitViewport();\n this.cdr.markForCheck();\n }\n\n public Rearrange(): void {\n this.InitializePositions();\n this.SimulatePhysics();\n }\n\n public SetLayoutMode(mode: GraphLayoutMode): void {\n const beforeEvent = new BeforeLayoutChangeEventArgs(mode, this.LayoutMode);\n this.BeforeLayoutChange.emit(beforeEvent);\n if (beforeEvent.Cancel) return;\n\n const prev = this.LayoutMode;\n this.LayoutMode = mode;\n this.SimulatePhysics();\n this.LayoutChanged.emit(new LayoutChangedEventArgs(mode, prev));\n }\n\n public SelectNode(id: string): void {\n const node = this.Nodes.find(n => UUIDsEqual(n.ID, id));\n if (node) this.OnNodeClick(node, new MouseEvent('click'));\n }\n\n public ClearSelection(): void {\n this.SelectedNode = null;\n this.SelectedEdge = null;\n this.cdr.markForCheck();\n }\n\n public SearchNodes(query: string): void {\n this.SearchQuery = query;\n this.ApplyFilters();\n }\n\n public ExpandHops(nodeId: string, depth: number): void {\n const node = this.Nodes.find(n => UUIDsEqual(n.ID, nodeId));\n if (!node) return;\n\n const beforeEvent = new BeforeHopExpandEventArgs(node, (node.HopDistance || 0) + depth, node.HopDistance || 0);\n this.BeforeHopExpand.emit(beforeEvent);\n if (beforeEvent.Cancel) return;\n\n // Fire after event for host listener to fetch incremental relations\n this.HopExpanded.emit(new HopExpandedEventArgs(node, [], [], (node.HopDistance || 0) + depth));\n }\n\n // ── Event Handlers ────────────────────────────────────────────────\n public OnNodeClick(node: GraphNode, event: MouseEvent): void {\n event.stopPropagation();\n const beforeEvent = new BeforeNodeSelectEventArgs(node, this.SelectedNode);\n this.BeforeNodeSelect.emit(beforeEvent);\n if (beforeEvent.Cancel) return;\n\n const prev = this.SelectedNode;\n this.SelectedNode = node;\n this.SelectedEdge = null;\n this.NodeSelected.emit(new NodeSelectedEventArgs(node, prev));\n this.cdr.markForCheck();\n }\n\n public OnEdgeClick(edge: GraphEdge, event: MouseEvent): void {\n event.stopPropagation();\n const src = this.Nodes.find(n => UUIDsEqual(n.ID, edge.SourceID)) || null;\n const tgt = this.Nodes.find(n => UUIDsEqual(n.ID, edge.TargetID)) || null;\n\n const beforeEvent = new BeforeEdgeSelectEventArgs(edge, src, tgt);\n this.BeforeEdgeSelect.emit(beforeEvent);\n if (beforeEvent.Cancel) return;\n\n this.SelectedEdge = edge;\n this.EdgeSelected.emit(new EdgeSelectedEventArgs(edge, src, tgt));\n this.cdr.markForCheck();\n }\n\n public NavigateToEntity(node: GraphNode): void {\n // Focal-node dblclick must not navigate away from the record this\n // graph is illustrating — the inspector already hides the navigate\n // button for the same reason.\n if (this.IsFocalNode(node)) {\n return;\n }\n const rawId = this.stripCategoryPrefix(String(node.Data?.['ID'] || node.ID));\n const entityName = String(node.Data?.['EntityName'] || (node.Category === 'person' ? 'MJ_BizApps_Common: People' : 'MJ_BizApps_Common: Organizations'));\n const beforeEvent = new BeforeNodeNavigateEventArgs(node, entityName, rawId);\n this.BeforeNodeNavigate.emit(beforeEvent);\n if (beforeEvent.Cancel) return;\n\n // Hosts navigate. This widget is L1 and must not import Explorer's\n // NavigationService — emit the intent and let the surface open the record.\n this.NodeNavigated.emit(new NodeNavigatedEventArgs(node, entityName, rawId));\n }\n\n // ── Mouse Drag & Pan Handlers ─────────────────────────────────────\n public OnCanvasMouseDown(event: MouseEvent): void {\n if (event.target === this.CanvasRef.nativeElement || (event.target as HTMLElement).tagName === 'svg') {\n this.IsPanning = true;\n this.panStartX = event.clientX - this.PanX;\n this.panStartY = event.clientY - this.PanY;\n }\n }\n\n public OnCanvasMouseMove(event: MouseEvent): void {\n if (this.IsPanning) {\n this.PanX = event.clientX - this.panStartX;\n this.PanY = event.clientY - this.panStartY;\n this.EmitViewport();\n this.cdr.markForCheck();\n } else if (this.draggedNode) {\n const coords = this.GetCanvasRelativeCoords(event);\n this.draggedNode.fx = coords.x;\n this.draggedNode.fy = coords.y;\n this.draggedNode.x = coords.x;\n this.draggedNode.y = coords.y;\n this.draggedNode.X = coords.x;\n this.draggedNode.Y = coords.y;\n this.cdr.markForCheck();\n }\n }\n\n public OnCanvasMouseUp(_event: MouseEvent): void {\n this.IsPanning = false;\n if (this.draggedNode) {\n this.draggedNode.fx = null;\n this.draggedNode.fy = null;\n this.draggedNode = null;\n if (this.simulation) {\n this.simulation.alphaTarget(0);\n }\n }\n }\n\n public OnCanvasWheel(event: WheelEvent): void {\n event.preventDefault();\n const delta = event.deltaY > 0 ? 0.9 : 1.1;\n this.Scale = Math.min(Math.max(this.Scale * delta, 0.3), 3.0);\n this.EmitViewport();\n this.cdr.markForCheck();\n }\n\n public OnNodeMouseDown(node: GraphNode, event: MouseEvent): void {\n event.stopPropagation();\n this.draggedNode = node;\n node.fx = node.x ?? node.X;\n node.fy = node.y ?? node.Y;\n if (this.simulation) {\n this.simulation.alphaTarget(0.3).restart();\n }\n }\n\n private EmitViewport(): void {\n this.ViewportTransform.emit(new ViewportTransformEventArgs({ Scale: this.Scale, PanX: this.PanX, PanY: this.PanY }));\n this.cdr.markForCheck();\n }\n\n private GetCanvasRelativeCoords(event: MouseEvent): { x: number; y: number } {\n const canvas = this.CanvasRef?.nativeElement;\n if (!canvas) {\n return {\n x: (event.clientX - this.PanX) / this.Scale,\n y: (event.clientY - this.PanY) / this.Scale\n };\n }\n const rect = canvas.getBoundingClientRect();\n const mouseX = event.clientX - rect.left;\n const mouseY = event.clientY - rect.top;\n return {\n x: (mouseX - this.PanX) / this.Scale,\n y: (mouseY - this.PanY) / this.Scale\n };\n }\n\n private GetContainerWidth(): number {\n return this.CanvasRef?.nativeElement?.clientWidth || this.WrapperRef?.nativeElement?.clientWidth || 800;\n }\n\n private GetContainerHeight(): number {\n return this.CanvasRef?.nativeElement?.clientHeight || this.WrapperRef?.nativeElement?.clientHeight || 420;\n }\n\n // ── Helpers ───────────────────────────────────────────────────────\n public ApplyFilters(): void {\n const q = this.SearchQuery.trim().toLowerCase();\n this.FilteredNodes = this.Nodes.filter(n => {\n return !q || n.Label.toLowerCase().includes(q) || (n.Sublabel && n.Sublabel.toLowerCase().includes(q));\n });\n this.cdr.markForCheck();\n }\n\n public GetNodeX(id: string): number {\n const node = this.Nodes.find(n => UUIDsEqual(n.ID, id));\n return node ? (node.X ?? node.x ?? 0) : 0;\n }\n\n public GetNodeY(id: string): number {\n const node = this.Nodes.find(n => UUIDsEqual(n.ID, id));\n return node ? (node.Y ?? node.y ?? 0) : 0;\n }\n\n public GetCategoryConfig(category?: string): GraphCategoryConfig {\n const key = String(category || '').toLowerCase();\n const found = this.Categories?.find(c => c.Category.toLowerCase() === key);\n if (found) return found;\n\n const builtin = DEFAULT_GRAPH_CATEGORIES.find(c => c.Category.toLowerCase() === key);\n if (builtin) return builtin;\n\n // Deterministic palette hash for arbitrary consumer-defined categories\n const hash = Math.abs(key.split('').reduce((acc, ch) => ((acc << 5) - acc) + ch.charCodeAt(0), 0));\n const fallbackColor = DYNAMIC_CATEGORY_PALETTE[hash % DYNAMIC_CATEGORY_PALETTE.length];\n const formattedLabel = category ? category.charAt(0).toUpperCase() + category.slice(1) : 'Item';\n return {\n Category: category || 'custom',\n Label: formattedLabel,\n Color: fallbackColor,\n IconClass: 'fa-solid fa-circle-dot'\n };\n }\n\n public get ActiveCategories(): GraphCategoryConfig[] {\n const present = new Set<string>();\n for (const n of this.Nodes) {\n if (n.Category) present.add(n.Category.toLowerCase());\n }\n const result: GraphCategoryConfig[] = [];\n for (const catKey of present) {\n result.push(this.GetCategoryConfig(catKey));\n }\n return result;\n }\n\n public GetCategoryLabel(category?: string): string {\n return this.GetCategoryConfig(category).Label;\n }\n\n public GetNodeColor(node: GraphNode): string {\n return node.Color ?? this.GetCategoryConfig(node.Category).Color;\n }\n\n public GetNodeIcon(node: GraphNode): string {\n return node.IconClass ?? this.GetCategoryConfig(node.Category).IconClass ?? 'fa-solid fa-circle-dot';\n }\n\n public GetNodeEdgeCount(id: string): number {\n return this.Edges.filter(e => UUIDsEqual(e.SourceID, id) || UUIDsEqual(e.TargetID, id)).length;\n }\n\n public IsEdgeHighlighted(edge: GraphEdge): boolean {\n return UUIDsEqual(this.SelectedEdge?.ID, edge.ID) ||\n UUIDsEqual(this.SelectedNode?.ID, edge.SourceID) ||\n UUIDsEqual(this.SelectedNode?.ID, edge.TargetID);\n }\n\n /**\n * Whether this node is the selected one. Exists as a method because the template cannot call\n * an imported function directly, and the comparison must go through UUIDsEqual rather than ===.\n */\n public IsNodeSelected(node: GraphNode): boolean {\n return UUIDsEqual(this.SelectedNode?.ID, node.ID);\n }\n\n public TruncateLabel(text: string, maxLen: number): string {\n if (!text) return '';\n return text.length > maxLen ? text.substring(0, maxLen - 1) + '…' : text;\n }\n\n public IsFocalNode(node: GraphNode): boolean {\n if (!node || !this.FocalNodeId) return false;\n const focalClean = this.stripCategoryPrefix(this.FocalNodeId).toLowerCase();\n const nodeClean = this.stripCategoryPrefix(node.ID).toLowerCase();\n const dataClean = node.Data?.['ID'] ? String(node.Data['ID']).toLowerCase() : '';\n return UUIDsEqual(node.ID, this.FocalNodeId) || nodeClean === focalClean || dataClean === focalClean;\n }\n\n /**\n * Hosts prefix node IDs with `{category}:`. Categories are dynamic\n * (`organization`, `asset`, `group`, plus caller keys), so strip any\n * known-category prefix rather than a hardcoded subset.\n */\n private stripCategoryPrefix(id: string): string {\n const idx = id.indexOf(':');\n if (idx <= 0) {\n return id;\n }\n const prefix = id.slice(0, idx).toLowerCase();\n const known =\n this.Categories?.some(c => c.Category.toLowerCase() === prefix) ||\n DEFAULT_GRAPH_CATEGORIES.some(c => c.Category.toLowerCase() === prefix);\n return known ? id.slice(idx + 1) : id;\n }\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@memberjunction/ng-graph-view",
3
- "version": "6.1.0-edge.5",
3
+ "version": "6.1.0-edge.7",
4
4
  "description": "MemberJunction: Generic interactive network and relationship graph viewer with force-directed physics, Before/After cancelable events, and MJ design tokens",
5
5
  "main": "./dist/public-api.js",
6
6
  "typings": "./dist/public-api.d.ts",
@@ -19,17 +19,17 @@
19
19
  "author": "",
20
20
  "license": "BUSL-1.1",
21
21
  "devDependencies": {
22
- "@angular/compiler": "21.1.3",
23
- "@angular/compiler-cli": "21.1.3"
22
+ "@angular/compiler": "21.2.22",
23
+ "@angular/compiler-cli": "21.2.22"
24
24
  },
25
25
  "peerDependencies": {
26
- "@angular/common": "^21.1.3",
27
- "@angular/core": "^21.1.3",
28
- "@angular/forms": "^21.1.3"
26
+ "@angular/common": "^21.2.22",
27
+ "@angular/core": "^21.2.22",
28
+ "@angular/forms": "^21.2.22"
29
29
  },
30
30
  "dependencies": {
31
- "@memberjunction/ng-ui-components": "6.1.0-edge.5",
32
- "@memberjunction/global": "6.1.0-edge.5",
31
+ "@memberjunction/ng-ui-components": "6.1.0-edge.7",
32
+ "@memberjunction/global": "6.1.0-edge.7",
33
33
  "@types/d3": "^7.4.3",
34
34
  "d3": "^7.9.0",
35
35
  "tslib": "^2.8.1",