@abi-software/map-utilities 1.1.3-beta.4 → 1.2.0-beta.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/dist/map-utilities.js +6890 -23425
- package/dist/map-utilities.umd.cjs +41 -61
- package/dist/style.css +1 -1
- package/package.json +1 -2
- package/src/App.vue +0 -34
- package/src/components/TreeControls/TreeControls.vue +38 -1
- package/src/components/index.js +1 -9
- package/src/components.d.ts +0 -4
- package/src/components/ConnectivityGraph/ConnectivityGraph.vue +0 -451
- package/src/components/ConnectivityGraph/graph.js +0 -264
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@abi-software/map-utilities",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.0-beta.1",
|
|
4
4
|
"files": [
|
|
5
5
|
"dist/*",
|
|
6
6
|
"src/*",
|
|
@@ -31,7 +31,6 @@
|
|
|
31
31
|
"dependencies": {
|
|
32
32
|
"@abi-software/svg-sprite": "^1.0.1",
|
|
33
33
|
"@element-plus/icons-vue": "^2.3.1",
|
|
34
|
-
"cytoscape": "^3.30.2",
|
|
35
34
|
"element-plus": "2.8.4",
|
|
36
35
|
"mitt": "^3.0.1",
|
|
37
36
|
"vue": "^3.4.21"
|
package/src/App.vue
CHANGED
|
@@ -38,7 +38,6 @@ const drawnTypes = [
|
|
|
38
38
|
{ value: "Polygon", label: "Polygon" },
|
|
39
39
|
{ value: "None", label: "None" },
|
|
40
40
|
];
|
|
41
|
-
const showConnectivityGraph = ref(false);
|
|
42
41
|
|
|
43
42
|
onMounted(() => {
|
|
44
43
|
console.log("🚀 ~ onMounted ~ appRef:", appRef.value);
|
|
@@ -423,25 +422,6 @@ function changeHover(value) {
|
|
|
423
422
|
</el-button>
|
|
424
423
|
</el-col>
|
|
425
424
|
</el-row>
|
|
426
|
-
<el-row>
|
|
427
|
-
<el-col>
|
|
428
|
-
<h3>Connectivity Graph</h3>
|
|
429
|
-
</el-col>
|
|
430
|
-
<el-col>
|
|
431
|
-
<el-button
|
|
432
|
-
@click="showConnectivityGraph = true"
|
|
433
|
-
size="small"
|
|
434
|
-
>
|
|
435
|
-
Show connectivity graph
|
|
436
|
-
</el-button>
|
|
437
|
-
<el-button
|
|
438
|
-
@click="showConnectivityGraph = false"
|
|
439
|
-
size="small"
|
|
440
|
-
>
|
|
441
|
-
Hide connectivity graph
|
|
442
|
-
</el-button>
|
|
443
|
-
</el-col>
|
|
444
|
-
</el-row>
|
|
445
425
|
|
|
446
426
|
<DrawToolbar
|
|
447
427
|
v-show="isFlatmap"
|
|
@@ -511,11 +491,6 @@ function changeHover(value) {
|
|
|
511
491
|
@setColour="setColour"
|
|
512
492
|
@checkChanged="checkChanged"
|
|
513
493
|
/>
|
|
514
|
-
<ConnectivityGraph
|
|
515
|
-
v-if="showConnectivityGraph"
|
|
516
|
-
entry="ilxtr:neuron-type-aacar-13"
|
|
517
|
-
map-server="https://mapcore-demo.org/curation/flatmap/"
|
|
518
|
-
/>
|
|
519
494
|
</div>
|
|
520
495
|
</template>
|
|
521
496
|
|
|
@@ -533,13 +508,4 @@ function changeHover(value) {
|
|
|
533
508
|
top: calc(50% - 100px);
|
|
534
509
|
left: calc(50% - 200px);
|
|
535
510
|
}
|
|
536
|
-
.toolbar-container {
|
|
537
|
-
height: 80px;
|
|
538
|
-
position: relative;
|
|
539
|
-
}
|
|
540
|
-
.connectivity-graph {
|
|
541
|
-
width: 600px;
|
|
542
|
-
height: 600px;
|
|
543
|
-
margin-top: 1rem;
|
|
544
|
-
}
|
|
545
511
|
</style>
|
|
@@ -6,12 +6,21 @@
|
|
|
6
6
|
{{ title }}
|
|
7
7
|
</div>
|
|
8
8
|
</el-col>
|
|
9
|
+
<el-col v-if="enableFilter" :span="12">
|
|
10
|
+
<div>
|
|
11
|
+
<el-input
|
|
12
|
+
class="tree-filter-input"
|
|
13
|
+
v-model="filterText"
|
|
14
|
+
placeholder="Filter keyword"
|
|
15
|
+
/>
|
|
16
|
+
</div>
|
|
17
|
+
</el-col>
|
|
9
18
|
</el-row>
|
|
10
19
|
<div class="tree-container" ref="treeContainer">
|
|
11
20
|
<div :class="['tree-tooltip', tooltipAtBottom ? 'bottom' : '']" >
|
|
12
21
|
<el-popover
|
|
13
22
|
ref="tooltip"
|
|
14
|
-
:visible="tooltipVisible"
|
|
23
|
+
:visible="tooltipVisible && tooltipLabel !== ''"
|
|
15
24
|
placement="top"
|
|
16
25
|
:show-arrow="false"
|
|
17
26
|
:teleported="false"
|
|
@@ -38,6 +47,7 @@
|
|
|
38
47
|
:default-expanded-keys="expandedKeys"
|
|
39
48
|
@check="checkChanged"
|
|
40
49
|
:indent="8"
|
|
50
|
+
:filter-node-method="filterNode"
|
|
41
51
|
:class="[mapType === 'flatmap' ? 'hide_grandchildren_checkbox': '']"
|
|
42
52
|
>
|
|
43
53
|
<template #default="{ node, data }">
|
|
@@ -138,10 +148,15 @@ export default {
|
|
|
138
148
|
type: [String, Array],
|
|
139
149
|
required: true,
|
|
140
150
|
},
|
|
151
|
+
enableFilter: {
|
|
152
|
+
type: Boolean,
|
|
153
|
+
default: true,
|
|
154
|
+
}
|
|
141
155
|
},
|
|
142
156
|
data: function () {
|
|
143
157
|
return {
|
|
144
158
|
defaultExpandedKeys: ["All"],
|
|
159
|
+
filterText: "",
|
|
145
160
|
myPopperClass: "hide-scaffold-colour-popup",
|
|
146
161
|
tooltipVisible: false,
|
|
147
162
|
tooltipLabel: "",
|
|
@@ -178,8 +193,17 @@ export default {
|
|
|
178
193
|
else this.myPopperClass = "hide-scaffold-colour-popup";
|
|
179
194
|
},
|
|
180
195
|
},
|
|
196
|
+
filterText: {
|
|
197
|
+
handler: function (value) {
|
|
198
|
+
if (this.$refs.regionTree) this.$refs.regionTree.filter(value);
|
|
199
|
+
},
|
|
200
|
+
},
|
|
181
201
|
},
|
|
182
202
|
methods: {
|
|
203
|
+
filterNode: function(value, data) {
|
|
204
|
+
if (!value) return true;
|
|
205
|
+
return data.label ? data.label.toLowerCase().includes(value) : false;
|
|
206
|
+
},
|
|
183
207
|
setColour: function (nodeData, value) {
|
|
184
208
|
this.$emit("setColour", nodeData, value);
|
|
185
209
|
},
|
|
@@ -250,6 +274,9 @@ export default {
|
|
|
250
274
|
unmounted: function () {
|
|
251
275
|
this.sortedPrimitiveGroups = undefined;
|
|
252
276
|
},
|
|
277
|
+
mounted: function() {
|
|
278
|
+
if (this.$refs.regionTree) this.$refs.regionTree.filter(this.filterText);
|
|
279
|
+
}
|
|
253
280
|
};
|
|
254
281
|
</script>
|
|
255
282
|
|
|
@@ -265,6 +292,7 @@ export default {
|
|
|
265
292
|
}
|
|
266
293
|
|
|
267
294
|
.selections-container {
|
|
295
|
+
width: 260px;
|
|
268
296
|
padding-top: 5px;
|
|
269
297
|
}
|
|
270
298
|
|
|
@@ -278,6 +306,15 @@ export default {
|
|
|
278
306
|
margin-left: 8px;
|
|
279
307
|
}
|
|
280
308
|
|
|
309
|
+
:deep(.tree-filter-input) {
|
|
310
|
+
.el-input__inner {
|
|
311
|
+
height: 20px;
|
|
312
|
+
}
|
|
313
|
+
.el-input__wrapper.is-focus{
|
|
314
|
+
box-shadow: 0 0 0 1px $app-primary-color;
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
|
|
281
318
|
.tree-container {
|
|
282
319
|
width: 260px;
|
|
283
320
|
border: 1px solid rgb(144, 147, 153);
|
package/src/components/index.js
CHANGED
|
@@ -3,13 +3,5 @@ import HelpModeDialog from "./HelpModeDialog/HelpModeDialog.vue";
|
|
|
3
3
|
import Tooltip from "./Tooltip/Tooltip.vue";
|
|
4
4
|
import TreeControls from "./TreeControls/TreeControls.vue";
|
|
5
5
|
import CopyToClipboard from "./CopyToClipboard/CopyToClipboard.vue";
|
|
6
|
-
import ConnectivityGraph from "./ConnectivityGraph/ConnectivityGraph.vue";
|
|
7
6
|
|
|
8
|
-
export {
|
|
9
|
-
DrawToolbar,
|
|
10
|
-
HelpModeDialog,
|
|
11
|
-
Tooltip,
|
|
12
|
-
TreeControls,
|
|
13
|
-
CopyToClipboard,
|
|
14
|
-
ConnectivityGraph,
|
|
15
|
-
};
|
|
7
|
+
export { DrawToolbar, HelpModeDialog, Tooltip, TreeControls, CopyToClipboard };
|
package/src/components.d.ts
CHANGED
|
@@ -9,7 +9,6 @@ declare module 'vue' {
|
|
|
9
9
|
export interface GlobalComponents {
|
|
10
10
|
AnnotationPopup: typeof import('./components/Tooltip/AnnotationPopup.vue')['default']
|
|
11
11
|
ConnectionDialog: typeof import('./components/DrawToolbar/ConnectionDialog.vue')['default']
|
|
12
|
-
ConnectivityGraph: typeof import('./components/ConnectivityGraph/ConnectivityGraph.vue')['default']
|
|
13
12
|
CopyToClipboard: typeof import('./components/CopyToClipboard/CopyToClipboard.vue')['default']
|
|
14
13
|
DrawToolbar: typeof import('./components/DrawToolbar/DrawToolbar.vue')['default']
|
|
15
14
|
ElButton: typeof import('element-plus/es')['ElButton']
|
|
@@ -18,7 +17,6 @@ declare module 'vue' {
|
|
|
18
17
|
ElCol: typeof import('element-plus/es')['ElCol']
|
|
19
18
|
ElColorPicker: typeof import('element-plus/es')['ElColorPicker']
|
|
20
19
|
ElIcon: typeof import('element-plus/es')['ElIcon']
|
|
21
|
-
ElIconAim: typeof import('@element-plus/icons-vue')['Aim']
|
|
22
20
|
ElIconArrowDown: typeof import('@element-plus/icons-vue')['ArrowDown']
|
|
23
21
|
ElIconArrowUp: typeof import('@element-plus/icons-vue')['ArrowUp']
|
|
24
22
|
ElIconClose: typeof import('@element-plus/icons-vue')['Close']
|
|
@@ -26,8 +24,6 @@ declare module 'vue' {
|
|
|
26
24
|
ElIconDelete: typeof import('@element-plus/icons-vue')['Delete']
|
|
27
25
|
ElIconEdit: typeof import('@element-plus/icons-vue')['Edit']
|
|
28
26
|
ElIconFinished: typeof import('@element-plus/icons-vue')['Finished']
|
|
29
|
-
ElIconLock: typeof import('@element-plus/icons-vue')['Lock']
|
|
30
|
-
ElIconUnlock: typeof import('@element-plus/icons-vue')['Unlock']
|
|
31
27
|
ElIconWarning: typeof import('@element-plus/icons-vue')['Warning']
|
|
32
28
|
ElInput: typeof import('element-plus/es')['ElInput']
|
|
33
29
|
ElMain: typeof import('element-plus/es')['ElMain']
|
|
@@ -1,451 +0,0 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<div class="connectivity-graph" v-loading="loading">
|
|
3
|
-
<div ref="graphCanvas" class="graph-canvas"></div>
|
|
4
|
-
<div class="control-panel">
|
|
5
|
-
<div class="node-key">
|
|
6
|
-
<div class="key-head">Node type:</div>
|
|
7
|
-
<div>
|
|
8
|
-
<div><span>Node:</span><span class="key-box" style="background: #80F0F0"/></div>
|
|
9
|
-
<div><span>Axon:</span><span class="key-box" style="background: green"/></div>
|
|
10
|
-
<div><span>Dendrite:</span><span class="key-box" style="background: red"/></div>
|
|
11
|
-
<div><span>Both:</span><span class="key-box" style="background: gray"/></div>
|
|
12
|
-
</div>
|
|
13
|
-
</div>
|
|
14
|
-
<div class="tools">
|
|
15
|
-
<el-tooltip
|
|
16
|
-
:content="resetLabel"
|
|
17
|
-
placement="bottom"
|
|
18
|
-
effect="control-tooltip"
|
|
19
|
-
>
|
|
20
|
-
<el-button
|
|
21
|
-
class="control-button"
|
|
22
|
-
:class="theme"
|
|
23
|
-
size="small"
|
|
24
|
-
@click="reset"
|
|
25
|
-
>
|
|
26
|
-
<el-icon color="white">
|
|
27
|
-
<el-icon-aim />
|
|
28
|
-
</el-icon>
|
|
29
|
-
<span class="visually-hidden">{{ resetLabel }}</span>
|
|
30
|
-
</el-button>
|
|
31
|
-
</el-tooltip>
|
|
32
|
-
<el-tooltip
|
|
33
|
-
:content="zoomLockLabel"
|
|
34
|
-
placement="bottom"
|
|
35
|
-
effect="control-tooltip"
|
|
36
|
-
>
|
|
37
|
-
<el-button
|
|
38
|
-
class="control-button"
|
|
39
|
-
:class="theme"
|
|
40
|
-
size="small"
|
|
41
|
-
@click="toggleZoom"
|
|
42
|
-
>
|
|
43
|
-
<el-icon color="white">
|
|
44
|
-
<template v-if="zoomEnabled">
|
|
45
|
-
<el-icon-lock />
|
|
46
|
-
</template>
|
|
47
|
-
<template v-else>
|
|
48
|
-
<el-icon-unlock />
|
|
49
|
-
</template>
|
|
50
|
-
</el-icon>
|
|
51
|
-
<span class="visually-hidden">{{ zoomLockLabel }}</span>
|
|
52
|
-
</el-button>
|
|
53
|
-
</el-tooltip>
|
|
54
|
-
</div>
|
|
55
|
-
</div>
|
|
56
|
-
</div>
|
|
57
|
-
</template>
|
|
58
|
-
|
|
59
|
-
<script>
|
|
60
|
-
import { ConnectivityGraph } from './graph';
|
|
61
|
-
|
|
62
|
-
const MIN_SCHEMA_VERSION = 1.3;
|
|
63
|
-
const CACHE_LIFETIME = 24 * 60 * 60 * 1000; // One day
|
|
64
|
-
const RESET_LABEL = 'Reset position';
|
|
65
|
-
const ZOOM_LOCK_LABEL = 'Lock zoom (to scroll)';
|
|
66
|
-
const ZOOM_UNLOCK_LABEL = 'Unlock zoom';
|
|
67
|
-
const APP_PRIMARY_COLOR = '#8300bf';
|
|
68
|
-
|
|
69
|
-
export default {
|
|
70
|
-
name: 'ConnectivityGraph',
|
|
71
|
-
props: {
|
|
72
|
-
/**
|
|
73
|
-
* Entity to load its connectivity graph.
|
|
74
|
-
*/
|
|
75
|
-
entry: {
|
|
76
|
-
type: String,
|
|
77
|
-
default: '',
|
|
78
|
-
},
|
|
79
|
-
mapServer: {
|
|
80
|
-
type: String,
|
|
81
|
-
default: '',
|
|
82
|
-
},
|
|
83
|
-
},
|
|
84
|
-
data: function () {
|
|
85
|
-
return {
|
|
86
|
-
loading: true,
|
|
87
|
-
connectivityGraph: null,
|
|
88
|
-
selectedSource: '',
|
|
89
|
-
pathList: [],
|
|
90
|
-
schemaVersion: '',
|
|
91
|
-
knowledgeByPath: new Map(),
|
|
92
|
-
labelledTerms: new Set(),
|
|
93
|
-
labelCache: new Map(),
|
|
94
|
-
resetLabel: RESET_LABEL,
|
|
95
|
-
zoomLockLabel: ZOOM_LOCK_LABEL,
|
|
96
|
-
iconColor: APP_PRIMARY_COLOR,
|
|
97
|
-
zoomEnabled: false,
|
|
98
|
-
};
|
|
99
|
-
},
|
|
100
|
-
mounted() {
|
|
101
|
-
this.refreshCache();
|
|
102
|
-
this.loadCacheData();
|
|
103
|
-
this.run().then((res) => {
|
|
104
|
-
this.showGraph(this.entry);
|
|
105
|
-
});
|
|
106
|
-
},
|
|
107
|
-
methods: {
|
|
108
|
-
loadCacheData: function () {
|
|
109
|
-
const selectedSource = sessionStorage.getItem('connectivity-graph-source');
|
|
110
|
-
const labelCache = sessionStorage.getItem('connectivity-graph-labels');
|
|
111
|
-
const pathList = sessionStorage.getItem('connectivity-graph-pathlist');
|
|
112
|
-
const schemaVersion = sessionStorage.getItem('connectivity-graph-schema-version');
|
|
113
|
-
|
|
114
|
-
if (selectedSource) {
|
|
115
|
-
this.selectedSource = selectedSource;
|
|
116
|
-
}
|
|
117
|
-
if (pathList) {
|
|
118
|
-
this.pathList = JSON.parse(pathList);
|
|
119
|
-
}
|
|
120
|
-
if (labelCache) {
|
|
121
|
-
const labelCacheObj = JSON.parse(labelCache);
|
|
122
|
-
this.labelCache = new Map(Object.entries(labelCacheObj));
|
|
123
|
-
}
|
|
124
|
-
if (schemaVersion) {
|
|
125
|
-
this.schemaVersion = schemaVersion;
|
|
126
|
-
}
|
|
127
|
-
},
|
|
128
|
-
removeAllCacheData: function () {
|
|
129
|
-
const keys = [
|
|
130
|
-
'connectivity-graph-expiry',
|
|
131
|
-
'connectivity-graph-source',
|
|
132
|
-
'connectivity-graph-labels',
|
|
133
|
-
'connectivity-graph-pathlist',
|
|
134
|
-
'connectivity-graph-schema-version',
|
|
135
|
-
];
|
|
136
|
-
keys.forEach((key) => {
|
|
137
|
-
sessionStorage.removeItem(key);
|
|
138
|
-
});
|
|
139
|
-
},
|
|
140
|
-
refreshCache: function () {
|
|
141
|
-
const expiry = sessionStorage.getItem('connectivity-graph-expiry');
|
|
142
|
-
const now = new Date();
|
|
143
|
-
|
|
144
|
-
if (now.getTime() > expiry) {
|
|
145
|
-
this.removeAllCacheData();
|
|
146
|
-
}
|
|
147
|
-
},
|
|
148
|
-
updateCacheExpiry: function () {
|
|
149
|
-
const now = new Date();
|
|
150
|
-
const expiry = now.getTime() + CACHE_LIFETIME;
|
|
151
|
-
|
|
152
|
-
sessionStorage.setItem('connectivity-graph-expiry', expiry);
|
|
153
|
-
},
|
|
154
|
-
run: async function () {
|
|
155
|
-
if (!this.schemaVersion) {
|
|
156
|
-
this.schemaVersion = await this.getSchemaVersion();
|
|
157
|
-
sessionStorage.setItem('connectivity-graph-schema-version', this.schemaVersion);
|
|
158
|
-
this.updateCacheExpiry();
|
|
159
|
-
}
|
|
160
|
-
if (this.schemaVersion < MIN_SCHEMA_VERSION) {
|
|
161
|
-
console.warn('No Server!');
|
|
162
|
-
return;
|
|
163
|
-
}
|
|
164
|
-
this.showSpinner();
|
|
165
|
-
if (!this.selectedSource) {
|
|
166
|
-
this.selectedSource = await this.setSourceList();
|
|
167
|
-
sessionStorage.setItem('connectivity-graph-source', this.selectedSource);
|
|
168
|
-
this.updateCacheExpiry();
|
|
169
|
-
}
|
|
170
|
-
await this.setPathList(this.selectedSource);
|
|
171
|
-
this.hideSpinner();
|
|
172
|
-
},
|
|
173
|
-
showGraph: async function (neuronPath) {
|
|
174
|
-
const graphCanvas = this.$refs.graphCanvas;
|
|
175
|
-
|
|
176
|
-
this.showSpinner();
|
|
177
|
-
|
|
178
|
-
this.connectivityGraph = new ConnectivityGraph(this.labelCache, graphCanvas);
|
|
179
|
-
await this.connectivityGraph.addConnectivity(this.knowledgeByPath.get(neuronPath));
|
|
180
|
-
|
|
181
|
-
this.hideSpinner();
|
|
182
|
-
|
|
183
|
-
this.connectivityGraph.showConnectivity(graphCanvas);
|
|
184
|
-
},
|
|
185
|
-
query: async function (sql, params) {
|
|
186
|
-
const url = `${this.mapServer}knowledge/query/`;
|
|
187
|
-
const query = { sql, params };
|
|
188
|
-
|
|
189
|
-
try {
|
|
190
|
-
const response = await fetch(url, {
|
|
191
|
-
method: 'POST',
|
|
192
|
-
headers: {
|
|
193
|
-
"Accept": "application/json; charset=utf-8",
|
|
194
|
-
"Cache-Control": "no-store",
|
|
195
|
-
"Content-Type": "application/json"
|
|
196
|
-
},
|
|
197
|
-
body: JSON.stringify(query)
|
|
198
|
-
});
|
|
199
|
-
|
|
200
|
-
if (!response.ok) {
|
|
201
|
-
throw new Error(`Cannot access ${url}`);
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
return await response.json();
|
|
205
|
-
} catch {
|
|
206
|
-
return {
|
|
207
|
-
values: []
|
|
208
|
-
};
|
|
209
|
-
}
|
|
210
|
-
},
|
|
211
|
-
setSourceList: async function () {
|
|
212
|
-
const data = await this.getJsonData(`${this.mapServer}knowledge/sources`);
|
|
213
|
-
const sources = data ? (data.sources || []) : [];
|
|
214
|
-
|
|
215
|
-
// Order with most recent first...
|
|
216
|
-
let firstSource = '';
|
|
217
|
-
const sourceList = [];
|
|
218
|
-
|
|
219
|
-
for (const source of sources) {
|
|
220
|
-
if (source) {
|
|
221
|
-
sourceList.push(source);
|
|
222
|
-
|
|
223
|
-
if (firstSource === '') {
|
|
224
|
-
firstSource = source;
|
|
225
|
-
}
|
|
226
|
-
}
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
return firstSource;
|
|
230
|
-
},
|
|
231
|
-
loadPathData: async function (source) {
|
|
232
|
-
const data = await this.query(
|
|
233
|
-
`select entity, knowledge from knowledge
|
|
234
|
-
where entity like 'ilxtr:%' and source=?
|
|
235
|
-
order by entity`,
|
|
236
|
-
[source]);
|
|
237
|
-
const pathList = data ? data.values : [];
|
|
238
|
-
return pathList;
|
|
239
|
-
},
|
|
240
|
-
setPathList: async function (source) {
|
|
241
|
-
if (!this.pathList.length) {
|
|
242
|
-
this.pathList = await this.loadPathData(source);
|
|
243
|
-
sessionStorage.setItem('connectivity-graph-pathlist', JSON.stringify(this.pathList));
|
|
244
|
-
this.updateCacheExpiry();
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
this.knowledgeByPath.clear();
|
|
248
|
-
this.labelledTerms = new Set();
|
|
249
|
-
|
|
250
|
-
for (const [key, jsonKnowledge] of this.pathList) {
|
|
251
|
-
const knowledge = JSON.parse(jsonKnowledge);
|
|
252
|
-
if ('connectivity' in knowledge) {
|
|
253
|
-
this.knowledgeByPath.set(key, knowledge);
|
|
254
|
-
this.cacheLabels(knowledge);
|
|
255
|
-
}
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
if (!this.labelCache.size) {
|
|
259
|
-
await this.getCachedTermLabels();
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
return '';
|
|
263
|
-
},
|
|
264
|
-
getSchemaVersion: async function () {
|
|
265
|
-
const data = await this.getJsonData(`${this.mapServer}knowledge/schema-version`);
|
|
266
|
-
return data ? (+data.version || 0) : 0;
|
|
267
|
-
},
|
|
268
|
-
getJsonData: async function (url) {
|
|
269
|
-
try {
|
|
270
|
-
const response = await fetch(url, {
|
|
271
|
-
method: 'GET',
|
|
272
|
-
headers: {
|
|
273
|
-
"Accept": "application/json; charset=utf-8",
|
|
274
|
-
"Cache-Control": "no-store",
|
|
275
|
-
"Content-Type": "application/json"
|
|
276
|
-
}
|
|
277
|
-
});
|
|
278
|
-
|
|
279
|
-
if (!response.ok) {
|
|
280
|
-
console.error(`Cannot access ${url}`);
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
return await response.json();
|
|
284
|
-
} catch {
|
|
285
|
-
return null;
|
|
286
|
-
}
|
|
287
|
-
},
|
|
288
|
-
getCachedTermLabels: async function () {
|
|
289
|
-
if (this.labelledTerms.size) {
|
|
290
|
-
const data = await this.query(`
|
|
291
|
-
select entity, label from labels
|
|
292
|
-
where entity in (?${', ?'.repeat(this.labelledTerms.size-1)})`,
|
|
293
|
-
[...this.labelledTerms.values()]
|
|
294
|
-
);
|
|
295
|
-
|
|
296
|
-
for (const termLabel of data.values) {
|
|
297
|
-
this.labelCache.set(termLabel[0], termLabel[1]);
|
|
298
|
-
}
|
|
299
|
-
|
|
300
|
-
const labelCacheObj = Object.fromEntries(this.labelCache);
|
|
301
|
-
sessionStorage.setItem('connectivity-graph-labels', JSON.stringify(labelCacheObj));
|
|
302
|
-
this.updateCacheExpiry();
|
|
303
|
-
}
|
|
304
|
-
},
|
|
305
|
-
cacheNodeLabels: function (node) {
|
|
306
|
-
for (const term of [node[0], ...node[1]]) {
|
|
307
|
-
this.labelledTerms.add(term);
|
|
308
|
-
}
|
|
309
|
-
},
|
|
310
|
-
cacheLabels: async function (knowledge) {
|
|
311
|
-
for (const edge of knowledge.connectivity) {
|
|
312
|
-
this.cacheNodeLabels(edge[0]);
|
|
313
|
-
this.cacheNodeLabels(edge[1]);
|
|
314
|
-
}
|
|
315
|
-
},
|
|
316
|
-
showSpinner: function () {
|
|
317
|
-
this.loading = true;
|
|
318
|
-
},
|
|
319
|
-
hideSpinner: function () {
|
|
320
|
-
this.loading = false;
|
|
321
|
-
},
|
|
322
|
-
reset: function () {
|
|
323
|
-
this.connectivityGraph.reset();
|
|
324
|
-
},
|
|
325
|
-
/**
|
|
326
|
-
* Enable/disable user zoom for scrolling
|
|
327
|
-
*/
|
|
328
|
-
toggleZoom: function () {
|
|
329
|
-
this.zoomEnabled = !this.zoomEnabled;
|
|
330
|
-
this.zoomLockLabel = this.zoomEnabled ? ZOOM_UNLOCK_LABEL : ZOOM_LOCK_LABEL;
|
|
331
|
-
this.connectivityGraph.enableZoom(!this.zoomEnabled);
|
|
332
|
-
},
|
|
333
|
-
},
|
|
334
|
-
};
|
|
335
|
-
</script>
|
|
336
|
-
|
|
337
|
-
<style lang="scss" scoped>
|
|
338
|
-
.connectivity-graph,
|
|
339
|
-
.graph-canvas {
|
|
340
|
-
width: 100%;
|
|
341
|
-
height: 600px;
|
|
342
|
-
background-color: white;
|
|
343
|
-
position: relative;
|
|
344
|
-
}
|
|
345
|
-
|
|
346
|
-
.connectivity-graph {
|
|
347
|
-
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.06);
|
|
348
|
-
border: solid 1px #e4e7ed;
|
|
349
|
-
}
|
|
350
|
-
|
|
351
|
-
.control-panel {
|
|
352
|
-
position: absolute;
|
|
353
|
-
top: 1rem;
|
|
354
|
-
right: 1rem;
|
|
355
|
-
}
|
|
356
|
-
|
|
357
|
-
.node-key {
|
|
358
|
-
border: 1px solid $app-primary-color;
|
|
359
|
-
padding: 4px;
|
|
360
|
-
background-color: rgba(#f7faff, 0.85);
|
|
361
|
-
|
|
362
|
-
div div {
|
|
363
|
-
width: 90px;
|
|
364
|
-
}
|
|
365
|
-
}
|
|
366
|
-
|
|
367
|
-
.key-head {
|
|
368
|
-
text-align: center;
|
|
369
|
-
font-weight: bold;
|
|
370
|
-
border-bottom: 1px solid gray;
|
|
371
|
-
padding-bottom: 4px;
|
|
372
|
-
margin-bottom: 4px;
|
|
373
|
-
}
|
|
374
|
-
|
|
375
|
-
.key-box {
|
|
376
|
-
float: right;
|
|
377
|
-
width: 12px;
|
|
378
|
-
height: 12px;
|
|
379
|
-
}
|
|
380
|
-
|
|
381
|
-
.tools {
|
|
382
|
-
margin-top: 0.5rem;
|
|
383
|
-
display: flex;
|
|
384
|
-
flex-direction: row;
|
|
385
|
-
gap: 0.5rem;
|
|
386
|
-
align-items: flex-end;
|
|
387
|
-
justify-content: flex-end;
|
|
388
|
-
}
|
|
389
|
-
|
|
390
|
-
.control-button {
|
|
391
|
-
margin: 0 !important;
|
|
392
|
-
padding: 0.25rem !important;
|
|
393
|
-
font-size: 14px !important;
|
|
394
|
-
border-color: $app-primary-color !important;
|
|
395
|
-
background: $app-primary-color !important;
|
|
396
|
-
transition: all 0.25s ease;
|
|
397
|
-
|
|
398
|
-
svg {
|
|
399
|
-
margin: 0;
|
|
400
|
-
}
|
|
401
|
-
|
|
402
|
-
&,
|
|
403
|
-
&:focus,
|
|
404
|
-
&:active {
|
|
405
|
-
box-shadow: none !important;
|
|
406
|
-
}
|
|
407
|
-
|
|
408
|
-
&:hover {
|
|
409
|
-
background: $lightPurple !important;
|
|
410
|
-
}
|
|
411
|
-
}
|
|
412
|
-
|
|
413
|
-
:deep(.cy-graph-tooltip) {
|
|
414
|
-
padding: 4px 10px;
|
|
415
|
-
font-family: Asap;
|
|
416
|
-
font-size: 12px;
|
|
417
|
-
background: #f3ecf6 !important;
|
|
418
|
-
border: 1px solid $app-primary-color;
|
|
419
|
-
border-radius: var(--el-border-radius-base);
|
|
420
|
-
position: relative;
|
|
421
|
-
top: 0;
|
|
422
|
-
left: 0;
|
|
423
|
-
width: fit-content;
|
|
424
|
-
z-index: 1;
|
|
425
|
-
}
|
|
426
|
-
|
|
427
|
-
.visually-hidden {
|
|
428
|
-
clip: rect(0 0 0 0);
|
|
429
|
-
clip-path: inset(50%);
|
|
430
|
-
height: 1px;
|
|
431
|
-
overflow: hidden;
|
|
432
|
-
position: absolute;
|
|
433
|
-
white-space: nowrap;
|
|
434
|
-
width: 1px;
|
|
435
|
-
}
|
|
436
|
-
</style>
|
|
437
|
-
|
|
438
|
-
<style lang="scss">
|
|
439
|
-
.el-popper.is-control-tooltip {
|
|
440
|
-
padding: 4px 10px;
|
|
441
|
-
font-family: Asap;
|
|
442
|
-
background: #f3ecf6 !important;
|
|
443
|
-
border: 1px solid $app-primary-color;
|
|
444
|
-
|
|
445
|
-
& .el-popper__arrow::before {
|
|
446
|
-
border: 1px solid;
|
|
447
|
-
border-color: $app-primary-color;
|
|
448
|
-
background: #f3ecf6;
|
|
449
|
-
}
|
|
450
|
-
}
|
|
451
|
-
</style>
|