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