@abi-software/map-utilities 1.1.3-beta.1 → 1.1.3-beta.11
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 +5894 -5532
- package/dist/map-utilities.umd.cjs +37 -32
- package/dist/style.css +1 -1
- package/package.json +1 -1
- package/src/App.vue +9 -2
- package/src/components/ConnectivityGraph/ConnectivityGraph.vue +444 -43
- package/src/components/ConnectivityGraph/graph.js +121 -22
- package/src/components/TreeControls/TreeControls.vue +38 -1
- package/src/components.d.ts +5 -0
package/package.json
CHANGED
package/src/App.vue
CHANGED
|
@@ -39,6 +39,9 @@ const drawnTypes = [
|
|
|
39
39
|
{ value: "None", label: "None" },
|
|
40
40
|
];
|
|
41
41
|
const showConnectivityGraph = ref(false);
|
|
42
|
+
const connectivityGraphEntry = "ilxtr:neuron-type-aacar-13";
|
|
43
|
+
// const connectivityGraphEntry = "ilxtr:sparc-nlp/kidney/134";
|
|
44
|
+
const mapServer = "https://mapcore-demo.org/curation/flatmap/";
|
|
42
45
|
|
|
43
46
|
onMounted(() => {
|
|
44
47
|
console.log("🚀 ~ onMounted ~ appRef:", appRef.value);
|
|
@@ -513,8 +516,8 @@ function changeHover(value) {
|
|
|
513
516
|
/>
|
|
514
517
|
<ConnectivityGraph
|
|
515
518
|
v-if="showConnectivityGraph"
|
|
516
|
-
entry="
|
|
517
|
-
map-server="
|
|
519
|
+
:entry="connectivityGraphEntry"
|
|
520
|
+
:map-server="mapServer"
|
|
518
521
|
/>
|
|
519
522
|
</div>
|
|
520
523
|
</template>
|
|
@@ -533,6 +536,10 @@ function changeHover(value) {
|
|
|
533
536
|
top: calc(50% - 100px);
|
|
534
537
|
left: calc(50% - 200px);
|
|
535
538
|
}
|
|
539
|
+
.toolbar-container {
|
|
540
|
+
height: 80px;
|
|
541
|
+
position: relative;
|
|
542
|
+
}
|
|
536
543
|
.connectivity-graph {
|
|
537
544
|
width: 600px;
|
|
538
545
|
height: 600px;
|
|
@@ -1,15 +1,115 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div class="connectivity-graph">
|
|
2
|
+
<div class="connectivity-graph" v-loading="loading">
|
|
3
|
+
|
|
3
4
|
<div ref="graphCanvas" class="graph-canvas"></div>
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
<div>
|
|
7
|
-
<
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
5
|
+
|
|
6
|
+
<div class="control-panel control-panel-tools">
|
|
7
|
+
<div class="tools" :class="{'zoom-locked': zoomEnabled}">
|
|
8
|
+
<el-tooltip
|
|
9
|
+
:content="resetLabel"
|
|
10
|
+
placement="top"
|
|
11
|
+
effect="control-tooltip"
|
|
12
|
+
>
|
|
13
|
+
<el-button
|
|
14
|
+
class="control-button"
|
|
15
|
+
:class="theme"
|
|
16
|
+
size="small"
|
|
17
|
+
@click="reset"
|
|
18
|
+
>
|
|
19
|
+
<el-icon color="white">
|
|
20
|
+
<el-icon-aim />
|
|
21
|
+
</el-icon>
|
|
22
|
+
<span class="visually-hidden">{{ resetLabel }}</span>
|
|
23
|
+
</el-button>
|
|
24
|
+
</el-tooltip>
|
|
25
|
+
|
|
26
|
+
<el-tooltip
|
|
27
|
+
:content="zoomLockLabel"
|
|
28
|
+
placement="top"
|
|
29
|
+
effect="control-tooltip"
|
|
30
|
+
>
|
|
31
|
+
<el-button
|
|
32
|
+
class="control-button"
|
|
33
|
+
:class="theme"
|
|
34
|
+
size="small"
|
|
35
|
+
@click="toggleZoom"
|
|
36
|
+
>
|
|
37
|
+
<el-icon color="white">
|
|
38
|
+
<template v-if="zoomEnabled">
|
|
39
|
+
<el-icon-lock />
|
|
40
|
+
</template>
|
|
41
|
+
<template v-else>
|
|
42
|
+
<el-icon-unlock />
|
|
43
|
+
</template>
|
|
44
|
+
</el-icon>
|
|
45
|
+
<span class="visually-hidden">{{ zoomLockLabel }}</span>
|
|
46
|
+
</el-button>
|
|
47
|
+
</el-tooltip>
|
|
48
|
+
|
|
49
|
+
<el-tooltip
|
|
50
|
+
:content="zoomInLabel"
|
|
51
|
+
placement="left"
|
|
52
|
+
effect="control-tooltip"
|
|
53
|
+
>
|
|
54
|
+
<el-button
|
|
55
|
+
class="control-button"
|
|
56
|
+
:class="theme"
|
|
57
|
+
size="small"
|
|
58
|
+
@click="zoomIn"
|
|
59
|
+
>
|
|
60
|
+
<el-icon color="white">
|
|
61
|
+
<el-icon-zoom-in />
|
|
62
|
+
</el-icon>
|
|
63
|
+
<span class="visually-hidden">{{ zoomInLabel }}</span>
|
|
64
|
+
</el-button>
|
|
65
|
+
</el-tooltip>
|
|
66
|
+
|
|
67
|
+
<el-tooltip
|
|
68
|
+
:content="zoomOutLabel"
|
|
69
|
+
placement="left"
|
|
70
|
+
effect="control-tooltip"
|
|
71
|
+
>
|
|
72
|
+
<el-button
|
|
73
|
+
class="control-button"
|
|
74
|
+
:class="theme"
|
|
75
|
+
size="small"
|
|
76
|
+
@click="zoomOut"
|
|
77
|
+
>
|
|
78
|
+
<el-icon color="white">
|
|
79
|
+
<el-icon-zoom-out />
|
|
80
|
+
</el-icon>
|
|
81
|
+
<span class="visually-hidden">{{ zoomOutLabel }}</span>
|
|
82
|
+
</el-button>
|
|
83
|
+
</el-tooltip>
|
|
84
|
+
</div>
|
|
85
|
+
</div>
|
|
86
|
+
|
|
87
|
+
<div class="control-panel control-panel-nodes">
|
|
88
|
+
<div class="node-key">
|
|
89
|
+
<!-- <div class="key-head">Node type:</div> -->
|
|
90
|
+
<div class="key-box-container">
|
|
91
|
+
<div class="key-box key-box-dendrite">
|
|
92
|
+
Origin
|
|
93
|
+
</div>
|
|
94
|
+
<div class="key-box key-box-node">
|
|
95
|
+
Components
|
|
96
|
+
</div>
|
|
97
|
+
<div class="key-box key-box-axon">
|
|
98
|
+
Destination
|
|
99
|
+
</div>
|
|
100
|
+
<!--
|
|
101
|
+
<div class="key-box key-box-both">
|
|
102
|
+
Both
|
|
103
|
+
</div>
|
|
104
|
+
-->
|
|
105
|
+
</div>
|
|
11
106
|
</div>
|
|
12
107
|
</div>
|
|
108
|
+
|
|
109
|
+
<div class="connectivity-graph-error" v-if="errorMessage">
|
|
110
|
+
{{ errorMessage }}
|
|
111
|
+
</div>
|
|
112
|
+
|
|
13
113
|
</div>
|
|
14
114
|
</template>
|
|
15
115
|
|
|
@@ -17,6 +117,14 @@
|
|
|
17
117
|
import { ConnectivityGraph } from './graph';
|
|
18
118
|
|
|
19
119
|
const MIN_SCHEMA_VERSION = 1.3;
|
|
120
|
+
const CACHE_LIFETIME = 24 * 60 * 60 * 1000; // One day
|
|
121
|
+
const RESET_LABEL = 'Reset position';
|
|
122
|
+
const ZOOM_LOCK_LABEL = 'Lock zoom';
|
|
123
|
+
const ZOOM_UNLOCK_LABEL = 'Unlock zoom';
|
|
124
|
+
const ZOOM_IN_LABEL = 'Zoom in';
|
|
125
|
+
const ZOOM_OUT_LABEL = 'Zoom out';
|
|
126
|
+
const ZOOM_INCREMENT = 0.25;
|
|
127
|
+
const APP_PRIMARY_COLOR = '#8300bf';
|
|
20
128
|
|
|
21
129
|
export default {
|
|
22
130
|
name: 'ConnectivityGraph',
|
|
@@ -35,42 +143,121 @@ export default {
|
|
|
35
143
|
},
|
|
36
144
|
data: function () {
|
|
37
145
|
return {
|
|
38
|
-
|
|
146
|
+
loading: true,
|
|
39
147
|
connectivityGraph: null,
|
|
148
|
+
selectedSource: '',
|
|
149
|
+
pathList: [],
|
|
150
|
+
schemaVersion: '',
|
|
40
151
|
knowledgeByPath: new Map(),
|
|
41
152
|
labelledTerms: new Set(),
|
|
42
153
|
labelCache: new Map(),
|
|
154
|
+
resetLabel: RESET_LABEL,
|
|
155
|
+
zoomLockLabel: ZOOM_LOCK_LABEL,
|
|
156
|
+
zoomInLabel: ZOOM_IN_LABEL,
|
|
157
|
+
zoomOutLabel: ZOOM_OUT_LABEL,
|
|
158
|
+
iconColor: APP_PRIMARY_COLOR,
|
|
159
|
+
zoomEnabled: false,
|
|
160
|
+
errorMessage: '',
|
|
43
161
|
};
|
|
44
162
|
},
|
|
45
163
|
mounted() {
|
|
164
|
+
this.refreshCache();
|
|
165
|
+
this.loadCacheData();
|
|
46
166
|
this.run().then((res) => {
|
|
47
167
|
this.showGraph(this.entry);
|
|
48
168
|
});
|
|
49
169
|
},
|
|
50
170
|
methods: {
|
|
171
|
+
loadCacheData: function () {
|
|
172
|
+
const selectedSource = sessionStorage.getItem('connectivity-graph-source');
|
|
173
|
+
const labelCache = sessionStorage.getItem('connectivity-graph-labels');
|
|
174
|
+
const pathList = sessionStorage.getItem('connectivity-graph-pathlist');
|
|
175
|
+
const schemaVersion = sessionStorage.getItem('connectivity-graph-schema-version');
|
|
176
|
+
|
|
177
|
+
if (selectedSource) {
|
|
178
|
+
this.selectedSource = selectedSource;
|
|
179
|
+
}
|
|
180
|
+
if (pathList) {
|
|
181
|
+
this.pathList = JSON.parse(pathList);
|
|
182
|
+
}
|
|
183
|
+
if (labelCache) {
|
|
184
|
+
const labelCacheObj = JSON.parse(labelCache);
|
|
185
|
+
this.labelCache = new Map(Object.entries(labelCacheObj));
|
|
186
|
+
}
|
|
187
|
+
if (schemaVersion) {
|
|
188
|
+
this.schemaVersion = schemaVersion;
|
|
189
|
+
}
|
|
190
|
+
},
|
|
191
|
+
removeAllCacheData: function () {
|
|
192
|
+
const keys = [
|
|
193
|
+
'connectivity-graph-expiry',
|
|
194
|
+
'connectivity-graph-source',
|
|
195
|
+
'connectivity-graph-labels',
|
|
196
|
+
'connectivity-graph-pathlist',
|
|
197
|
+
'connectivity-graph-schema-version',
|
|
198
|
+
];
|
|
199
|
+
keys.forEach((key) => {
|
|
200
|
+
sessionStorage.removeItem(key);
|
|
201
|
+
});
|
|
202
|
+
},
|
|
203
|
+
refreshCache: function () {
|
|
204
|
+
const expiry = sessionStorage.getItem('connectivity-graph-expiry');
|
|
205
|
+
const now = new Date();
|
|
206
|
+
|
|
207
|
+
if (now.getTime() > expiry) {
|
|
208
|
+
this.removeAllCacheData();
|
|
209
|
+
}
|
|
210
|
+
},
|
|
211
|
+
updateCacheExpiry: function () {
|
|
212
|
+
const now = new Date();
|
|
213
|
+
const expiry = now.getTime() + CACHE_LIFETIME;
|
|
214
|
+
|
|
215
|
+
sessionStorage.setItem('connectivity-graph-expiry', expiry);
|
|
216
|
+
},
|
|
51
217
|
run: async function () {
|
|
52
|
-
|
|
53
|
-
|
|
218
|
+
if (!this.schemaVersion) {
|
|
219
|
+
this.schemaVersion = await this.getSchemaVersion();
|
|
220
|
+
sessionStorage.setItem('connectivity-graph-schema-version', this.schemaVersion);
|
|
221
|
+
this.updateCacheExpiry();
|
|
222
|
+
}
|
|
223
|
+
if (this.schemaVersion < MIN_SCHEMA_VERSION) {
|
|
54
224
|
console.warn('No Server!');
|
|
55
225
|
return;
|
|
56
226
|
}
|
|
57
227
|
this.showSpinner();
|
|
58
|
-
|
|
59
|
-
|
|
228
|
+
if (!this.selectedSource) {
|
|
229
|
+
this.selectedSource = await this.setSourceList();
|
|
230
|
+
sessionStorage.setItem('connectivity-graph-source', this.selectedSource);
|
|
231
|
+
this.updateCacheExpiry();
|
|
232
|
+
}
|
|
233
|
+
await this.setPathList(this.selectedSource);
|
|
60
234
|
this.hideSpinner();
|
|
61
235
|
},
|
|
62
236
|
showGraph: async function (neuronPath) {
|
|
63
237
|
const graphCanvas = this.$refs.graphCanvas;
|
|
238
|
+
|
|
64
239
|
this.showSpinner();
|
|
240
|
+
|
|
65
241
|
this.connectivityGraph = new ConnectivityGraph(this.labelCache, graphCanvas);
|
|
66
242
|
await this.connectivityGraph.addConnectivity(this.knowledgeByPath.get(neuronPath));
|
|
243
|
+
|
|
67
244
|
this.hideSpinner();
|
|
245
|
+
|
|
68
246
|
this.connectivityGraph.showConnectivity(graphCanvas);
|
|
69
|
-
|
|
247
|
+
|
|
248
|
+
this.connectivityGraph.on('tap-node', (event) => {
|
|
249
|
+
const { label } = event.detail;
|
|
250
|
+
const labels = label ? label.split(`\n`) : [];
|
|
251
|
+
/**
|
|
252
|
+
* This event is triggered after a node on the connectivity graph is clicked.
|
|
253
|
+
*/
|
|
254
|
+
this.$emit('tap-node', labels);
|
|
255
|
+
});
|
|
70
256
|
},
|
|
71
257
|
query: async function (sql, params) {
|
|
72
258
|
const url = `${this.mapServer}knowledge/query/`;
|
|
73
|
-
const query = { sql, params }
|
|
259
|
+
const query = { sql, params };
|
|
260
|
+
|
|
74
261
|
try {
|
|
75
262
|
const response = await fetch(url, {
|
|
76
263
|
method: 'POST',
|
|
@@ -81,9 +268,11 @@ export default {
|
|
|
81
268
|
},
|
|
82
269
|
body: JSON.stringify(query)
|
|
83
270
|
});
|
|
271
|
+
|
|
84
272
|
if (!response.ok) {
|
|
85
273
|
throw new Error(`Cannot access ${url}`);
|
|
86
274
|
}
|
|
275
|
+
|
|
87
276
|
return await response.json();
|
|
88
277
|
} catch {
|
|
89
278
|
return {
|
|
@@ -98,38 +287,50 @@ export default {
|
|
|
98
287
|
// Order with most recent first...
|
|
99
288
|
let firstSource = '';
|
|
100
289
|
const sourceList = [];
|
|
290
|
+
|
|
101
291
|
for (const source of sources) {
|
|
102
292
|
if (source) {
|
|
103
293
|
sourceList.push(source);
|
|
294
|
+
|
|
104
295
|
if (firstSource === '') {
|
|
105
296
|
firstSource = source;
|
|
106
297
|
}
|
|
107
298
|
}
|
|
108
299
|
}
|
|
300
|
+
|
|
109
301
|
return firstSource;
|
|
110
302
|
},
|
|
111
|
-
|
|
303
|
+
loadPathData: async function (source) {
|
|
112
304
|
const data = await this.query(
|
|
113
305
|
`select entity, knowledge from knowledge
|
|
114
306
|
where entity like 'ilxtr:%' and source=?
|
|
115
307
|
order by entity`,
|
|
116
308
|
[source]);
|
|
117
|
-
const pathList = [];
|
|
309
|
+
const pathList = data ? data.values : [];
|
|
310
|
+
return pathList;
|
|
311
|
+
},
|
|
312
|
+
setPathList: async function (source) {
|
|
313
|
+
if (!this.pathList.length) {
|
|
314
|
+
this.pathList = await this.loadPathData(source);
|
|
315
|
+
sessionStorage.setItem('connectivity-graph-pathlist', JSON.stringify(this.pathList));
|
|
316
|
+
this.updateCacheExpiry();
|
|
317
|
+
}
|
|
318
|
+
|
|
118
319
|
this.knowledgeByPath.clear();
|
|
119
320
|
this.labelledTerms = new Set();
|
|
120
|
-
|
|
321
|
+
|
|
322
|
+
for (const [key, jsonKnowledge] of this.pathList) {
|
|
121
323
|
const knowledge = JSON.parse(jsonKnowledge);
|
|
122
324
|
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
325
|
this.knowledgeByPath.set(key, knowledge);
|
|
129
326
|
this.cacheLabels(knowledge);
|
|
130
327
|
}
|
|
131
328
|
}
|
|
132
|
-
|
|
329
|
+
|
|
330
|
+
if (!this.labelCache.size) {
|
|
331
|
+
await this.getCachedTermLabels();
|
|
332
|
+
}
|
|
333
|
+
|
|
133
334
|
return '';
|
|
134
335
|
},
|
|
135
336
|
getSchemaVersion: async function () {
|
|
@@ -146,9 +347,11 @@ export default {
|
|
|
146
347
|
"Content-Type": "application/json"
|
|
147
348
|
}
|
|
148
349
|
});
|
|
350
|
+
|
|
149
351
|
if (!response.ok) {
|
|
150
352
|
console.error(`Cannot access ${url}`);
|
|
151
353
|
}
|
|
354
|
+
|
|
152
355
|
return await response.json();
|
|
153
356
|
} catch {
|
|
154
357
|
return null;
|
|
@@ -156,14 +359,25 @@ export default {
|
|
|
156
359
|
},
|
|
157
360
|
getCachedTermLabels: async function () {
|
|
158
361
|
if (this.labelledTerms.size) {
|
|
159
|
-
const
|
|
160
|
-
select entity,
|
|
161
|
-
|
|
362
|
+
const data = await this.query(
|
|
363
|
+
`select entity, knowledge from knowledge
|
|
364
|
+
where entity in (?${', ?'.repeat(this.labelledTerms.size-1)})
|
|
365
|
+
order by source desc`,
|
|
162
366
|
[...this.labelledTerms.values()]
|
|
163
367
|
);
|
|
164
|
-
|
|
165
|
-
|
|
368
|
+
|
|
369
|
+
let last_entity = null;
|
|
370
|
+
for (const [key, jsonKnowledge] of data.values) {
|
|
371
|
+
if (key !== last_entity) {
|
|
372
|
+
const knowledge = JSON.parse(jsonKnowledge);
|
|
373
|
+
this.labelCache.set(key, knowledge['label'] || key);
|
|
374
|
+
last_entity = key;
|
|
375
|
+
}
|
|
166
376
|
}
|
|
377
|
+
|
|
378
|
+
const labelCacheObj = Object.fromEntries(this.labelCache);
|
|
379
|
+
sessionStorage.setItem('connectivity-graph-labels', JSON.stringify(labelCacheObj));
|
|
380
|
+
this.updateCacheExpiry();
|
|
167
381
|
}
|
|
168
382
|
},
|
|
169
383
|
cacheNodeLabels: function (node) {
|
|
@@ -178,10 +392,34 @@ export default {
|
|
|
178
392
|
}
|
|
179
393
|
},
|
|
180
394
|
showSpinner: function () {
|
|
181
|
-
|
|
395
|
+
this.loading = true;
|
|
182
396
|
},
|
|
183
397
|
hideSpinner: function () {
|
|
184
|
-
|
|
398
|
+
this.loading = false;
|
|
399
|
+
},
|
|
400
|
+
reset: function () {
|
|
401
|
+
this.connectivityGraph.reset();
|
|
402
|
+
},
|
|
403
|
+
zoomIn: function () {
|
|
404
|
+
this.connectivityGraph.zoom(ZOOM_INCREMENT);
|
|
405
|
+
},
|
|
406
|
+
zoomOut: function () {
|
|
407
|
+
this.connectivityGraph.zoom(-ZOOM_INCREMENT);
|
|
408
|
+
},
|
|
409
|
+
/**
|
|
410
|
+
* Enable/disable user zoom for scrolling
|
|
411
|
+
*/
|
|
412
|
+
toggleZoom: function () {
|
|
413
|
+
this.zoomEnabled = !this.zoomEnabled;
|
|
414
|
+
this.zoomLockLabel = this.zoomEnabled ? ZOOM_UNLOCK_LABEL : ZOOM_LOCK_LABEL;
|
|
415
|
+
this.connectivityGraph.enableZoom(!this.zoomEnabled);
|
|
416
|
+
},
|
|
417
|
+
showErrorMessage: function (errorMessage) {
|
|
418
|
+
this.errorMessage = errorMessage;
|
|
419
|
+
// Show error for 3 seconds
|
|
420
|
+
setTimeout(() => {
|
|
421
|
+
this.errorMessage = '';
|
|
422
|
+
}, 3000);
|
|
185
423
|
},
|
|
186
424
|
},
|
|
187
425
|
};
|
|
@@ -201,30 +439,193 @@ export default {
|
|
|
201
439
|
border: solid 1px #e4e7ed;
|
|
202
440
|
}
|
|
203
441
|
|
|
204
|
-
.
|
|
442
|
+
.control-panel {
|
|
205
443
|
position: absolute;
|
|
206
|
-
top: 1rem;
|
|
207
444
|
right: 1rem;
|
|
208
|
-
border: 1px solid $app-primary-color;
|
|
209
|
-
padding: 4px;
|
|
210
|
-
background-color: rgba(240, 240, 240, 0.8);
|
|
211
445
|
|
|
212
|
-
|
|
213
|
-
|
|
446
|
+
&-tools {
|
|
447
|
+
top: 1rem;
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
&-nodes {
|
|
451
|
+
bottom: 1rem;
|
|
214
452
|
}
|
|
215
453
|
}
|
|
216
454
|
|
|
455
|
+
.node-key {
|
|
456
|
+
padding: 0.5rem;
|
|
457
|
+
font-size: 12px;
|
|
458
|
+
border: 1px solid var(--el-border-color);
|
|
459
|
+
background-color: rgba(#f7faff, 0.85);
|
|
460
|
+
}
|
|
461
|
+
|
|
217
462
|
.key-head {
|
|
218
463
|
text-align: center;
|
|
219
464
|
font-weight: bold;
|
|
220
|
-
border-bottom: 1px solid
|
|
465
|
+
border-bottom: 1px solid var(--el-border-color);
|
|
221
466
|
padding-bottom: 4px;
|
|
222
|
-
margin-bottom:
|
|
467
|
+
margin-bottom: 0.5rem;
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
.key-box-container {
|
|
471
|
+
display: flex;
|
|
472
|
+
flex-direction: row;
|
|
473
|
+
gap: 1rem;
|
|
223
474
|
}
|
|
224
475
|
|
|
225
476
|
.key-box {
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
477
|
+
display: flex;
|
|
478
|
+
align-items: center;
|
|
479
|
+
gap: 0.35rem;
|
|
480
|
+
position: relative;
|
|
481
|
+
line-height: 1;
|
|
482
|
+
|
|
483
|
+
&::before {
|
|
484
|
+
content: "";
|
|
485
|
+
display: block;
|
|
486
|
+
width: 14px;
|
|
487
|
+
height: 14px;
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
&-node::before,
|
|
491
|
+
&-both::before {
|
|
492
|
+
border: 1px solid gray;
|
|
493
|
+
border-radius: var(--el-border-radius-small);
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
// &-node {
|
|
497
|
+
// background: #80F0F0;
|
|
498
|
+
// }
|
|
499
|
+
|
|
500
|
+
// &-both {
|
|
501
|
+
// background: gray;
|
|
502
|
+
// }
|
|
503
|
+
|
|
504
|
+
&-axon::before {
|
|
505
|
+
border: 1px solid gray;
|
|
506
|
+
border-radius: var(--el-border-radius-small);
|
|
507
|
+
transform: rotate(45deg);
|
|
508
|
+
// background: green;
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
&-dendrite::before {
|
|
512
|
+
border: 1px solid gray;
|
|
513
|
+
border-radius: 50%;
|
|
514
|
+
// background: red;
|
|
515
|
+
}
|
|
229
516
|
}
|
|
517
|
+
|
|
518
|
+
.tools {
|
|
519
|
+
display: grid;
|
|
520
|
+
grid-template-columns: repeat(2, 1fr);
|
|
521
|
+
grid-template-rows: repeat(3, 1fr);
|
|
522
|
+
gap: 0.5rem;
|
|
523
|
+
|
|
524
|
+
:deep(.el-button:nth-child(3)) {
|
|
525
|
+
grid-column: 2;
|
|
526
|
+
grid-row: 2;
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
:deep(.el-button:nth-child(4)) {
|
|
530
|
+
grid-column: 2;
|
|
531
|
+
grid-row: 3;
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
:deep(.el-button:nth-child(3)),
|
|
535
|
+
:deep(.el-button:nth-child(4)) {
|
|
536
|
+
opacity: 0;
|
|
537
|
+
visibility: hidden;
|
|
538
|
+
pointer-events: none;
|
|
539
|
+
transform: translateY(-100%);
|
|
540
|
+
transition: all 0.25s ease;
|
|
541
|
+
}
|
|
542
|
+
|
|
543
|
+
&.zoom-locked {
|
|
544
|
+
:deep(.el-button:nth-child(3)),
|
|
545
|
+
:deep(.el-button:nth-child(4)) {
|
|
546
|
+
opacity: 1;
|
|
547
|
+
visibility: visible;
|
|
548
|
+
pointer-events: initial;
|
|
549
|
+
transform: translateY(0%);
|
|
550
|
+
}
|
|
551
|
+
|
|
552
|
+
:deep(.el-button:nth-child(4)) {
|
|
553
|
+
transition-delay: 0.125s;
|
|
554
|
+
}
|
|
555
|
+
}
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
.control-button {
|
|
559
|
+
width: 24px;
|
|
560
|
+
height: 24px;
|
|
561
|
+
margin: 0 !important;
|
|
562
|
+
padding: 0 !important;
|
|
563
|
+
font-size: 16px !important;
|
|
564
|
+
border-color: $app-primary-color !important;
|
|
565
|
+
border-radius: 50%;
|
|
566
|
+
background: $app-primary-color !important;
|
|
567
|
+
transition: all 0.25s ease;
|
|
568
|
+
|
|
569
|
+
svg {
|
|
570
|
+
margin: 0;
|
|
571
|
+
}
|
|
572
|
+
|
|
573
|
+
&,
|
|
574
|
+
&:focus,
|
|
575
|
+
&:active {
|
|
576
|
+
box-shadow: none !important;
|
|
577
|
+
}
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
:deep(.cy-graph-tooltip) {
|
|
581
|
+
padding: 4px 10px;
|
|
582
|
+
font-family: Asap;
|
|
583
|
+
font-size: 12px;
|
|
584
|
+
background: #f3ecf6 !important;
|
|
585
|
+
border: 1px solid $app-primary-color;
|
|
586
|
+
border-radius: var(--el-border-radius-base);
|
|
587
|
+
position: relative;
|
|
588
|
+
top: 0;
|
|
589
|
+
left: 0;
|
|
590
|
+
width: fit-content;
|
|
591
|
+
z-index: 1;
|
|
592
|
+
}
|
|
593
|
+
|
|
594
|
+
.connectivity-graph-error {
|
|
595
|
+
position: absolute;
|
|
596
|
+
top: 1rem;
|
|
597
|
+
left: 50%;
|
|
598
|
+
transform: translateX(-50%);
|
|
599
|
+
width: fit-content;
|
|
600
|
+
font-size: 12px;
|
|
601
|
+
padding: 0.25rem 0.5rem;
|
|
602
|
+
background-color: var(--el-color-error-light-9);
|
|
603
|
+
border-radius: var(--el-border-radius-small);
|
|
604
|
+
border: 1px solid var(--el-color-error);
|
|
605
|
+
}
|
|
606
|
+
|
|
607
|
+
.visually-hidden {
|
|
608
|
+
clip: rect(0 0 0 0);
|
|
609
|
+
clip-path: inset(50%);
|
|
610
|
+
height: 1px;
|
|
611
|
+
overflow: hidden;
|
|
612
|
+
position: absolute;
|
|
613
|
+
white-space: nowrap;
|
|
614
|
+
width: 1px;
|
|
615
|
+
}
|
|
616
|
+
</style>
|
|
617
|
+
|
|
618
|
+
<style lang="scss">
|
|
619
|
+
.el-popper.is-control-tooltip {
|
|
620
|
+
padding: 4px 10px;
|
|
621
|
+
font-family: Asap;
|
|
622
|
+
background: #f3ecf6 !important;
|
|
623
|
+
border: 1px solid $app-primary-color;
|
|
624
|
+
|
|
625
|
+
& .el-popper__arrow::before {
|
|
626
|
+
border: 1px solid;
|
|
627
|
+
border-color: $app-primary-color;
|
|
628
|
+
background: #f3ecf6;
|
|
629
|
+
}
|
|
630
|
+
}
|
|
230
631
|
</style>
|