@rws-framework/ai-tools 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.bin/add-v.sh +10 -0
- package/.bin/emerge.sh +11 -0
- package/.emerge-vis-output/rws-server/emerge-file_result_dependency_graph.graphml +2067 -0
- package/.emerge-vis-output/rws-server/emerge-filesystem_graph.graphml +1505 -0
- package/.emerge-vis-output/rws-server/emerge-statistics-and-metrics.json +1 -0
- package/.emerge-vis-output/rws-server/emerge-statistics-metrics.txt +1147 -0
- package/.emerge-vis-output/rws-server/html/emerge.html +501 -0
- package/.emerge-vis-output/rws-server/html/jsconfig.json +9 -0
- package/.emerge-vis-output/rws-server/html/resources/css/custom.css +211 -0
- package/.emerge-vis-output/rws-server/html/resources/js/emerge_common.js +45 -0
- package/.emerge-vis-output/rws-server/html/resources/js/emerge_data.js +13 -0
- package/.emerge-vis-output/rws-server/html/resources/js/emerge_git.js +1414 -0
- package/.emerge-vis-output/rws-server/html/resources/js/emerge_graph.js +539 -0
- package/.emerge-vis-output/rws-server/html/resources/js/emerge_heatmap.js +220 -0
- package/.emerge-vis-output/rws-server/html/resources/js/emerge_hull.js +180 -0
- package/.emerge-vis-output/rws-server/html/resources/js/emerge_main.js +1003 -0
- package/.emerge-vis-output/rws-server/html/resources/js/emerge_search.js +71 -0
- package/.emerge-vis-output/rws-server/html/resources/js/emerge_ui.js +199 -0
- package/.emerge-vis-output/rws-server/html/vendors/bootstrap/css/bootstrap-grid.css +4124 -0
- package/.emerge-vis-output/rws-server/html/vendors/bootstrap/css/bootstrap-grid.css.map +1 -0
- package/.emerge-vis-output/rws-server/html/vendors/bootstrap/css/bootstrap-grid.min.css +7 -0
- package/.emerge-vis-output/rws-server/html/vendors/bootstrap/css/bootstrap-grid.min.css.map +1 -0
- package/.emerge-vis-output/rws-server/html/vendors/bootstrap/css/bootstrap-grid.rtl.css +4123 -0
- package/.emerge-vis-output/rws-server/html/vendors/bootstrap/css/bootstrap-grid.rtl.css.map +1 -0
- package/.emerge-vis-output/rws-server/html/vendors/bootstrap/css/bootstrap-grid.rtl.min.css +7 -0
- package/.emerge-vis-output/rws-server/html/vendors/bootstrap/css/bootstrap-grid.rtl.min.css.map +1 -0
- package/.emerge-vis-output/rws-server/html/vendors/bootstrap/css/bootstrap-reboot.css +488 -0
- package/.emerge-vis-output/rws-server/html/vendors/bootstrap/css/bootstrap-reboot.css.map +1 -0
- package/.emerge-vis-output/rws-server/html/vendors/bootstrap/css/bootstrap-reboot.min.css +7 -0
- package/.emerge-vis-output/rws-server/html/vendors/bootstrap/css/bootstrap-reboot.min.css.map +1 -0
- package/.emerge-vis-output/rws-server/html/vendors/bootstrap/css/bootstrap-reboot.rtl.css +485 -0
- package/.emerge-vis-output/rws-server/html/vendors/bootstrap/css/bootstrap-reboot.rtl.css.map +1 -0
- package/.emerge-vis-output/rws-server/html/vendors/bootstrap/css/bootstrap-reboot.rtl.min.css +7 -0
- package/.emerge-vis-output/rws-server/html/vendors/bootstrap/css/bootstrap-reboot.rtl.min.css.map +1 -0
- package/.emerge-vis-output/rws-server/html/vendors/bootstrap/css/bootstrap-utilities.css +4266 -0
- package/.emerge-vis-output/rws-server/html/vendors/bootstrap/css/bootstrap-utilities.css.map +1 -0
- package/.emerge-vis-output/rws-server/html/vendors/bootstrap/css/bootstrap-utilities.min.css +7 -0
- package/.emerge-vis-output/rws-server/html/vendors/bootstrap/css/bootstrap-utilities.min.css.map +1 -0
- package/.emerge-vis-output/rws-server/html/vendors/bootstrap/css/bootstrap-utilities.rtl.css +4257 -0
- package/.emerge-vis-output/rws-server/html/vendors/bootstrap/css/bootstrap-utilities.rtl.css.map +1 -0
- package/.emerge-vis-output/rws-server/html/vendors/bootstrap/css/bootstrap-utilities.rtl.min.css +7 -0
- package/.emerge-vis-output/rws-server/html/vendors/bootstrap/css/bootstrap-utilities.rtl.min.css.map +1 -0
- package/.emerge-vis-output/rws-server/html/vendors/bootstrap/css/bootstrap.css +10878 -0
- package/.emerge-vis-output/rws-server/html/vendors/bootstrap/css/bootstrap.css.map +1 -0
- package/.emerge-vis-output/rws-server/html/vendors/bootstrap/css/bootstrap.min.css +7 -0
- package/.emerge-vis-output/rws-server/html/vendors/bootstrap/css/bootstrap.min.css.map +1 -0
- package/.emerge-vis-output/rws-server/html/vendors/bootstrap/css/bootstrap.rtl.css +10842 -0
- package/.emerge-vis-output/rws-server/html/vendors/bootstrap/css/bootstrap.rtl.css.map +1 -0
- package/.emerge-vis-output/rws-server/html/vendors/bootstrap/css/bootstrap.rtl.min.css +7 -0
- package/.emerge-vis-output/rws-server/html/vendors/bootstrap/css/bootstrap.rtl.min.css.map +1 -0
- package/.emerge-vis-output/rws-server/html/vendors/bootstrap/js/bootstrap.bundle.js +7075 -0
- package/.emerge-vis-output/rws-server/html/vendors/bootstrap/js/bootstrap.bundle.js.map +1 -0
- package/.emerge-vis-output/rws-server/html/vendors/bootstrap/js/bootstrap.bundle.min.js +7 -0
- package/.emerge-vis-output/rws-server/html/vendors/bootstrap/js/bootstrap.bundle.min.js.map +1 -0
- package/.emerge-vis-output/rws-server/html/vendors/bootstrap/js/bootstrap.esm.js +5202 -0
- package/.emerge-vis-output/rws-server/html/vendors/bootstrap/js/bootstrap.esm.js.map +1 -0
- package/.emerge-vis-output/rws-server/html/vendors/bootstrap/js/bootstrap.esm.min.js +7 -0
- package/.emerge-vis-output/rws-server/html/vendors/bootstrap/js/bootstrap.esm.min.js.map +1 -0
- package/.emerge-vis-output/rws-server/html/vendors/bootstrap/js/bootstrap.js +5249 -0
- package/.emerge-vis-output/rws-server/html/vendors/bootstrap/js/bootstrap.js.map +1 -0
- package/.emerge-vis-output/rws-server/html/vendors/bootstrap/js/bootstrap.min.js +7 -0
- package/.emerge-vis-output/rws-server/html/vendors/bootstrap/js/bootstrap.min.js.map +1 -0
- package/.emerge-vis-output/rws-server/html/vendors/d3/d3.v7.8.4.min.js +2 -0
- package/.emerge-vis-output/rws-server/html/vendors/d3/d3.v7.min.js +2 -0
- package/.emerge-vis-output/rws-server/html/vendors/dark-mode-switch/css/dark-mode.css +148 -0
- package/.emerge-vis-output/rws-server/html/vendors/dark-mode-switch/js/dark-mode-switch.min.js +1 -0
- package/.emerge-vis-output/rws-server/html/vendors/daterangepicker/daterangepicker.css +410 -0
- package/.emerge-vis-output/rws-server/html/vendors/daterangepicker/daterangepicker.min.js +8 -0
- package/.emerge-vis-output/rws-server/html/vendors/daterangepicker/moment.min.js +7 -0
- package/.emerge-vis-output/rws-server/html/vendors/hull/hull.js +373 -0
- package/.emerge-vis-output/rws-server/html/vendors/jquery/jquery-3.6.0.min.js +2 -0
- package/.emerge-vis-output/rws-server/html/vendors/popper/popper.min.js +6 -0
- package/.emerge-vis-output/rws-server/html/vendors/simpleheat/simpleheat.js +141 -0
- package/.eslintrc.json +53 -0
- package/README.md +862 -0
- package/package.json +49 -0
- package/src/index.ts +22 -0
- package/src/models/convo/ConvoLoader.ts +415 -0
- package/src/models/convo/VectorStore.ts +33 -0
- package/src/models/prompts/_prompt.ts +388 -0
- package/src/services/VectorStoreService.ts +15 -0
- package/tsconfig.json +24 -0
|
@@ -0,0 +1,539 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* * MARK: - Drawing on canvas
|
|
3
|
+
*/
|
|
4
|
+
function drawEdges(context) {
|
|
5
|
+
currentGraph.links.forEach(function(d) {
|
|
6
|
+
|
|
7
|
+
context.beginPath();
|
|
8
|
+
context.moveTo(d.source.x, d.source.y);
|
|
9
|
+
context.lineTo(d.target.x, d.target.y);
|
|
10
|
+
|
|
11
|
+
if (closeNode == null) { // not hovering over any node
|
|
12
|
+
if (isSearching == false) { // not searching
|
|
13
|
+
context.fillStyle = context.strokeStyle = nodeSourceColor = nodeColorByModularity(d.source, 0.7)
|
|
14
|
+
|
|
15
|
+
} else { // node search is active
|
|
16
|
+
|
|
17
|
+
if (addSemanticSearch == true) {
|
|
18
|
+
|
|
19
|
+
// the edge is between two nodes that are included in the search OR the edge is between two nodes that includes the search in one of their semantic keywords
|
|
20
|
+
if ( edgeBetweenSearchTerms(d.source, d.target) || searchTermsIncludedInNodeTags(d.source, d.target) )
|
|
21
|
+
{
|
|
22
|
+
context.strokeStyle = currentActiveEdgeColor
|
|
23
|
+
context.fillStyle = currentActiveEdgeColor
|
|
24
|
+
} else { // the edge is not connected to a node which is included in the search
|
|
25
|
+
context.fillStyle = context.strokeStyle = currentPassiveEdgeColor
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
} else { // normal search without semantic
|
|
30
|
+
// the edge is between two nodes that are included in the search
|
|
31
|
+
if (edgeBetweenSearchTerms(d.source, d.target))
|
|
32
|
+
{
|
|
33
|
+
context.strokeStyle = currentActiveEdgeColor
|
|
34
|
+
context.fillStyle = currentActiveEdgeColor
|
|
35
|
+
} else { // the edge is not connected to a node which is included in the search
|
|
36
|
+
context.fillStyle = context.strokeStyle = currentPassiveEdgeColor
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
if (addContributorSearch == true ) {
|
|
41
|
+
// the edge is between two nodes that are included in the search OR the edge is between two nodes that includes the search in one of their semantic keywords
|
|
42
|
+
if ( searchTermsIncludedInNodeContributors(d.source, d.target) )
|
|
43
|
+
{
|
|
44
|
+
context.strokeStyle = currentActiveEdgeColor
|
|
45
|
+
context.fillStyle = currentActiveEdgeColor
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
} else {
|
|
52
|
+
if ((d.target.id == closeNode.id) || (d.source.id == closeNode.id)) { // there is an edge that contains our hovered node
|
|
53
|
+
context.strokeStyle = currentActiveEdgeColor
|
|
54
|
+
context.fillStyle = currentActiveEdgeColor
|
|
55
|
+
|
|
56
|
+
} else { // node is not included in the edge
|
|
57
|
+
context.fillStyle = context.strokeStyle = nodeColorByModularity(d.source, 0.2)
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// highlight edge if the corresponding nodes are selected
|
|
62
|
+
if (d.source.id.toLowerCase() in selectedNodesMap && d.target.id.toLowerCase() in selectedNodesMap) {
|
|
63
|
+
context.strokeStyle = activeSelectionColor
|
|
64
|
+
context.fillStyle = currentActiveEdgeColor
|
|
65
|
+
context.lineWidth = 2.0;
|
|
66
|
+
} else {
|
|
67
|
+
if (fadeUnselectedNodes == true || normalHeatmapIsActive() || churnHeatmapIsActive() || hotspotHeatmapIsActive()) { // also fade away non-relevant egdes
|
|
68
|
+
context.fillStyle = context.strokeStyle = nodeColorByModularity(d.source, unselectedNodesOpacity)
|
|
69
|
+
}
|
|
70
|
+
context.lineWidth = 1.0;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
context.stroke();
|
|
74
|
+
|
|
75
|
+
if (closeNode != null && ((d.target.id == closeNode.id) || (d.source.id == closeNode.id))) { // draw an arrow if there is an edge that contains our hovered node
|
|
76
|
+
drawArrowhead(context, d.source, d.target, 5)
|
|
77
|
+
|
|
78
|
+
} else if (isSearching && ( (searchTermIncludedInNode(d.target) ) && ( searchTermIncludedInNode(d.source)) )) { // draw an arrow if searching is enabled and there's an egde between searched nodes
|
|
79
|
+
drawArrowhead(context, d.source, d.target, 5)
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
else if (d.source.id.toLowerCase() in selectedNodesMap && d.target.id.toLowerCase() in selectedNodesMap) {
|
|
83
|
+
drawArrowhead(context, d.source, d.target, 5)
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
function drawNodes(context) {
|
|
90
|
+
currentGraph.nodes.forEach(function(d, i) {
|
|
91
|
+
|
|
92
|
+
context.beginPath();
|
|
93
|
+
|
|
94
|
+
//render outer circle if node was selected
|
|
95
|
+
if (d.id.toLowerCase() in selectedNodesMap) {
|
|
96
|
+
|
|
97
|
+
context.arc(d.x, d.y, d.radius + 2.0, 0, TWO_TIMES_PI);
|
|
98
|
+
context.fillStyle = '#FF0000' //activeSelectionColor
|
|
99
|
+
drawNodeLabel(d.id, d.x + 14, d.y - 7)
|
|
100
|
+
context.fill();
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
context.arc(d.x, d.y, d.radius, 0, TWO_TIMES_PI, true);
|
|
104
|
+
|
|
105
|
+
if (fadeUnselectedNodes == true || normalHeatmapIsActive() || churnHeatmapIsActive() || hotspotHeatmapIsActive()) {
|
|
106
|
+
context.strokeStyle = nodeStrokeStyle
|
|
107
|
+
context.fillStyle = hexToRGB(nodeStrokeStyle, unselectedNodesOpacity)
|
|
108
|
+
context.stroke();
|
|
109
|
+
|
|
110
|
+
if (nodeLabelsEnabled) {
|
|
111
|
+
context.fillStyle = currentPassiveNodeLabelColor;
|
|
112
|
+
drawNodeLabel(d.id, d.x + 14, d.y - 7)
|
|
113
|
+
context.fillStyle = nodeColorByModularity(d, unselectedNodesOpacity)
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
} else {
|
|
117
|
+
|
|
118
|
+
if (closeNode == null) { // not hovering over any node
|
|
119
|
+
if (isSearching == false) {
|
|
120
|
+
|
|
121
|
+
context.fillStyle = nodeColorByModularity(d)
|
|
122
|
+
context.strokeStyle = nodeStrokeStyle;
|
|
123
|
+
context.stroke();
|
|
124
|
+
|
|
125
|
+
if (nodeLabelsEnabled) {
|
|
126
|
+
context.fillStyle = currentActiveNodeLabelColor;
|
|
127
|
+
drawNodeLabel(d.id, d.x + 14, d.y - 7)
|
|
128
|
+
context.fillStyle = nodeColorByModularity(d)
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
} else { // searching for nodes
|
|
132
|
+
|
|
133
|
+
// normal (non-semantic) search
|
|
134
|
+
if ( addSemanticSearch == false && normalSearch(d)) {
|
|
135
|
+
|
|
136
|
+
context.fillStyle = nodeColorByModularity(d)
|
|
137
|
+
context.strokeStyle = nodeStrokeStyle;
|
|
138
|
+
context.stroke();
|
|
139
|
+
|
|
140
|
+
context.fillStyle = currentActiveNodeLabelColor;
|
|
141
|
+
drawNodeLabel(d.id, d.x + 14, d.y - 7)
|
|
142
|
+
context.fillStyle = nodeColorByModularity(d)
|
|
143
|
+
|
|
144
|
+
searchResults += 1
|
|
145
|
+
|
|
146
|
+
} else if ( addSemanticSearch == true && (searchTermIncludedInNode(d) || searchTermIncludedInNodeTags(d)) )
|
|
147
|
+
// add semantic search
|
|
148
|
+
// the node is included in the current search OR if the search in included in one of the node's semantic tags
|
|
149
|
+
// draw a highlight circle behind the found node due to semantic search
|
|
150
|
+
{
|
|
151
|
+
if ( searchTermIncludedInNodeTags(d) )
|
|
152
|
+
{
|
|
153
|
+
context.fillStyle = currentActiveNodeLabelColor;
|
|
154
|
+
drawNodeLabel(d.id, d.x + 14, d.y - 7)
|
|
155
|
+
|
|
156
|
+
drawNodeHighlight(d, nodeColorByModularity(d, 1.0))
|
|
157
|
+
context.strokeStyle = nodeStrokeStyle;
|
|
158
|
+
context.stroke();
|
|
159
|
+
|
|
160
|
+
drawNodeHighlight(d, semanticHeaderYellow, 2)
|
|
161
|
+
context.strokeStyle = nodeStrokeStyle;
|
|
162
|
+
context.stroke();
|
|
163
|
+
|
|
164
|
+
searchResults += 1
|
|
165
|
+
|
|
166
|
+
} else {
|
|
167
|
+
|
|
168
|
+
context.fillStyle = nodeColorByModularity(d)
|
|
169
|
+
context.strokeStyle = nodeStrokeStyle;
|
|
170
|
+
context.stroke();
|
|
171
|
+
|
|
172
|
+
context.fillStyle = currentActiveNodeLabelColor;
|
|
173
|
+
drawNodeLabel(d.id, d.x + 14, d.y - 7)
|
|
174
|
+
context.fillStyle = nodeColorByModularity(d)
|
|
175
|
+
|
|
176
|
+
searchResults += 1
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
} else {
|
|
180
|
+
context.fillStyle = nodeColorByModularity(d, 0.2)
|
|
181
|
+
context.strokeStyle = hexToRGB(nodeStrokeStyle, 0.2)
|
|
182
|
+
context.stroke();
|
|
183
|
+
|
|
184
|
+
if (nodeLabelsEnabled) {
|
|
185
|
+
context.fillStyle = currentPassiveNodeLabelColor;
|
|
186
|
+
drawNodeLabel(d.id, d.x + 14, d.y - 7)
|
|
187
|
+
context.fillStyle = nodeColorByModularity(d, 0.2)
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
// contributors search
|
|
193
|
+
if (addContributorSearch == true && searchTermIncludedInNodeContributors(d)) {
|
|
194
|
+
|
|
195
|
+
context.fillStyle = currentActiveNodeLabelColor;
|
|
196
|
+
drawNodeLabel(d.id, d.x + 14, d.y - 7)
|
|
197
|
+
|
|
198
|
+
drawNodeHighlight(d, nodeColorByModularity(d, 1.0))
|
|
199
|
+
context.strokeStyle = nodeStrokeStyle;
|
|
200
|
+
context.stroke();
|
|
201
|
+
|
|
202
|
+
drawNodeHighlight(d, contributorsPurple, 2)
|
|
203
|
+
context.strokeStyle = nodeStrokeStyle;
|
|
204
|
+
context.stroke();
|
|
205
|
+
|
|
206
|
+
searchResults += 1
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
} else { // hovering over a node
|
|
210
|
+
if (isConnected(d, closeNode)) { // node is connected to hovered node
|
|
211
|
+
context.fillStyle = nodeColorByModularity(d)
|
|
212
|
+
context.strokeStyle = nodeStrokeStyle;
|
|
213
|
+
context.stroke();
|
|
214
|
+
|
|
215
|
+
// show/highlight node label of every connected node from the hovered node
|
|
216
|
+
context.fillStyle = currentActiveNodeLabelColor;
|
|
217
|
+
drawNodeLabel(d.id, d.x + 14, d.y - 7)
|
|
218
|
+
context.fillStyle = nodeColorByModularity(d)
|
|
219
|
+
|
|
220
|
+
} else if ( hoverCoupling == true && nodeNamesHaveChangeCoupling(d.id, closeNode.id) ) {
|
|
221
|
+
|
|
222
|
+
context.fillStyle = currentActiveNodeLabelColor;
|
|
223
|
+
drawNodeLabel(d.id, d.x + 14, d.y - 7)
|
|
224
|
+
|
|
225
|
+
drawNodeHighlight(d, nodeColorByModularity(d, 1.0))
|
|
226
|
+
context.strokeStyle = nodeStrokeStyle;
|
|
227
|
+
context.stroke();
|
|
228
|
+
|
|
229
|
+
drawNodeHighlight(d, changeCouplingColor, 2)
|
|
230
|
+
context.strokeStyle = nodeStrokeStyle;
|
|
231
|
+
context.stroke();
|
|
232
|
+
|
|
233
|
+
} else { // node is not connected
|
|
234
|
+
|
|
235
|
+
if (d.id.toLowerCase() in selectedNodesMap) {
|
|
236
|
+
context.strokeStyle = nodeStrokeStyle
|
|
237
|
+
context.fillStyle = nodeColorByModularity(d)
|
|
238
|
+
context.stroke();
|
|
239
|
+
} else {
|
|
240
|
+
context.strokeStyle = hexToRGB(nodeStrokeStyle, 0.2)
|
|
241
|
+
context.fillStyle = nodeColorByModularity(d, 0.2)
|
|
242
|
+
context.stroke();
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
if (nodeLabelsEnabled) {
|
|
246
|
+
context.fillStyle = currentPassiveNodeLabelColor;
|
|
247
|
+
drawNodeLabel(d.id, d.x + 14, d.y - 7)
|
|
248
|
+
context.fillStyle = nodeColorByModularity(d, 0.2)
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
} // else not fade away unselected nodes
|
|
254
|
+
|
|
255
|
+
context.fill();
|
|
256
|
+
|
|
257
|
+
if (i == currentGraph.nodes.length - 1) { // dont call this to often due to performance
|
|
258
|
+
|
|
259
|
+
if (closeNode) {
|
|
260
|
+
context.beginPath();
|
|
261
|
+
drawNode(closeNode)
|
|
262
|
+
|
|
263
|
+
if (closeNode.id.toLowerCase() in selectedNodesMap) {
|
|
264
|
+
context.fillStyle = activeSelectionColor
|
|
265
|
+
} else {
|
|
266
|
+
context.fillStyle = nodeColorByModularity(closeNode)
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
context.fill();
|
|
270
|
+
context.strokeStyle = "#000000";
|
|
271
|
+
context.lineWidth = 1.0;
|
|
272
|
+
context.stroke();
|
|
273
|
+
|
|
274
|
+
drawNodeToolTip(closeNode.id, closeNode.x + 14, closeNode.y - 7, closeNode.metrics)
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
});
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
/**
|
|
281
|
+
* * MARK: - Connectivity checks
|
|
282
|
+
*/
|
|
283
|
+
let linkedByIndex = {};
|
|
284
|
+
|
|
285
|
+
function isConnected(a, b) {
|
|
286
|
+
return isConnectedAsTarget(a, b) || isConnectedAsSource(a, b) || a.id === b.id;
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
function isConnectedAsSource(a, b) {
|
|
290
|
+
return linkedByIndex[`${a.id},${b.id}`];
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
function isConnectedAsTarget(a, b) {
|
|
294
|
+
return linkedByIndex[`${b.id},${a.id}`];
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
|
|
298
|
+
|
|
299
|
+
function drawLink(d) {
|
|
300
|
+
context.moveTo(d.source.x, d.source.y);
|
|
301
|
+
context.lineTo(d.target.x, d.target.y);
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
function drawNode(d) {
|
|
305
|
+
context.arc(d.x, d.y, d.radius, 0, TWO_TIMES_PI);
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
function drawNodeHighlight(node, color, radiusOffset) {
|
|
309
|
+
context.arc(node.x, node.y, node.radius + radiusOffset, 0, TWO_TIMES_PI);
|
|
310
|
+
context.fillStyle = color
|
|
311
|
+
context.strokeStyle = color;
|
|
312
|
+
context.stroke();
|
|
313
|
+
context.fill();
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
function drawNodeLabel(text, xPos, yPos) {
|
|
317
|
+
const fontSize = 8
|
|
318
|
+
context.font = fontSize + 'px Helvetica';
|
|
319
|
+
context.fillText(text, xPos, yPos);
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
function stringIncludedInNodeTags(string, node) {
|
|
323
|
+
let propertyNames = Object.getOwnPropertyNames(node.metrics)
|
|
324
|
+
let searchedTag = 'metric_tag_' + string
|
|
325
|
+
let found = false
|
|
326
|
+
|
|
327
|
+
let tagProperties = propertyNames.filter(function(property) {
|
|
328
|
+
return property.startsWith('metric_tag_')
|
|
329
|
+
})
|
|
330
|
+
|
|
331
|
+
tagProperties.forEach(function(propertyName) {
|
|
332
|
+
if (propertyName.toLowerCase().includes(string.toLowerCase())) {
|
|
333
|
+
found = true
|
|
334
|
+
}
|
|
335
|
+
})
|
|
336
|
+
|
|
337
|
+
return found
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
function stringIncludedInNodeContributors(string, node) {
|
|
341
|
+
let found = false
|
|
342
|
+
if (node.hasOwnProperty('metrics')) {
|
|
343
|
+
let metrics = node['metrics']
|
|
344
|
+
if ('metric_git_contributors' in metrics) {
|
|
345
|
+
const contributors = metrics['metric_git_contributors']
|
|
346
|
+
contributors.forEach(function(name) {
|
|
347
|
+
if (name.toLowerCase().includes(string.toLowerCase())) {
|
|
348
|
+
found = true
|
|
349
|
+
}
|
|
350
|
+
})
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
return found
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
function drawNodeToolTip(text, xPos, yPos, nodeMetrics) {
|
|
358
|
+
|
|
359
|
+
// $('#overallStatisticsModal').modal('show');
|
|
360
|
+
|
|
361
|
+
const fontSize = 14
|
|
362
|
+
context.font = fontSize + 'px Helvetica';
|
|
363
|
+
|
|
364
|
+
// determine the maximum label width
|
|
365
|
+
let maxLineWidth = 0
|
|
366
|
+
for (metricKey in nodeMetrics) {
|
|
367
|
+
const val = nodeMetrics[metricKey]
|
|
368
|
+
let human_readable_metric_name = metricKey.replace('metric_', '').replace(/_/gi, " ")
|
|
369
|
+
const w = context.measureText(human_readable_metric_name + ": " + val).width;
|
|
370
|
+
if (maxLineWidth < w) {
|
|
371
|
+
maxLineWidth = w
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
// check if actually the title line width if bigger than any metric label line width?
|
|
376
|
+
const nodeTitleLineWidth = context.measureText(text).width
|
|
377
|
+
if (nodeTitleLineWidth > maxLineWidth)
|
|
378
|
+
maxLineWidth = nodeTitleLineWidth
|
|
379
|
+
|
|
380
|
+
// draw the header/title of the toolip
|
|
381
|
+
let lineHeight = fontSize * 1.286;
|
|
382
|
+
context.fillStyle = hexToRGB("#0069d9", 1.0);
|
|
383
|
+
context.fillRect(xPos - 6, (yPos - lineHeight) + 2, maxLineWidth + 10, lineHeight + 4);
|
|
384
|
+
context.strokeStyle = hexToRGB("#333333", 1.0);
|
|
385
|
+
context.strokeRect(xPos - 6, (yPos - lineHeight) + 2, maxLineWidth + 10, lineHeight + 4)
|
|
386
|
+
|
|
387
|
+
context.fillStyle = hexToRGB("#FFFFFF", 0.8);
|
|
388
|
+
context.fillText(text, xPos, yPos);
|
|
389
|
+
|
|
390
|
+
// now draw the second tooltip box with all metric labels
|
|
391
|
+
let metricItem = 1
|
|
392
|
+
const metricFontSize = 14
|
|
393
|
+
const metricLineHeight = (metricFontSize * 1.286);
|
|
394
|
+
let yPosOffset = yPos + 10
|
|
395
|
+
let newYPos = 0
|
|
396
|
+
let renderWithTags = false
|
|
397
|
+
|
|
398
|
+
context.font = metricFontSize + 'px Helvetica';
|
|
399
|
+
|
|
400
|
+
for (metricKey in nodeMetrics) {
|
|
401
|
+
|
|
402
|
+
// do not include any tag/tfidf metric in the primary metric section
|
|
403
|
+
if (metricKey.includes('metric_tag')) {
|
|
404
|
+
renderWithTags = true
|
|
405
|
+
continue
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
let val = nodeMetrics[metricKey]
|
|
409
|
+
let human_readable_metric_name = metricKey.replace('metric_', '').replace(/_/gi, " ")
|
|
410
|
+
let metricItemText = human_readable_metric_name + ": " + val
|
|
411
|
+
|
|
412
|
+
newYPos = yPosOffset + (metricLineHeight * metricItem)
|
|
413
|
+
|
|
414
|
+
// Interesting bug: on Safari it seems to cause random lags if you do fillStyle/fillRect BEFORE strokeStyle/strokeRect
|
|
415
|
+
context.strokeStyle = toolTipMetricItemBoxColor
|
|
416
|
+
context.strokeRect(xPos - 6, (newYPos - metricLineHeight), maxLineWidth + 10, metricLineHeight)
|
|
417
|
+
|
|
418
|
+
context.fillStyle = toolTipMetricItemBoxFillColor
|
|
419
|
+
context.fillRect(xPos - 6, (newYPos - metricLineHeight), maxLineWidth + 10, metricLineHeight);
|
|
420
|
+
|
|
421
|
+
context.fillStyle = toolTipMetricItemTextColor;
|
|
422
|
+
context.fillText(metricItemText, xPos, newYPos - 4);
|
|
423
|
+
|
|
424
|
+
metricItem = metricItem + 1
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
// render tag/tfidf metric section
|
|
428
|
+
if (renderWithTags) {
|
|
429
|
+
let metricItem = 1
|
|
430
|
+
newYPos += 20
|
|
431
|
+
|
|
432
|
+
// draw the header/title of the toolip
|
|
433
|
+
context.fillStyle = hexToRGB("#f5bc42", 1.0);
|
|
434
|
+
context.fillRect(xPos - 6, (newYPos - lineHeight) + 2, maxLineWidth + 10, lineHeight + 4);
|
|
435
|
+
context.strokeStyle = hexToRGB("#333333", 1.0);
|
|
436
|
+
context.strokeRect(xPos - 6, (newYPos - lineHeight) + 2, maxLineWidth + 10, lineHeight + 4)
|
|
437
|
+
context.fillStyle = hexToRGB("#333333", 0.8);
|
|
438
|
+
context.fillText('Semantic keywords', xPos, newYPos);
|
|
439
|
+
|
|
440
|
+
let yTagPosOffset = newYPos + 10
|
|
441
|
+
|
|
442
|
+
// render tag/tfidf metrics
|
|
443
|
+
for (metricKey in nodeMetrics) {
|
|
444
|
+
|
|
445
|
+
// do not include any tag/tfidf metric in the primary metric section
|
|
446
|
+
if (!metricKey.includes('metric_tag')) {
|
|
447
|
+
continue
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
let val = nodeMetrics[metricKey]
|
|
451
|
+
let human_readable_metric_name = metricKey.replace('metric_tag', '').replace(/_/gi, "")
|
|
452
|
+
let metricItemText = human_readable_metric_name // + ": " + val
|
|
453
|
+
|
|
454
|
+
newYPos = yTagPosOffset + (metricLineHeight * metricItem)
|
|
455
|
+
|
|
456
|
+
// Interesting bug: on Safari it seems to cause random lags if you do fillStyle/fillRect BEFORE strokeStyle/strokeRect
|
|
457
|
+
context.strokeStyle = toolTipMetricItemBoxColor
|
|
458
|
+
context.strokeRect(xPos - 6, (newYPos - metricLineHeight), maxLineWidth + 10, metricLineHeight)
|
|
459
|
+
|
|
460
|
+
context.fillStyle = toolTipMetricItemBoxFillColor
|
|
461
|
+
context.fillRect(xPos - 6, (newYPos - metricLineHeight), maxLineWidth + 10, metricLineHeight);
|
|
462
|
+
|
|
463
|
+
context.fillStyle = toolTipMetricItemTextColor;
|
|
464
|
+
context.fillText(metricItemText, xPos, newYPos - 4);
|
|
465
|
+
|
|
466
|
+
metricItem = metricItem + 1
|
|
467
|
+
}
|
|
468
|
+
}
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
// borrowed from Scott Johnson / https://gist.github.com/jwir3/d797037d2e1bf78a9b04838d73436197 with minor adjustments
|
|
472
|
+
function drawArrowhead(context, from, to, radius) {
|
|
473
|
+
const x_center = 0.5 * (from.x + to.x)
|
|
474
|
+
const y_center = 0.5 * (from.y + to.y)
|
|
475
|
+
|
|
476
|
+
let angle;
|
|
477
|
+
let x;
|
|
478
|
+
let y;
|
|
479
|
+
|
|
480
|
+
context.beginPath();
|
|
481
|
+
|
|
482
|
+
angle = Math.atan2(to.y - from.y, to.x - from.x)
|
|
483
|
+
x = radius * Math.cos(angle) + x_center;
|
|
484
|
+
y = radius * Math.sin(angle) + y_center;
|
|
485
|
+
|
|
486
|
+
context.moveTo(x, y);
|
|
487
|
+
|
|
488
|
+
angle += ONE_THIRD_TWO_TIMES_PI
|
|
489
|
+
x = radius * Math.cos(angle) + x_center;
|
|
490
|
+
y = radius * Math.sin(angle) + y_center;
|
|
491
|
+
|
|
492
|
+
context.lineTo(x, y);
|
|
493
|
+
|
|
494
|
+
angle += ONE_THIRD_TWO_TIMES_PI
|
|
495
|
+
x = radius * Math.cos(angle) + x_center;
|
|
496
|
+
y = radius * Math.sin(angle) + y_center;
|
|
497
|
+
|
|
498
|
+
context.lineTo(x, y);
|
|
499
|
+
context.closePath();
|
|
500
|
+
context.fill();
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
function initNodeColorMap() {
|
|
504
|
+
currentGraph.nodes.forEach(function(node, i) {
|
|
505
|
+
nodeColorMap[node.id] = hexToRGB(color(node.metric_file_result_dependency_graph_louvain_modularity_in_file), 1.0)
|
|
506
|
+
})
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
function nodeColorByModularity(node, alpha = 1.0) {
|
|
510
|
+
if (currentGraphType.includes('file_result') || currentGraphType.includes('filesystem')) {
|
|
511
|
+
if ('metric_file_result_dependency_graph_louvain_modularity_in_file' in node) {
|
|
512
|
+
return hexToRGB(color(node.metric_file_result_dependency_graph_louvain_modularity_in_file), alpha)
|
|
513
|
+
} else if ('directory' in node) {
|
|
514
|
+
if (node.directory == true) {
|
|
515
|
+
return hexToRGB(directoryNodeColor)
|
|
516
|
+
}
|
|
517
|
+
}
|
|
518
|
+
} else {
|
|
519
|
+
if (currentGraphType.includes('entity_result_dependency_graph')) {
|
|
520
|
+
if ('metric_entity_result_dependency_graph_louvain_modularity_in_entity' in node) {
|
|
521
|
+
return hexToRGB(color(node.metric_entity_result_dependency_graph_louvain_modularity_in_entity), alpha)
|
|
522
|
+
}
|
|
523
|
+
}
|
|
524
|
+
if (currentGraphType.includes('entity_result_inheritance_graph')) {
|
|
525
|
+
if ('metric_entity_result_inheritance_graph_louvain_modularity_in_entity' in node) {
|
|
526
|
+
return hexToRGB(color(node.metric_entity_result_inheritance_graph_louvain_modularity_in_entity), alpha)
|
|
527
|
+
}
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
if (currentGraphType.includes('entity_result_complete_graph')) {
|
|
531
|
+
if ('metric_entity_result_complete_graph_louvain_modularity_in_entity' in node) {
|
|
532
|
+
return hexToRGB(color(node.metric_entity_result_complete_graph_louvain_modularity_in_entity), alpha)
|
|
533
|
+
}
|
|
534
|
+
}
|
|
535
|
+
}
|
|
536
|
+
|
|
537
|
+
return hexToRGB(defaultNodeColor)
|
|
538
|
+
}
|
|
539
|
+
|