@abi-software/map-utilities 1.5.0-beta.0 → 1.5.0-beta.2
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 +15927 -10148
- package/dist/map-utilities.umd.cjs +63 -63
- package/dist/style.css +1 -1
- package/package.json +2 -1
- package/src/App.vue +135 -49
- package/src/components/ConnectivityGraph/ConnectivityGraph.vue +48 -16
- package/src/components/ConnectivityGraph/graph.js +9 -5
- package/src/components/ConnectivityList/ConnectivityList.vue +430 -0
- package/src/components/DrawToolbar/DrawToolbar.vue +2 -2
- package/src/components/Tooltip/AnnotationPopup.vue +135 -42
- package/src/components/Tooltip/ProvenancePopup.vue +155 -266
- package/src/components/Tooltip/Tooltip.vue +2 -2
- package/src/components/index.js +2 -0
- package/src/components/utilities.js +7 -0
- package/src/components.d.ts +2 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@abi-software/map-utilities",
|
|
3
|
-
"version": "1.5.0-beta.
|
|
3
|
+
"version": "1.5.0-beta.2",
|
|
4
4
|
"files": [
|
|
5
5
|
"dist/*",
|
|
6
6
|
"src/*",
|
|
@@ -32,6 +32,7 @@
|
|
|
32
32
|
"@abi-software/svg-sprite": "^1.0.1",
|
|
33
33
|
"@element-plus/icons-vue": "^2.3.1",
|
|
34
34
|
"cytoscape": "^3.30.2",
|
|
35
|
+
"cytoscape-dagre": "^2.5.0",
|
|
35
36
|
"element-plus": "2.8.4",
|
|
36
37
|
"mitt": "^3.0.1",
|
|
37
38
|
"vue": "^3.4.21"
|
package/src/App.vue
CHANGED
|
@@ -39,8 +39,16 @@ 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
|
-
|
|
42
|
+
const connectivityGraphEntry = ref("ilxtr:neuron-type-aacar-13");
|
|
43
|
+
const connectivityGraphEntries = [
|
|
44
|
+
"ilxtr:neuron-type-aacar-13",
|
|
45
|
+
"ilxtr:sparc-nlp/kidney/134",
|
|
46
|
+
"ilxtr:neuron-type-aacar-11",
|
|
47
|
+
"ilxtr:neuron-type-sstom-14",
|
|
48
|
+
"ilxtr:neuron-type-keast-6",
|
|
49
|
+
"ilxtr:neuron-type-aacar-4",
|
|
50
|
+
"ilxtr:neuron-type-aacar-12",
|
|
51
|
+
];
|
|
44
52
|
const mapServer = "https://mapcore-demo.org/curation/flatmap/";
|
|
45
53
|
const sckanVersion = "sckan-2024-09-21-npo";
|
|
46
54
|
|
|
@@ -130,7 +138,7 @@ function onActionClick(value) {
|
|
|
130
138
|
* Tooltip
|
|
131
139
|
*/
|
|
132
140
|
const tooltipDisplay = ref(false);
|
|
133
|
-
const tooltipEntry = ref(
|
|
141
|
+
const tooltipEntry = ref([]);
|
|
134
142
|
const featuresAlert = ref(undefined);
|
|
135
143
|
const annotationDisplay = ref(false);
|
|
136
144
|
const annotationEntry = ref({});
|
|
@@ -141,33 +149,90 @@ provide(/* key */ "userApiKey", /* value */ undefined);
|
|
|
141
149
|
|
|
142
150
|
function addTooltipEntry() {
|
|
143
151
|
tooltipDisplay.value = true;
|
|
144
|
-
tooltipEntry.value =
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
152
|
+
tooltipEntry.value = [
|
|
153
|
+
{
|
|
154
|
+
destinations: ["eccrine sweat gland of the trunk"],
|
|
155
|
+
origins: [
|
|
156
|
+
"Sixth thoracic ganglion",
|
|
157
|
+
"Twelfth thoracic ganglion",
|
|
158
|
+
"Fifth thoracic ganglion",
|
|
159
|
+
"Ninth thoracic ganglion",
|
|
160
|
+
"Seventh thoracic ganglion",
|
|
161
|
+
"Eighth thoracic ganglion",
|
|
162
|
+
"Fourth thoracic ganglion",
|
|
163
|
+
"Tenth thoracic ganglion",
|
|
164
|
+
"Eleventh thoracic ganglion",
|
|
165
|
+
],
|
|
166
|
+
components: ["nerve"],
|
|
167
|
+
destinationsWithDatasets: [
|
|
168
|
+
{ id: "ILX:0795061", name: "eccrine sweat gland of the trunk" },
|
|
169
|
+
],
|
|
170
|
+
originsWithDatasets: [
|
|
171
|
+
{ id: "ILX:0784378", name: "Ninth thoracic ganglion" },
|
|
172
|
+
{ id: "ILX:0784569", name: "Tenth thoracic ganglion" },
|
|
173
|
+
{ id: "ILX:0784721", name: "Eighth thoracic ganglion" },
|
|
174
|
+
{ id: "ILX:0786141", name: "Fifth thoracic ganglion" },
|
|
175
|
+
{ id: "ILX:0786272", name: "Fourth thoracic ganglion" },
|
|
176
|
+
{ id: "ILX:0787009", name: "Twelfth thoracic ganglion" },
|
|
177
|
+
{ id: "ILX:0787015", name: "Eleventh thoracic ganglion" },
|
|
178
|
+
{ id: "ILX:0789947", name: "Sixth thoracic ganglion" },
|
|
179
|
+
{ id: "ILX:0790482", name: "Seventh thoracic ganglion" },
|
|
180
|
+
],
|
|
181
|
+
componentsWithDatasets: [{ id: "UBERON:0001021", name: "nerve" }],
|
|
182
|
+
title: "neuron type swglnd 161",
|
|
183
|
+
featureId: ["ilxtr:sparc-nlp/swglnd/161"],
|
|
184
|
+
hyperlinks: [
|
|
185
|
+
"https://doi.org/10.1007/s10286-015-0282-1",
|
|
186
|
+
"https://doi.org/10.1111/bjd.15808",
|
|
187
|
+
"https://doi.org/10.1159/000060678",
|
|
188
|
+
],
|
|
189
|
+
provenanceTaxonomy: ["NCBITaxon:9606"],
|
|
190
|
+
provenanceTaxonomyLabel: ["Homo sapiens"],
|
|
191
|
+
knowledgeSource: "sckan-2024-09-21-npo",
|
|
192
|
+
mapId: "rat-flatmap",
|
|
193
|
+
mapuuid: "b4ae1699-5690-5640-97b7-d711ae02dcb9",
|
|
194
|
+
},
|
|
195
|
+
{
|
|
196
|
+
destinations: ["intramural ganglion of the kidney"],
|
|
197
|
+
origins: ["dorsal motor nucleus of vagus nerve"],
|
|
198
|
+
components: [
|
|
199
|
+
"renal nerve plexus",
|
|
200
|
+
"aortic plexus",
|
|
201
|
+
"esophageal vagus trunk",
|
|
202
|
+
"vagus X nerve trunk",
|
|
203
|
+
"vagus nerve",
|
|
204
|
+
],
|
|
205
|
+
destinationsWithDatasets: [
|
|
206
|
+
{ id: "ILX:0795056", name: "intramural ganglion of the kidney" },
|
|
207
|
+
],
|
|
208
|
+
originsWithDatasets: [
|
|
209
|
+
{ id: "UBERON:0002870", name: "dorsal motor nucleus of vagus nerve" },
|
|
210
|
+
],
|
|
211
|
+
componentsWithDatasets: [
|
|
212
|
+
{ id: "ILX:0794853", name: "esophageal vagus trunk" },
|
|
213
|
+
{ id: "UBERON:0001759", name: "vagus nerve" },
|
|
214
|
+
{ id: "UBERON:0003535", name: "vagus X nerve trunk" },
|
|
215
|
+
{ id: "UBERON:0018676", name: "renal nerve plexus" },
|
|
216
|
+
{ id: "UBERON:0035772", name: "aortic plexus" },
|
|
217
|
+
],
|
|
218
|
+
title:
|
|
219
|
+
"dorsal motor nucleus of vagus nerve to intramural ganglia of the kidney via vagus nerve via esophageal vagus trunk via vagal trunks via aortic plexus via renal plexus",
|
|
220
|
+
featureId: ["ilxtr:sparc-nlp/kidney/135"],
|
|
221
|
+
hyperlinks: [
|
|
222
|
+
"https://uilx.org/tgbugs/u/r/isbn-13/978-0323680424",
|
|
223
|
+
"https://doi.org/10.1016/j.aanat.2015.11.004",
|
|
224
|
+
],
|
|
225
|
+
provenanceTaxonomy: ["NCBITaxon:9606"],
|
|
226
|
+
provenanceTaxonomyLabel: ["Homo sapiens"],
|
|
227
|
+
knowledgeSource: "sckan-2024-09-21-npo",
|
|
228
|
+
mapId: "rat-flatmap",
|
|
229
|
+
mapuuid: "b4ae1699-5690-5640-97b7-d711ae02dcb9",
|
|
230
|
+
},
|
|
231
|
+
];
|
|
167
232
|
}
|
|
168
233
|
function removeTooltipEntry() {
|
|
169
234
|
tooltipDisplay.value = false;
|
|
170
|
-
tooltipEntry.value =
|
|
235
|
+
tooltipEntry.value = [];
|
|
171
236
|
}
|
|
172
237
|
function addAnnotationEntry() {
|
|
173
238
|
tooltipDisplay.value = true;
|
|
@@ -234,7 +299,7 @@ function setColourField(treeData, nodeData, activeColour) {
|
|
|
234
299
|
function setColour(nodeData, value) {
|
|
235
300
|
if (nodeData && nodeData.isPrimitives) {
|
|
236
301
|
const activeColour = value ? value : nodeData.defaultColour;
|
|
237
|
-
setColourField(treeDataEntry.value, nodeData, activeColour)
|
|
302
|
+
setColourField(treeDataEntry.value, nodeData, activeColour);
|
|
238
303
|
}
|
|
239
304
|
}
|
|
240
305
|
function checkAll(value) {
|
|
@@ -263,7 +328,7 @@ const createData = ref({
|
|
|
263
328
|
editingIndex: -1,
|
|
264
329
|
faceIndex: -1,
|
|
265
330
|
toBeDeleted: false,
|
|
266
|
-
})
|
|
331
|
+
});
|
|
267
332
|
function cancelCreate() {
|
|
268
333
|
console.log("🚀 ~ CreateTooltipContent : cancelCreate");
|
|
269
334
|
}
|
|
@@ -422,14 +487,14 @@ function confirmCreate(value) {
|
|
|
422
487
|
Add Tooltip Entry
|
|
423
488
|
</el-button>
|
|
424
489
|
<el-button
|
|
425
|
-
v-show="
|
|
490
|
+
v-show="tooltipEntry.length > 0"
|
|
426
491
|
@click="removeTooltipEntry"
|
|
427
492
|
size="small"
|
|
428
493
|
>
|
|
429
494
|
Remove Tooltip Entry
|
|
430
495
|
</el-button>
|
|
431
496
|
<el-button
|
|
432
|
-
v-show="
|
|
497
|
+
v-show="tooltipEntry.length === 0"
|
|
433
498
|
@click="addAnnotationEntry"
|
|
434
499
|
size="small"
|
|
435
500
|
>
|
|
@@ -449,10 +514,18 @@ function confirmCreate(value) {
|
|
|
449
514
|
<h3>TreeControls - {{ mapType }}</h3>
|
|
450
515
|
</el-col>
|
|
451
516
|
<el-col>
|
|
452
|
-
<el-button
|
|
517
|
+
<el-button
|
|
518
|
+
v-show="mapType === 'scaffold'"
|
|
519
|
+
@click="switchTreeEntry('flatmap')"
|
|
520
|
+
size="small"
|
|
521
|
+
>
|
|
453
522
|
Display Flatmap Tree
|
|
454
523
|
</el-button>
|
|
455
|
-
<el-button
|
|
524
|
+
<el-button
|
|
525
|
+
v-show="mapType === 'flatmap'"
|
|
526
|
+
@click="switchTreeEntry('scaffold')"
|
|
527
|
+
size="small"
|
|
528
|
+
>
|
|
456
529
|
Display Scaffold Tree
|
|
457
530
|
</el-button>
|
|
458
531
|
</el-col>
|
|
@@ -462,18 +535,34 @@ function confirmCreate(value) {
|
|
|
462
535
|
<h3>Connectivity Graph</h3>
|
|
463
536
|
</el-col>
|
|
464
537
|
<el-col>
|
|
465
|
-
<el-button
|
|
466
|
-
@click="showConnectivityGraph = true"
|
|
467
|
-
size="small"
|
|
468
|
-
>
|
|
538
|
+
<el-button @click="showConnectivityGraph = true" size="small">
|
|
469
539
|
Show connectivity graph
|
|
470
540
|
</el-button>
|
|
471
|
-
<el-button
|
|
472
|
-
@click="showConnectivityGraph = false"
|
|
473
|
-
size="small"
|
|
474
|
-
>
|
|
541
|
+
<el-button @click="showConnectivityGraph = false" size="small">
|
|
475
542
|
Hide connectivity graph
|
|
476
543
|
</el-button>
|
|
544
|
+
<el-select
|
|
545
|
+
v-model="connectivityGraphEntry"
|
|
546
|
+
placeholder="Select featureId"
|
|
547
|
+
style="width: 180px"
|
|
548
|
+
size="small"
|
|
549
|
+
>
|
|
550
|
+
<el-option
|
|
551
|
+
v-for="item in connectivityGraphEntries"
|
|
552
|
+
:key="item"
|
|
553
|
+
:label="item"
|
|
554
|
+
:value="item"
|
|
555
|
+
/>
|
|
556
|
+
</el-select>
|
|
557
|
+
</el-col>
|
|
558
|
+
<el-col>
|
|
559
|
+
<ConnectivityGraph
|
|
560
|
+
v-if="showConnectivityGraph"
|
|
561
|
+
:key="connectivityGraphEntry"
|
|
562
|
+
:entry="connectivityGraphEntry"
|
|
563
|
+
:map-server="mapServer"
|
|
564
|
+
:sckanVersion="sckanVersion"
|
|
565
|
+
/>
|
|
477
566
|
</el-col>
|
|
478
567
|
</el-row>
|
|
479
568
|
|
|
@@ -545,12 +634,6 @@ function confirmCreate(value) {
|
|
|
545
634
|
@setColour="setColour"
|
|
546
635
|
@checkChanged="checkChanged"
|
|
547
636
|
/>
|
|
548
|
-
<ConnectivityGraph
|
|
549
|
-
v-if="showConnectivityGraph"
|
|
550
|
-
:entry="connectivityGraphEntry"
|
|
551
|
-
:map-server="mapServer"
|
|
552
|
-
:sckanVersion="sckanVersion"
|
|
553
|
-
/>
|
|
554
637
|
</div>
|
|
555
638
|
</template>
|
|
556
639
|
|
|
@@ -568,9 +651,9 @@ function confirmCreate(value) {
|
|
|
568
651
|
top: calc(50% - 100px);
|
|
569
652
|
left: calc(50% - 200px);
|
|
570
653
|
}
|
|
571
|
-
.annotation-popup{
|
|
654
|
+
.annotation-popup {
|
|
572
655
|
margin-top: 8px;
|
|
573
|
-
width:400px;
|
|
656
|
+
width: 400px;
|
|
574
657
|
border-style: solid;
|
|
575
658
|
border-width: 1px;
|
|
576
659
|
border-color: black;
|
|
@@ -584,4 +667,7 @@ function confirmCreate(value) {
|
|
|
584
667
|
height: 600px;
|
|
585
668
|
margin-top: 1rem;
|
|
586
669
|
}
|
|
670
|
+
.el-button + .el-select {
|
|
671
|
+
margin-left: 12px;
|
|
672
|
+
}
|
|
587
673
|
</style>
|
|
@@ -160,6 +160,10 @@ export default {
|
|
|
160
160
|
type: Array,
|
|
161
161
|
default: [],
|
|
162
162
|
},
|
|
163
|
+
connectivityFromMap: {
|
|
164
|
+
type: Object,
|
|
165
|
+
default: () => null,
|
|
166
|
+
},
|
|
163
167
|
},
|
|
164
168
|
data: function () {
|
|
165
169
|
return {
|
|
@@ -184,26 +188,20 @@ export default {
|
|
|
184
188
|
connectivityGraphContainer: null,
|
|
185
189
|
};
|
|
186
190
|
},
|
|
191
|
+
watch: {
|
|
192
|
+
connectivityFromMap: function (oldVal, newVal) {
|
|
193
|
+
if (oldVal != newVal) {
|
|
194
|
+
this.showSpinner();
|
|
195
|
+
this.start();
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
},
|
|
187
199
|
mounted() {
|
|
188
200
|
this.showSpinner();
|
|
189
201
|
this.updateTooltipContainer();
|
|
190
202
|
this.refreshCache();
|
|
191
203
|
this.loadCacheData();
|
|
192
|
-
this.
|
|
193
|
-
.then((res) => {
|
|
194
|
-
if (res?.success) {
|
|
195
|
-
this.showGraph(this.entry);
|
|
196
|
-
} else if (res?.error) {
|
|
197
|
-
this.loadingError = res.error;
|
|
198
|
-
} else {
|
|
199
|
-
this.loadingError = 'Loading error!';
|
|
200
|
-
}
|
|
201
|
-
this.hideSpinner();
|
|
202
|
-
})
|
|
203
|
-
.catch((error) => {
|
|
204
|
-
this.loadingError = 'Loading error!';
|
|
205
|
-
this.hideSpinner();
|
|
206
|
-
});
|
|
204
|
+
this.start();
|
|
207
205
|
},
|
|
208
206
|
methods: {
|
|
209
207
|
updateTooltipContainer: function () {
|
|
@@ -275,6 +273,22 @@ export default {
|
|
|
275
273
|
|
|
276
274
|
sessionStorage.setItem('connectivity-graph-expiry', expiry);
|
|
277
275
|
},
|
|
276
|
+
start: function () {
|
|
277
|
+
this.run()
|
|
278
|
+
.then((res) => {
|
|
279
|
+
if (res?.success) {
|
|
280
|
+
this.showGraph(this.entry);
|
|
281
|
+
} else if (res?.error) {
|
|
282
|
+
this.loadingError = res.error;
|
|
283
|
+
} else {
|
|
284
|
+
this.loadingError = 'Loading error!';
|
|
285
|
+
}
|
|
286
|
+
})
|
|
287
|
+
.catch((error) => {
|
|
288
|
+
this.loadingError = 'Loading error!';
|
|
289
|
+
this.hideSpinner();
|
|
290
|
+
});
|
|
291
|
+
},
|
|
278
292
|
run: async function () {
|
|
279
293
|
if (!this.schemaVersion) {
|
|
280
294
|
this.schemaVersion = await this.getSchemaVersion();
|
|
@@ -305,8 +319,24 @@ export default {
|
|
|
305
319
|
showGraph: async function (neuronPath) {
|
|
306
320
|
const graphCanvas = this.$refs.graphCanvas;
|
|
307
321
|
|
|
322
|
+
// Update label data
|
|
323
|
+
if (this.connectivityFromMap) {
|
|
324
|
+
this.cacheLabels(this.connectivityFromMap);
|
|
325
|
+
await this.getCachedTermLabels();
|
|
326
|
+
}
|
|
327
|
+
|
|
308
328
|
this.connectivityGraph = new ConnectivityGraph(this.labelCache, graphCanvas);
|
|
309
|
-
|
|
329
|
+
const connectivityInfo = this.knowledgeByPath.get(neuronPath);
|
|
330
|
+
|
|
331
|
+
// Update connectivity
|
|
332
|
+
if (this.connectivityFromMap) {
|
|
333
|
+
connectivityInfo.axons = this.connectivityFromMap.axons;
|
|
334
|
+
connectivityInfo.connectivity = this.connectivityFromMap.connectivity;
|
|
335
|
+
connectivityInfo.dendrites = this.connectivityFromMap.dendrites;
|
|
336
|
+
connectivityInfo.somas = this.connectivityFromMap.somas;
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
await this.connectivityGraph.addConnectivity(connectivityInfo);
|
|
310
340
|
|
|
311
341
|
this.connectivityGraph.showConnectivity(graphCanvas);
|
|
312
342
|
|
|
@@ -322,6 +352,8 @@ export default {
|
|
|
322
352
|
*/
|
|
323
353
|
this.$emit('tap-node', data);
|
|
324
354
|
});
|
|
355
|
+
|
|
356
|
+
this.hideSpinner();
|
|
325
357
|
},
|
|
326
358
|
query: async function (sql, params) {
|
|
327
359
|
const url = `${this.mapServer}knowledge/query/`;
|
|
@@ -19,6 +19,8 @@ limitations under the License.
|
|
|
19
19
|
==============================================================================*/
|
|
20
20
|
|
|
21
21
|
import cytoscape from 'cytoscape'
|
|
22
|
+
import dagre from 'cytoscape-dagre'
|
|
23
|
+
cytoscape.use( dagre );
|
|
22
24
|
|
|
23
25
|
//==============================================================================
|
|
24
26
|
|
|
@@ -264,7 +266,7 @@ export class ConnectivityGraph extends EventTarget
|
|
|
264
266
|
}
|
|
265
267
|
} else if (this.dendrites.includes(id) || this.somas.includes(id)) {
|
|
266
268
|
result['dendrite'] = true
|
|
267
|
-
|
|
269
|
+
|
|
268
270
|
}
|
|
269
271
|
}
|
|
270
272
|
return result
|
|
@@ -406,11 +408,13 @@ class CytoscapeGraph extends EventTarget
|
|
|
406
408
|
container: graphCanvas,
|
|
407
409
|
elements: connectivityGraph.elements,
|
|
408
410
|
layout: {
|
|
409
|
-
name: '
|
|
410
|
-
|
|
411
|
-
|
|
411
|
+
name: 'dagre',
|
|
412
|
+
nodeSep: 150,
|
|
413
|
+
edgeSep: 50,
|
|
414
|
+
rankSep: 100,
|
|
415
|
+
rankDir: 'TB',
|
|
416
|
+
roots: connectivityGraph.roots.length ? connectivityGraph.roots : undefined,
|
|
412
417
|
},
|
|
413
|
-
directed: true,
|
|
414
418
|
style: GRAPH_STYLE,
|
|
415
419
|
minZoom: 0.1,
|
|
416
420
|
maxZoom: 10,
|