@abi-software/map-utilities 1.1.3-beta.1 → 1.1.3-beta.3
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 +4653 -4507
- package/dist/map-utilities.umd.cjs +28 -28
- package/dist/style.css +1 -1
- package/package.json +1 -1
- package/src/components/ConnectivityGraph/ConnectivityGraph.vue +186 -27
- package/src/components/ConnectivityGraph/graph.js +21 -6
- package/src/components.d.ts +3 -0
package/package.json
CHANGED
|
@@ -1,13 +1,56 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div class="connectivity-graph">
|
|
2
|
+
<div class="connectivity-graph" v-loading="loading">
|
|
3
3
|
<div ref="graphCanvas" class="graph-canvas"></div>
|
|
4
|
-
<div class="
|
|
5
|
-
<div class="key
|
|
6
|
-
|
|
7
|
-
<div
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
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>
|
|
11
54
|
</div>
|
|
12
55
|
</div>
|
|
13
56
|
</div>
|
|
@@ -17,6 +60,10 @@
|
|
|
17
60
|
import { ConnectivityGraph } from './graph';
|
|
18
61
|
|
|
19
62
|
const MIN_SCHEMA_VERSION = 1.3;
|
|
63
|
+
const RESET_LABEL = 'Reset position';
|
|
64
|
+
const ZOOM_LOCK_LABEL = 'Lock zoom (to scroll)';
|
|
65
|
+
const ZOOM_UNLOCK_LABEL = 'Unlock zoom';
|
|
66
|
+
const APP_PRIMARY_COLOR = '#8300bf';
|
|
20
67
|
|
|
21
68
|
export default {
|
|
22
69
|
name: 'ConnectivityGraph',
|
|
@@ -35,28 +82,62 @@ export default {
|
|
|
35
82
|
},
|
|
36
83
|
data: function () {
|
|
37
84
|
return {
|
|
38
|
-
|
|
85
|
+
loading: true,
|
|
39
86
|
connectivityGraph: null,
|
|
87
|
+
selectedSource: '',
|
|
88
|
+
pathList: [],
|
|
89
|
+
schemaVersion: '',
|
|
40
90
|
knowledgeByPath: new Map(),
|
|
41
91
|
labelledTerms: new Set(),
|
|
42
92
|
labelCache: new Map(),
|
|
93
|
+
resetLabel: RESET_LABEL,
|
|
94
|
+
zoomLockLabel: ZOOM_LOCK_LABEL,
|
|
95
|
+
iconColor: APP_PRIMARY_COLOR,
|
|
96
|
+
zoomEnabled: false,
|
|
43
97
|
};
|
|
44
98
|
},
|
|
45
99
|
mounted() {
|
|
100
|
+
this.loadCacheData();
|
|
46
101
|
this.run().then((res) => {
|
|
47
102
|
this.showGraph(this.entry);
|
|
48
103
|
});
|
|
49
104
|
},
|
|
50
105
|
methods: {
|
|
106
|
+
loadCacheData: function () {
|
|
107
|
+
const selectedSource = sessionStorage.getItem('connectivity-graph-source');
|
|
108
|
+
const labelCache = sessionStorage.getItem('connectivity-graph-labels');
|
|
109
|
+
const pathList = sessionStorage.getItem('connectivity-graph-pathlist');
|
|
110
|
+
const schemaVersion = sessionStorage.getItem('connectivity-graph-schema-version');
|
|
111
|
+
|
|
112
|
+
if (selectedSource) {
|
|
113
|
+
this.selectedSource = selectedSource;
|
|
114
|
+
}
|
|
115
|
+
if (pathList) {
|
|
116
|
+
this.pathList = JSON.parse(pathList);
|
|
117
|
+
}
|
|
118
|
+
if (labelCache) {
|
|
119
|
+
const labelCacheObj = JSON.parse(labelCache);
|
|
120
|
+
this.labelCache = new Map(Object.entries(labelCacheObj));
|
|
121
|
+
}
|
|
122
|
+
if (schemaVersion) {
|
|
123
|
+
this.schemaVersion = schemaVersion;
|
|
124
|
+
}
|
|
125
|
+
},
|
|
51
126
|
run: async function () {
|
|
52
|
-
|
|
53
|
-
|
|
127
|
+
if (!this.schemaVersion) {
|
|
128
|
+
this.schemaVersion = await this.getSchemaVersion();
|
|
129
|
+
sessionStorage.setItem('connectivity-graph-schema-version', this.schemaVersion);
|
|
130
|
+
}
|
|
131
|
+
if (this.schemaVersion < MIN_SCHEMA_VERSION) {
|
|
54
132
|
console.warn('No Server!');
|
|
55
133
|
return;
|
|
56
134
|
}
|
|
57
135
|
this.showSpinner();
|
|
58
|
-
|
|
59
|
-
|
|
136
|
+
if (!this.selectedSource) {
|
|
137
|
+
this.selectedSource = await this.setSourceList();
|
|
138
|
+
sessionStorage.setItem('connectivity-graph-source', this.selectedSource);
|
|
139
|
+
}
|
|
140
|
+
await this.setPathList(this.selectedSource)
|
|
60
141
|
this.hideSpinner();
|
|
61
142
|
},
|
|
62
143
|
showGraph: async function (neuronPath) {
|
|
@@ -108,28 +189,33 @@ export default {
|
|
|
108
189
|
}
|
|
109
190
|
return firstSource;
|
|
110
191
|
},
|
|
111
|
-
|
|
192
|
+
loadPathData: async function (source) {
|
|
112
193
|
const data = await this.query(
|
|
113
194
|
`select entity, knowledge from knowledge
|
|
114
195
|
where entity like 'ilxtr:%' and source=?
|
|
115
196
|
order by entity`,
|
|
116
197
|
[source]);
|
|
117
|
-
const pathList = [];
|
|
198
|
+
const pathList = data ? data.values : [];
|
|
199
|
+
return pathList;
|
|
200
|
+
},
|
|
201
|
+
setPathList: async function (source) {
|
|
202
|
+
if (!this.pathList.length) {
|
|
203
|
+
this.pathList = await this.loadPathData(source);
|
|
204
|
+
sessionStorage.setItem('connectivity-graph-pathlist', JSON.stringify(this.pathList));
|
|
205
|
+
}
|
|
118
206
|
this.knowledgeByPath.clear();
|
|
119
207
|
this.labelledTerms = new Set();
|
|
120
|
-
for (const [key, jsonKnowledge] of
|
|
208
|
+
for (const [key, jsonKnowledge] of this.pathList) {
|
|
121
209
|
const knowledge = JSON.parse(jsonKnowledge);
|
|
122
210
|
if ('connectivity' in knowledge) {
|
|
123
|
-
const label = knowledge.label || key;
|
|
124
|
-
const shortLabel = (label === key.slice(6).replace('-prime', "'").replaceAll('-', ' '))
|
|
125
|
-
? ''
|
|
126
|
-
: (label.length < 50) ? label : `${label.slice(0, 50)}...`;
|
|
127
|
-
pathList.push(key);
|
|
128
211
|
this.knowledgeByPath.set(key, knowledge);
|
|
129
212
|
this.cacheLabels(knowledge);
|
|
130
213
|
}
|
|
131
214
|
}
|
|
132
|
-
|
|
215
|
+
|
|
216
|
+
if (!this.labelCache.size) {
|
|
217
|
+
await this.getCachedTermLabels();
|
|
218
|
+
}
|
|
133
219
|
return '';
|
|
134
220
|
},
|
|
135
221
|
getSchemaVersion: async function () {
|
|
@@ -156,14 +242,16 @@ export default {
|
|
|
156
242
|
},
|
|
157
243
|
getCachedTermLabels: async function () {
|
|
158
244
|
if (this.labelledTerms.size) {
|
|
159
|
-
const
|
|
245
|
+
const data = await this.query(`
|
|
160
246
|
select entity, label from labels
|
|
161
247
|
where entity in (?${', ?'.repeat(this.labelledTerms.size-1)})`,
|
|
162
248
|
[...this.labelledTerms.values()]
|
|
163
249
|
);
|
|
164
|
-
for (const termLabel of
|
|
250
|
+
for (const termLabel of data.values) {
|
|
165
251
|
this.labelCache.set(termLabel[0], termLabel[1]);
|
|
166
252
|
}
|
|
253
|
+
const labelCacheObj = Object.fromEntries(this.labelCache);
|
|
254
|
+
sessionStorage.setItem('connectivity-graph-labels', JSON.stringify(labelCacheObj));
|
|
167
255
|
}
|
|
168
256
|
},
|
|
169
257
|
cacheNodeLabels: function (node) {
|
|
@@ -178,10 +266,21 @@ export default {
|
|
|
178
266
|
}
|
|
179
267
|
},
|
|
180
268
|
showSpinner: function () {
|
|
181
|
-
|
|
269
|
+
this.loading = true;
|
|
182
270
|
},
|
|
183
271
|
hideSpinner: function () {
|
|
184
|
-
|
|
272
|
+
this.loading = false;
|
|
273
|
+
},
|
|
274
|
+
reset: function () {
|
|
275
|
+
this.connectivityGraph.reset();
|
|
276
|
+
},
|
|
277
|
+
/**
|
|
278
|
+
* Enable/disable user zoom for scrolling
|
|
279
|
+
*/
|
|
280
|
+
toggleZoom: function () {
|
|
281
|
+
this.zoomEnabled = !this.zoomEnabled;
|
|
282
|
+
this.zoomLockLabel = this.zoomEnabled ? ZOOM_UNLOCK_LABEL : ZOOM_LOCK_LABEL;
|
|
283
|
+
this.connectivityGraph.enableZoom(!this.zoomEnabled);
|
|
185
284
|
},
|
|
186
285
|
},
|
|
187
286
|
};
|
|
@@ -201,10 +300,13 @@ export default {
|
|
|
201
300
|
border: solid 1px #e4e7ed;
|
|
202
301
|
}
|
|
203
302
|
|
|
204
|
-
.
|
|
303
|
+
.control-panel {
|
|
205
304
|
position: absolute;
|
|
206
305
|
top: 1rem;
|
|
207
306
|
right: 1rem;
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
.node-key {
|
|
208
310
|
border: 1px solid $app-primary-color;
|
|
209
311
|
padding: 4px;
|
|
210
312
|
background-color: rgba(240, 240, 240, 0.8);
|
|
@@ -227,4 +329,61 @@ export default {
|
|
|
227
329
|
width: 12px;
|
|
228
330
|
height: 12px;
|
|
229
331
|
}
|
|
332
|
+
|
|
333
|
+
.tools {
|
|
334
|
+
margin-top: 0.5rem;
|
|
335
|
+
display: flex;
|
|
336
|
+
flex-direction: row;
|
|
337
|
+
gap: 0.5rem;
|
|
338
|
+
align-items: flex-end;
|
|
339
|
+
justify-content: flex-end;
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
.control-button {
|
|
343
|
+
margin: 0 !important;
|
|
344
|
+
padding: 0.25rem !important;
|
|
345
|
+
font-size: 14px !important;
|
|
346
|
+
border-color: $app-primary-color !important;
|
|
347
|
+
background: $app-primary-color !important;
|
|
348
|
+
transition: all 0.25s ease;
|
|
349
|
+
|
|
350
|
+
svg {
|
|
351
|
+
margin: 0;
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
&,
|
|
355
|
+
&:focus,
|
|
356
|
+
&:active {
|
|
357
|
+
box-shadow: none !important;
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
&:hover {
|
|
361
|
+
background: $lightPurple !important;
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
.visually-hidden {
|
|
366
|
+
clip: rect(0 0 0 0);
|
|
367
|
+
clip-path: inset(50%);
|
|
368
|
+
height: 1px;
|
|
369
|
+
overflow: hidden;
|
|
370
|
+
position: absolute;
|
|
371
|
+
white-space: nowrap;
|
|
372
|
+
width: 1px;
|
|
373
|
+
}
|
|
374
|
+
</style>
|
|
375
|
+
|
|
376
|
+
<style lang="scss">
|
|
377
|
+
.el-popper.is-control-tooltip {
|
|
378
|
+
padding: 4px 10px;
|
|
379
|
+
font-family: Asap;
|
|
380
|
+
background: #f3ecf6 !important;
|
|
381
|
+
border: 1px solid $app-primary-color;
|
|
382
|
+
|
|
383
|
+
& .el-popper__arrow::before {
|
|
384
|
+
border: 1px solid;
|
|
385
|
+
border-color: $app-primary-color;
|
|
386
|
+
background: #f3ecf6;
|
|
387
|
+
}
|
|
388
|
+
}
|
|
230
389
|
</style>
|
|
@@ -27,7 +27,7 @@ import cytoscape from 'cytoscape'
|
|
|
27
27
|
|
|
28
28
|
export class ConnectivityGraph
|
|
29
29
|
{
|
|
30
|
-
|
|
30
|
+
cyg = null
|
|
31
31
|
nodes = []
|
|
32
32
|
edges = []
|
|
33
33
|
axons = []
|
|
@@ -69,15 +69,31 @@ export class ConnectivityGraph
|
|
|
69
69
|
showConnectivity(graphCanvas)
|
|
70
70
|
//================
|
|
71
71
|
{
|
|
72
|
-
this.
|
|
72
|
+
this.cyg = new CytoscapeGraph(this, graphCanvas)
|
|
73
73
|
}
|
|
74
74
|
|
|
75
75
|
clearConnectivity()
|
|
76
76
|
//=================
|
|
77
77
|
{
|
|
78
|
-
if (this.cy) {
|
|
79
|
-
this.cy.remove()
|
|
80
|
-
this.cy = null
|
|
78
|
+
if (this.cyg?.cy) {
|
|
79
|
+
this.cyg.cy.remove()
|
|
80
|
+
this.cyg.cy = null
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
reset()
|
|
85
|
+
//=================
|
|
86
|
+
{
|
|
87
|
+
if (this.cyg?.cy) {
|
|
88
|
+
this.cyg.cy.reset()
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
enableZoom(option)
|
|
93
|
+
//=================
|
|
94
|
+
{
|
|
95
|
+
if (this.cyg?.cy) {
|
|
96
|
+
this.cyg.cy.userZoomingEnabled(option)
|
|
81
97
|
}
|
|
82
98
|
}
|
|
83
99
|
|
|
@@ -179,7 +195,6 @@ class CytoscapeGraph
|
|
|
179
195
|
|
|
180
196
|
constructor(connectivityGraph, graphCanvas)
|
|
181
197
|
{
|
|
182
|
-
// const graphCanvas = document.getElementById('graph-canvas')
|
|
183
198
|
this.cy = cytoscape({
|
|
184
199
|
container: graphCanvas,
|
|
185
200
|
elements: connectivityGraph.elements,
|
package/src/components.d.ts
CHANGED
|
@@ -18,6 +18,7 @@ declare module 'vue' {
|
|
|
18
18
|
ElCol: typeof import('element-plus/es')['ElCol']
|
|
19
19
|
ElColorPicker: typeof import('element-plus/es')['ElColorPicker']
|
|
20
20
|
ElIcon: typeof import('element-plus/es')['ElIcon']
|
|
21
|
+
ElIconAim: typeof import('@element-plus/icons-vue')['Aim']
|
|
21
22
|
ElIconArrowDown: typeof import('@element-plus/icons-vue')['ArrowDown']
|
|
22
23
|
ElIconArrowUp: typeof import('@element-plus/icons-vue')['ArrowUp']
|
|
23
24
|
ElIconClose: typeof import('@element-plus/icons-vue')['Close']
|
|
@@ -25,6 +26,8 @@ declare module 'vue' {
|
|
|
25
26
|
ElIconDelete: typeof import('@element-plus/icons-vue')['Delete']
|
|
26
27
|
ElIconEdit: typeof import('@element-plus/icons-vue')['Edit']
|
|
27
28
|
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']
|
|
28
31
|
ElIconWarning: typeof import('@element-plus/icons-vue')['Warning']
|
|
29
32
|
ElInput: typeof import('element-plus/es')['ElInput']
|
|
30
33
|
ElMain: typeof import('element-plus/es')['ElMain']
|