@abi-software/flatmapvuer 1.5.6 → 1.6.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/flatmapvuer.js +22005 -21593
- package/dist/flatmapvuer.umd.cjs +132 -126
- package/dist/style.css +1 -1
- package/package.json +3 -3
- package/src/App.vue +19 -7
- package/src/components/FlatmapVuer.vue +338 -133
- package/src/components/MultiFlatmapVuer.vue +43 -5
- package/src/components/SelectionsGroup.vue +31 -8
- package/src/components/utilities.js +9 -0
- package/src/services/flatmapQueries.js +118 -46
|
@@ -257,7 +257,7 @@ Please use `const` to assign meaningful names to them...
|
|
|
257
257
|
<div
|
|
258
258
|
class="pathway-location"
|
|
259
259
|
:class="{ open: drawerOpen, close: !drawerOpen }"
|
|
260
|
-
v-show="!
|
|
260
|
+
v-show="!disableUI"
|
|
261
261
|
>
|
|
262
262
|
<div
|
|
263
263
|
class="pathway-container"
|
|
@@ -388,17 +388,6 @@ Please use `const` to assign meaningful names to them...
|
|
|
388
388
|
ref="taxonSelection"
|
|
389
389
|
key="taxonSelection"
|
|
390
390
|
/>
|
|
391
|
-
<selections-group
|
|
392
|
-
v-if="!(isCentreLine || isFC) && centreLines && centreLines.length > 0"
|
|
393
|
-
title="Nerves"
|
|
394
|
-
labelKey="label"
|
|
395
|
-
identifierKey="key"
|
|
396
|
-
:selections="centreLines"
|
|
397
|
-
@changed="centreLinesSelected"
|
|
398
|
-
@selections-data-changed="onSelectionsDataChanged"
|
|
399
|
-
ref="centrelinesSelection"
|
|
400
|
-
key="centrelinesSelection"
|
|
401
|
-
/>
|
|
402
391
|
</div>
|
|
403
392
|
<div
|
|
404
393
|
@click="toggleDrawer"
|
|
@@ -519,8 +508,8 @@ Please use `const` to assign meaningful names to them...
|
|
|
519
508
|
class="flatmap-radio"
|
|
520
509
|
@change="setFlightPath3D"
|
|
521
510
|
>
|
|
522
|
-
<el-radio :
|
|
523
|
-
<el-radio :
|
|
511
|
+
<el-radio :value="false">2D</el-radio>
|
|
512
|
+
<el-radio :value="true">3D</el-radio>
|
|
524
513
|
</el-radio-group>
|
|
525
514
|
</el-row>
|
|
526
515
|
<el-row class="backgroundSpacer"></el-row>
|
|
@@ -531,8 +520,8 @@ Please use `const` to assign meaningful names to them...
|
|
|
531
520
|
class="flatmap-radio"
|
|
532
521
|
@change="setColour"
|
|
533
522
|
>
|
|
534
|
-
<el-radio :
|
|
535
|
-
<el-radio :
|
|
523
|
+
<el-radio :value="true">Colour</el-radio>
|
|
524
|
+
<el-radio :value="false">Greyscale</el-radio>
|
|
536
525
|
</el-radio-group>
|
|
537
526
|
</el-row>
|
|
538
527
|
<el-row class="backgroundSpacer"></el-row>
|
|
@@ -543,8 +532,8 @@ Please use `const` to assign meaningful names to them...
|
|
|
543
532
|
class="flatmap-radio"
|
|
544
533
|
@change="setOutlines"
|
|
545
534
|
>
|
|
546
|
-
<el-radio :
|
|
547
|
-
<el-radio :
|
|
535
|
+
<el-radio :value="true">Show</el-radio>
|
|
536
|
+
<el-radio :value="false">Hide</el-radio>
|
|
548
537
|
</el-radio-group>
|
|
549
538
|
</el-row>
|
|
550
539
|
<el-row class="backgroundSpacer"></el-row>
|
|
@@ -634,7 +623,7 @@ Please use `const` to assign meaningful names to them...
|
|
|
634
623
|
|
|
635
624
|
<script>
|
|
636
625
|
/* eslint-disable no-alert, no-console */
|
|
637
|
-
import { shallowRef, markRaw } from 'vue'
|
|
626
|
+
import { inject, provide, shallowRef, markRaw } from 'vue'
|
|
638
627
|
import {
|
|
639
628
|
WarningFilled as ElIconWarningFilled,
|
|
640
629
|
ArrowDown as ElIconArrowDown,
|
|
@@ -658,8 +647,9 @@ import {
|
|
|
658
647
|
import flatmapMarker from '../icons/flatmap-marker'
|
|
659
648
|
import {
|
|
660
649
|
FlatmapQueries,
|
|
661
|
-
|
|
650
|
+
findTaxonomyLabels,
|
|
662
651
|
} from '../services/flatmapQueries.js'
|
|
652
|
+
import { capitalise } from './utilities.js'
|
|
663
653
|
import yellowstar from '../icons/yellowstar'
|
|
664
654
|
import ResizeSensor from 'css-element-queries/src/ResizeSensor'
|
|
665
655
|
import * as flatmap from '@abi-software/flatmap-viewer'
|
|
@@ -717,28 +707,6 @@ const processFTUs = (parent, key) => {
|
|
|
717
707
|
return ftus
|
|
718
708
|
}
|
|
719
709
|
|
|
720
|
-
const processSystems = (systems) => {
|
|
721
|
-
const allSystems = []
|
|
722
|
-
if (systems && systems.length > 0) {
|
|
723
|
-
const data = { label: 'All', key: 'All', children: [] }
|
|
724
|
-
systems.forEach((system) => {
|
|
725
|
-
const child = {
|
|
726
|
-
colour: system.colour,
|
|
727
|
-
enabled: system.enabled,
|
|
728
|
-
label: system.id,
|
|
729
|
-
key: system.id,
|
|
730
|
-
}
|
|
731
|
-
const children = processFTUs(system, child.key)
|
|
732
|
-
if (children.length > 0) child.children = children
|
|
733
|
-
data.children.push(child)
|
|
734
|
-
})
|
|
735
|
-
|
|
736
|
-
allSystems.push(data)
|
|
737
|
-
}
|
|
738
|
-
|
|
739
|
-
return allSystems
|
|
740
|
-
}
|
|
741
|
-
|
|
742
710
|
const createUnfilledTooltipData = function () {
|
|
743
711
|
return {
|
|
744
712
|
destinations: [],
|
|
@@ -784,10 +752,23 @@ export default {
|
|
|
784
752
|
this.setStateRequired = false
|
|
785
753
|
},
|
|
786
754
|
setup(props) {
|
|
787
|
-
|
|
755
|
+
let annotator = inject('$annotator')
|
|
756
|
+
if (!annotator) {
|
|
757
|
+
annotator = markRaw(new AnnotationService(`${props.flatmapAPI}annotator`));
|
|
758
|
+
provide('$annotator', annotator)
|
|
759
|
+
}
|
|
788
760
|
return { annotator }
|
|
789
761
|
},
|
|
790
762
|
methods: {
|
|
763
|
+
/**
|
|
764
|
+
* @public
|
|
765
|
+
* Function to manually send aborted signal when annotation tooltip popup or sidebar tab closed.
|
|
766
|
+
*/
|
|
767
|
+
manualAbortedOnClose: function () {
|
|
768
|
+
if (this.annotationSidebar) this.$emit("annotation-close")
|
|
769
|
+
this.closeTooltip()
|
|
770
|
+
this.annotationEventCallback({}, { type: 'aborted' })
|
|
771
|
+
},
|
|
791
772
|
/**
|
|
792
773
|
* @public
|
|
793
774
|
* Function to initialise drawing.
|
|
@@ -804,6 +785,7 @@ export default {
|
|
|
804
785
|
*/
|
|
805
786
|
cancelDrawnFeature: function () {
|
|
806
787
|
if (this.isValidDrawnCreated) {
|
|
788
|
+
if (this.annotationSidebar) this.$emit("annotation-close")
|
|
807
789
|
this.closeTooltip()
|
|
808
790
|
this.annotationEntry = {
|
|
809
791
|
...this.drawnCreatedEvent.feature,
|
|
@@ -861,17 +843,13 @@ export default {
|
|
|
861
843
|
* @arg {String} `name`
|
|
862
844
|
*/
|
|
863
845
|
toolbarEvent: function (type, name) {
|
|
864
|
-
this.
|
|
846
|
+
this.manualAbortedOnClose()
|
|
865
847
|
this.doubleClickedFeature = false
|
|
866
848
|
this.connectionEntry = {}
|
|
867
849
|
if (type === 'mode') {
|
|
868
850
|
// Deselect any feature when draw mode is changed
|
|
869
851
|
this.changeAnnotationDrawMode({ mode: 'simple_select' })
|
|
870
852
|
this.activeDrawMode = name
|
|
871
|
-
// rollback modified feature when exit edit/delete mode
|
|
872
|
-
if (Object.keys(this.annotationEntry).length > 0 && !this.featureAnnotationSubmitted) {
|
|
873
|
-
this.rollbackAnnotationEvent()
|
|
874
|
-
}
|
|
875
853
|
} else if (type === 'tool') {
|
|
876
854
|
if (name) {
|
|
877
855
|
const tool = name.replace(/[A-Z]/g, letter => `_${letter.toLowerCase()}`)
|
|
@@ -990,12 +968,11 @@ export default {
|
|
|
990
968
|
this.featureAnnotationSubmitted = true
|
|
991
969
|
this.mapImp.commitAnnotationEvent(this.annotationEntry)
|
|
992
970
|
if (this.annotationEntry.type === 'deleted') {
|
|
971
|
+
if (this.annotationSidebar) this.$emit("annotation-close")
|
|
993
972
|
this.closeTooltip()
|
|
994
973
|
this.annotationEntry = {}
|
|
995
|
-
} else {
|
|
996
|
-
// Update 'existDrawnFeatures' when created or updated event
|
|
997
|
-
this.addAnnotationFeature()
|
|
998
974
|
}
|
|
975
|
+
this.addAnnotationFeature()
|
|
999
976
|
}
|
|
1000
977
|
},
|
|
1001
978
|
/**
|
|
@@ -1088,6 +1065,7 @@ export default {
|
|
|
1088
1065
|
setDrawnType: function (flag) {
|
|
1089
1066
|
this.drawnType = flag
|
|
1090
1067
|
if (this.mapImp) {
|
|
1068
|
+
this.manualAbortedOnClose()
|
|
1091
1069
|
this.addAnnotationFeature()
|
|
1092
1070
|
this.initialiseDrawing()
|
|
1093
1071
|
}
|
|
@@ -1100,6 +1078,7 @@ export default {
|
|
|
1100
1078
|
setAnnotatedType: function (flag) {
|
|
1101
1079
|
this.annotatedType = flag
|
|
1102
1080
|
if (this.mapImp) {
|
|
1081
|
+
this.manualAbortedOnClose()
|
|
1103
1082
|
this.addAnnotationFeature()
|
|
1104
1083
|
}
|
|
1105
1084
|
},
|
|
@@ -1166,7 +1145,6 @@ export default {
|
|
|
1166
1145
|
if (children.length > 0) child.children = children
|
|
1167
1146
|
data.children.push(child)
|
|
1168
1147
|
})
|
|
1169
|
-
|
|
1170
1148
|
this.systems.push(data)
|
|
1171
1149
|
}
|
|
1172
1150
|
},
|
|
@@ -1177,14 +1155,22 @@ export default {
|
|
|
1177
1155
|
* @arg {String} `flatmapAPI`,
|
|
1178
1156
|
* @arg {Array} `taxonIdentifiers`
|
|
1179
1157
|
*/
|
|
1180
|
-
processTaxon: function (
|
|
1158
|
+
processTaxon: function (taxonIdentifiers, state) {
|
|
1181
1159
|
this.taxonConnectivity.length = 0
|
|
1182
|
-
taxonIdentifiers.
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1160
|
+
findTaxonomyLabels(this.mapImp, taxonIdentifiers).then((entityLabels) => {
|
|
1161
|
+
if (entityLabels.length) {
|
|
1162
|
+
entityLabels.forEach((entityLabel) => {
|
|
1163
|
+
let enabled = true
|
|
1164
|
+
if (state) {
|
|
1165
|
+
enabled = state.checkAll ? true : state.checked.includes(entityLabel.taxon)
|
|
1166
|
+
}
|
|
1167
|
+
this.taxonConnectivity.push({...entityLabel, enabled});
|
|
1168
|
+
if (this.mapImp) {
|
|
1169
|
+
this.mapImp.enableConnectivityByTaxonIds(entityLabel.taxon, enabled)
|
|
1170
|
+
}
|
|
1171
|
+
});
|
|
1172
|
+
}
|
|
1173
|
+
});
|
|
1188
1174
|
},
|
|
1189
1175
|
/**
|
|
1190
1176
|
* @public
|
|
@@ -1202,7 +1188,7 @@ export default {
|
|
|
1202
1188
|
setColour: function (flag) {
|
|
1203
1189
|
this.colourRadio = flag
|
|
1204
1190
|
if (this.mapImp) {
|
|
1205
|
-
this.mapImp.
|
|
1191
|
+
this.mapImp.setPaint({ colour: flag, outline: this.outlinesRadio })
|
|
1206
1192
|
}
|
|
1207
1193
|
},
|
|
1208
1194
|
/**
|
|
@@ -1212,9 +1198,25 @@ export default {
|
|
|
1212
1198
|
* @arg {Boolean} `flag`
|
|
1213
1199
|
*/
|
|
1214
1200
|
setOutlines: function (flag) {
|
|
1215
|
-
this.
|
|
1201
|
+
this.outlinesRadio = flag
|
|
1202
|
+
if (this.mapImp) {
|
|
1203
|
+
this.mapImp.setPaint({ colour: this.colourRadio, outline: flag })
|
|
1204
|
+
}
|
|
1205
|
+
},
|
|
1206
|
+
setInitMapState: function () {
|
|
1216
1207
|
if (this.mapImp) {
|
|
1217
|
-
this.mapImp.
|
|
1208
|
+
const map = this.mapImp._map;
|
|
1209
|
+
const bounds = this.mapImp.options.bounds;
|
|
1210
|
+
const initBounds = [
|
|
1211
|
+
[bounds[0], bounds[1]],
|
|
1212
|
+
[bounds[2], bounds[3]]
|
|
1213
|
+
];
|
|
1214
|
+
|
|
1215
|
+
map.setMaxBounds(null); // override default
|
|
1216
|
+
|
|
1217
|
+
this.initMapState = {
|
|
1218
|
+
initBounds,
|
|
1219
|
+
};
|
|
1218
1220
|
}
|
|
1219
1221
|
},
|
|
1220
1222
|
/**
|
|
@@ -1224,9 +1226,18 @@ export default {
|
|
|
1224
1226
|
*/
|
|
1225
1227
|
resetView: function () {
|
|
1226
1228
|
if (this.mapImp) {
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1229
|
+
// fit to window
|
|
1230
|
+
const map = this.mapImp._map;
|
|
1231
|
+
const { initBounds } = this.initMapState;
|
|
1232
|
+
// reset rotation
|
|
1233
|
+
map.resetNorthPitch({
|
|
1234
|
+
animate: false,
|
|
1235
|
+
});
|
|
1236
|
+
if (initBounds) {
|
|
1237
|
+
// reset zoom and position
|
|
1238
|
+
map.fitBounds(initBounds, {
|
|
1239
|
+
animate: false
|
|
1240
|
+
});
|
|
1230
1241
|
}
|
|
1231
1242
|
if (this.$refs.skcanSelection) {
|
|
1232
1243
|
this.$refs.skcanSelection.reset()
|
|
@@ -1262,18 +1273,6 @@ export default {
|
|
|
1262
1273
|
this.mapImp.zoomOut()
|
|
1263
1274
|
}
|
|
1264
1275
|
},
|
|
1265
|
-
/**
|
|
1266
|
-
* @public
|
|
1267
|
-
* Function to show or hide centrelines and nodes.
|
|
1268
|
-
* The parameter ``payload`` is an object with a boolean property, ``value``,
|
|
1269
|
-
* ``payload.value = true/false``.
|
|
1270
|
-
* @arg {Object} `payload`
|
|
1271
|
-
*/
|
|
1272
|
-
centreLinesSelected: function (payload) {
|
|
1273
|
-
if (this.mapImp) {
|
|
1274
|
-
this.mapImp.enableCentrelines(payload.value)
|
|
1275
|
-
}
|
|
1276
|
-
},
|
|
1277
1276
|
onSelectionsDataChanged: function (data) {
|
|
1278
1277
|
this.$emit('pathway-selection-changed', data);
|
|
1279
1278
|
},
|
|
@@ -1314,7 +1313,7 @@ export default {
|
|
|
1314
1313
|
let pathFeatures = paths.map((p) => this.mapImp.featureProperties(p))
|
|
1315
1314
|
|
|
1316
1315
|
// Query the flatmap knowledge graph for connectivity, we use this to grab the origins
|
|
1317
|
-
let connectivity = await this.flatmapQueries.
|
|
1316
|
+
let connectivity = await this.flatmapQueries.queryForConnectivityNew(this.mapImp, payload)
|
|
1318
1317
|
|
|
1319
1318
|
// Check and flatten the origins node graph
|
|
1320
1319
|
let originsFlat = connectivity?.ids?.dendrites?.flat().flat()
|
|
@@ -1582,8 +1581,12 @@ export default {
|
|
|
1582
1581
|
// Rollback drawing when no new annotation submitted
|
|
1583
1582
|
if (!this.featureAnnotationSubmitted) this.rollbackAnnotationEvent()
|
|
1584
1583
|
else this.featureAnnotationSubmitted = false
|
|
1584
|
+
this.annotationEntry = {}
|
|
1585
1585
|
} else if (data.type === 'modeChanged') {
|
|
1586
1586
|
if (data.feature.mode === 'direct_select') this.doubleClickedFeature = true
|
|
1587
|
+
if (this.annotationSidebar && data.feature.mode === 'simple_select') {
|
|
1588
|
+
this.annotationEventCallback({}, { type: 'aborted' })
|
|
1589
|
+
}
|
|
1587
1590
|
} else if (data.type === 'selectionChanged') {
|
|
1588
1591
|
this.selectedDrawnFeature = data.feature.features.length === 0 ?
|
|
1589
1592
|
undefined : data.feature.features[0]
|
|
@@ -1616,6 +1619,8 @@ export default {
|
|
|
1616
1619
|
if (data.type === 'created') this.drawnCreatedEvent = payload
|
|
1617
1620
|
else this.checkAndCreatePopups(payload)
|
|
1618
1621
|
}
|
|
1622
|
+
if (data.type === 'deleted') this.previousDeletedEvent = data
|
|
1623
|
+
else this.previousDeletedEvent = {}
|
|
1619
1624
|
},
|
|
1620
1625
|
/**
|
|
1621
1626
|
* @public
|
|
@@ -1660,6 +1665,9 @@ export default {
|
|
|
1660
1665
|
}
|
|
1661
1666
|
if (eventType === 'click') {
|
|
1662
1667
|
this.featuresAlert = data.alert
|
|
1668
|
+
//The following will be used to track either a feature is selected
|
|
1669
|
+
this.statesTracking.activeClick = true
|
|
1670
|
+
this.statesTracking.activeTerm = data?.models
|
|
1663
1671
|
if (this.viewingMode === 'Neuron Connection') {
|
|
1664
1672
|
this.highlightConnectedPaths([data.models])
|
|
1665
1673
|
} else {
|
|
@@ -1717,7 +1725,123 @@ export default {
|
|
|
1717
1725
|
if (modeName) {
|
|
1718
1726
|
this.viewingMode = modeName
|
|
1719
1727
|
}
|
|
1720
|
-
this.
|
|
1728
|
+
this.manualAbortedOnClose()
|
|
1729
|
+
},
|
|
1730
|
+
/**
|
|
1731
|
+
* @public
|
|
1732
|
+
* Function to remove active tooltips on map.
|
|
1733
|
+
*/
|
|
1734
|
+
removeActiveTooltips: function () {
|
|
1735
|
+
const tooltips = this.$el.querySelectorAll('.flatmap-tooltip-popup');
|
|
1736
|
+
tooltips.forEach((tooltip) => tooltip.remove());
|
|
1737
|
+
},
|
|
1738
|
+
/**
|
|
1739
|
+
* Function to create tooltip for the provided connectivity data.
|
|
1740
|
+
* @arg {Array} `connectivityData`
|
|
1741
|
+
*/
|
|
1742
|
+
createTooltipForConnectivity: function (connectivityData) {
|
|
1743
|
+
// combine all labels to show together
|
|
1744
|
+
// content type must be DOM object to use HTML
|
|
1745
|
+
const labelsContainer = document.createElement('div');
|
|
1746
|
+
labelsContainer.classList.add('flatmap-feature-label');
|
|
1747
|
+
|
|
1748
|
+
connectivityData.forEach((connectivity, i) => {
|
|
1749
|
+
const { label } = connectivity;
|
|
1750
|
+
labelsContainer.append(capitalise(label));
|
|
1751
|
+
|
|
1752
|
+
if ((i + 1) < connectivityData.length) {
|
|
1753
|
+
const hr = document.createElement('hr');
|
|
1754
|
+
labelsContainer.appendChild(hr);
|
|
1755
|
+
}
|
|
1756
|
+
});
|
|
1757
|
+
|
|
1758
|
+
this.mapImp.showPopup(
|
|
1759
|
+
connectivityData[0].featureId,
|
|
1760
|
+
labelsContainer,
|
|
1761
|
+
{
|
|
1762
|
+
className: 'custom-popup flatmap-tooltip-popup',
|
|
1763
|
+
positionAtLastClick: false,
|
|
1764
|
+
preserveSelection: true,
|
|
1765
|
+
}
|
|
1766
|
+
);
|
|
1767
|
+
},
|
|
1768
|
+
/**
|
|
1769
|
+
* Function to show connectivity tooltips on the map
|
|
1770
|
+
* and highlight the nerve.
|
|
1771
|
+
* @arg {Object} `payload`
|
|
1772
|
+
*/
|
|
1773
|
+
showConnectivityTooltips: function (payload) {
|
|
1774
|
+
const { connectivityInfo, data } = payload;
|
|
1775
|
+
const featuresToHighlight = [];
|
|
1776
|
+
const connectivityData = [];
|
|
1777
|
+
const filteredConnectivityData = [];
|
|
1778
|
+
const errorData = [];
|
|
1779
|
+
|
|
1780
|
+
if (!data.length) {
|
|
1781
|
+
// Close all tooltips on the current flatmap element
|
|
1782
|
+
this.removeActiveTooltips();
|
|
1783
|
+
} else {
|
|
1784
|
+
data.forEach((item) => {
|
|
1785
|
+
connectivityData.push({
|
|
1786
|
+
id: item.id,
|
|
1787
|
+
label: item.label,
|
|
1788
|
+
});
|
|
1789
|
+
});
|
|
1790
|
+
}
|
|
1791
|
+
|
|
1792
|
+
// to keep the highlighted path on map
|
|
1793
|
+
if (connectivityInfo && connectivityInfo.featureId) {
|
|
1794
|
+
featuresToHighlight.push(...connectivityInfo.featureId);
|
|
1795
|
+
}
|
|
1796
|
+
|
|
1797
|
+
// search the features on the map first
|
|
1798
|
+
if (this.mapImp) {
|
|
1799
|
+
connectivityData.forEach((connectivity, i) => {
|
|
1800
|
+
const {id, label} = connectivity;
|
|
1801
|
+
const response = this.mapImp.search(id);
|
|
1802
|
+
|
|
1803
|
+
if (response?.results.length) {
|
|
1804
|
+
const featureId = response?.results[0].featureId;
|
|
1805
|
+
|
|
1806
|
+
filteredConnectivityData.push({
|
|
1807
|
+
featureId,
|
|
1808
|
+
id,
|
|
1809
|
+
label,
|
|
1810
|
+
});
|
|
1811
|
+
featuresToHighlight.push(id);
|
|
1812
|
+
} else {
|
|
1813
|
+
errorData.push(connectivity);
|
|
1814
|
+
}
|
|
1815
|
+
});
|
|
1816
|
+
|
|
1817
|
+
if (filteredConnectivityData.length) {
|
|
1818
|
+
// show tooltip of the first item
|
|
1819
|
+
// with all labels
|
|
1820
|
+
this.createTooltipForConnectivity(filteredConnectivityData);
|
|
1821
|
+
} else {
|
|
1822
|
+
errorData.push(...connectivityData);
|
|
1823
|
+
// Close all tooltips on the current flatmap element
|
|
1824
|
+
this.removeActiveTooltips();
|
|
1825
|
+
}
|
|
1826
|
+
|
|
1827
|
+
// Emit error message for connectivity graph
|
|
1828
|
+
if (errorData.length) {
|
|
1829
|
+
this.emitConnectivityGraphError(errorData);
|
|
1830
|
+
}
|
|
1831
|
+
|
|
1832
|
+
// highlight all available features
|
|
1833
|
+
this.mapImp.zoomToFeatures(featuresToHighlight, { noZoomIn: true });
|
|
1834
|
+
}
|
|
1835
|
+
},
|
|
1836
|
+
emitConnectivityGraphError: function (errorData) {
|
|
1837
|
+
const errorMessage = 'cannot be found on the map!';
|
|
1838
|
+
|
|
1839
|
+
this.$emit('connectivity-graph-error', {
|
|
1840
|
+
data: {
|
|
1841
|
+
errorData: errorData,
|
|
1842
|
+
errorMessage: errorMessage,
|
|
1843
|
+
}
|
|
1844
|
+
});
|
|
1721
1845
|
},
|
|
1722
1846
|
/**
|
|
1723
1847
|
* @public
|
|
@@ -1729,6 +1853,13 @@ export default {
|
|
|
1729
1853
|
// Call flatmap database to get the connection data
|
|
1730
1854
|
if (this.viewingMode === 'Annotation') {
|
|
1731
1855
|
if (data.feature) {
|
|
1856
|
+
if (this.annotationSidebar && this.previousDeletedEvent.type === 'deleted') {
|
|
1857
|
+
this.annotationEntry = {
|
|
1858
|
+
...this.previousDeletedEvent,
|
|
1859
|
+
resourceId: this.serverURL
|
|
1860
|
+
}
|
|
1861
|
+
this.annotationEventCallback({}, { type: 'aborted' })
|
|
1862
|
+
}
|
|
1732
1863
|
this.annotationEntry = {
|
|
1733
1864
|
...data.feature,
|
|
1734
1865
|
resourceId: this.serverURL,
|
|
@@ -1744,7 +1875,9 @@ export default {
|
|
|
1744
1875
|
) {
|
|
1745
1876
|
this.featureAnnotationSubmitted = false
|
|
1746
1877
|
this.annotationEntry.featureId = data.feature.feature.id
|
|
1747
|
-
if (this.activeDrawTool)
|
|
1878
|
+
if (this.activeDrawTool) {
|
|
1879
|
+
this.createConnectivityBody()
|
|
1880
|
+
}
|
|
1748
1881
|
this.displayTooltip(
|
|
1749
1882
|
data.feature.feature.id,
|
|
1750
1883
|
centroid(data.feature.feature.geometry)
|
|
@@ -1757,13 +1890,13 @@ export default {
|
|
|
1757
1890
|
this.annotation = {}
|
|
1758
1891
|
}
|
|
1759
1892
|
} else {
|
|
1893
|
+
//require data.resource && data.feature.source
|
|
1760
1894
|
let results =
|
|
1761
|
-
await this.flatmapQueries.retrieveFlatmapKnowledgeForEvent(data)
|
|
1895
|
+
await this.flatmapQueries.retrieveFlatmapKnowledgeForEvent(this.mapImp, data)
|
|
1762
1896
|
// The line below only creates the tooltip if some data was found on the path
|
|
1763
|
-
//
|
|
1897
|
+
// the pubmed URLs are in knowledge response.references
|
|
1764
1898
|
if (
|
|
1765
|
-
results[0] ||
|
|
1766
|
-
results[1] ||
|
|
1899
|
+
(results && results[0]) ||
|
|
1767
1900
|
(data.feature.hyperlinks && data.feature.hyperlinks.length > 0)
|
|
1768
1901
|
) {
|
|
1769
1902
|
this.resourceForTooltip = data.resource[0]
|
|
@@ -1807,7 +1940,7 @@ export default {
|
|
|
1807
1940
|
* @arg {Object} `data`
|
|
1808
1941
|
*/
|
|
1809
1942
|
createTooltipFromNeuronCuration: async function (data) {
|
|
1810
|
-
this.tooltipEntry = await this.flatmapQueries.createTooltipData(data)
|
|
1943
|
+
this.tooltipEntry = await this.flatmapQueries.createTooltipData(this.mapImp, data)
|
|
1811
1944
|
this.displayTooltip(data.resource[0])
|
|
1812
1945
|
},
|
|
1813
1946
|
/**
|
|
@@ -2027,6 +2160,9 @@ export default {
|
|
|
2027
2160
|
}
|
|
2028
2161
|
this.$emit('connectivity-info-open', this.tooltipEntry);
|
|
2029
2162
|
}
|
|
2163
|
+
if (this.annotationSidebar && this.viewingMode === 'Annotation') {
|
|
2164
|
+
this.$emit('annotation-open', {annotationEntry: this.annotationEntry, commitCallback: this.commitAnnotationEvent});
|
|
2165
|
+
}
|
|
2030
2166
|
// If UI is not disabled,
|
|
2031
2167
|
// And connectivityInfoSidebar is not set (default) or set to `false`
|
|
2032
2168
|
// Provenance popup will be shown on map
|
|
@@ -2035,6 +2171,7 @@ export default {
|
|
|
2035
2171
|
!this.disableUI && (
|
|
2036
2172
|
(
|
|
2037
2173
|
this.viewingMode === 'Annotation' &&
|
|
2174
|
+
!this.annotationSidebar &&
|
|
2038
2175
|
this.userInformation
|
|
2039
2176
|
) ||
|
|
2040
2177
|
(
|
|
@@ -2146,6 +2283,48 @@ export default {
|
|
|
2146
2283
|
return Array.from(new Set(labels))
|
|
2147
2284
|
}
|
|
2148
2285
|
},
|
|
2286
|
+
/**
|
|
2287
|
+
* Function to get and store the state (object) of the map in
|
|
2288
|
+
* the provided argument
|
|
2289
|
+
*/
|
|
2290
|
+
getVisibilityState: function (state) {
|
|
2291
|
+
const refs = ['alertSelection', 'pathwaysSelection', 'taxonSelection']
|
|
2292
|
+
refs.forEach(ref => {
|
|
2293
|
+
let comp = this.$refs[ref]
|
|
2294
|
+
if (comp) {
|
|
2295
|
+
state[ref] = comp.getState()
|
|
2296
|
+
}
|
|
2297
|
+
})
|
|
2298
|
+
if (this.$refs.treeControls) {
|
|
2299
|
+
const checkedKeys = this.$refs.treeControls.$refs.regionTree.getCheckedKeys();
|
|
2300
|
+
//Only store first level systems (terms without .)
|
|
2301
|
+
state['systemsSelection'] = checkedKeys.filter(term => !term.includes('.'))
|
|
2302
|
+
}
|
|
2303
|
+
},
|
|
2304
|
+
/**
|
|
2305
|
+
* Function to set and restore the visibility state (object) of
|
|
2306
|
+
* the map with the provided argument
|
|
2307
|
+
*/
|
|
2308
|
+
setVisibilityState: function (state) {
|
|
2309
|
+
const refs = ['alertSelection', 'pathwaysSelection', 'taxonSelection']
|
|
2310
|
+
refs.forEach(ref => {
|
|
2311
|
+
const settings = state[ref]
|
|
2312
|
+
if (settings) {
|
|
2313
|
+
const comp = this.$refs[ref]
|
|
2314
|
+
if (comp) {
|
|
2315
|
+
comp.setState(settings)
|
|
2316
|
+
}
|
|
2317
|
+
}
|
|
2318
|
+
})
|
|
2319
|
+
if ('systemsSelection' in state) {
|
|
2320
|
+
if (this.$refs.treeControls) {
|
|
2321
|
+
this.$refs.treeControls.$refs.regionTree.setCheckedKeys(state['systemsSelection']);
|
|
2322
|
+
this.systems[0].children.forEach((item) => {
|
|
2323
|
+
this.mapImp.enableSystem(item.key, state['systemsSelection'].includes(item.key))
|
|
2324
|
+
})
|
|
2325
|
+
}
|
|
2326
|
+
}
|
|
2327
|
+
},
|
|
2149
2328
|
/**
|
|
2150
2329
|
* @public
|
|
2151
2330
|
* Function to get the state (object) of the map.
|
|
@@ -2161,6 +2340,13 @@ export default {
|
|
|
2161
2340
|
else if (identifier && identifier.biologicalSex)
|
|
2162
2341
|
state['biologicalSex'] = identifier.biologicalSex
|
|
2163
2342
|
if (identifier && identifier.uuid) state['uuid'] = identifier.uuid
|
|
2343
|
+
state['viewingMode'] = this.viewingMode
|
|
2344
|
+
state['searchTerm'] = this.statesTracking.activeTerm
|
|
2345
|
+
state['flightPath3D'] = this.flightPath3DRadio
|
|
2346
|
+
state['colour'] = this.colourRadio
|
|
2347
|
+
state['outlinesRadio'] = this.outlinesRadio
|
|
2348
|
+
state['background'] = this.currentBackground
|
|
2349
|
+
this.getVisibilityState(state)
|
|
2164
2350
|
return state
|
|
2165
2351
|
}
|
|
2166
2352
|
return undefined
|
|
@@ -2178,9 +2364,7 @@ export default {
|
|
|
2178
2364
|
this.entry == state.entry &&
|
|
2179
2365
|
(!state.biologicalSex || state.biologicalSex === this.biologicalSex)
|
|
2180
2366
|
) {
|
|
2181
|
-
|
|
2182
|
-
this.mapImp.setState(state.viewport)
|
|
2183
|
-
}
|
|
2367
|
+
this.restoreMapState(state)
|
|
2184
2368
|
} else {
|
|
2185
2369
|
this.createFlatmap(state)
|
|
2186
2370
|
}
|
|
@@ -2196,7 +2380,33 @@ export default {
|
|
|
2196
2380
|
restoreMapState: function (state) {
|
|
2197
2381
|
if (state) {
|
|
2198
2382
|
if (state.viewport) this.mapImp.setState(state.viewport)
|
|
2199
|
-
if (state.
|
|
2383
|
+
if (state.viewingMode) this.changeViewingMode(state.viewingMode)
|
|
2384
|
+
//The following three are boolean
|
|
2385
|
+
if ('flightPath3D' in state) this.setFlightPath3D(state.flightPath3D)
|
|
2386
|
+
if ('colour' in state) this.setColour(state.colour)
|
|
2387
|
+
if ('outlines' in state) this.setOutlines(state.outlines)
|
|
2388
|
+
if (state.background) this.backgroundChangeCallback(state.background)
|
|
2389
|
+
if (state.searchTerm) {
|
|
2390
|
+
const searchTerm = state.searchTerm
|
|
2391
|
+
this.searchAndShowResult(searchTerm, true)
|
|
2392
|
+
if (state.viewingMode === "Neuron Connection") {
|
|
2393
|
+
this.highlightConnectedPaths([searchTerm])
|
|
2394
|
+
} else {
|
|
2395
|
+
const geoID = this.mapImp.modelFeatureIds(searchTerm)
|
|
2396
|
+
if (geoID.length > 0) {
|
|
2397
|
+
const feature = this.mapImp.featureProperties(geoID[0])
|
|
2398
|
+
this.searchAndShowResult(searchTerm, true)
|
|
2399
|
+
const data = {
|
|
2400
|
+
resource: [feature.source],
|
|
2401
|
+
feature,
|
|
2402
|
+
label: feature.label,
|
|
2403
|
+
provenanceTaxonomy: feature.taxons
|
|
2404
|
+
}
|
|
2405
|
+
this.checkAndCreatePopups(data)
|
|
2406
|
+
}
|
|
2407
|
+
}
|
|
2408
|
+
}
|
|
2409
|
+
this.setVisibilityState(state)
|
|
2200
2410
|
}
|
|
2201
2411
|
},
|
|
2202
2412
|
/**
|
|
@@ -2289,16 +2499,13 @@ export default {
|
|
|
2289
2499
|
this.serverURL = this.mapImp.makeServerUrl('').slice(0, -1)
|
|
2290
2500
|
let mapVersion = this.mapImp.details.version
|
|
2291
2501
|
this.setFlightPathInfo(mapVersion)
|
|
2292
|
-
this.
|
|
2293
|
-
|
|
2294
|
-
|
|
2295
|
-
this.restoreMapState(state)
|
|
2296
|
-
}
|
|
2502
|
+
const stateToSet = this._stateToBeSet ? this._stateToBeSet : state
|
|
2503
|
+
this.onFlatmapReady(stateToSet)
|
|
2504
|
+
this.$nextTick(() => this.restoreMapState(stateToSet))
|
|
2297
2505
|
})
|
|
2298
2506
|
} else if (state) {
|
|
2299
2507
|
this._stateToBeSet = {
|
|
2300
|
-
|
|
2301
|
-
searchTerm: state.searchTerm,
|
|
2508
|
+
...state
|
|
2302
2509
|
}
|
|
2303
2510
|
if (this.mapImp && !this.loading)
|
|
2304
2511
|
this.restoreMapState(this._stateToBeSet)
|
|
@@ -2340,32 +2547,28 @@ export default {
|
|
|
2340
2547
|
* @public
|
|
2341
2548
|
* This function is used for functions that need to run immediately after the flatmap is loaded.
|
|
2342
2549
|
*/
|
|
2343
|
-
onFlatmapReady: function () {
|
|
2550
|
+
onFlatmapReady: function (state) {
|
|
2344
2551
|
// onFlatmapReady is used for functions that need to run immediately after the flatmap is loaded
|
|
2345
2552
|
this.sensor = markRaw(new ResizeSensor(this.$refs.display, this.mapResize))
|
|
2346
|
-
console.log(this.mapImp.options)
|
|
2347
2553
|
if (this.mapImp.options?.style === 'functional') {
|
|
2348
2554
|
this.isFC = true
|
|
2349
|
-
} else if (this.mapImp.options?.style === 'centreline') {
|
|
2350
|
-
this.isCentreLine = true
|
|
2351
2555
|
}
|
|
2352
2556
|
this.mapImp.setBackgroundOpacity(1)
|
|
2353
2557
|
this.backgroundChangeCallback(this.currentBackground)
|
|
2354
2558
|
this.pathways = this.mapImp.pathTypes()
|
|
2355
|
-
if (!this.isCentreLine) {
|
|
2356
|
-
this.mapImp.enableCentrelines(false)
|
|
2357
|
-
}
|
|
2358
2559
|
//Disable layers for now
|
|
2359
2560
|
//this.layers = this.mapImp.getLayers();
|
|
2360
2561
|
this.processSystems(this.mapImp.getSystems())
|
|
2361
|
-
|
|
2562
|
+
//Async, pass the state for checking
|
|
2563
|
+
this.processTaxon(this.mapImp.taxonIdentifiers, state ? state['taxonSelection'] : undefined)
|
|
2362
2564
|
this.containsAlert = "alert" in this.mapImp.featureFilterRanges()
|
|
2363
2565
|
this.addResizeButtonToMinimap()
|
|
2364
2566
|
this.loading = false
|
|
2365
2567
|
this.computePathControlsMaximumHeight()
|
|
2366
|
-
this.drawerOpen =
|
|
2568
|
+
this.drawerOpen = true;
|
|
2367
2569
|
this.mapResize()
|
|
2368
2570
|
this.handleMapClick();
|
|
2571
|
+
this.setInitMapState();
|
|
2369
2572
|
/**
|
|
2370
2573
|
* This is ``onFlatmapReady`` event.
|
|
2371
2574
|
* @arg ``this`` (Component Vue Instance)
|
|
@@ -2379,9 +2582,15 @@ export default {
|
|
|
2379
2582
|
*/
|
|
2380
2583
|
handleMapClick: function () {
|
|
2381
2584
|
const _map = this.mapImp._map;
|
|
2382
|
-
|
|
2383
2585
|
if (_map) {
|
|
2384
2586
|
_map.on('click', (e) => {
|
|
2587
|
+
//A little logic to make sure we are keeping track
|
|
2588
|
+
//of selected term
|
|
2589
|
+
if (this.statesTracking.activeClick) {
|
|
2590
|
+
this.statesTracking.activeClick = false
|
|
2591
|
+
} else {
|
|
2592
|
+
this.statesTracking.activeTerm = ""
|
|
2593
|
+
}
|
|
2385
2594
|
if (this.tooltipEntry.featureId) {
|
|
2386
2595
|
this.$emit('connectivity-info-close');
|
|
2387
2596
|
}
|
|
@@ -2417,6 +2626,7 @@ export default {
|
|
|
2417
2626
|
if (this.mapImp) {
|
|
2418
2627
|
if (term === undefined || term === '') {
|
|
2419
2628
|
this.mapImp.clearSearchResults()
|
|
2629
|
+
this.statesTracking.activeTerm = ""
|
|
2420
2630
|
return true
|
|
2421
2631
|
} else {
|
|
2422
2632
|
const searchResults = this.mapImp.search(term)
|
|
@@ -2425,6 +2635,7 @@ export default {
|
|
|
2425
2635
|
searchResults.results &&
|
|
2426
2636
|
searchResults.results.length > 0
|
|
2427
2637
|
) {
|
|
2638
|
+
this.statesTracking.activeTerm = term
|
|
2428
2639
|
this.mapImp.showSearchResults(searchResults)
|
|
2429
2640
|
if (
|
|
2430
2641
|
displayLabel &&
|
|
@@ -2488,7 +2699,7 @@ export default {
|
|
|
2488
2699
|
*/
|
|
2489
2700
|
minZoom: {
|
|
2490
2701
|
type: Number,
|
|
2491
|
-
default:
|
|
2702
|
+
default: 1,
|
|
2492
2703
|
},
|
|
2493
2704
|
/**
|
|
2494
2705
|
* The option to add another feature label _(`FeatureSmallSymbolLayer`)_
|
|
@@ -2645,12 +2856,18 @@ export default {
|
|
|
2645
2856
|
type: Boolean,
|
|
2646
2857
|
default: false,
|
|
2647
2858
|
},
|
|
2859
|
+
/**
|
|
2860
|
+
* The option to show annotation in sidebar
|
|
2861
|
+
*/
|
|
2862
|
+
annotationSidebar: {
|
|
2863
|
+
type: Boolean,
|
|
2864
|
+
default: false,
|
|
2865
|
+
},
|
|
2648
2866
|
},
|
|
2649
2867
|
provide() {
|
|
2650
2868
|
return {
|
|
2651
2869
|
flatmapAPI: this.flatmapAPI,
|
|
2652
2870
|
sparcAPI: this.sparcAPI,
|
|
2653
|
-
$annotator: this.annotator,
|
|
2654
2871
|
getFeaturesAlert: () => this.featuresAlert,
|
|
2655
2872
|
userApiKey: this.userToken,
|
|
2656
2873
|
}
|
|
@@ -2668,19 +2885,13 @@ export default {
|
|
|
2668
2885
|
serverURL: undefined,
|
|
2669
2886
|
layers: [],
|
|
2670
2887
|
pathways: [],
|
|
2888
|
+
initMapState: {},
|
|
2671
2889
|
sckanDisplay: [
|
|
2672
2890
|
{
|
|
2673
2891
|
label: 'Display Path with SCKAN',
|
|
2674
2892
|
key: 'VALID',
|
|
2675
2893
|
},
|
|
2676
2894
|
],
|
|
2677
|
-
centreLines: [
|
|
2678
|
-
{
|
|
2679
|
-
label: 'Display Nerves',
|
|
2680
|
-
key: 'centrelines',
|
|
2681
|
-
enabled: false,
|
|
2682
|
-
},
|
|
2683
|
-
],
|
|
2684
2895
|
systems: [],
|
|
2685
2896
|
taxonConnectivity: [],
|
|
2686
2897
|
pathwaysMaxHeight: 1000,
|
|
@@ -2706,7 +2917,6 @@ export default {
|
|
|
2706
2917
|
helpModeActiveIndex: this.helpModeInitialIndex,
|
|
2707
2918
|
yellowstar: yellowstar,
|
|
2708
2919
|
isFC: false,
|
|
2709
|
-
isCentreLine: false,
|
|
2710
2920
|
inHelp: false,
|
|
2711
2921
|
currentBackground: 'white',
|
|
2712
2922
|
availableBackground: ['white', 'lightskyblue', 'black'],
|
|
@@ -2751,6 +2961,7 @@ export default {
|
|
|
2751
2961
|
activeDrawTool: undefined,
|
|
2752
2962
|
featureAnnotationSubmitted: false,
|
|
2753
2963
|
drawnCreatedEvent: {},
|
|
2964
|
+
previousDeletedEvent: {},
|
|
2754
2965
|
connectionEntry: {},
|
|
2755
2966
|
existDrawnFeatures: [], // Store all exist drawn features
|
|
2756
2967
|
doubleClickedFeature: false,
|
|
@@ -2772,7 +2983,11 @@ export default {
|
|
|
2772
2983
|
with: true,
|
|
2773
2984
|
without: true,
|
|
2774
2985
|
}
|
|
2775
|
-
})
|
|
2986
|
+
}),
|
|
2987
|
+
statesTracking: markRaw({
|
|
2988
|
+
activeClick: false,
|
|
2989
|
+
activeTerm: "",
|
|
2990
|
+
}),
|
|
2776
2991
|
}
|
|
2777
2992
|
},
|
|
2778
2993
|
computed: {
|
|
@@ -2820,9 +3035,7 @@ export default {
|
|
|
2820
3035
|
this.showAnnotator(true)
|
|
2821
3036
|
this.userInformation = userData
|
|
2822
3037
|
this.setFeatureAnnotated()
|
|
2823
|
-
|
|
2824
|
-
this.addAnnotationFeature()
|
|
2825
|
-
}
|
|
3038
|
+
this.addAnnotationFeature()
|
|
2826
3039
|
}
|
|
2827
3040
|
this.loading = false
|
|
2828
3041
|
})
|
|
@@ -2920,6 +3133,11 @@ export default {
|
|
|
2920
3133
|
left: 0px;
|
|
2921
3134
|
transform: translateX(0);
|
|
2922
3135
|
transition: all var(--el-transition-duration);
|
|
3136
|
+
z-index: 99;
|
|
3137
|
+
display: flex;
|
|
3138
|
+
flex-direction: row;
|
|
3139
|
+
align-items: center;
|
|
3140
|
+
|
|
2923
3141
|
&.open {
|
|
2924
3142
|
transform: translateX(0);
|
|
2925
3143
|
}
|
|
@@ -3465,7 +3683,6 @@ export default {
|
|
|
3465
3683
|
}
|
|
3466
3684
|
}
|
|
3467
3685
|
|
|
3468
|
-
.open-drawer,
|
|
3469
3686
|
.drawer-button {
|
|
3470
3687
|
z-index: 8;
|
|
3471
3688
|
width: 20px;
|
|
@@ -3475,18 +3692,6 @@ export default {
|
|
|
3475
3692
|
vertical-align: middle;
|
|
3476
3693
|
cursor: pointer;
|
|
3477
3694
|
pointer-events: auto;
|
|
3478
|
-
}
|
|
3479
|
-
|
|
3480
|
-
.open-drawer {
|
|
3481
|
-
position: absolute;
|
|
3482
|
-
left: 0px;
|
|
3483
|
-
background-color: #f7faff;
|
|
3484
|
-
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.06);
|
|
3485
|
-
}
|
|
3486
|
-
|
|
3487
|
-
.drawer-button {
|
|
3488
|
-
float: left;
|
|
3489
|
-
margin-top: calc(50% - 36px);
|
|
3490
3695
|
background-color: #f9f2fc;
|
|
3491
3696
|
|
|
3492
3697
|
i {
|