@abi-software/flatmapvuer 1.13.0 → 1.13.1-simulation.0
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 +2717 -2403
- package/dist/flatmapvuer.umd.cjs +11 -11
- package/dist/style.css +1 -1
- package/package.json +2 -2
- package/src/components/FlatmapVuer.vue +1134 -648
- package/src/components/MultiFlatmapVuer.vue +2 -0
- package/src/components/index.js +17 -3
- package/src/services/flatmapKnowledge.js +1 -0
|
@@ -11,7 +11,11 @@
|
|
|
11
11
|
style="height: 100%; width: 100%; position: relative; overflow-y: none"
|
|
12
12
|
>
|
|
13
13
|
<!-- flatmap-display -->
|
|
14
|
-
<div
|
|
14
|
+
<div
|
|
15
|
+
style="height: 100%; width: 100%"
|
|
16
|
+
ref="display"
|
|
17
|
+
class="flatmap-display"
|
|
18
|
+
></div>
|
|
15
19
|
<!-- flatmap-error -->
|
|
16
20
|
<FlatmapError v-if="flatmapError" :flatmapError="flatmapError" />
|
|
17
21
|
|
|
@@ -25,7 +29,7 @@
|
|
|
25
29
|
:visible="hoverVisibilities[7].value"
|
|
26
30
|
ref="warningPopover"
|
|
27
31
|
>
|
|
28
|
-
<!--
|
|
32
|
+
<!--
|
|
29
33
|
What magic meaning do the numbers 6, 7, etc have?
|
|
30
34
|
|
|
31
35
|
Please use `const` to assign meaningful names to them...
|
|
@@ -59,10 +63,7 @@ Please use `const` to assign meaningful names to them...
|
|
|
59
63
|
SCKAN </a
|
|
60
64
|
>.
|
|
61
65
|
</p>
|
|
62
|
-
<p v-else
|
|
63
|
-
@mouseover="showTooltip(7)"
|
|
64
|
-
@mouseout="hideTooltip(7)"
|
|
65
|
-
>
|
|
66
|
+
<p v-else @mouseover="showTooltip(7)" @mouseout="hideTooltip(7)">
|
|
66
67
|
This map displays the connectivity of neuron populations.
|
|
67
68
|
Specifically, those from the primarily rat-based
|
|
68
69
|
<a
|
|
@@ -86,7 +87,9 @@ Please use `const` to assign meaningful names to them...
|
|
|
86
87
|
@mouseover="showTooltip(7)"
|
|
87
88
|
@mouseout="hideTooltip(7)"
|
|
88
89
|
>
|
|
89
|
-
<el-icon v-if="displayWarning || isLegacy"
|
|
90
|
+
<el-icon v-if="displayWarning || isLegacy"
|
|
91
|
+
><el-icon-warning-filled
|
|
92
|
+
/></el-icon>
|
|
90
93
|
<template v-if="isLegacy">
|
|
91
94
|
<span class="warning-text">Legacy Map</span>
|
|
92
95
|
<div class="latest-map-text" @click="viewLatestMap">
|
|
@@ -123,13 +126,13 @@ Please use `const` to assign meaningful names to them...
|
|
|
123
126
|
<template #default>
|
|
124
127
|
<b>Connectivity References</b>
|
|
125
128
|
<p>
|
|
126
|
-
Connectivity references have been improved and available
|
|
127
|
-
|
|
129
|
+
Connectivity references have been improved and available in
|
|
130
|
+
various formats.
|
|
128
131
|
</p>
|
|
129
132
|
<b>Improved state storing</b>
|
|
130
133
|
<p>
|
|
131
|
-
Current selection and visibility filters are now stored
|
|
132
|
-
|
|
134
|
+
Current selection and visibility filters are now stored when
|
|
135
|
+
creating a permalink.
|
|
133
136
|
</p>
|
|
134
137
|
</template>
|
|
135
138
|
</el-popover>
|
|
@@ -147,7 +150,11 @@ Please use `const` to assign meaningful names to them...
|
|
|
147
150
|
</el-icon>
|
|
148
151
|
|
|
149
152
|
<DrawToolbar
|
|
150
|
-
v-if="
|
|
153
|
+
v-if="
|
|
154
|
+
viewingMode === 'Annotation' &&
|
|
155
|
+
(authorisedUser || offlineAnnotationEnabled) &&
|
|
156
|
+
!disableUI
|
|
157
|
+
"
|
|
151
158
|
:mapCanvas="{
|
|
152
159
|
containerHTML: this.$el,
|
|
153
160
|
class: '.maplibregl-canvas',
|
|
@@ -166,7 +173,79 @@ Please use `const` to assign meaningful names to them...
|
|
|
166
173
|
@hideTooltip="hideTooltip"
|
|
167
174
|
ref="toolbarPopover"
|
|
168
175
|
/>
|
|
169
|
-
|
|
176
|
+
<!-- <div class="top-left-control" v-if="simulationInfo.length > 0"> -->
|
|
177
|
+
<el-popover
|
|
178
|
+
content="Open simulation protocols"
|
|
179
|
+
v-if="simulationInfo.length > 0"
|
|
180
|
+
placement="right"
|
|
181
|
+
:teleported="false"
|
|
182
|
+
trigger="manual"
|
|
183
|
+
:offset="-18"
|
|
184
|
+
popper-class="flatmap-popper"
|
|
185
|
+
:visible="hoverVisibilities[16].value"
|
|
186
|
+
ref="simulationPopover"
|
|
187
|
+
>
|
|
188
|
+
<template #reference>
|
|
189
|
+
<div
|
|
190
|
+
class="popover-location top"
|
|
191
|
+
:class="{
|
|
192
|
+
open: simulationDrawerOpen,
|
|
193
|
+
close: !simulationDrawerOpen,
|
|
194
|
+
}"
|
|
195
|
+
v-show="!disableUI"
|
|
196
|
+
>
|
|
197
|
+
<div
|
|
198
|
+
class="pathway-container"
|
|
199
|
+
:class="{
|
|
200
|
+
open: simulationDrawerOpen,
|
|
201
|
+
close: !simulationDrawerOpen,
|
|
202
|
+
}"
|
|
203
|
+
v-popover:simulationPopover
|
|
204
|
+
>
|
|
205
|
+
<h4 style="margin-top: 0; margin-bottom: 10px">
|
|
206
|
+
Available Protocols
|
|
207
|
+
</h4>
|
|
208
|
+
<el-select
|
|
209
|
+
v-model="selectedSimulation"
|
|
210
|
+
placeholder="Select a simulation"
|
|
211
|
+
size="default"
|
|
212
|
+
style="width: 100%; margin-bottom: 10px"
|
|
213
|
+
value-key="path"
|
|
214
|
+
>
|
|
215
|
+
<el-option
|
|
216
|
+
v-for="info in simulationInfo"
|
|
217
|
+
:key="info.path"
|
|
218
|
+
:label="getSimulationLabel(info)"
|
|
219
|
+
:value="info"
|
|
220
|
+
/>
|
|
221
|
+
</el-select>
|
|
222
|
+
<el-button
|
|
223
|
+
type="primary"
|
|
224
|
+
@click="openSimulation"
|
|
225
|
+
:disabled="!selectedSimulation"
|
|
226
|
+
style="width: 100%"
|
|
227
|
+
>
|
|
228
|
+
Open Simulation
|
|
229
|
+
</el-button>
|
|
230
|
+
</div>
|
|
231
|
+
<div
|
|
232
|
+
@click="simulationDrawerOpen = !simulationDrawerOpen"
|
|
233
|
+
class="drawer-button"
|
|
234
|
+
:class="{
|
|
235
|
+
open: simulationDrawerOpen,
|
|
236
|
+
close: !simulationDrawerOpen,
|
|
237
|
+
}"
|
|
238
|
+
title="Toggle Simulation Panel"
|
|
239
|
+
>
|
|
240
|
+
<!-- Arrow icons for open/close state -->
|
|
241
|
+
<el-icon>
|
|
242
|
+
<el-icon-arrow-left />
|
|
243
|
+
</el-icon>
|
|
244
|
+
</div>
|
|
245
|
+
</div>
|
|
246
|
+
</template>
|
|
247
|
+
</el-popover>
|
|
248
|
+
<!-- </div> -->
|
|
170
249
|
<div class="bottom-right-control" v-show="!disableUI">
|
|
171
250
|
<el-popover
|
|
172
251
|
content="Zoom in"
|
|
@@ -185,10 +264,7 @@ Please use `const` to assign meaningful names to them...
|
|
|
185
264
|
@mouseover="showTooltip(1)"
|
|
186
265
|
@mouseout="hideTooltip(1)"
|
|
187
266
|
>
|
|
188
|
-
<map-svg-icon
|
|
189
|
-
class="icon-button zoomIn"
|
|
190
|
-
icon="zoomIn"
|
|
191
|
-
/>
|
|
267
|
+
<map-svg-icon class="icon-button zoomIn" icon="zoomIn" />
|
|
192
268
|
</div>
|
|
193
269
|
</template>
|
|
194
270
|
</el-popover>
|
|
@@ -196,23 +272,14 @@ Please use `const` to assign meaningful names to them...
|
|
|
196
272
|
content="Zoom out"
|
|
197
273
|
placement="top-end"
|
|
198
274
|
:teleported="false"
|
|
199
|
-
|
|
275
|
+
:auto-close="1300"
|
|
200
276
|
width="70"
|
|
201
277
|
popper-class="flatmap-popper"
|
|
202
|
-
:visible="hoverVisibilities[2].value"
|
|
203
278
|
ref="zoomOutPopover"
|
|
204
279
|
>
|
|
205
280
|
<template #reference>
|
|
206
|
-
<div
|
|
207
|
-
class="icon-button
|
|
208
|
-
@click="zoomOut()"
|
|
209
|
-
@mouseover="showTooltip(2)"
|
|
210
|
-
@mouseout="hideTooltip(2)"
|
|
211
|
-
>
|
|
212
|
-
<map-svg-icon
|
|
213
|
-
class="icon-button zoomOut"
|
|
214
|
-
icon="zoomOut"
|
|
215
|
-
/>
|
|
281
|
+
<div class="icon-button-container" @click="zoomOut()">
|
|
282
|
+
<map-svg-icon class="icon-button zoomOut" icon="zoomOut" />
|
|
216
283
|
</div>
|
|
217
284
|
</template>
|
|
218
285
|
</el-popover>
|
|
@@ -238,16 +305,14 @@ Please use `const` to assign meaningful names to them...
|
|
|
238
305
|
@mouseover="showTooltip(3)"
|
|
239
306
|
@mouseout="hideTooltip(3)"
|
|
240
307
|
>
|
|
241
|
-
<map-svg-icon
|
|
242
|
-
class="icon-button fitWindow"
|
|
243
|
-
icon="fitWindow"
|
|
244
|
-
/>
|
|
308
|
+
<map-svg-icon class="icon-button fitWindow" icon="fitWindow" />
|
|
245
309
|
</div>
|
|
246
310
|
</template>
|
|
247
311
|
</el-popover>
|
|
248
312
|
</div>
|
|
249
313
|
<el-popover
|
|
250
314
|
content="Change pathway visibility"
|
|
315
|
+
class="somerandomclass"
|
|
251
316
|
placement="right"
|
|
252
317
|
:teleported="false"
|
|
253
318
|
trigger="manual"
|
|
@@ -258,7 +323,7 @@ Please use `const` to assign meaningful names to them...
|
|
|
258
323
|
>
|
|
259
324
|
<template #reference>
|
|
260
325
|
<div
|
|
261
|
-
class="
|
|
326
|
+
class="popover-location bottom"
|
|
262
327
|
:class="{ open: drawerOpen, close: !drawerOpen }"
|
|
263
328
|
v-show="!disableUI && requiresDrawer"
|
|
264
329
|
>
|
|
@@ -268,7 +333,7 @@ Please use `const` to assign meaningful names to them...
|
|
|
268
333
|
:style="{ 'max-height': pathwaysMaxHeight + 'px' }"
|
|
269
334
|
v-popover:checkBoxPopover
|
|
270
335
|
>
|
|
271
|
-
<
|
|
336
|
+
<DynamicLegends
|
|
272
337
|
v-if="legendEntry.length"
|
|
273
338
|
identifierKey="prompt"
|
|
274
339
|
colourKey="colour"
|
|
@@ -366,7 +431,11 @@ Please use `const` to assign meaningful names to them...
|
|
|
366
431
|
key="pathwaysSelection"
|
|
367
432
|
/>
|
|
368
433
|
<selections-group
|
|
369
|
-
v-if="
|
|
434
|
+
v-if="
|
|
435
|
+
taxonConnectivity &&
|
|
436
|
+
taxonConnectivity.length > 0 &&
|
|
437
|
+
showPathwayFilter
|
|
438
|
+
"
|
|
370
439
|
title="Studied in"
|
|
371
440
|
labelKey="label"
|
|
372
441
|
identifierKey="taxon"
|
|
@@ -408,9 +477,7 @@ Please use `const` to assign meaningful names to them...
|
|
|
408
477
|
@event open-map
|
|
409
478
|
@arg {String} `mapOption.key`
|
|
410
479
|
-->
|
|
411
|
-
<el-button type="primary" plain
|
|
412
|
-
@click="$emit('open-map', item.key)"
|
|
413
|
-
>
|
|
480
|
+
<el-button type="primary" plain @click="$emit('open-map', item.key)">
|
|
414
481
|
{{ item.display }}
|
|
415
482
|
</el-button>
|
|
416
483
|
</el-row>
|
|
@@ -428,23 +495,29 @@ Please use `const` to assign meaningful names to them...
|
|
|
428
495
|
<div>
|
|
429
496
|
<el-row class="backgroundText">Viewing Mode</el-row>
|
|
430
497
|
<el-row class="backgroundControl">
|
|
431
|
-
<div style="margin-bottom: 2px
|
|
432
|
-
<template
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
<
|
|
440
|
-
|
|
441
|
-
|
|
498
|
+
<div style="margin-bottom: 2px">
|
|
499
|
+
<template v-for="(value, key, index) in viewingModes" :key="key">
|
|
500
|
+
<template v-if="key === viewingMode">
|
|
501
|
+
<span class="viewing-mode-title"
|
|
502
|
+
><b>{{ key }}</b></span
|
|
503
|
+
>
|
|
504
|
+
</template>
|
|
505
|
+
<template v-else>
|
|
506
|
+
<span
|
|
507
|
+
class="viewing-mode-unselected"
|
|
508
|
+
@click="changeViewingMode(key)"
|
|
509
|
+
>{{ key }}</span
|
|
510
|
+
>
|
|
511
|
+
</template>
|
|
442
512
|
</template>
|
|
443
513
|
</div>
|
|
444
514
|
<el-row class="viewing-mode-description">
|
|
445
515
|
{{ modeDescription }}
|
|
446
516
|
</el-row>
|
|
447
|
-
<el-row
|
|
517
|
+
<el-row
|
|
518
|
+
v-if="viewingMode === 'Annotation' && offlineAnnotationEnabled"
|
|
519
|
+
class="viewing-mode-description"
|
|
520
|
+
>
|
|
448
521
|
(Anonymous annotate)
|
|
449
522
|
</el-row>
|
|
450
523
|
</el-row>
|
|
@@ -472,16 +545,21 @@ Please use `const` to assign meaningful names to them...
|
|
|
472
545
|
</el-select>
|
|
473
546
|
</el-row>
|
|
474
547
|
</template>
|
|
475
|
-
<el-row
|
|
476
|
-
|
|
548
|
+
<el-row
|
|
549
|
+
class="backgroundSpacer"
|
|
550
|
+
v-if="displayFlightPathOption"
|
|
551
|
+
></el-row>
|
|
552
|
+
<el-row class="backgroundText" v-if="displayFlightPathOption"
|
|
553
|
+
>Flight path display</el-row
|
|
554
|
+
>
|
|
477
555
|
<el-row class="backgroundControl" v-if="displayFlightPathOption">
|
|
478
556
|
<el-radio-group
|
|
479
557
|
v-model="flightPath3DRadio"
|
|
480
558
|
class="flatmap-radio"
|
|
481
559
|
@change="setFlightPath3D"
|
|
482
560
|
>
|
|
483
|
-
|
|
484
|
-
|
|
561
|
+
<el-radio :value="false">2D</el-radio>
|
|
562
|
+
<el-radio :value="true">3D</el-radio>
|
|
485
563
|
</el-radio-group>
|
|
486
564
|
</el-row>
|
|
487
565
|
<el-row class="backgroundSpacer"></el-row>
|
|
@@ -571,10 +649,7 @@ Please use `const` to assign meaningful names to them...
|
|
|
571
649
|
@mouseover="showTooltip(5)"
|
|
572
650
|
@mouseout="hideTooltip(5)"
|
|
573
651
|
>
|
|
574
|
-
<map-svg-icon
|
|
575
|
-
icon="changeBckgd"
|
|
576
|
-
class="icon-button"
|
|
577
|
-
/>
|
|
652
|
+
<map-svg-icon icon="changeBckgd" class="icon-button" />
|
|
578
653
|
</div>
|
|
579
654
|
</template>
|
|
580
655
|
</el-popover>
|
|
@@ -636,24 +711,24 @@ import ResizeSensor from 'css-element-queries/src/ResizeSensor'
|
|
|
636
711
|
import flatmap from '../services/flatmapLoader.js'
|
|
637
712
|
import { AnnotationService } from '@abi-software/sparc-annotation'
|
|
638
713
|
import { mapState } from 'pinia'
|
|
639
|
-
import { useMainStore } from '
|
|
714
|
+
import { useMainStore } from '../store/index.js'
|
|
640
715
|
import {
|
|
641
716
|
fetchLabels,
|
|
642
717
|
DrawToolbar,
|
|
643
718
|
Tooltip,
|
|
644
719
|
TreeControls,
|
|
645
|
-
getFlatmapFilterOptions
|
|
720
|
+
getFlatmapFilterOptions,
|
|
646
721
|
} from '@abi-software/map-utilities'
|
|
647
722
|
import '@abi-software/map-utilities/dist/style.css'
|
|
648
723
|
import EventBus from './EventBus.js'
|
|
649
724
|
import FlatmapError from './FlatmapError.vue'
|
|
650
725
|
|
|
651
|
-
const ERROR_MESSAGE = 'cannot be found on the map.'
|
|
726
|
+
const ERROR_MESSAGE = 'cannot be found on the map.'
|
|
652
727
|
|
|
653
728
|
const centroid = (geometry) => {
|
|
654
|
-
let featureGeometry = { lng: 0, lat: 0
|
|
729
|
+
let featureGeometry = { lng: 0, lat: 0 }
|
|
655
730
|
let coordinates
|
|
656
|
-
if (geometry.type ===
|
|
731
|
+
if (geometry.type === 'Polygon') {
|
|
657
732
|
if (geometry.coordinates.length) {
|
|
658
733
|
coordinates = geometry.coordinates[0]
|
|
659
734
|
}
|
|
@@ -727,6 +802,7 @@ export default {
|
|
|
727
802
|
ElIconArrowDown,
|
|
728
803
|
ElIconArrowLeft,
|
|
729
804
|
DrawToolbar,
|
|
805
|
+
DynamicLegends,
|
|
730
806
|
FlatmapError,
|
|
731
807
|
},
|
|
732
808
|
beforeCreate: function () {
|
|
@@ -738,7 +814,7 @@ export default {
|
|
|
738
814
|
setup(props) {
|
|
739
815
|
let annotator = inject('$annotator')
|
|
740
816
|
if (!annotator) {
|
|
741
|
-
annotator = markRaw(new AnnotationService(`${props.flatmapAPI}annotator`))
|
|
817
|
+
annotator = markRaw(new AnnotationService(`${props.flatmapAPI}annotator`))
|
|
742
818
|
provide('$annotator', annotator)
|
|
743
819
|
}
|
|
744
820
|
return { annotator }
|
|
@@ -763,17 +839,17 @@ export default {
|
|
|
763
839
|
if (this.mapImp) {
|
|
764
840
|
if (this.mapImp.contextLost) {
|
|
765
841
|
if (filter) {
|
|
766
|
-
this.filterToRestore = markRaw(JSON.parse(JSON.stringify(filter)))
|
|
842
|
+
this.filterToRestore = markRaw(JSON.parse(JSON.stringify(filter)))
|
|
767
843
|
} else {
|
|
768
|
-
this.filterToRestore = undefined
|
|
844
|
+
this.filterToRestore = undefined
|
|
769
845
|
}
|
|
770
846
|
} else {
|
|
771
847
|
if (filter) {
|
|
772
|
-
this.mapImp.setVisibilityFilter(filter)
|
|
848
|
+
this.mapImp.setVisibilityFilter(filter)
|
|
773
849
|
} else {
|
|
774
|
-
this.mapImp.clearVisibilityFilter()
|
|
850
|
+
this.mapImp.clearVisibilityFilter()
|
|
775
851
|
}
|
|
776
|
-
this.filterToRestore = undefined
|
|
852
|
+
this.filterToRestore = undefined
|
|
777
853
|
}
|
|
778
854
|
}
|
|
779
855
|
},
|
|
@@ -782,7 +858,7 @@ export default {
|
|
|
782
858
|
* Function to manually send aborted signal when annotation tooltip popup or sidebar tab closed.
|
|
783
859
|
*/
|
|
784
860
|
manualAbortedOnClose: function () {
|
|
785
|
-
if (this.annotationSidebar) this.$emit(
|
|
861
|
+
if (this.annotationSidebar) this.$emit('annotation-close')
|
|
786
862
|
this.closeTooltip()
|
|
787
863
|
this.annotationEventCallback({}, { type: 'aborted' })
|
|
788
864
|
this.initialiseDrawing()
|
|
@@ -803,12 +879,14 @@ export default {
|
|
|
803
879
|
*/
|
|
804
880
|
cancelDrawnFeature: function () {
|
|
805
881
|
if (this.isValidDrawnCreated) {
|
|
806
|
-
if (this.annotationSidebar) this.$emit(
|
|
882
|
+
if (this.annotationSidebar) this.$emit('annotation-close')
|
|
807
883
|
this.closeTooltip()
|
|
808
|
-
this.annotationEntry = [
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
884
|
+
this.annotationEntry = [
|
|
885
|
+
{
|
|
886
|
+
...this.drawnCreatedEvent.feature,
|
|
887
|
+
resourceId: this.serverURL,
|
|
888
|
+
},
|
|
889
|
+
]
|
|
812
890
|
this.rollbackAnnotationEvent()
|
|
813
891
|
this.initialiseDrawing()
|
|
814
892
|
}
|
|
@@ -824,7 +902,11 @@ export default {
|
|
|
824
902
|
const numericId = Number(value)
|
|
825
903
|
const featureObject = numericId
|
|
826
904
|
? this.mapImp.featureProperties(numericId)
|
|
827
|
-
: {
|
|
905
|
+
: {
|
|
906
|
+
feature: this.existDrawnFeatures.find(
|
|
907
|
+
(feature) => feature.id === value.trim()
|
|
908
|
+
),
|
|
909
|
+
}
|
|
828
910
|
let payload = { feature: featureObject }
|
|
829
911
|
this.checkAndCreatePopups([payload], false)
|
|
830
912
|
} else {
|
|
@@ -855,7 +937,7 @@ export default {
|
|
|
855
937
|
* @arg {String} `name`
|
|
856
938
|
*/
|
|
857
939
|
toolbarEvent: function (type, name) {
|
|
858
|
-
if (this.isValidDrawnCreated) return
|
|
940
|
+
if (this.isValidDrawnCreated) return
|
|
859
941
|
this.manualAbortedOnClose()
|
|
860
942
|
this.doubleClickedFeature = false
|
|
861
943
|
// Deselect any feature when draw mode/tool is changed
|
|
@@ -866,7 +948,10 @@ export default {
|
|
|
866
948
|
// Remove any unsubmitted drawn
|
|
867
949
|
this.cancelDrawnFeature()
|
|
868
950
|
if (name) {
|
|
869
|
-
const tool = name.replace(
|
|
951
|
+
const tool = name.replace(
|
|
952
|
+
/[A-Z]/g,
|
|
953
|
+
(letter) => `_${letter.toLowerCase()}`
|
|
954
|
+
)
|
|
870
955
|
this.changeAnnotationDrawMode({ mode: `draw${tool}` })
|
|
871
956
|
}
|
|
872
957
|
this.activeDrawTool = name
|
|
@@ -884,7 +969,7 @@ export default {
|
|
|
884
969
|
if (data.feature.feature.geometry.type !== 'Point') {
|
|
885
970
|
this.changeAnnotationDrawMode({
|
|
886
971
|
mode: 'direct_select',
|
|
887
|
-
options: { featureId: data.feature.feature.id }
|
|
972
|
+
options: { featureId: data.feature.feature.id },
|
|
888
973
|
})
|
|
889
974
|
this.modifyAnnotationFeature()
|
|
890
975
|
}
|
|
@@ -893,7 +978,7 @@ export default {
|
|
|
893
978
|
} else if (this.activeDrawMode === 'Delete') {
|
|
894
979
|
this.changeAnnotationDrawMode({
|
|
895
980
|
mode: 'simple_select',
|
|
896
|
-
options: { featureIds: [data.feature.feature.id] }
|
|
981
|
+
options: { featureIds: [data.feature.feature.id] },
|
|
897
982
|
})
|
|
898
983
|
this.modifyAnnotationFeature()
|
|
899
984
|
}
|
|
@@ -908,7 +993,9 @@ export default {
|
|
|
908
993
|
type: 'connectivity',
|
|
909
994
|
source: features[0],
|
|
910
995
|
target: features[features.length - 1],
|
|
911
|
-
intermediates: features.filter(
|
|
996
|
+
intermediates: features.filter(
|
|
997
|
+
(f, index) => index !== 0 && index !== features.length - 1
|
|
998
|
+
),
|
|
912
999
|
}
|
|
913
1000
|
this.annotationEntry[0].body = body
|
|
914
1001
|
}
|
|
@@ -932,12 +1019,12 @@ export default {
|
|
|
932
1019
|
this.mapImp.clearAnnotationFeature()
|
|
933
1020
|
}
|
|
934
1021
|
},
|
|
935
|
-
forceContextLoss: function() {
|
|
1022
|
+
forceContextLoss: function () {
|
|
936
1023
|
if (this.mapImp && !this.mapImp.contextLost && !this.loading) {
|
|
937
1024
|
this.mapImp.forceContextLoss()
|
|
938
1025
|
}
|
|
939
1026
|
},
|
|
940
|
-
forceContextRestore: function() {
|
|
1027
|
+
forceContextRestore: function () {
|
|
941
1028
|
if (this.mapImp) {
|
|
942
1029
|
this.flatmapError = null
|
|
943
1030
|
this.mapImp.forceContextRestore()
|
|
@@ -979,22 +1066,35 @@ export default {
|
|
|
979
1066
|
commitAnnotationEvent: function (annotation) {
|
|
980
1067
|
if (this.mapImp) {
|
|
981
1068
|
if (this.offlineAnnotationEnabled) {
|
|
982
|
-
this.offlineAnnotations =
|
|
1069
|
+
this.offlineAnnotations =
|
|
1070
|
+
JSON.parse(sessionStorage.getItem('anonymous-annotation')) || []
|
|
983
1071
|
this.offlineAnnotations.push(annotation)
|
|
984
1072
|
if (this.annotationEntry[0].type === 'deleted') {
|
|
985
|
-
this.offlineAnnotations = this.offlineAnnotations.filter(
|
|
986
|
-
|
|
987
|
-
|
|
1073
|
+
this.offlineAnnotations = this.offlineAnnotations.filter(
|
|
1074
|
+
(offline) => {
|
|
1075
|
+
return (
|
|
1076
|
+
offline.resource !== this.serverURL ||
|
|
1077
|
+
offline.item.id !== annotation.item.id
|
|
1078
|
+
)
|
|
1079
|
+
}
|
|
1080
|
+
)
|
|
988
1081
|
}
|
|
989
|
-
sessionStorage.setItem(
|
|
1082
|
+
sessionStorage.setItem(
|
|
1083
|
+
'anonymous-annotation',
|
|
1084
|
+
JSON.stringify(this.offlineAnnotations)
|
|
1085
|
+
)
|
|
990
1086
|
}
|
|
991
|
-
if (
|
|
1087
|
+
if (
|
|
1088
|
+
['created', 'updated', 'deleted'].includes(
|
|
1089
|
+
this.annotationEntry[0].type
|
|
1090
|
+
)
|
|
1091
|
+
) {
|
|
992
1092
|
this.featureAnnotationSubmitted = true
|
|
993
1093
|
this.mapImp.commitAnnotationEvent(this.annotationEntry[0])
|
|
994
|
-
if (annotation.body.comment ===
|
|
1094
|
+
if (annotation.body.comment === 'Position Updated') {
|
|
995
1095
|
this.annotationEntry[0].positionUpdated = false
|
|
996
1096
|
} else if (this.annotationEntry[0].type === 'deleted') {
|
|
997
|
-
if (this.annotationSidebar) this.$emit(
|
|
1097
|
+
if (this.annotationSidebar) this.$emit('annotation-close')
|
|
998
1098
|
this.closeTooltip()
|
|
999
1099
|
// Only delete need, keep the annotation tooltip/sidebar open if created/updated
|
|
1000
1100
|
this.annotationEntry = []
|
|
@@ -1009,17 +1109,29 @@ export default {
|
|
|
1009
1109
|
* @arg {String} `userId`,
|
|
1010
1110
|
* @arg {String} `participated`
|
|
1011
1111
|
*/
|
|
1012
|
-
fetchAnnotatedItemIds: async function (
|
|
1112
|
+
fetchAnnotatedItemIds: async function (
|
|
1113
|
+
userId = undefined,
|
|
1114
|
+
participated = undefined
|
|
1115
|
+
) {
|
|
1013
1116
|
let annotatedItemIds
|
|
1014
1117
|
if (this.offlineAnnotationEnabled) {
|
|
1015
|
-
this.offlineAnnotations =
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1118
|
+
this.offlineAnnotations =
|
|
1119
|
+
JSON.parse(sessionStorage.getItem('anonymous-annotation')) || []
|
|
1120
|
+
annotatedItemIds = this.offlineAnnotations
|
|
1121
|
+
.filter((offline) => {
|
|
1122
|
+
return offline.resource === this.serverURL
|
|
1123
|
+
})
|
|
1124
|
+
.map((offline) => offline.item.id)
|
|
1019
1125
|
} else {
|
|
1020
|
-
annotatedItemIds = await this.annotator.annotatedItemIds(
|
|
1126
|
+
annotatedItemIds = await this.annotator.annotatedItemIds(
|
|
1127
|
+
this.userToken,
|
|
1128
|
+
this.serverURL,
|
|
1129
|
+
userId,
|
|
1130
|
+
participated
|
|
1131
|
+
)
|
|
1021
1132
|
// The annotator has `resource` and `items` fields
|
|
1022
|
-
if ('resource' in annotatedItemIds)
|
|
1133
|
+
if ('resource' in annotatedItemIds)
|
|
1134
|
+
annotatedItemIds = annotatedItemIds.itemIds
|
|
1023
1135
|
}
|
|
1024
1136
|
return annotatedItemIds
|
|
1025
1137
|
},
|
|
@@ -1044,13 +1156,23 @@ export default {
|
|
|
1044
1156
|
fetchDrawnFeatures: async function (userId, participated) {
|
|
1045
1157
|
let drawnFeatures
|
|
1046
1158
|
if (this.offlineAnnotationEnabled) {
|
|
1047
|
-
this.offlineAnnotations =
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1159
|
+
this.offlineAnnotations =
|
|
1160
|
+
JSON.parse(sessionStorage.getItem('anonymous-annotation')) || []
|
|
1161
|
+
drawnFeatures = this.offlineAnnotations
|
|
1162
|
+
.filter((offline) => {
|
|
1163
|
+
return offline.feature && offline.resource === this.serverURL
|
|
1164
|
+
})
|
|
1165
|
+
.map((offline) => offline.feature)
|
|
1051
1166
|
} else {
|
|
1052
|
-
const annotatedItemIds = await this.fetchAnnotatedItemIds(
|
|
1053
|
-
|
|
1167
|
+
const annotatedItemIds = await this.fetchAnnotatedItemIds(
|
|
1168
|
+
userId,
|
|
1169
|
+
participated
|
|
1170
|
+
)
|
|
1171
|
+
drawnFeatures = await this.annotator.drawnFeatures(
|
|
1172
|
+
this.userToken,
|
|
1173
|
+
this.serverURL,
|
|
1174
|
+
annotatedItemIds
|
|
1175
|
+
)
|
|
1054
1176
|
// The annotator has `resource` and `features` fields
|
|
1055
1177
|
if ('resource' in drawnFeatures) drawnFeatures = drawnFeatures.features
|
|
1056
1178
|
}
|
|
@@ -1066,13 +1188,22 @@ export default {
|
|
|
1066
1188
|
this.clearAnnotationFeature()
|
|
1067
1189
|
this.loading = true
|
|
1068
1190
|
}
|
|
1069
|
-
const userId =
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
const
|
|
1191
|
+
const userId =
|
|
1192
|
+
this.annotationFrom === 'Anyone'
|
|
1193
|
+
? undefined
|
|
1194
|
+
: this.authorisedUser.orcid
|
|
1195
|
+
? this.authorisedUser.orcid
|
|
1196
|
+
: '0000-0000-0000-0000'
|
|
1197
|
+
const participated =
|
|
1198
|
+
this.annotationFrom === 'Anyone'
|
|
1199
|
+
? undefined
|
|
1200
|
+
: this.annotationFrom === 'Me'
|
|
1201
|
+
? true
|
|
1202
|
+
: false
|
|
1203
|
+
const drawnFeatures = await this.fetchDrawnFeatures(
|
|
1204
|
+
userId,
|
|
1205
|
+
participated
|
|
1206
|
+
)
|
|
1076
1207
|
this.existDrawnFeatures = drawnFeatures
|
|
1077
1208
|
this.loading = false
|
|
1078
1209
|
if (!this.featureAnnotationSubmitted) {
|
|
@@ -1111,7 +1242,10 @@ export default {
|
|
|
1111
1242
|
* Function to emit offline annotation enabled status
|
|
1112
1243
|
*/
|
|
1113
1244
|
emitOfflineAnnotationUpdate: function () {
|
|
1114
|
-
this.$emit(
|
|
1245
|
+
this.$emit(
|
|
1246
|
+
'update-offline-annotation-enabled',
|
|
1247
|
+
this.offlineAnnotationEnabled
|
|
1248
|
+
)
|
|
1115
1249
|
},
|
|
1116
1250
|
/**
|
|
1117
1251
|
* @public
|
|
@@ -1193,15 +1327,20 @@ export default {
|
|
|
1193
1327
|
entityLabels.forEach((entityLabel) => {
|
|
1194
1328
|
let enabled = true
|
|
1195
1329
|
if (state) {
|
|
1196
|
-
enabled = state.checkAll
|
|
1330
|
+
enabled = state.checkAll
|
|
1331
|
+
? true
|
|
1332
|
+
: state.checked.includes(entityLabel.taxon)
|
|
1197
1333
|
}
|
|
1198
|
-
this.taxonConnectivity.push({...entityLabel, enabled})
|
|
1334
|
+
this.taxonConnectivity.push({ ...entityLabel, enabled })
|
|
1199
1335
|
if (this.mapImp) {
|
|
1200
|
-
this.mapImp.enableConnectivityByTaxonIds(
|
|
1336
|
+
this.mapImp.enableConnectivityByTaxonIds(
|
|
1337
|
+
entityLabel.taxon,
|
|
1338
|
+
enabled
|
|
1339
|
+
)
|
|
1201
1340
|
}
|
|
1202
|
-
})
|
|
1341
|
+
})
|
|
1203
1342
|
}
|
|
1204
|
-
})
|
|
1343
|
+
})
|
|
1205
1344
|
},
|
|
1206
1345
|
/**
|
|
1207
1346
|
* @public
|
|
@@ -1236,19 +1375,19 @@ export default {
|
|
|
1236
1375
|
},
|
|
1237
1376
|
setInitMapState: function () {
|
|
1238
1377
|
if (this.mapImp) {
|
|
1239
|
-
const map = this.mapImp.map
|
|
1240
|
-
const bounds = this.mapImp.options.bounds
|
|
1378
|
+
const map = this.mapImp.map
|
|
1379
|
+
const bounds = this.mapImp.options.bounds
|
|
1241
1380
|
const initBounds = [
|
|
1242
1381
|
[bounds[0], bounds[1]],
|
|
1243
|
-
[bounds[2], bounds[3]]
|
|
1244
|
-
]
|
|
1382
|
+
[bounds[2], bounds[3]],
|
|
1383
|
+
]
|
|
1245
1384
|
|
|
1246
|
-
map.setMaxBounds(null)
|
|
1247
|
-
map.setRenderWorldCopies(false)
|
|
1385
|
+
map.setMaxBounds(null) // override default
|
|
1386
|
+
map.setRenderWorldCopies(false)
|
|
1248
1387
|
|
|
1249
1388
|
this.initMapState = markRaw({
|
|
1250
1389
|
initBounds,
|
|
1251
|
-
})
|
|
1390
|
+
})
|
|
1252
1391
|
}
|
|
1253
1392
|
},
|
|
1254
1393
|
/**
|
|
@@ -1259,17 +1398,17 @@ export default {
|
|
|
1259
1398
|
resetView: function () {
|
|
1260
1399
|
if (this.mapImp) {
|
|
1261
1400
|
// fit to window
|
|
1262
|
-
const map = this.mapImp.map
|
|
1263
|
-
const { initBounds } = this.initMapState
|
|
1401
|
+
const map = this.mapImp.map
|
|
1402
|
+
const { initBounds } = this.initMapState
|
|
1264
1403
|
// reset rotation
|
|
1265
1404
|
map.resetNorthPitch({
|
|
1266
1405
|
animate: false,
|
|
1267
|
-
})
|
|
1406
|
+
})
|
|
1268
1407
|
if (initBounds) {
|
|
1269
1408
|
// reset zoom and position
|
|
1270
1409
|
map.fitBounds(initBounds, {
|
|
1271
|
-
animate: false
|
|
1272
|
-
})
|
|
1410
|
+
animate: false,
|
|
1411
|
+
})
|
|
1273
1412
|
}
|
|
1274
1413
|
if (this.$refs.skcanSelection) {
|
|
1275
1414
|
this.$refs.skcanSelection.reset()
|
|
@@ -1306,7 +1445,7 @@ export default {
|
|
|
1306
1445
|
}
|
|
1307
1446
|
},
|
|
1308
1447
|
onSelectionsDataChanged: function (data) {
|
|
1309
|
-
this.$emit('pathway-selection-changed', data)
|
|
1448
|
+
this.$emit('pathway-selection-changed', data)
|
|
1310
1449
|
},
|
|
1311
1450
|
/**
|
|
1312
1451
|
* // Currently not in use
|
|
@@ -1349,76 +1488,94 @@ export default {
|
|
|
1349
1488
|
retrieveConnectedPaths: async function (payload, options = {}) {
|
|
1350
1489
|
// query all connected paths from flatmap
|
|
1351
1490
|
if (this.mapImp) {
|
|
1352
|
-
let connectedPaths = []
|
|
1353
|
-
let connectedTarget = options.target?.length ? options.target : []
|
|
1491
|
+
let connectedPaths = []
|
|
1492
|
+
let connectedTarget = options.target?.length ? options.target : []
|
|
1354
1493
|
// The line below is to get the path features from the geojson ids
|
|
1355
|
-
const nodeFeatureIds = [...this.mapImp.pathModelNodes(payload)]
|
|
1356
|
-
const pathsOfEntities = await this.mapImp.queryPathsForFeatures(payload)
|
|
1494
|
+
const nodeFeatureIds = [...this.mapImp.pathModelNodes(payload)]
|
|
1495
|
+
const pathsOfEntities = await this.mapImp.queryPathsForFeatures(payload)
|
|
1357
1496
|
if (nodeFeatureIds.length) {
|
|
1358
1497
|
if (!connectedTarget.length) {
|
|
1359
|
-
const connectedType = options.type?.length ? options.type : [
|
|
1360
|
-
const connectivity =
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1498
|
+
const connectedType = options.type?.length ? options.type : ['all']
|
|
1499
|
+
const connectivity =
|
|
1500
|
+
await this.flatmapQueries.queryForConnectivityNew(
|
|
1501
|
+
this.mapImp,
|
|
1502
|
+
payload[0]
|
|
1503
|
+
)
|
|
1504
|
+
const originsFlat = connectivity?.ids?.dendrites.flat(Infinity)
|
|
1505
|
+
const componentsFlat = connectivity?.ids?.components.flat(Infinity)
|
|
1506
|
+
const destinationsFlat = connectivity?.ids?.axons.flat(Infinity)
|
|
1507
|
+
let connected = []
|
|
1508
|
+
if (connectedType.includes('origins'))
|
|
1509
|
+
connected.push(...originsFlat)
|
|
1510
|
+
if (connectedType.includes('components'))
|
|
1511
|
+
connected.push(...componentsFlat)
|
|
1512
|
+
if (connectedType.includes('destinations'))
|
|
1513
|
+
connected.push(...destinationsFlat)
|
|
1514
|
+
if (connectedType.includes('all'))
|
|
1515
|
+
connected.push(
|
|
1516
|
+
...originsFlat,
|
|
1517
|
+
...componentsFlat,
|
|
1518
|
+
...destinationsFlat
|
|
1519
|
+
)
|
|
1520
|
+
connectedTarget = [...new Set(connected)]
|
|
1370
1521
|
}
|
|
1371
1522
|
// Loop through the node features and check if we have certain nodes
|
|
1372
1523
|
nodeFeatureIds.forEach((featureId) => {
|
|
1373
1524
|
// Get the paths from each node feature
|
|
1374
|
-
const pathsL2 = this.mapImp.nodePathModels(featureId)
|
|
1525
|
+
const pathsL2 = this.mapImp.nodePathModels(featureId)
|
|
1375
1526
|
pathsL2.forEach((path) => {
|
|
1376
1527
|
// nodes of the second level path
|
|
1377
|
-
const nodeFeatureIdsL2 = this.mapImp.pathModelNodes(path)
|
|
1528
|
+
const nodeFeatureIdsL2 = this.mapImp.pathModelNodes(path)
|
|
1378
1529
|
const nodeModelsL2 = nodeFeatureIdsL2.map((featureIdL2) => {
|
|
1379
|
-
return this.mapImp.featureProperties(featureIdL2).models
|
|
1380
|
-
})
|
|
1381
|
-
const intersection = connectedTarget.filter(element =>
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1530
|
+
return this.mapImp.featureProperties(featureIdL2).models
|
|
1531
|
+
})
|
|
1532
|
+
const intersection = connectedTarget.filter((element) =>
|
|
1533
|
+
nodeModelsL2.includes(element)
|
|
1534
|
+
)
|
|
1535
|
+
if (intersection.length && !connectedPaths.includes(path))
|
|
1536
|
+
connectedPaths.push(path)
|
|
1537
|
+
})
|
|
1538
|
+
})
|
|
1385
1539
|
} else if (pathsOfEntities.length) {
|
|
1386
1540
|
if (connectedTarget.length) {
|
|
1387
1541
|
pathsOfEntities.forEach((path) => {
|
|
1388
|
-
const nodeFeatureIds = this.mapImp.pathModelNodes(path)
|
|
1542
|
+
const nodeFeatureIds = this.mapImp.pathModelNodes(path)
|
|
1389
1543
|
const nodeModels = nodeFeatureIds.map((featureId) => {
|
|
1390
|
-
return this.mapImp.featureProperties(featureId).models
|
|
1391
|
-
})
|
|
1392
|
-
const intersection = connectedTarget.filter(element =>
|
|
1393
|
-
|
|
1394
|
-
|
|
1544
|
+
return this.mapImp.featureProperties(featureId).models
|
|
1545
|
+
})
|
|
1546
|
+
const intersection = connectedTarget.filter((element) =>
|
|
1547
|
+
nodeModels.includes(element)
|
|
1548
|
+
)
|
|
1549
|
+
if (intersection.length && !connectedPaths.includes(path))
|
|
1550
|
+
connectedPaths.push(path)
|
|
1551
|
+
})
|
|
1395
1552
|
} else {
|
|
1396
|
-
connectedPaths = pathsOfEntities
|
|
1553
|
+
connectedPaths = pathsOfEntities
|
|
1397
1554
|
}
|
|
1398
1555
|
}
|
|
1399
|
-
connectedPaths = [...new Set([...connectedPaths, ...payload])]
|
|
1400
|
-
return connectedPaths
|
|
1556
|
+
connectedPaths = [...new Set([...connectedPaths, ...payload])]
|
|
1557
|
+
return connectedPaths
|
|
1401
1558
|
}
|
|
1402
1559
|
},
|
|
1403
|
-
resetMapFilter: function() {
|
|
1404
|
-
const alert = this.mapFilters.alert
|
|
1405
|
-
let filter
|
|
1406
|
-
const isPathways = { 'tile-layer': 'pathways' }
|
|
1407
|
-
const notPathways = { NOT: isPathways }
|
|
1560
|
+
resetMapFilter: function () {
|
|
1561
|
+
const alert = this.mapFilters.alert
|
|
1562
|
+
let filter
|
|
1563
|
+
const isPathways = { 'tile-layer': 'pathways' }
|
|
1564
|
+
const notPathways = { NOT: isPathways }
|
|
1408
1565
|
|
|
1409
1566
|
if (alert.with && !alert.without) {
|
|
1410
1567
|
// Show pathways with alert
|
|
1411
1568
|
filter = {
|
|
1412
|
-
OR: [notPathways, { AND: [isPathways, { HAS: 'alert' }] }]
|
|
1413
|
-
}
|
|
1569
|
+
OR: [notPathways, { AND: [isPathways, { HAS: 'alert' }] }],
|
|
1570
|
+
}
|
|
1414
1571
|
} else if (!alert.with && alert.without) {
|
|
1415
1572
|
// Show pathways without alert
|
|
1416
1573
|
filter = {
|
|
1417
|
-
OR: [notPathways, { AND: [isPathways, { NOT: { HAS: 'alert' } }] }]
|
|
1418
|
-
}
|
|
1574
|
+
OR: [notPathways, { AND: [isPathways, { NOT: { HAS: 'alert' } }] }],
|
|
1575
|
+
}
|
|
1419
1576
|
} else if (!alert.with && !alert.without) {
|
|
1420
1577
|
// Hide all pathways
|
|
1421
|
-
filter = notPathways
|
|
1578
|
+
filter = notPathways
|
|
1422
1579
|
}
|
|
1423
1580
|
this.setVisibilityFilter(filter)
|
|
1424
1581
|
},
|
|
@@ -1431,16 +1588,17 @@ export default {
|
|
|
1431
1588
|
alertMouseEnterEmitted: function (payload) {
|
|
1432
1589
|
if (this.mapImp) {
|
|
1433
1590
|
if (payload.value) {
|
|
1434
|
-
let filter
|
|
1435
|
-
const isPathways = { 'tile-layer': 'pathways' }
|
|
1436
|
-
const notPathways = { NOT: isPathways }
|
|
1591
|
+
let filter
|
|
1592
|
+
const isPathways = { 'tile-layer': 'pathways' }
|
|
1593
|
+
const notPathways = { NOT: isPathways }
|
|
1437
1594
|
|
|
1438
|
-
if (payload.key ===
|
|
1439
|
-
const hasAlert =
|
|
1440
|
-
|
|
1441
|
-
|
|
1595
|
+
if (payload.key === 'alert' || payload.key === 'withoutAlert') {
|
|
1596
|
+
const hasAlert =
|
|
1597
|
+
payload.key === 'alert'
|
|
1598
|
+
? { HAS: 'alert' }
|
|
1599
|
+
: { NOT: { HAS: 'alert' } }
|
|
1442
1600
|
|
|
1443
|
-
filter = { OR: [notPathways, { AND: [isPathways, hasAlert] }] }
|
|
1601
|
+
filter = { OR: [notPathways, { AND: [isPathways, hasAlert] }] }
|
|
1444
1602
|
}
|
|
1445
1603
|
this.setVisibilityFilter(filter)
|
|
1446
1604
|
} else {
|
|
@@ -1456,13 +1614,13 @@ export default {
|
|
|
1456
1614
|
*/
|
|
1457
1615
|
alertSelected: function (payload) {
|
|
1458
1616
|
if (this.mapImp) {
|
|
1459
|
-
if (payload.key ===
|
|
1617
|
+
if (payload.key === 'alert') {
|
|
1460
1618
|
if (payload.value) {
|
|
1461
1619
|
this.mapFilters.alert.with = true
|
|
1462
1620
|
} else {
|
|
1463
1621
|
this.mapFilters.alert.with = false
|
|
1464
1622
|
}
|
|
1465
|
-
} else if (payload.key ===
|
|
1623
|
+
} else if (payload.key === 'withoutAlert') {
|
|
1466
1624
|
if (payload.value) {
|
|
1467
1625
|
this.mapFilters.alert.without = true
|
|
1468
1626
|
} else {
|
|
@@ -1563,7 +1721,7 @@ export default {
|
|
|
1563
1721
|
clearTimeout(this.taxonLeaveDelay)
|
|
1564
1722
|
let gid = this.mapImp.taxonFeatureIds(payload.key)
|
|
1565
1723
|
this.mapImp.enableConnectivityByTaxonIds(payload.key, payload.value) // make sure path is visible
|
|
1566
|
-
this.mapImp.zoomToGeoJSONFeatures(gid, {noZoomIn: true})
|
|
1724
|
+
this.mapImp.zoomToGeoJSONFeatures(gid, { noZoomIn: true })
|
|
1567
1725
|
} else {
|
|
1568
1726
|
this.taxonLeaveDelay = setTimeout(() => {
|
|
1569
1727
|
// reset visibility of paths
|
|
@@ -1572,7 +1730,7 @@ export default {
|
|
|
1572
1730
|
let show = payload.checked.includes(item.taxon)
|
|
1573
1731
|
this.mapImp.enableConnectivityByTaxonIds(item.taxon, show)
|
|
1574
1732
|
})
|
|
1575
|
-
}, 1000)
|
|
1733
|
+
}, 1000)
|
|
1576
1734
|
}
|
|
1577
1735
|
}
|
|
1578
1736
|
},
|
|
@@ -1634,15 +1792,23 @@ export default {
|
|
|
1634
1792
|
else this.featureAnnotationSubmitted = false
|
|
1635
1793
|
this.annotationEntry = []
|
|
1636
1794
|
} else if (data.type === 'modeChanged') {
|
|
1637
|
-
if (data.feature.mode === 'direct_select')
|
|
1638
|
-
|
|
1795
|
+
if (data.feature.mode === 'direct_select')
|
|
1796
|
+
this.doubleClickedFeature = true
|
|
1797
|
+
if (
|
|
1798
|
+
this.annotationSidebar &&
|
|
1799
|
+
data.feature.mode === 'simple_select' &&
|
|
1800
|
+
this.activeDrawMode === 'Deleted'
|
|
1801
|
+
) {
|
|
1639
1802
|
this.annotationEventCallback({}, { type: 'aborted' })
|
|
1640
1803
|
}
|
|
1641
1804
|
} else if (data.type === 'selectionChanged') {
|
|
1642
|
-
this.selectedDrawnFeature =
|
|
1643
|
-
|
|
1805
|
+
this.selectedDrawnFeature =
|
|
1806
|
+
data.feature.features.length === 0
|
|
1807
|
+
? undefined
|
|
1808
|
+
: data.feature.features[0]
|
|
1644
1809
|
payload.feature.feature = this.selectedDrawnFeature
|
|
1645
|
-
if (!this.activeDrawTool) {
|
|
1810
|
+
if (!this.activeDrawTool) {
|
|
1811
|
+
// Make sure dialog content doesn't change
|
|
1646
1812
|
this.connectionEntry = {}
|
|
1647
1813
|
// For exist drawn annotation features
|
|
1648
1814
|
if (this.selectedDrawnFeature) {
|
|
@@ -1656,11 +1822,16 @@ export default {
|
|
|
1656
1822
|
}
|
|
1657
1823
|
this.annotationDrawModeEvent(payload)
|
|
1658
1824
|
} else {
|
|
1659
|
-
if (
|
|
1660
|
-
this.
|
|
1661
|
-
|
|
1662
|
-
|
|
1663
|
-
|
|
1825
|
+
if (
|
|
1826
|
+
this.annotationSidebar &&
|
|
1827
|
+
this.previousEditEvent.type === 'updated'
|
|
1828
|
+
) {
|
|
1829
|
+
this.annotationEntry = [
|
|
1830
|
+
{
|
|
1831
|
+
...this.previousEditEvent,
|
|
1832
|
+
resourceId: this.serverURL,
|
|
1833
|
+
},
|
|
1834
|
+
]
|
|
1664
1835
|
this.annotationEventCallback({}, { type: 'aborted' })
|
|
1665
1836
|
}
|
|
1666
1837
|
this.previousEditEvent = {}
|
|
@@ -1671,7 +1842,9 @@ export default {
|
|
|
1671
1842
|
if (data.type === 'updated' && data.feature.action) {
|
|
1672
1843
|
data.positionUpdated = data.feature.action === 'move'
|
|
1673
1844
|
}
|
|
1674
|
-
const feature = this.mapImp.refreshAnnotationFeatureGeometry(
|
|
1845
|
+
const feature = this.mapImp.refreshAnnotationFeatureGeometry(
|
|
1846
|
+
data.feature
|
|
1847
|
+
)
|
|
1675
1848
|
payload.feature.feature = feature
|
|
1676
1849
|
// NB. this might now be `null` if user has deleted it (before OK/Submit)
|
|
1677
1850
|
// so maybe then no `service.addAnnotation` ??
|
|
@@ -1725,36 +1898,39 @@ export default {
|
|
|
1725
1898
|
const biologicalSex = this.biologicalSex
|
|
1726
1899
|
const featuresAlert = data.alert
|
|
1727
1900
|
const taxons = this.getTaxons(data)
|
|
1728
|
-
let payload = [
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
|
|
1732
|
-
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
|
|
1739
|
-
|
|
1901
|
+
let payload = [
|
|
1902
|
+
{
|
|
1903
|
+
dataset: data.dataset,
|
|
1904
|
+
biologicalSex: biologicalSex,
|
|
1905
|
+
taxonomy: taxonomy,
|
|
1906
|
+
resource: resource,
|
|
1907
|
+
label: label,
|
|
1908
|
+
feature: data,
|
|
1909
|
+
protocol: this.selectedSimulation,
|
|
1910
|
+
userData: args,
|
|
1911
|
+
eventType: eventType,
|
|
1912
|
+
provenanceTaxonomy: taxons,
|
|
1913
|
+
alert: featuresAlert,
|
|
1914
|
+
},
|
|
1915
|
+
]
|
|
1740
1916
|
if (eventType === 'click') {
|
|
1741
1917
|
// If multiple paths overlap at the click location,
|
|
1742
1918
|
// `data` is an object with numeric keys for each feature (e.g., {0: {...}, 1: {...}, ..., mapUUID: '...'}).
|
|
1743
1919
|
// If only one feature or path is clicked,
|
|
1744
1920
|
// `data` is a single object (e.g., {featureId: '...', mapUUID: '...'}).
|
|
1745
|
-
const singleSelection = !data[0]
|
|
1921
|
+
const singleSelection = !data[0]
|
|
1746
1922
|
if (!singleSelection) {
|
|
1747
1923
|
payload = []
|
|
1748
1924
|
const mapuuid = data.mapUUID
|
|
1749
|
-
const seenIds = new Set()
|
|
1925
|
+
const seenIds = new Set()
|
|
1750
1926
|
for (let [key, value] of Object.entries(data)) {
|
|
1751
1927
|
if (key !== 'mapUUID') {
|
|
1752
1928
|
const id = value.featureId
|
|
1753
1929
|
const label = value.label
|
|
1754
1930
|
const resource = [value.models]
|
|
1755
1931
|
const taxons = this.getTaxons(value)
|
|
1756
|
-
if (seenIds.has(id)) continue
|
|
1757
|
-
seenIds.add(id)
|
|
1932
|
+
if (seenIds.has(id)) continue
|
|
1933
|
+
seenIds.add(id)
|
|
1758
1934
|
payload.push({
|
|
1759
1935
|
dataset: value.dataset,
|
|
1760
1936
|
biologicalSex: biologicalSex,
|
|
@@ -1766,13 +1942,13 @@ export default {
|
|
|
1766
1942
|
eventType: eventType,
|
|
1767
1943
|
provenanceTaxonomy: taxons,
|
|
1768
1944
|
alert: value.alert,
|
|
1769
|
-
mapUUID: mapuuid
|
|
1945
|
+
mapUUID: mapuuid,
|
|
1770
1946
|
})
|
|
1771
1947
|
}
|
|
1772
1948
|
}
|
|
1773
1949
|
}
|
|
1774
1950
|
const clickedItem = singleSelection ? data : data[0]
|
|
1775
|
-
this.setConnectivityDataSource(this.viewingMode, clickedItem)
|
|
1951
|
+
this.setConnectivityDataSource(this.viewingMode, clickedItem)
|
|
1776
1952
|
if (this.viewingMode === 'Neuron Connection') {
|
|
1777
1953
|
// do nothing here
|
|
1778
1954
|
// the method to highlight paths is moved to checkAndCreatePopups function
|
|
@@ -1781,20 +1957,33 @@ export default {
|
|
|
1781
1957
|
// This is for annotation mode - draw connectivity between features/paths
|
|
1782
1958
|
if (this.activeDrawTool && !this.isValidDrawnCreated) {
|
|
1783
1959
|
// Check if flatmap features or existing drawn features
|
|
1784
|
-
const validDrawnFeature =
|
|
1785
|
-
|
|
1786
|
-
|
|
1960
|
+
const validDrawnFeature =
|
|
1961
|
+
clickedItem.featureId ||
|
|
1962
|
+
this.existDrawnFeatures.find(
|
|
1963
|
+
(feature) => feature.id === clickedItem.id
|
|
1964
|
+
)
|
|
1787
1965
|
// Only the linestring will have connection
|
|
1788
1966
|
if (this.activeDrawTool === 'LineString' && validDrawnFeature) {
|
|
1789
|
-
const key = clickedItem.featureId
|
|
1790
|
-
|
|
1967
|
+
const key = clickedItem.featureId
|
|
1968
|
+
? clickedItem.featureId
|
|
1969
|
+
: clickedItem.id
|
|
1970
|
+
const nodeLabel = clickedItem.label
|
|
1971
|
+
? clickedItem.label
|
|
1972
|
+
: `Feature ${clickedItem.id}`
|
|
1791
1973
|
// Add space before key to make sure properties follows adding order
|
|
1792
1974
|
this.connectionEntry[` ${key}`] = Object.assign(
|
|
1793
1975
|
{ label: nodeLabel },
|
|
1794
1976
|
Object.fromEntries(
|
|
1795
1977
|
Object.entries(clickedItem)
|
|
1796
|
-
.filter(([key]) =>
|
|
1797
|
-
|
|
1978
|
+
.filter(([key]) =>
|
|
1979
|
+
['featureId', 'models'].includes(key)
|
|
1980
|
+
)
|
|
1981
|
+
.map(([key, value]) => [
|
|
1982
|
+
key === 'featureId' ? 'id' : key,
|
|
1983
|
+
value,
|
|
1984
|
+
])
|
|
1985
|
+
)
|
|
1986
|
+
)
|
|
1798
1987
|
}
|
|
1799
1988
|
}
|
|
1800
1989
|
}
|
|
@@ -1803,7 +1992,10 @@ export default {
|
|
|
1803
1992
|
if (data && data.type !== 'marker' && !this.activeDrawTool) {
|
|
1804
1993
|
this.checkAndCreatePopups(payload)
|
|
1805
1994
|
}
|
|
1806
|
-
} else if (
|
|
1995
|
+
} else if (
|
|
1996
|
+
eventType === 'mouseenter' &&
|
|
1997
|
+
this.viewingMode !== 'Neuron Connection'
|
|
1998
|
+
) {
|
|
1807
1999
|
this.currentHover = data.models ? data.models : ''
|
|
1808
2000
|
}
|
|
1809
2001
|
|
|
@@ -1823,11 +2015,13 @@ export default {
|
|
|
1823
2015
|
setConnectivityDataSource: function (viewingMode, data) {
|
|
1824
2016
|
// Exploration mode, only path click will be used as data source
|
|
1825
2017
|
if (viewingMode === 'Exploration') {
|
|
1826
|
-
this.connectivityDataSource = data.models?.startsWith('ilxtr:')
|
|
2018
|
+
this.connectivityDataSource = data.models?.startsWith('ilxtr:')
|
|
2019
|
+
? data.models
|
|
2020
|
+
: ''
|
|
1827
2021
|
} else {
|
|
1828
2022
|
// Other modes, it can be anything
|
|
1829
2023
|
// (annotation drawing doesn't have featureId or models)
|
|
1830
|
-
this.connectivityDataSource = data.featureId || data.id
|
|
2024
|
+
this.connectivityDataSource = data.featureId || data.id
|
|
1831
2025
|
}
|
|
1832
2026
|
},
|
|
1833
2027
|
/**
|
|
@@ -1850,12 +2044,12 @@ export default {
|
|
|
1850
2044
|
removeActiveTooltips: function () {
|
|
1851
2045
|
// Remove active tooltip/popup on map
|
|
1852
2046
|
if (this.mapImp) {
|
|
1853
|
-
this.mapImp.removePopup()
|
|
2047
|
+
this.mapImp.removePopup()
|
|
1854
2048
|
}
|
|
1855
2049
|
|
|
1856
2050
|
// Fallback: remove any existing toolitp on DOM
|
|
1857
|
-
const tooltips = this.$el.querySelectorAll('.flatmap-tooltip-popup')
|
|
1858
|
-
tooltips.forEach((tooltip) => tooltip.remove())
|
|
2051
|
+
const tooltips = this.$el.querySelectorAll('.flatmap-tooltip-popup')
|
|
2052
|
+
tooltips.forEach((tooltip) => tooltip.remove())
|
|
1859
2053
|
},
|
|
1860
2054
|
/**
|
|
1861
2055
|
* Function to create tooltip for the provided connectivity data.
|
|
@@ -1864,28 +2058,24 @@ export default {
|
|
|
1864
2058
|
createTooltipForConnectivity: function (connectivityData, geojsonId) {
|
|
1865
2059
|
// combine all labels to show together
|
|
1866
2060
|
// content type must be DOM object to use HTML
|
|
1867
|
-
const labelsContainer = document.createElement('div')
|
|
1868
|
-
labelsContainer.classList.add('flatmap-feature-label')
|
|
2061
|
+
const labelsContainer = document.createElement('div')
|
|
2062
|
+
labelsContainer.classList.add('flatmap-feature-label')
|
|
1869
2063
|
|
|
1870
2064
|
connectivityData.forEach((connectivity, i) => {
|
|
1871
|
-
const { label } = connectivity
|
|
1872
|
-
labelsContainer.append(capitalise(label))
|
|
2065
|
+
const { label } = connectivity
|
|
2066
|
+
labelsContainer.append(capitalise(label))
|
|
1873
2067
|
|
|
1874
|
-
if (
|
|
1875
|
-
const hr = document.createElement('hr')
|
|
1876
|
-
labelsContainer.appendChild(hr)
|
|
2068
|
+
if (i + 1 < connectivityData.length) {
|
|
2069
|
+
const hr = document.createElement('hr')
|
|
2070
|
+
labelsContainer.appendChild(hr)
|
|
1877
2071
|
}
|
|
1878
|
-
})
|
|
2072
|
+
})
|
|
1879
2073
|
|
|
1880
|
-
this.mapImp.showPopup(
|
|
1881
|
-
|
|
1882
|
-
|
|
1883
|
-
|
|
1884
|
-
|
|
1885
|
-
positionAtLastClick: false,
|
|
1886
|
-
preserveSelection: true,
|
|
1887
|
-
}
|
|
1888
|
-
);
|
|
2074
|
+
this.mapImp.showPopup(geojsonId, labelsContainer, {
|
|
2075
|
+
className: 'custom-popup flatmap-tooltip-popup',
|
|
2076
|
+
positionAtLastClick: false,
|
|
2077
|
+
preserveSelection: true,
|
|
2078
|
+
})
|
|
1889
2079
|
},
|
|
1890
2080
|
/**
|
|
1891
2081
|
* Function to show connectivity tooltips on the map
|
|
@@ -1893,53 +2083,53 @@ export default {
|
|
|
1893
2083
|
* @arg {Object} `payload`
|
|
1894
2084
|
*/
|
|
1895
2085
|
showConnectivityTooltips: function (payload) {
|
|
1896
|
-
const { connectivityInfo, data } = payload
|
|
1897
|
-
const featuresToHighlight = []
|
|
1898
|
-
const geojsonHighlights = []
|
|
1899
|
-
const connectivityData = []
|
|
1900
|
-
const errorData = []
|
|
2086
|
+
const { connectivityInfo, data } = payload
|
|
2087
|
+
const featuresToHighlight = []
|
|
2088
|
+
const geojsonHighlights = []
|
|
2089
|
+
const connectivityData = []
|
|
2090
|
+
const errorData = []
|
|
1901
2091
|
|
|
1902
2092
|
// to keep the highlighted path on map
|
|
1903
2093
|
if (connectivityInfo && connectivityInfo.featureId) {
|
|
1904
|
-
featuresToHighlight.push(...connectivityInfo.featureId)
|
|
2094
|
+
featuresToHighlight.push(...connectivityInfo.featureId)
|
|
1905
2095
|
}
|
|
1906
2096
|
|
|
1907
2097
|
if (this.mapImp) {
|
|
1908
2098
|
// search the features on the map first
|
|
1909
2099
|
data.forEach((connectivity) => {
|
|
1910
|
-
const response = this.mapImp.search(connectivity.id)
|
|
2100
|
+
const response = this.mapImp.search(connectivity.id)
|
|
1911
2101
|
|
|
1912
2102
|
if (response?.results.length) {
|
|
1913
|
-
const featureId = response?.results[0].featureId
|
|
1914
|
-
connectivityData.push({ featureId, ...connectivity })
|
|
2103
|
+
const featureId = response?.results[0].featureId
|
|
2104
|
+
connectivityData.push({ featureId, ...connectivity })
|
|
1915
2105
|
} else {
|
|
1916
|
-
errorData.push(connectivity)
|
|
2106
|
+
errorData.push(connectivity)
|
|
1917
2107
|
}
|
|
1918
|
-
})
|
|
2108
|
+
})
|
|
1919
2109
|
|
|
1920
2110
|
if (connectivityData.length) {
|
|
1921
|
-
let geojsonId = connectivityData[0].featureId
|
|
2111
|
+
let geojsonId = connectivityData[0].featureId
|
|
1922
2112
|
|
|
1923
2113
|
this.mapImp.annotations.forEach((annotation) => {
|
|
1924
|
-
const anatomicalNodes = annotation['anatomical-nodes']
|
|
2114
|
+
const anatomicalNodes = annotation['anatomical-nodes']
|
|
1925
2115
|
|
|
1926
2116
|
if (anatomicalNodes) {
|
|
1927
|
-
const anatomicalNodesString = anatomicalNodes.join('')
|
|
1928
|
-
const foundItem = connectivityData.every(
|
|
1929
|
-
anatomicalNodesString.indexOf(item.id) !== -1
|
|
1930
|
-
)
|
|
2117
|
+
const anatomicalNodesString = anatomicalNodes.join('')
|
|
2118
|
+
const foundItem = connectivityData.every(
|
|
2119
|
+
(item) => anatomicalNodesString.indexOf(item.id) !== -1
|
|
2120
|
+
)
|
|
1931
2121
|
|
|
1932
2122
|
if (foundItem) {
|
|
1933
|
-
geojsonId = annotation.featureId
|
|
1934
|
-
geojsonHighlights.push(geojsonId)
|
|
2123
|
+
geojsonId = annotation.featureId
|
|
2124
|
+
geojsonHighlights.push(geojsonId)
|
|
1935
2125
|
}
|
|
1936
2126
|
}
|
|
1937
|
-
})
|
|
2127
|
+
})
|
|
1938
2128
|
|
|
1939
|
-
this.createTooltipForConnectivity(connectivityData, geojsonId)
|
|
2129
|
+
this.createTooltipForConnectivity(connectivityData, geojsonId)
|
|
1940
2130
|
} else {
|
|
1941
2131
|
// Close all tooltips on the current flatmap element
|
|
1942
|
-
this.removeActiveTooltips()
|
|
2132
|
+
this.removeActiveTooltips()
|
|
1943
2133
|
}
|
|
1944
2134
|
|
|
1945
2135
|
// Emit error message for connectivity
|
|
@@ -1949,75 +2139,86 @@ export default {
|
|
|
1949
2139
|
|
|
1950
2140
|
// highlight all available features
|
|
1951
2141
|
const connectivityFeatures = featuresToHighlight.reduce((arr, path) => {
|
|
1952
|
-
const connectivityObj = this.mapImp.pathways.paths[path]
|
|
1953
|
-
const connectivities = connectivityObj
|
|
2142
|
+
const connectivityObj = this.mapImp.pathways.paths[path]
|
|
2143
|
+
const connectivities = connectivityObj
|
|
2144
|
+
? connectivityObj.connectivity
|
|
2145
|
+
: null
|
|
1954
2146
|
if (connectivities) {
|
|
1955
|
-
const flatFeatures = connectivities.flat(Infinity)
|
|
1956
|
-
arr.push(...flatFeatures)
|
|
2147
|
+
const flatFeatures = connectivities.flat(Infinity)
|
|
2148
|
+
arr.push(...flatFeatures)
|
|
1957
2149
|
}
|
|
1958
|
-
return arr
|
|
1959
|
-
}, [])
|
|
1960
|
-
const uniqueConnectivityFeatures = [...new Set(connectivityFeatures)]
|
|
1961
|
-
const combinedFeatures = [
|
|
1962
|
-
|
|
2150
|
+
return arr
|
|
2151
|
+
}, [])
|
|
2152
|
+
const uniqueConnectivityFeatures = [...new Set(connectivityFeatures)]
|
|
2153
|
+
const combinedFeatures = [
|
|
2154
|
+
...featuresToHighlight,
|
|
2155
|
+
...uniqueConnectivityFeatures,
|
|
2156
|
+
]
|
|
2157
|
+
const featureIdsToHighlight =
|
|
2158
|
+
this.mapImp.modelFeatureIdList(combinedFeatures)
|
|
1963
2159
|
const allFeaturesToHighlight = [
|
|
1964
2160
|
...featureIdsToHighlight,
|
|
1965
|
-
...geojsonHighlights
|
|
1966
|
-
]
|
|
2161
|
+
...geojsonHighlights,
|
|
2162
|
+
]
|
|
1967
2163
|
|
|
1968
|
-
this.mapImp.selectGeoJSONFeatures(allFeaturesToHighlight)
|
|
2164
|
+
this.mapImp.selectGeoJSONFeatures(allFeaturesToHighlight)
|
|
1969
2165
|
}
|
|
1970
2166
|
},
|
|
1971
2167
|
showConnectivitiesByReference: function (resource) {
|
|
1972
2168
|
this.searchConnectivitiesByReference(resource).then((featureIds) => {
|
|
1973
|
-
this.mapImp.selectFeatures(featureIds)
|
|
1974
|
-
})
|
|
2169
|
+
this.mapImp.selectFeatures(featureIds)
|
|
2170
|
+
})
|
|
1975
2171
|
},
|
|
1976
2172
|
searchConnectivitiesByReference: async function (resource) {
|
|
1977
|
-
const flatmapKnowledge = sessionStorage.getItem('flatmap-knowledge')
|
|
1978
|
-
let featureIds = []
|
|
2173
|
+
const flatmapKnowledge = sessionStorage.getItem('flatmap-knowledge')
|
|
2174
|
+
let featureIds = []
|
|
1979
2175
|
|
|
1980
2176
|
if (flatmapKnowledge) {
|
|
1981
|
-
featureIds = await getReferenceConnectivitiesFromStorage(resource)
|
|
2177
|
+
featureIds = await getReferenceConnectivitiesFromStorage(resource)
|
|
1982
2178
|
} else {
|
|
1983
|
-
featureIds = await getReferenceConnectivitiesByAPI(
|
|
1984
|
-
|
|
1985
|
-
|
|
1986
|
-
|
|
1987
|
-
|
|
1988
|
-
let flatmapKnowledge = [];
|
|
1989
|
-
const flatmapKnowledgeRaw = sessionStorage.getItem('flatmap-knowledge');
|
|
1990
|
-
if (flatmapKnowledgeRaw) {
|
|
1991
|
-
flatmapKnowledge = JSON.parse(flatmapKnowledgeRaw);
|
|
2179
|
+
featureIds = await getReferenceConnectivitiesByAPI(
|
|
2180
|
+
this.mapImp,
|
|
2181
|
+
resource,
|
|
2182
|
+
this.flatmapQueries
|
|
2183
|
+
)
|
|
1992
2184
|
}
|
|
1993
|
-
return
|
|
2185
|
+
return featureIds
|
|
1994
2186
|
},
|
|
1995
2187
|
emitConnectivityError: function (errorData) {
|
|
1996
2188
|
this.$emit('connectivity-error', {
|
|
1997
2189
|
data: {
|
|
1998
2190
|
errorData: errorData,
|
|
1999
2191
|
errorMessage: ERROR_MESSAGE,
|
|
2000
|
-
}
|
|
2001
|
-
})
|
|
2192
|
+
},
|
|
2193
|
+
})
|
|
2002
2194
|
},
|
|
2003
|
-
checkConnectivityTooltipEntry: function(tooltipEntry) {
|
|
2195
|
+
checkConnectivityTooltipEntry: function (tooltipEntry) {
|
|
2004
2196
|
if (tooltipEntry?.length) {
|
|
2005
|
-
return
|
|
2197
|
+
return (
|
|
2198
|
+
undefined !==
|
|
2199
|
+
tooltipEntry.find(
|
|
2200
|
+
(entry) => entry?.destinations?.length || entry?.components?.length
|
|
2201
|
+
)
|
|
2202
|
+
)
|
|
2006
2203
|
}
|
|
2007
2204
|
return false
|
|
2008
2205
|
},
|
|
2009
2206
|
changeConnectivitySource: async function (payload) {
|
|
2010
|
-
const { entry, connectivitySource } = payload
|
|
2207
|
+
const { entry, connectivitySource } = payload
|
|
2011
2208
|
if (entry.mapId === this.mapImp.id) {
|
|
2012
|
-
await this.flatmapQueries.queryForConnectivityNew(
|
|
2209
|
+
await this.flatmapQueries.queryForConnectivityNew(
|
|
2210
|
+
this.mapImp,
|
|
2211
|
+
entry.featureId[0],
|
|
2212
|
+
connectivitySource
|
|
2213
|
+
)
|
|
2013
2214
|
this.tooltipEntry = this.tooltipEntry.map((tooltip) => {
|
|
2014
2215
|
if (tooltip.featureId[0] === entry.featureId[0]) {
|
|
2015
|
-
return this.flatmapQueries.updateTooltipData(tooltip)
|
|
2216
|
+
return this.flatmapQueries.updateTooltipData(tooltip)
|
|
2016
2217
|
}
|
|
2017
|
-
return tooltip
|
|
2218
|
+
return tooltip
|
|
2018
2219
|
})
|
|
2019
2220
|
if (this.checkConnectivityTooltipEntry(this.tooltipEntry)) {
|
|
2020
|
-
this.$emit('connectivity-info-open', this.tooltipEntry)
|
|
2221
|
+
this.$emit('connectivity-info-open', this.tooltipEntry)
|
|
2021
2222
|
}
|
|
2022
2223
|
}
|
|
2023
2224
|
},
|
|
@@ -2030,28 +2231,39 @@ export default {
|
|
|
2030
2231
|
checkAndCreatePopups: async function (data, mapclick = true) {
|
|
2031
2232
|
// Call flatmap database to get the connection data
|
|
2032
2233
|
if (this.viewingMode === 'Annotation') {
|
|
2033
|
-
const features = data.filter(d => d.feature).map(d => d.feature)
|
|
2234
|
+
const features = data.filter((d) => d.feature).map((d) => d.feature)
|
|
2034
2235
|
if (features.length > 0) {
|
|
2035
|
-
if (
|
|
2036
|
-
this.
|
|
2037
|
-
|
|
2038
|
-
|
|
2039
|
-
|
|
2236
|
+
if (
|
|
2237
|
+
this.annotationSidebar &&
|
|
2238
|
+
this.previousDeletedEvent.type === 'deleted'
|
|
2239
|
+
) {
|
|
2240
|
+
this.annotationEntry = [
|
|
2241
|
+
{
|
|
2242
|
+
...this.previousDeletedEvent,
|
|
2243
|
+
resourceId: this.serverURL,
|
|
2244
|
+
},
|
|
2245
|
+
]
|
|
2040
2246
|
this.annotationEventCallback({}, { type: 'aborted' })
|
|
2041
2247
|
}
|
|
2042
2248
|
this.annotationEntry = []
|
|
2043
|
-
features.forEach(feature => {
|
|
2249
|
+
features.forEach((feature) => {
|
|
2044
2250
|
this.annotationEntry.push({
|
|
2045
2251
|
...feature,
|
|
2046
2252
|
resourceId: this.serverURL,
|
|
2047
|
-
featureId: feature.featureId
|
|
2048
|
-
|
|
2253
|
+
featureId: feature.featureId
|
|
2254
|
+
? feature.featureId
|
|
2255
|
+
: feature.feature?.id,
|
|
2256
|
+
offline: this.offlineAnnotationEnabled,
|
|
2049
2257
|
})
|
|
2050
|
-
})
|
|
2258
|
+
})
|
|
2051
2259
|
// Drawn feature annotationEntry will always have length of 1
|
|
2052
2260
|
if (features[0].feature) {
|
|
2053
2261
|
// in drawing or edit/delete mode is on or valid drawn
|
|
2054
|
-
if (
|
|
2262
|
+
if (
|
|
2263
|
+
this.activeDrawTool ||
|
|
2264
|
+
this.activeDrawMode ||
|
|
2265
|
+
this.isValidDrawnCreated
|
|
2266
|
+
) {
|
|
2055
2267
|
this.featureAnnotationSubmitted = false
|
|
2056
2268
|
if (this.activeDrawTool) {
|
|
2057
2269
|
this.createConnectivityBody()
|
|
@@ -2065,8 +2277,8 @@ export default {
|
|
|
2065
2277
|
}
|
|
2066
2278
|
} else {
|
|
2067
2279
|
const featureIds = this.annotationEntry
|
|
2068
|
-
.filter(annotation => annotation.featureId && annotation.models)
|
|
2069
|
-
.map(annotation => annotation.models)
|
|
2280
|
+
.filter((annotation) => annotation.featureId && annotation.models)
|
|
2281
|
+
.map((annotation) => annotation.models)
|
|
2070
2282
|
if (featureIds.length > 0) {
|
|
2071
2283
|
this.displayTooltip(featureIds)
|
|
2072
2284
|
}
|
|
@@ -2078,115 +2290,131 @@ export default {
|
|
|
2078
2290
|
// clicking on a connectivity explorer card will be the same as exploration mode
|
|
2079
2291
|
// the card should be opened without doing other functions
|
|
2080
2292
|
else if (this.viewingMode === 'Neuron Connection' && mapclick) {
|
|
2081
|
-
const resources = data.map(tooltip => tooltip.resource[0])
|
|
2293
|
+
const resources = data.map((tooltip) => tooltip.resource[0])
|
|
2082
2294
|
|
|
2083
2295
|
// filter out paths
|
|
2084
|
-
const featureId = resources.find(
|
|
2296
|
+
const featureId = resources.find(
|
|
2297
|
+
(resource) => !resource.startsWith('ilxtr:')
|
|
2298
|
+
)
|
|
2085
2299
|
if (featureId) {
|
|
2086
2300
|
// fallback if it cannot find in anatomical nodes
|
|
2087
|
-
const transformResources = Array.isArray(resources)
|
|
2301
|
+
const transformResources = Array.isArray(resources)
|
|
2302
|
+
? [...resources]
|
|
2303
|
+
: [resources]
|
|
2088
2304
|
if (transformResources.length === 1) {
|
|
2089
|
-
transformResources.push([])
|
|
2305
|
+
transformResources.push([])
|
|
2090
2306
|
}
|
|
2091
2307
|
|
|
2092
|
-
const featureId = data[0].feature?.featureId
|
|
2093
|
-
const annotation = this.mapImp.annotations.get(featureId)
|
|
2094
|
-
const anatomicalNodes = annotation?.['anatomical-nodes']
|
|
2095
|
-
const annotationModels = annotation?.['models']
|
|
2096
|
-
let anatomicalNode
|
|
2097
|
-
let uniqueResource = transformResources
|
|
2098
|
-
const models = annotation?.['models']
|
|
2308
|
+
const featureId = data[0].feature?.featureId
|
|
2309
|
+
const annotation = this.mapImp.annotations.get(featureId)
|
|
2310
|
+
const anatomicalNodes = annotation?.['anatomical-nodes']
|
|
2311
|
+
const annotationModels = annotation?.['models']
|
|
2312
|
+
let anatomicalNode
|
|
2313
|
+
let uniqueResource = transformResources
|
|
2314
|
+
const models = annotation?.['models']
|
|
2099
2315
|
if (anatomicalNodes?.length) {
|
|
2100
2316
|
// get the node which match the feature in a location
|
|
2101
2317
|
// [feature, location]
|
|
2102
|
-
anatomicalNode = anatomicalNodes.find(
|
|
2103
|
-
JSON.parse(node)[0] === annotationModels
|
|
2104
|
-
)
|
|
2318
|
+
anatomicalNode = anatomicalNodes.find(
|
|
2319
|
+
(node) => JSON.parse(node)[0] === annotationModels
|
|
2320
|
+
)
|
|
2105
2321
|
}
|
|
2106
2322
|
if (anatomicalNode) {
|
|
2107
|
-
uniqueResource = JSON.parse(anatomicalNode)
|
|
2323
|
+
uniqueResource = JSON.parse(anatomicalNode)
|
|
2108
2324
|
} else if (models) {
|
|
2109
|
-
uniqueResource = [models, []]
|
|
2325
|
+
uniqueResource = [models, []]
|
|
2110
2326
|
}
|
|
2111
2327
|
|
|
2112
|
-
const knowledgeSource = this.mapImp.knowledgeSource
|
|
2113
|
-
const terms = uniqueResource.flat(Infinity)
|
|
2114
|
-
const uniqueTerms = [...new Set(terms)]
|
|
2115
|
-
const fetchResults = await fetchLabels(this.flatmapAPI, uniqueTerms)
|
|
2328
|
+
const knowledgeSource = this.mapImp.knowledgeSource
|
|
2329
|
+
const terms = uniqueResource.flat(Infinity)
|
|
2330
|
+
const uniqueTerms = [...new Set(terms)]
|
|
2331
|
+
const fetchResults = await fetchLabels(this.flatmapAPI, uniqueTerms)
|
|
2116
2332
|
const objectResults = fetchResults.reduce((arr, item) => {
|
|
2117
|
-
const id = item[0]
|
|
2118
|
-
const valObj = JSON.parse(item[1])
|
|
2119
|
-
arr.push({ id, label: valObj.label, source: valObj.source })
|
|
2120
|
-
return arr
|
|
2121
|
-
}, [])
|
|
2333
|
+
const id = item[0]
|
|
2334
|
+
const valObj = JSON.parse(item[1])
|
|
2335
|
+
arr.push({ id, label: valObj.label, source: valObj.source })
|
|
2336
|
+
return arr
|
|
2337
|
+
}, [])
|
|
2122
2338
|
|
|
2123
2339
|
// sort matched knowledgeSource items for same id
|
|
2124
2340
|
objectResults.sort((a, b) => {
|
|
2125
2341
|
if (a.id === b.id) {
|
|
2126
|
-
if (a.source === knowledgeSource && b.source !== knowledgeSource)
|
|
2127
|
-
|
|
2128
|
-
|
|
2342
|
+
if (a.source === knowledgeSource && b.source !== knowledgeSource)
|
|
2343
|
+
return -1
|
|
2344
|
+
if (a.source !== knowledgeSource && b.source === knowledgeSource)
|
|
2345
|
+
return 1
|
|
2346
|
+
return 0
|
|
2129
2347
|
}
|
|
2130
|
-
return a.id.localeCompare(b.id)
|
|
2131
|
-
})
|
|
2348
|
+
return a.id.localeCompare(b.id)
|
|
2349
|
+
})
|
|
2132
2350
|
|
|
2133
|
-
const labels = []
|
|
2351
|
+
const labels = []
|
|
2134
2352
|
for (let i = 0; i < uniqueTerms.length; i++) {
|
|
2135
|
-
const foundObj = objectResults.find(
|
|
2353
|
+
const foundObj = objectResults.find(
|
|
2354
|
+
(obj) => obj.id === uniqueTerms[i]
|
|
2355
|
+
)
|
|
2136
2356
|
if (foundObj) {
|
|
2137
|
-
labels.push(foundObj.label)
|
|
2357
|
+
labels.push(foundObj.label)
|
|
2138
2358
|
}
|
|
2139
2359
|
}
|
|
2140
|
-
const filterItemLabel = capitalise(labels.join(', '))
|
|
2360
|
+
const filterItemLabel = capitalise(labels.join(', '))
|
|
2141
2361
|
const newConnectivityfilter = {
|
|
2142
2362
|
facet: JSON.stringify(uniqueResource),
|
|
2143
2363
|
facetPropPath: `flatmap.connectivity.source.${this.connectionType.toLowerCase()}`,
|
|
2144
2364
|
tagLabel: filterItemLabel, // used tagLabel here instead of label since the label and value are different
|
|
2145
|
-
term: this.connectionType
|
|
2146
|
-
}
|
|
2365
|
+
term: this.connectionType,
|
|
2366
|
+
}
|
|
2147
2367
|
// check for existing item
|
|
2148
|
-
const isNewFilterItemExist = this.connectivityFilters.some(
|
|
2149
|
-
connectivityfilter
|
|
2150
|
-
|
|
2151
|
-
|
|
2368
|
+
const isNewFilterItemExist = this.connectivityFilters.some(
|
|
2369
|
+
(connectivityfilter) =>
|
|
2370
|
+
connectivityfilter.facet === newConnectivityfilter.facet &&
|
|
2371
|
+
connectivityfilter.facetPropPath ===
|
|
2372
|
+
newConnectivityfilter.facetPropPath
|
|
2373
|
+
)
|
|
2152
2374
|
|
|
2153
2375
|
if (!isNewFilterItemExist) {
|
|
2154
|
-
this.connectivityFilters.push(newConnectivityfilter)
|
|
2376
|
+
this.connectivityFilters.push(newConnectivityfilter)
|
|
2155
2377
|
}
|
|
2156
2378
|
|
|
2157
2379
|
this.$emit('neuron-connection-feature-click', {
|
|
2158
2380
|
filters: this.connectivityFilters,
|
|
2159
2381
|
search: '',
|
|
2160
|
-
})
|
|
2382
|
+
})
|
|
2161
2383
|
} else {
|
|
2162
2384
|
// clicking on paths
|
|
2163
2385
|
await this.openConnectivityInfo(data);
|
|
2164
2386
|
}
|
|
2165
2387
|
} else {
|
|
2166
|
-
await this.openConnectivityInfo(data)
|
|
2388
|
+
await this.openConnectivityInfo(data)
|
|
2167
2389
|
}
|
|
2168
2390
|
},
|
|
2169
2391
|
openConnectivityInfo: async function (data) {
|
|
2170
2392
|
// load and store knowledge
|
|
2171
|
-
loadAndStoreKnowledge(this.mapImp, this.flatmapQueries)
|
|
2393
|
+
loadAndStoreKnowledge(this.mapImp, this.flatmapQueries)
|
|
2172
2394
|
let prom1 = []
|
|
2173
2395
|
// Emit placeholders first.
|
|
2174
2396
|
// This may contain invalid connectivity.
|
|
2175
2397
|
this.tooltipEntry = data
|
|
2176
|
-
.filter(tooltip => tooltip.resource[0] in this.mapImp.pathways.paths)
|
|
2398
|
+
.filter((tooltip) => tooltip.resource[0] in this.mapImp.pathways.paths)
|
|
2177
2399
|
.map((tooltip) => {
|
|
2178
|
-
return {
|
|
2400
|
+
return {
|
|
2401
|
+
title: tooltip.label,
|
|
2402
|
+
featureId: tooltip.resource,
|
|
2403
|
+
ready: false,
|
|
2404
|
+
}
|
|
2179
2405
|
})
|
|
2180
2406
|
// this should only for flatmap paths not all features
|
|
2181
2407
|
if (this.tooltipEntry.length) {
|
|
2182
|
-
this.$emit('connectivity-info-open', this.tooltipEntry)
|
|
2408
|
+
this.$emit('connectivity-info-open', this.tooltipEntry)
|
|
2183
2409
|
|
|
2184
2410
|
// While having placeholders displayed, get details for all paths and then replace.
|
|
2185
2411
|
for (let index = 0; index < data.length; index++) {
|
|
2186
2412
|
prom1.push(await this.getKnowledgeTooltip(data[index]))
|
|
2187
2413
|
}
|
|
2188
2414
|
this.tooltipEntry = await Promise.all(prom1)
|
|
2189
|
-
const featureIds = this.tooltipEntry.map(
|
|
2415
|
+
const featureIds = this.tooltipEntry.map(
|
|
2416
|
+
(tooltip) => tooltip.featureId[0]
|
|
2417
|
+
)
|
|
2190
2418
|
if (featureIds.length > 0) {
|
|
2191
2419
|
this.displayTooltip(featureIds)
|
|
2192
2420
|
}
|
|
@@ -2198,79 +2426,93 @@ export default {
|
|
|
2198
2426
|
* @param {Array} payload - The array of filter items to update.
|
|
2199
2427
|
*/
|
|
2200
2428
|
updateConnectivityFilters: function (payload) {
|
|
2201
|
-
if (!payload.length) return
|
|
2202
|
-
this.connectivityFilters = payload.filter(
|
|
2203
|
-
filterItem.facet.toLowerCase() !== 'show all'
|
|
2204
|
-
)
|
|
2429
|
+
if (!payload.length) return
|
|
2430
|
+
this.connectivityFilters = payload.filter(
|
|
2431
|
+
(filterItem) => filterItem.facet.toLowerCase() !== 'show all'
|
|
2432
|
+
)
|
|
2205
2433
|
},
|
|
2206
2434
|
resetConnectivityfilters: function (payload) {
|
|
2207
2435
|
if (payload.length) {
|
|
2208
2436
|
// remove not found items
|
|
2209
|
-
this.connectivityFilters = this.connectivityFilters.filter(
|
|
2210
|
-
|
|
2211
|
-
|
|
2212
|
-
|
|
2213
|
-
|
|
2437
|
+
this.connectivityFilters = this.connectivityFilters.filter(
|
|
2438
|
+
(connectivityfilter) =>
|
|
2439
|
+
payload.some(
|
|
2440
|
+
(notFoundItem) =>
|
|
2441
|
+
notFoundItem.facetPropPath ===
|
|
2442
|
+
connectivityfilter.facetPropPath &&
|
|
2443
|
+
notFoundItem.facet !== connectivityfilter.facet
|
|
2444
|
+
)
|
|
2214
2445
|
)
|
|
2215
2446
|
} else {
|
|
2216
2447
|
// full reset
|
|
2217
|
-
this.connectivityFilters = []
|
|
2448
|
+
this.connectivityFilters = []
|
|
2218
2449
|
}
|
|
2219
2450
|
},
|
|
2220
2451
|
getKnowledgeTooltip: async function (data) {
|
|
2221
2452
|
//require data.resource && data.feature.source
|
|
2222
|
-
const results =
|
|
2223
|
-
|
|
2453
|
+
const results =
|
|
2454
|
+
await this.flatmapQueries.retrieveFlatmapKnowledgeForEvent(
|
|
2455
|
+
this.mapImp,
|
|
2456
|
+
data
|
|
2457
|
+
)
|
|
2458
|
+
let tooltip = await this.flatmapQueries.createTooltipData(
|
|
2459
|
+
this.mapImp,
|
|
2460
|
+
data
|
|
2461
|
+
)
|
|
2462
|
+
|
|
2224
2463
|
// The line below only creates the tooltip if some data was found on the path
|
|
2225
2464
|
// the pubmed URLs are in knowledge response.references
|
|
2226
|
-
if (
|
|
2227
|
-
|
|
2228
|
-
|
|
2465
|
+
if (
|
|
2466
|
+
(results && results[0]) ||
|
|
2467
|
+
(data.feature.hyperlinks && data.feature.hyperlinks.length > 0)
|
|
2468
|
+
) {
|
|
2469
|
+
tooltip['featuresAlert'] = data.alert
|
|
2470
|
+
tooltip['knowledgeSource'] = getKnowledgeSource(this.mapImp)
|
|
2229
2471
|
// Map id and uuid to load connectivity information from the map
|
|
2230
|
-
tooltip['mapId'] = this.mapImp.mapMetadata.id
|
|
2231
|
-
tooltip['mapuuid'] = this.mapImp.mapMetadata.uuid
|
|
2232
|
-
|
|
2233
|
-
|
|
2234
|
-
|
|
2235
|
-
|
|
2236
|
-
|
|
2237
|
-
|
|
2238
|
-
|
|
2239
|
-
|
|
2240
|
-
|
|
2241
|
-
|
|
2242
|
-
|
|
2243
|
-
|
|
2244
|
-
|
|
2245
|
-
|
|
2246
|
-
|
|
2247
|
-
|
|
2248
|
-
|
|
2249
|
-
|
|
2250
|
-
|
|
2251
|
-
|
|
2252
|
-
|
|
2253
|
-
|
|
2254
|
-
|
|
2255
|
-
|
|
2256
|
-
|
|
2257
|
-
|
|
2258
|
-
|
|
2259
|
-
|
|
2260
|
-
|
|
2261
|
-
|
|
2262
|
-
|
|
2263
|
-
|
|
2264
|
-
|
|
2265
|
-
|
|
2266
|
-
|
|
2267
|
-
|
|
2268
|
-
|
|
2269
|
-
|
|
2270
|
-
|
|
2271
|
-
}
|
|
2272
|
-
tooltip['ready'] = true
|
|
2273
|
-
return tooltip
|
|
2472
|
+
tooltip['mapId'] = this.mapImp.mapMetadata.id
|
|
2473
|
+
tooltip['mapuuid'] = this.mapImp.mapMetadata.uuid
|
|
2474
|
+
// } else {
|
|
2475
|
+
// tooltip = {
|
|
2476
|
+
// ...tooltip,
|
|
2477
|
+
// origins: [data.label],
|
|
2478
|
+
// originsWithDatasets: [{ id: data.resource[0], name: data.label }],
|
|
2479
|
+
// components: [],
|
|
2480
|
+
// componentsWithDatasets: [],
|
|
2481
|
+
// destinations: [],
|
|
2482
|
+
// destinationsWithDatasets: [],
|
|
2483
|
+
// }
|
|
2484
|
+
// let featureIds = []
|
|
2485
|
+
// const pathsOfEntities = await this.mapImp.queryPathsForFeatures(data.resource)
|
|
2486
|
+
// if (pathsOfEntities.length) {
|
|
2487
|
+
// pathsOfEntities.forEach((path) => {
|
|
2488
|
+
// featureIds.push(...this.mapImp.pathModelNodes(path))
|
|
2489
|
+
// const searchResults = this.mapImp.search(path)
|
|
2490
|
+
// let featureId = undefined;
|
|
2491
|
+
// for (let i = 0; i < searchResults.results.length; i++) {
|
|
2492
|
+
// featureId = searchResults.results[i].featureId
|
|
2493
|
+
// const annotation = this.mapImp.annotation(featureId)
|
|
2494
|
+
// if (featureId && annotation?.label) break;
|
|
2495
|
+
// }
|
|
2496
|
+
// if (featureId) {
|
|
2497
|
+
// const feature = this.mapImp.featureProperties(featureId)
|
|
2498
|
+
// if (feature.label && !tooltip.components.includes(feature.label)) {
|
|
2499
|
+
// tooltip.components.push(feature.label)
|
|
2500
|
+
// tooltip.componentsWithDatasets.push({ id: feature.models, name: feature.label })
|
|
2501
|
+
// }
|
|
2502
|
+
// }
|
|
2503
|
+
// })
|
|
2504
|
+
// featureIds = [...new Set(featureIds)].filter(id => id !== data.feature.featureId)
|
|
2505
|
+
// featureIds.forEach((id) => {
|
|
2506
|
+
// const feature = this.mapImp.featureProperties(id)
|
|
2507
|
+
// if (feature.label && !tooltip.destinations.includes(feature.label)) {
|
|
2508
|
+
// tooltip.destinations.push(feature.label)
|
|
2509
|
+
// tooltip.destinationsWithDatasets.push({ id: feature.models, name: feature.label })
|
|
2510
|
+
// }
|
|
2511
|
+
// })
|
|
2512
|
+
// }
|
|
2513
|
+
}
|
|
2514
|
+
tooltip['ready'] = true
|
|
2515
|
+
return tooltip
|
|
2274
2516
|
},
|
|
2275
2517
|
/**
|
|
2276
2518
|
* A hack to remove flatmap tooltips while popup is open
|
|
@@ -2278,7 +2520,9 @@ export default {
|
|
|
2278
2520
|
popUpCssHacks: function () {
|
|
2279
2521
|
// Below is a hack to remove flatmap tooltips while popup is open
|
|
2280
2522
|
const ftooltip = document.querySelector('.flatmap-tooltip-popup')
|
|
2281
|
-
const popupCloseButton = document.querySelector(
|
|
2523
|
+
const popupCloseButton = document.querySelector(
|
|
2524
|
+
'.maplibregl-popup-close-button'
|
|
2525
|
+
)
|
|
2282
2526
|
if (ftooltip) ftooltip.style.display = 'none'
|
|
2283
2527
|
popupCloseButton.style.display = 'block'
|
|
2284
2528
|
this.$refs.tooltip.$el.style.display = 'flex'
|
|
@@ -2287,7 +2531,7 @@ export default {
|
|
|
2287
2531
|
* This event is emitted
|
|
2288
2532
|
* when a connectivity info (provenance popup) is closed.
|
|
2289
2533
|
*/
|
|
2290
|
-
this.$emit('connectivity-info-close')
|
|
2534
|
+
this.$emit('connectivity-info-close')
|
|
2291
2535
|
if (ftooltip) ftooltip.style.display = 'block'
|
|
2292
2536
|
}
|
|
2293
2537
|
},
|
|
@@ -2360,10 +2604,13 @@ export default {
|
|
|
2360
2604
|
'.maplibregl-ctrl-minimap'
|
|
2361
2605
|
)
|
|
2362
2606
|
if (minimapEl) {
|
|
2363
|
-
if (
|
|
2364
|
-
|
|
2607
|
+
if (
|
|
2608
|
+
this.$refs.minimapResize &&
|
|
2609
|
+
this.$refs.minimapResize.$el.parentNode
|
|
2610
|
+
) {
|
|
2365
2611
|
this.$refs.minimapResize.$el.parentNode.removeChild(
|
|
2366
|
-
this.$refs.minimapResize.$el
|
|
2612
|
+
this.$refs.minimapResize.$el
|
|
2613
|
+
)
|
|
2367
2614
|
}
|
|
2368
2615
|
minimapEl.appendChild(this.$refs.minimapResize.$el)
|
|
2369
2616
|
this.minimapResizeShow = true
|
|
@@ -2376,52 +2623,58 @@ export default {
|
|
|
2376
2623
|
* @arg {Boolean} `helpMode`
|
|
2377
2624
|
*/
|
|
2378
2625
|
setHelpMode: function (helpMode) {
|
|
2379
|
-
const toolTipsLength = this.hoverVisibilities.length
|
|
2380
|
-
const lastIndex = toolTipsLength - 1
|
|
2381
|
-
const activePopoverObj = this.hoverVisibilities[this.helpModeActiveIndex]
|
|
2626
|
+
const toolTipsLength = this.hoverVisibilities.length
|
|
2627
|
+
const lastIndex = toolTipsLength - 1
|
|
2628
|
+
const activePopoverObj = this.hoverVisibilities[this.helpModeActiveIndex]
|
|
2382
2629
|
|
|
2383
2630
|
if (activePopoverObj) {
|
|
2384
|
-
const popoverRefsId = activePopoverObj?.refs
|
|
2385
|
-
const popoverRefId = activePopoverObj?.ref
|
|
2386
|
-
const popoverRef =
|
|
2631
|
+
const popoverRefsId = activePopoverObj?.refs
|
|
2632
|
+
const popoverRefId = activePopoverObj?.ref
|
|
2633
|
+
const popoverRef =
|
|
2634
|
+
this.$refs[popoverRefsId ? popoverRefsId : popoverRefId]
|
|
2387
2635
|
|
|
2388
2636
|
if (popoverRef) {
|
|
2389
2637
|
// Open pathway drawer if the tooltip is inside or beside
|
|
2390
|
-
const { parentElement, nextElementSibling } = popoverRef.$el
|
|
2638
|
+
const { parentElement, nextElementSibling } = popoverRef.$el
|
|
2391
2639
|
const isPathwayContainer = (element) => {
|
|
2392
|
-
return
|
|
2393
|
-
element
|
|
2394
|
-
element.classList.contains('pathway-
|
|
2395
|
-
|
|
2396
|
-
|
|
2640
|
+
return (
|
|
2641
|
+
element &&
|
|
2642
|
+
(element.classList.contains('pathway-container') ||
|
|
2643
|
+
element.classList.contains('pathway-location'))
|
|
2644
|
+
)
|
|
2645
|
+
}
|
|
2397
2646
|
|
|
2398
2647
|
if (
|
|
2399
2648
|
isPathwayContainer(parentElement) ||
|
|
2400
2649
|
isPathwayContainer(nextElementSibling)
|
|
2401
2650
|
) {
|
|
2402
2651
|
if (this.requiresDrawer) {
|
|
2403
|
-
this.drawerOpen = true
|
|
2652
|
+
this.drawerOpen = true
|
|
2404
2653
|
} else {
|
|
2405
|
-
this.helpModeActiveIndex += 1
|
|
2654
|
+
this.helpModeActiveIndex += 1
|
|
2406
2655
|
}
|
|
2407
2656
|
}
|
|
2408
2657
|
} else {
|
|
2409
2658
|
// skip the unavailable tooltips
|
|
2410
|
-
this.helpModeActiveIndex += 1
|
|
2411
|
-
this.setHelpMode(helpMode)
|
|
2659
|
+
this.helpModeActiveIndex += 1
|
|
2660
|
+
this.setHelpMode(helpMode)
|
|
2412
2661
|
}
|
|
2413
2662
|
}
|
|
2414
2663
|
|
|
2415
2664
|
// Skip checkbox tooltip if pathway filter is not shown
|
|
2416
|
-
const activePopoverObjAfter =
|
|
2417
|
-
|
|
2418
|
-
|
|
2419
|
-
|
|
2665
|
+
const activePopoverObjAfter =
|
|
2666
|
+
this.hoverVisibilities[this.helpModeActiveIndex]
|
|
2667
|
+
if (
|
|
2668
|
+
activePopoverObjAfter?.ref === 'checkBoxPopover' &&
|
|
2669
|
+
!this.showPathwayFilter
|
|
2670
|
+
) {
|
|
2671
|
+
this.helpModeActiveIndex += 1
|
|
2672
|
+
this.setHelpMode(helpMode)
|
|
2420
2673
|
}
|
|
2421
2674
|
|
|
2422
2675
|
if (!helpMode) {
|
|
2423
2676
|
// reset to iniital state
|
|
2424
|
-
this.helpModeActiveIndex = this.helpModeInitialIndex
|
|
2677
|
+
this.helpModeActiveIndex = this.helpModeInitialIndex
|
|
2425
2678
|
}
|
|
2426
2679
|
|
|
2427
2680
|
if (this.viewingMode !== 'Annotation' && this.helpModeActiveIndex > 9) {
|
|
@@ -2432,31 +2685,34 @@ export default {
|
|
|
2432
2685
|
/**
|
|
2433
2686
|
* This event is emitted when the tooltips in help mode reach the last item.
|
|
2434
2687
|
*/
|
|
2435
|
-
this.$emit('help-mode-last-item', true)
|
|
2688
|
+
this.$emit('help-mode-last-item', true)
|
|
2436
2689
|
}
|
|
2437
2690
|
|
|
2438
2691
|
if (helpMode && !this.helpModeDialog) {
|
|
2439
|
-
this.inHelp = true
|
|
2692
|
+
this.inHelp = true
|
|
2440
2693
|
this.hoverVisibilities.forEach((item) => {
|
|
2441
|
-
item.value = true
|
|
2442
|
-
})
|
|
2443
|
-
} else if (
|
|
2444
|
-
|
|
2694
|
+
item.value = true
|
|
2695
|
+
})
|
|
2696
|
+
} else if (
|
|
2697
|
+
helpMode &&
|
|
2698
|
+
this.helpModeDialog &&
|
|
2699
|
+
toolTipsLength > this.helpModeActiveIndex
|
|
2700
|
+
) {
|
|
2445
2701
|
// Show the map tooltip as first item
|
|
2446
2702
|
if (this.helpModeActiveIndex > -1) {
|
|
2447
|
-
this.closeFlatmapHelpPopup()
|
|
2703
|
+
this.closeFlatmapHelpPopup()
|
|
2448
2704
|
|
|
2449
2705
|
// wait for CSS transition
|
|
2450
2706
|
setTimeout(() => {
|
|
2451
|
-
this.inHelp = false
|
|
2707
|
+
this.inHelp = false
|
|
2452
2708
|
this.hoverVisibilities.forEach((item) => {
|
|
2453
|
-
item.value = false
|
|
2454
|
-
})
|
|
2709
|
+
item.value = false
|
|
2710
|
+
})
|
|
2455
2711
|
|
|
2456
|
-
this.showTooltip(this.helpModeActiveIndex, 200)
|
|
2457
|
-
}, 300)
|
|
2712
|
+
this.showTooltip(this.helpModeActiveIndex, 200)
|
|
2713
|
+
}, 300)
|
|
2458
2714
|
} else if (this.helpModeActiveIndex === -1) {
|
|
2459
|
-
this.openFlatmapHelpPopup()
|
|
2715
|
+
this.openFlatmapHelpPopup()
|
|
2460
2716
|
}
|
|
2461
2717
|
} else {
|
|
2462
2718
|
this.inHelp = false
|
|
@@ -2481,7 +2737,7 @@ export default {
|
|
|
2481
2737
|
/**
|
|
2482
2738
|
* This event is emitted after a tooltip in Flatmap is shown.
|
|
2483
2739
|
*/
|
|
2484
|
-
this.$emit('shown-tooltip')
|
|
2740
|
+
this.$emit('shown-tooltip')
|
|
2485
2741
|
}, timeout)
|
|
2486
2742
|
}
|
|
2487
2743
|
},
|
|
@@ -2510,6 +2766,7 @@ export default {
|
|
|
2510
2766
|
*/
|
|
2511
2767
|
displayTooltip: function (feature, geometry = undefined) {
|
|
2512
2768
|
let featureId = undefined
|
|
2769
|
+
console.log('Displaying tooltip for feature:', feature)
|
|
2513
2770
|
let options = { className: 'flatmapvuer-popover' }
|
|
2514
2771
|
if (geometry) {
|
|
2515
2772
|
featureId = feature
|
|
@@ -2517,7 +2774,7 @@ export default {
|
|
|
2517
2774
|
if (this.annotationEntry.length) {
|
|
2518
2775
|
options['annotationEvent'] = {
|
|
2519
2776
|
type: this.annotationEntry[0].type,
|
|
2520
|
-
feature: this.annotationEntry[0].feature
|
|
2777
|
+
feature: this.annotationEntry[0].feature,
|
|
2521
2778
|
}
|
|
2522
2779
|
}
|
|
2523
2780
|
} else {
|
|
@@ -2532,15 +2789,19 @@ export default {
|
|
|
2532
2789
|
// If connectivityInfoSidebar is set to `true`
|
|
2533
2790
|
// Connectivity info will show in sidebar
|
|
2534
2791
|
if (
|
|
2535
|
-
|
|
2792
|
+
this.connectivityInfoSidebar &&
|
|
2793
|
+
this.tooltipEntry.length &&
|
|
2536
2794
|
this.viewingMode !== 'Annotation'
|
|
2537
2795
|
) {
|
|
2538
2796
|
if (this.checkConnectivityTooltipEntry(this.tooltipEntry)) {
|
|
2539
|
-
this.$emit('connectivity-info-open', this.tooltipEntry)
|
|
2797
|
+
this.$emit('connectivity-info-open', this.tooltipEntry)
|
|
2540
2798
|
}
|
|
2541
2799
|
}
|
|
2542
2800
|
if (this.annotationSidebar && this.viewingMode === 'Annotation') {
|
|
2543
|
-
this.$emit('annotation-open', {
|
|
2801
|
+
this.$emit('annotation-open', {
|
|
2802
|
+
annotationEntry: this.annotationEntry,
|
|
2803
|
+
commitCallback: this.commitAnnotationEvent,
|
|
2804
|
+
})
|
|
2544
2805
|
}
|
|
2545
2806
|
// If UI is not disabled,
|
|
2546
2807
|
// And connectivityInfoSidebar is not set (default) or set to `false`
|
|
@@ -2549,16 +2810,14 @@ export default {
|
|
|
2549
2810
|
if (
|
|
2550
2811
|
featureId &&
|
|
2551
2812
|
!this.disableUI &&
|
|
2552
|
-
(
|
|
2553
|
-
(this.viewingMode === '
|
|
2554
|
-
(this.viewingMode === 'Exploration' && !this.connectivityInfoSidebar)
|
|
2555
|
-
)
|
|
2813
|
+
((this.viewingMode === 'Annotation' && !this.annotationSidebar) ||
|
|
2814
|
+
(this.viewingMode === 'Exploration' && !this.connectivityInfoSidebar))
|
|
2556
2815
|
) {
|
|
2557
|
-
this.tooltipDisplay = true
|
|
2816
|
+
this.tooltipDisplay = true
|
|
2558
2817
|
this.$nextTick(() => {
|
|
2559
|
-
this.mapImp.showPopup(featureId, this.$refs.tooltip.$el, options)
|
|
2560
|
-
this.popUpCssHacks()
|
|
2561
|
-
})
|
|
2818
|
+
this.mapImp.showPopup(featureId, this.$refs.tooltip.$el, options)
|
|
2819
|
+
this.popUpCssHacks()
|
|
2820
|
+
})
|
|
2562
2821
|
}
|
|
2563
2822
|
},
|
|
2564
2823
|
/**
|
|
@@ -2567,18 +2826,18 @@ export default {
|
|
|
2567
2826
|
* because the sidebar is opened
|
|
2568
2827
|
* @arg featureIds
|
|
2569
2828
|
*/
|
|
2570
|
-
|
|
2829
|
+
moveMap: function (featureIds, options = {}) {
|
|
2571
2830
|
if (this.mapImp) {
|
|
2572
|
-
const { offsetX = 0, offsetY = 0, zoom = 4 } = options
|
|
2573
|
-
const Map = this.mapImp.map
|
|
2574
|
-
const bbox = this.mapImp.bounds.toArray()
|
|
2831
|
+
const { offsetX = 0, offsetY = 0, zoom = 4 } = options
|
|
2832
|
+
const Map = this.mapImp.map
|
|
2833
|
+
const bbox = this.mapImp.bounds.toArray()
|
|
2575
2834
|
|
|
2576
2835
|
// Zoom the map to features first
|
|
2577
|
-
this.mapImp.zoomToFeatures(featureIds, { noZoomIn: true })
|
|
2836
|
+
this.mapImp.zoomToFeatures(featureIds, { noZoomIn: true })
|
|
2578
2837
|
|
|
2579
2838
|
// Hide the left pathway drawer
|
|
2580
2839
|
// to get more space for the map
|
|
2581
|
-
this.showPathwaysDrawer(false)
|
|
2840
|
+
this.showPathwaysDrawer(false)
|
|
2582
2841
|
|
|
2583
2842
|
// Move the map to left side
|
|
2584
2843
|
// since the sidebar is taking space on the right
|
|
@@ -2587,9 +2846,9 @@ export default {
|
|
|
2587
2846
|
Map.fitBounds(bbox, {
|
|
2588
2847
|
offset: [offsetX, offsetY],
|
|
2589
2848
|
zoom: zoom,
|
|
2590
|
-
animate: true
|
|
2591
|
-
})
|
|
2592
|
-
})
|
|
2849
|
+
animate: true,
|
|
2850
|
+
})
|
|
2851
|
+
})
|
|
2593
2852
|
}
|
|
2594
2853
|
}
|
|
2595
2854
|
},
|
|
@@ -2609,7 +2868,7 @@ export default {
|
|
|
2609
2868
|
/**
|
|
2610
2869
|
* This event is emitted after a tooltip on Flatmap's map is shown.
|
|
2611
2870
|
*/
|
|
2612
|
-
this.$emit('shown-map-tooltip')
|
|
2871
|
+
this.$emit('shown-map-tooltip')
|
|
2613
2872
|
}
|
|
2614
2873
|
}
|
|
2615
2874
|
},
|
|
@@ -2644,16 +2903,19 @@ export default {
|
|
|
2644
2903
|
*/
|
|
2645
2904
|
getVisibilityState: function (state) {
|
|
2646
2905
|
const refs = ['alertSelection', 'pathwaysSelection', 'taxonSelection']
|
|
2647
|
-
refs.forEach(ref => {
|
|
2906
|
+
refs.forEach((ref) => {
|
|
2648
2907
|
let comp = this.$refs[ref]
|
|
2649
2908
|
if (comp) {
|
|
2650
2909
|
state[ref] = comp.getState()
|
|
2651
2910
|
}
|
|
2652
2911
|
})
|
|
2653
2912
|
if (this.$refs.treeControls) {
|
|
2654
|
-
const checkedKeys =
|
|
2913
|
+
const checkedKeys =
|
|
2914
|
+
this.$refs.treeControls.$refs.regionTree.getCheckedKeys()
|
|
2655
2915
|
//Only store first level systems (terms without .)
|
|
2656
|
-
state['systemsSelection'] = checkedKeys.filter(
|
|
2916
|
+
state['systemsSelection'] = checkedKeys.filter(
|
|
2917
|
+
(term) => !term.includes('.')
|
|
2918
|
+
)
|
|
2657
2919
|
}
|
|
2658
2920
|
},
|
|
2659
2921
|
/**
|
|
@@ -2662,7 +2924,7 @@ export default {
|
|
|
2662
2924
|
*/
|
|
2663
2925
|
setVisibilityState: function (state) {
|
|
2664
2926
|
const refs = ['alertSelection', 'pathwaysSelection', 'taxonSelection']
|
|
2665
|
-
refs.forEach(ref => {
|
|
2927
|
+
refs.forEach((ref) => {
|
|
2666
2928
|
const settings = state[ref]
|
|
2667
2929
|
if (settings) {
|
|
2668
2930
|
const comp = this.$refs[ref]
|
|
@@ -2673,9 +2935,14 @@ export default {
|
|
|
2673
2935
|
})
|
|
2674
2936
|
if ('systemsSelection' in state) {
|
|
2675
2937
|
if (this.$refs.treeControls) {
|
|
2676
|
-
this.$refs.treeControls.$refs.regionTree.setCheckedKeys(
|
|
2938
|
+
this.$refs.treeControls.$refs.regionTree.setCheckedKeys(
|
|
2939
|
+
state['systemsSelection']
|
|
2940
|
+
)
|
|
2677
2941
|
this.systems[0].children.forEach((item) => {
|
|
2678
|
-
this.mapImp.enableSystem(
|
|
2942
|
+
this.mapImp.enableSystem(
|
|
2943
|
+
item.key,
|
|
2944
|
+
state['systemsSelection'].includes(item.key)
|
|
2945
|
+
)
|
|
2679
2946
|
})
|
|
2680
2947
|
}
|
|
2681
2948
|
}
|
|
@@ -2702,7 +2969,9 @@ export default {
|
|
|
2702
2969
|
state['outlines'] = this.outlinesRadio
|
|
2703
2970
|
state['background'] = this.currentBackground
|
|
2704
2971
|
if (this.offlineAnnotationEnabled) {
|
|
2705
|
-
state['offlineAnnotations'] = sessionStorage.getItem(
|
|
2972
|
+
state['offlineAnnotations'] = sessionStorage.getItem(
|
|
2973
|
+
'anonymous-annotation'
|
|
2974
|
+
)
|
|
2706
2975
|
}
|
|
2707
2976
|
this.getVisibilityState(state)
|
|
2708
2977
|
return state
|
|
@@ -2739,7 +3008,10 @@ export default {
|
|
|
2739
3008
|
if (state) {
|
|
2740
3009
|
if (state.viewport) this.mapImp.setState(state.viewport)
|
|
2741
3010
|
if (state.offlineAnnotations) {
|
|
2742
|
-
sessionStorage.setItem(
|
|
3011
|
+
sessionStorage.setItem(
|
|
3012
|
+
'anonymous-annotation',
|
|
3013
|
+
state.offlineAnnotations
|
|
3014
|
+
)
|
|
2743
3015
|
}
|
|
2744
3016
|
if (state.viewingMode) this.changeViewingMode(state.viewingMode)
|
|
2745
3017
|
//The following three are boolean
|
|
@@ -2763,7 +3035,10 @@ export default {
|
|
|
2763
3035
|
*/
|
|
2764
3036
|
setFlightPathInfo: function (mapVersion) {
|
|
2765
3037
|
const mapVersionForFlightPath = 1.6
|
|
2766
|
-
if (
|
|
3038
|
+
if (
|
|
3039
|
+
mapVersion === mapVersionForFlightPath ||
|
|
3040
|
+
mapVersion > mapVersionForFlightPath
|
|
3041
|
+
) {
|
|
2767
3042
|
// Show flight path option UI
|
|
2768
3043
|
this.displayFlightPathOption = true
|
|
2769
3044
|
// Show 2D as default on FC type
|
|
@@ -2809,10 +3084,10 @@ export default {
|
|
|
2809
3084
|
identifier.taxon = state.entry
|
|
2810
3085
|
}
|
|
2811
3086
|
if (state.biologicalSex) {
|
|
2812
|
-
|
|
3087
|
+
identifier['biologicalSex'] = state.biologicalSex
|
|
2813
3088
|
} else if (identifier.taxon === 'NCBITaxon:9606') {
|
|
2814
3089
|
//For backward compatibility
|
|
2815
|
-
identifier['biologicalSex'] = 'PATO:0000384'
|
|
3090
|
+
identifier['biologicalSex'] = 'PATO:0000384'
|
|
2816
3091
|
}
|
|
2817
3092
|
} else {
|
|
2818
3093
|
// Set the bioloicalSex now if map is not resumed from
|
|
@@ -2822,6 +3097,8 @@ export default {
|
|
|
2822
3097
|
}
|
|
2823
3098
|
}
|
|
2824
3099
|
|
|
3100
|
+
console.log("tooltip delay")
|
|
3101
|
+
|
|
2825
3102
|
let promise1 = this.mapManagerRef.loadMap(
|
|
2826
3103
|
identifier,
|
|
2827
3104
|
this.eventCallback(),
|
|
@@ -2833,51 +3110,55 @@ export default {
|
|
|
2833
3110
|
tooltips: this.tooltips,
|
|
2834
3111
|
minimap: false,
|
|
2835
3112
|
container: this.$refs.display,
|
|
2836
|
-
|
|
3113
|
+
tooltipDelay: 15, // new feature to delay tooltips showing
|
|
2837
3114
|
}
|
|
2838
3115
|
)
|
|
2839
|
-
promise1
|
|
2840
|
-
|
|
2841
|
-
|
|
2842
|
-
|
|
2843
|
-
|
|
2844
|
-
|
|
2845
|
-
|
|
2846
|
-
|
|
2847
|
-
|
|
2848
|
-
|
|
2849
|
-
|
|
2850
|
-
|
|
2851
|
-
|
|
2852
|
-
this.flatmapError
|
|
2853
|
-
|
|
2854
|
-
|
|
2855
|
-
|
|
2856
|
-
|
|
2857
|
-
|
|
2858
|
-
|
|
2859
|
-
|
|
2860
|
-
|
|
2861
|
-
|
|
2862
|
-
|
|
2863
|
-
|
|
2864
|
-
|
|
2865
|
-
|
|
2866
|
-
|
|
2867
|
-
|
|
2868
|
-
this
|
|
2869
|
-
|
|
2870
|
-
|
|
2871
|
-
|
|
2872
|
-
|
|
3116
|
+
promise1
|
|
3117
|
+
.then((returnedObject) => {
|
|
3118
|
+
this.mapImp = returnedObject
|
|
3119
|
+
this.serverURL = this.mapImp.makeServerUrl('').slice(0, -1)
|
|
3120
|
+
let mapVersion = this.mapImp.details.version
|
|
3121
|
+
this.setFlightPathInfo(mapVersion)
|
|
3122
|
+
const stateToSet = this._stateToBeSet ? this._stateToBeSet : state
|
|
3123
|
+
this.onFlatmapReady(stateToSet)
|
|
3124
|
+
this.$nextTick(() => this.restoreMapState(stateToSet))
|
|
3125
|
+
})
|
|
3126
|
+
.catch((error) => {
|
|
3127
|
+
console.error('Flatmap loading error:', error)
|
|
3128
|
+
// prepare error object
|
|
3129
|
+
this.flatmapError = {}
|
|
3130
|
+
if (error.message && error.message.indexOf('Unknown map') !== -1) {
|
|
3131
|
+
this.flatmapError['title'] = 'Unknown Map!'
|
|
3132
|
+
this.flatmapError['messages'] = Object.keys(identifier).map(
|
|
3133
|
+
(key) => {
|
|
3134
|
+
const keyName = key === 'uuid' ? 'UUID' : capitalise(key)
|
|
3135
|
+
return `${keyName}: ${identifier[key]}`
|
|
3136
|
+
}
|
|
3137
|
+
)
|
|
3138
|
+
} else {
|
|
3139
|
+
this.flatmapError['title'] = 'Error Loading Map!'
|
|
3140
|
+
this.flatmapError['messages'] = [
|
|
3141
|
+
error.message ? error.message : error.toString(),
|
|
3142
|
+
'Please try again later or contact support if the problem persists.',
|
|
3143
|
+
]
|
|
3144
|
+
}
|
|
3145
|
+
if (this.$parent?.$refs?.multiContainer) {
|
|
3146
|
+
// if the flatmap is in a multiflatmapvuer
|
|
3147
|
+
// show a button to load default map
|
|
3148
|
+
const multiFlatmapVuer = this.$parent
|
|
3149
|
+
this.flatmapError['button'] = {
|
|
3150
|
+
text: 'Load Default Map',
|
|
3151
|
+
callback: () => {
|
|
3152
|
+
const defaultSpecies = multiFlatmapVuer.initial
|
|
3153
|
+
multiFlatmapVuer.setSpecies(defaultSpecies, undefined, 3)
|
|
3154
|
+
},
|
|
2873
3155
|
}
|
|
2874
|
-
}
|
|
2875
|
-
|
|
2876
|
-
|
|
2877
|
-
})
|
|
3156
|
+
}
|
|
3157
|
+
this.loading = false
|
|
3158
|
+
})
|
|
2878
3159
|
} else if (state) {
|
|
2879
3160
|
this._stateToBeSet = {
|
|
2880
|
-
...state
|
|
3161
|
+
...state,
|
|
2881
3162
|
}
|
|
2882
3163
|
if (this.mapImp && !this.loading) {
|
|
2883
3164
|
this.restoreMapState(this._stateToBeSet)
|
|
@@ -2919,7 +3200,7 @@ export default {
|
|
|
2919
3200
|
let filterSourcesMap = new Map()
|
|
2920
3201
|
for (const annotation of this.mapImp.annotations.values()) {
|
|
2921
3202
|
if (annotation.source) {
|
|
2922
|
-
if (
|
|
3203
|
+
if ('alert' in annotation) {
|
|
2923
3204
|
withAlert.add(annotation.source)
|
|
2924
3205
|
} else {
|
|
2925
3206
|
withoutAlert.add(annotation.source)
|
|
@@ -2936,7 +3217,7 @@ export default {
|
|
|
2936
3217
|
sourceMap.set(setKey, new Set())
|
|
2937
3218
|
}
|
|
2938
3219
|
sourceMap.get(setKey).add(`${annotation.source}`)
|
|
2939
|
-
}
|
|
3220
|
+
}
|
|
2940
3221
|
if (Array.isArray(value)) {
|
|
2941
3222
|
value.forEach(addToSourceMap)
|
|
2942
3223
|
} else {
|
|
@@ -2947,10 +3228,10 @@ export default {
|
|
|
2947
3228
|
}
|
|
2948
3229
|
}
|
|
2949
3230
|
let filterSources = {
|
|
2950
|
-
|
|
2951
|
-
|
|
2952
|
-
|
|
2953
|
-
}
|
|
3231
|
+
alert: {
|
|
3232
|
+
with: [...withAlert],
|
|
3233
|
+
without: [...withoutAlert],
|
|
3234
|
+
},
|
|
2954
3235
|
}
|
|
2955
3236
|
for (const [key, value] of filterSourcesMap.entries()) {
|
|
2956
3237
|
filterSources[key] = {}
|
|
@@ -2961,10 +3242,15 @@ export default {
|
|
|
2961
3242
|
return filterSources
|
|
2962
3243
|
},
|
|
2963
3244
|
getFilterOptions: async function (mapImp, _providedKnowledge) {
|
|
2964
|
-
const providedKnowledge = _providedKnowledge || this.getFlatmapKnowledge()
|
|
2965
|
-
const providedPathways = this.pathways
|
|
2966
|
-
const flatmapFilterOptions = await getFlatmapFilterOptions(
|
|
2967
|
-
|
|
3245
|
+
const providedKnowledge = _providedKnowledge || this.getFlatmapKnowledge()
|
|
3246
|
+
const providedPathways = this.pathways
|
|
3247
|
+
const flatmapFilterOptions = await getFlatmapFilterOptions(
|
|
3248
|
+
this.flatmapAPI,
|
|
3249
|
+
mapImp,
|
|
3250
|
+
providedKnowledge,
|
|
3251
|
+
providedPathways
|
|
3252
|
+
)
|
|
3253
|
+
return flatmapFilterOptions
|
|
2968
3254
|
},
|
|
2969
3255
|
/**
|
|
2970
3256
|
* @public
|
|
@@ -2972,33 +3258,40 @@ export default {
|
|
|
2972
3258
|
*/
|
|
2973
3259
|
onFlatmapReady: function (state) {
|
|
2974
3260
|
// onFlatmapReady is used for functions that need to run immediately after the flatmap is loaded
|
|
2975
|
-
this.sensor = markRaw(
|
|
3261
|
+
this.sensor = markRaw(
|
|
3262
|
+
new ResizeSensor(this.$refs.display, this.mapResize)
|
|
3263
|
+
)
|
|
2976
3264
|
if (this.mapImp.options?.style === 'functional') {
|
|
2977
3265
|
this.isFC = true
|
|
2978
3266
|
}
|
|
2979
3267
|
this.mapImp.setBackgroundOpacity(1)
|
|
2980
3268
|
this.backgroundChangeCallback(this.currentBackground)
|
|
2981
3269
|
this.pathways = this.mapImp.pathTypes()
|
|
2982
|
-
this.pathways = this.pathways.filter(path => {
|
|
3270
|
+
this.pathways = this.pathways.filter((path) => {
|
|
2983
3271
|
return path.enabled && path.type !== 'other'
|
|
2984
3272
|
})
|
|
2985
3273
|
//Disable layers for now
|
|
2986
3274
|
//this.layers = this.mapImp.getLayers();
|
|
2987
3275
|
this.processSystems(this.mapImp.getSystems())
|
|
2988
3276
|
//Async, pass the state for checking
|
|
2989
|
-
this.processTaxon(
|
|
2990
|
-
|
|
3277
|
+
this.processTaxon(
|
|
3278
|
+
this.mapImp.taxonIdentifiers,
|
|
3279
|
+
state ? state['taxonSelection'] : undefined
|
|
3280
|
+
)
|
|
3281
|
+
|
|
3282
|
+
this.containsAlert = 'alert' in this.mapImp.featureFilterRanges()
|
|
2991
3283
|
this.flatmapLegends = this.mapImp.flatmapLegend
|
|
2992
3284
|
this.loading = false
|
|
2993
3285
|
this.computePathControlsMaximumHeight()
|
|
2994
3286
|
this.mapResize()
|
|
2995
|
-
this.handleMapClick()
|
|
2996
|
-
this.setInitMapState()
|
|
3287
|
+
this.handleMapClick()
|
|
3288
|
+
this.setInitMapState()
|
|
2997
3289
|
if (this.displayMinimap) {
|
|
2998
|
-
const minimapOptions = { position: 'top-right' }
|
|
2999
|
-
this.mapImp.createMinimap(minimapOptions)
|
|
3290
|
+
const minimapOptions = { position: 'top-right' }
|
|
3291
|
+
this.mapImp.createMinimap(minimapOptions)
|
|
3000
3292
|
this.addResizeButtonToMinimap()
|
|
3001
3293
|
}
|
|
3294
|
+
this.currentFlatmapUuid = this.mapImp?.mapMetadata?.uuid
|
|
3002
3295
|
/**
|
|
3003
3296
|
* This is ``onFlatmapReady`` event.
|
|
3004
3297
|
* @arg ``this`` (Component Vue Instance)
|
|
@@ -3011,33 +3304,35 @@ export default {
|
|
|
3011
3304
|
* after the map is loaded.
|
|
3012
3305
|
*/
|
|
3013
3306
|
handleMapClick: function () {
|
|
3014
|
-
const _map = this.mapImp.map
|
|
3307
|
+
const _map = this.mapImp.map
|
|
3015
3308
|
if (_map) {
|
|
3016
3309
|
_map.on('click', (e) => {
|
|
3017
3310
|
if (!this.connectivityDataSource) {
|
|
3018
|
-
this.$emit('connectivity-info-close')
|
|
3311
|
+
this.$emit('connectivity-info-close')
|
|
3019
3312
|
}
|
|
3020
|
-
this.connectivityDataSource = ''
|
|
3021
|
-
})
|
|
3313
|
+
this.connectivityDataSource = '' // reset
|
|
3314
|
+
})
|
|
3022
3315
|
}
|
|
3023
3316
|
},
|
|
3024
|
-
onContextLost: function() {
|
|
3317
|
+
onContextLost: function () {
|
|
3025
3318
|
this.lastViewport = markRaw(this.mapImp.getState())
|
|
3026
|
-
this.flatmapError = {}
|
|
3319
|
+
this.flatmapError = {}
|
|
3027
3320
|
this.flatmapError['title'] = 'GL context lost!'
|
|
3028
|
-
this.flatmapError['messages'] = [
|
|
3321
|
+
this.flatmapError['messages'] = [
|
|
3322
|
+
`A display issue has occurred due
|
|
3029
3323
|
to a limit on available WebGL contexts. You can restore the display
|
|
3030
3324
|
using the Restore Context button. Please see the
|
|
3031
3325
|
<a href="https://docs.sparc.science/docs/integrated-maps-viewer-overview#limit-on-available-webgl-contexts" target='_blank'>documentation</a>
|
|
3032
|
-
for more details
|
|
3326
|
+
for more details.`,
|
|
3327
|
+
]
|
|
3033
3328
|
this.flatmapError['button'] = {
|
|
3034
3329
|
text: 'Restore Context',
|
|
3035
3330
|
callback: () => {
|
|
3036
3331
|
this.forceContextRestore()
|
|
3037
|
-
}
|
|
3038
|
-
}
|
|
3332
|
+
},
|
|
3333
|
+
}
|
|
3039
3334
|
},
|
|
3040
|
-
onContextRestored: function() {
|
|
3335
|
+
onContextRestored: function () {
|
|
3041
3336
|
if (this.mapImp) {
|
|
3042
3337
|
this.handleMapClick()
|
|
3043
3338
|
this.setInitMapState()
|
|
@@ -3047,8 +3342,8 @@ export default {
|
|
|
3047
3342
|
}
|
|
3048
3343
|
this.restoreMapState(lostState)
|
|
3049
3344
|
if (this.displayMinimap) {
|
|
3050
|
-
const minimapOptions = { position: 'top-right' }
|
|
3051
|
-
this.mapImp.createMinimap(minimapOptions)
|
|
3345
|
+
const minimapOptions = { position: 'top-right' }
|
|
3346
|
+
this.mapImp.createMinimap(minimapOptions)
|
|
3052
3347
|
this.addResizeButtonToMinimap()
|
|
3053
3348
|
}
|
|
3054
3349
|
if (this.filterToRestore) {
|
|
@@ -3079,23 +3374,23 @@ export default {
|
|
|
3079
3374
|
if (this.mapImp) {
|
|
3080
3375
|
if (term === undefined || term === '') {
|
|
3081
3376
|
this.mapImp.clearSearchResults()
|
|
3082
|
-
if (this.viewingMode ===
|
|
3083
|
-
this.$emit('connectivity-info-close')
|
|
3084
|
-
} else if (this.viewingMode ===
|
|
3377
|
+
if (this.viewingMode === 'Exploration') {
|
|
3378
|
+
this.$emit('connectivity-info-close')
|
|
3379
|
+
} else if (this.viewingMode === 'Annotation') {
|
|
3085
3380
|
this.manualAbortedOnClose()
|
|
3086
3381
|
}
|
|
3087
|
-
this.searchTerm =
|
|
3382
|
+
this.searchTerm = ''
|
|
3088
3383
|
return true
|
|
3089
3384
|
} else {
|
|
3090
3385
|
const searchResults = this.mapImp.search(term)
|
|
3091
3386
|
if (searchResults?.results?.length) {
|
|
3092
3387
|
this.mapImp.showSearchResults(searchResults)
|
|
3093
3388
|
if (displayInfo) {
|
|
3094
|
-
let featureId = undefined
|
|
3389
|
+
let featureId = undefined
|
|
3095
3390
|
for (let i = 0; i < searchResults.results.length; i++) {
|
|
3096
3391
|
featureId = searchResults.results[i].featureId
|
|
3097
3392
|
const annotation = this.mapImp.annotation(featureId)
|
|
3098
|
-
if (featureId && annotation?.label) break
|
|
3393
|
+
if (featureId && annotation?.label) break
|
|
3099
3394
|
}
|
|
3100
3395
|
if (featureId) {
|
|
3101
3396
|
const feature = this.mapImp.featureProperties(featureId)
|
|
@@ -3131,10 +3426,13 @@ export default {
|
|
|
3131
3426
|
highlightConnectedPaths: function (paths) {
|
|
3132
3427
|
if (paths.length) {
|
|
3133
3428
|
// filter paths for this map
|
|
3134
|
-
const filteredPaths = paths.filter(
|
|
3429
|
+
const filteredPaths = paths.filter(
|
|
3430
|
+
(path) => path in this.mapImp.pathways.paths
|
|
3431
|
+
)
|
|
3135
3432
|
// this.zoomToFeatures is replaced with selectGeoJSONFeatures to highlight paths
|
|
3136
|
-
const featureIdsToHighlight =
|
|
3137
|
-
|
|
3433
|
+
const featureIdsToHighlight =
|
|
3434
|
+
this.mapImp.modelFeatureIdList(filteredPaths)
|
|
3435
|
+
this.mapImp.selectGeoJSONFeatures(featureIdsToHighlight)
|
|
3138
3436
|
}
|
|
3139
3437
|
},
|
|
3140
3438
|
/**
|
|
@@ -3151,7 +3449,144 @@ export default {
|
|
|
3151
3449
|
EventBus.emit('onActionClick', data)
|
|
3152
3450
|
},
|
|
3153
3451
|
setConnectionType: function (type) {
|
|
3154
|
-
this.connectionType = type
|
|
3452
|
+
this.connectionType = type
|
|
3453
|
+
},
|
|
3454
|
+
/**
|
|
3455
|
+
* Main function to coordinate fetching dataset info and processing files.
|
|
3456
|
+
*/
|
|
3457
|
+
async fetchFlatmapProtocols(uuid) {
|
|
3458
|
+
const cacheKey = `flatmap_dataset_${uuid}`
|
|
3459
|
+
|
|
3460
|
+
// Try to get from cache first
|
|
3461
|
+
// console.log('------- caching temporary disabled for debugging -------')
|
|
3462
|
+
// const cachedData = null
|
|
3463
|
+
const cachedData = this.getSessionCache(cacheKey)
|
|
3464
|
+
if (cachedData) {
|
|
3465
|
+
this.datasetInfo = cachedData
|
|
3466
|
+
this.processDatasetFiles(cachedData)
|
|
3467
|
+
return
|
|
3468
|
+
}
|
|
3469
|
+
|
|
3470
|
+
// If not in cache, call the API
|
|
3471
|
+
const apiLocation = import.meta.env.VITE_API_LOCATION
|
|
3472
|
+
if (!apiLocation) {
|
|
3473
|
+
console.warn('VITE_API_LOCATION is not defined.')
|
|
3474
|
+
return
|
|
3475
|
+
}
|
|
3476
|
+
|
|
3477
|
+
try {
|
|
3478
|
+
console.log('Fetching dataset info from API...')
|
|
3479
|
+
// Ensure the URL matches your backend route structure
|
|
3480
|
+
const response = await fetch(`${apiLocation}flatmap/uuid?uuid=${uuid}`)
|
|
3481
|
+
|
|
3482
|
+
if (!response.ok)
|
|
3483
|
+
throw new Error(`API call failed: ${response.statusText}`)
|
|
3484
|
+
|
|
3485
|
+
const data = await response.json()
|
|
3486
|
+
|
|
3487
|
+
// Save to cache and process
|
|
3488
|
+
this.setSessionCache(cacheKey, data)
|
|
3489
|
+
this.datasetInfo = data
|
|
3490
|
+
this.processDatasetFiles(data)
|
|
3491
|
+
} catch (error) {
|
|
3492
|
+
console.error('Error fetching flatmap protocols:', error)
|
|
3493
|
+
}
|
|
3494
|
+
},
|
|
3495
|
+
|
|
3496
|
+
/**
|
|
3497
|
+
* Extract the bucket name from an S3 URI.
|
|
3498
|
+
*
|
|
3499
|
+
* @param s3Uri
|
|
3500
|
+
*/
|
|
3501
|
+
extractBucketNameFromS3Uri(s3Uri) {
|
|
3502
|
+
try {
|
|
3503
|
+
// Use the native URL API to parse the s3:// URI
|
|
3504
|
+
// s3://bucket-name/path/to/key -> hostname is bucket-name
|
|
3505
|
+
const url = new URL(s3Uri)
|
|
3506
|
+
return url.hostname
|
|
3507
|
+
} catch (e) {
|
|
3508
|
+
console.error('Error converting S3 URI:', e)
|
|
3509
|
+
return null
|
|
3510
|
+
}
|
|
3511
|
+
},
|
|
3512
|
+
/**
|
|
3513
|
+
* Iterates through the file list, constructs full URLs, and checks for simulation content.
|
|
3514
|
+
*/
|
|
3515
|
+
async processDatasetFiles(data) {
|
|
3516
|
+
if (!data || data.length === 0) return
|
|
3517
|
+
|
|
3518
|
+
this.simulationInfo = [] // Reset list
|
|
3519
|
+
|
|
3520
|
+
//FIXME: Currently only process the first dataset entry
|
|
3521
|
+
const firstData = data[0]
|
|
3522
|
+
const apiLocation = import.meta.env.VITE_API_LOCATION
|
|
3523
|
+
// Base URL for Pennsieve public assets
|
|
3524
|
+
const baseUrl = `${apiLocation}/s3-resource/${firstData.dataset_id}/files`
|
|
3525
|
+
const bucketName = this.extractBucketNameFromS3Uri(firstData.s3uri)
|
|
3526
|
+
|
|
3527
|
+
firstData.urls.map(async (filePath) => {
|
|
3528
|
+
const fullUrl = `${baseUrl}/${filePath}?s3BucketName=${bucketName}`
|
|
3529
|
+
// Add to our list of valid files
|
|
3530
|
+
this.simulationInfo.push({
|
|
3531
|
+
label: firstData.title,
|
|
3532
|
+
s3uri: firstData.s3uri,
|
|
3533
|
+
dataset_id: firstData.dataset_id,
|
|
3534
|
+
version: firstData.version,
|
|
3535
|
+
path: filePath,
|
|
3536
|
+
type: 'Simulation',
|
|
3537
|
+
resource: fullUrl,
|
|
3538
|
+
})
|
|
3539
|
+
})
|
|
3540
|
+
},
|
|
3541
|
+
/**
|
|
3542
|
+
* Retrieve data from session storage if it hasn't expired.
|
|
3543
|
+
*/
|
|
3544
|
+
getSessionCache(key) {
|
|
3545
|
+
const itemStr = sessionStorage.getItem(key)
|
|
3546
|
+
if (!itemStr) return null
|
|
3547
|
+
|
|
3548
|
+
try {
|
|
3549
|
+
const item = JSON.parse(itemStr)
|
|
3550
|
+
const now = new Date()
|
|
3551
|
+
|
|
3552
|
+
// Check if expired (compare current time to expiry time)
|
|
3553
|
+
if (now.getTime() > item.expiry) {
|
|
3554
|
+
sessionStorage.removeItem(key)
|
|
3555
|
+
return null
|
|
3556
|
+
}
|
|
3557
|
+
return item.value
|
|
3558
|
+
} catch (e) {
|
|
3559
|
+
return null
|
|
3560
|
+
}
|
|
3561
|
+
},
|
|
3562
|
+
|
|
3563
|
+
/**
|
|
3564
|
+
* Save data to session storage with a 24-hour expiry.
|
|
3565
|
+
*/
|
|
3566
|
+
setSessionCache(key, value) {
|
|
3567
|
+
const now = new Date()
|
|
3568
|
+
// 24 hours in milliseconds: 24 * 60 * 60 * 1000 = 86400000
|
|
3569
|
+
const ttl = 86400000
|
|
3570
|
+
|
|
3571
|
+
const item = {
|
|
3572
|
+
value: value,
|
|
3573
|
+
expiry: now.getTime() + ttl,
|
|
3574
|
+
}
|
|
3575
|
+
|
|
3576
|
+
try {
|
|
3577
|
+
sessionStorage.setItem(key, JSON.stringify(item))
|
|
3578
|
+
} catch (e) {
|
|
3579
|
+
console.warn('Session storage full or disabled', e)
|
|
3580
|
+
}
|
|
3581
|
+
},
|
|
3582
|
+
getSimulationLabel(info) {
|
|
3583
|
+
console.log(info.path)
|
|
3584
|
+
return info.path.split('/').pop()
|
|
3585
|
+
},
|
|
3586
|
+
openSimulation() {
|
|
3587
|
+
if (this.selectedSimulation) {
|
|
3588
|
+
this.$emit('open-simulation', this.selectedSimulation)
|
|
3589
|
+
}
|
|
3155
3590
|
},
|
|
3156
3591
|
},
|
|
3157
3592
|
props: {
|
|
@@ -3210,7 +3645,7 @@ export default {
|
|
|
3210
3645
|
* On default, `false`, clicking help will show all tooltips.
|
|
3211
3646
|
* If `true`, clicking help will show the help-mode-dialog.
|
|
3212
3647
|
*/
|
|
3213
|
-
|
|
3648
|
+
helpModeDialog: {
|
|
3214
3649
|
type: Boolean,
|
|
3215
3650
|
default: false,
|
|
3216
3651
|
},
|
|
@@ -3344,7 +3779,7 @@ export default {
|
|
|
3344
3779
|
/**
|
|
3345
3780
|
* Flag to disable UIs on Map
|
|
3346
3781
|
*/
|
|
3347
|
-
|
|
3782
|
+
disableUI: {
|
|
3348
3783
|
type: Boolean,
|
|
3349
3784
|
default: false,
|
|
3350
3785
|
},
|
|
@@ -3407,12 +3842,14 @@ export default {
|
|
|
3407
3842
|
flatmapError: null,
|
|
3408
3843
|
sensor: null,
|
|
3409
3844
|
mapManagerRef: undefined,
|
|
3845
|
+
currentFlatmapUuid: undefined,
|
|
3410
3846
|
flatmapQueries: undefined,
|
|
3411
3847
|
annotationEntry: [],
|
|
3412
3848
|
//tooltip display has to be set to false until it is rendered
|
|
3413
|
-
//for the first time, otherwise it may display an arrow at
|
|
3849
|
+
//for the first time, otherwise it may display an arrow at an
|
|
3414
3850
|
//undesired location.
|
|
3415
3851
|
tooltipDisplay: false,
|
|
3852
|
+
tooltipTimer: null,
|
|
3416
3853
|
serverURL: undefined,
|
|
3417
3854
|
layers: [],
|
|
3418
3855
|
pathways: [],
|
|
@@ -3438,12 +3875,13 @@ export default {
|
|
|
3438
3875
|
{ value: false, ref: 'warningPopover' }, // 7
|
|
3439
3876
|
{ value: false, ref: 'whatsNewPopover' }, // 8
|
|
3440
3877
|
{ value: false, ref: 'featuredMarkerPopover' }, // 9
|
|
3441
|
-
{ value: false, refs:
|
|
3442
|
-
{ value: false, refs:
|
|
3443
|
-
{ value: false, refs:
|
|
3444
|
-
{ value: false, refs:
|
|
3445
|
-
{ value: false, refs:
|
|
3446
|
-
{ value: false, refs:
|
|
3878
|
+
{ value: false, refs: 'toolbarPopover', ref: 'editPopover' }, // 10
|
|
3879
|
+
{ value: false, refs: 'toolbarPopover', ref: 'deletePopover' }, // 11
|
|
3880
|
+
{ value: false, refs: 'toolbarPopover', ref: 'pointPopover' }, // 12
|
|
3881
|
+
{ value: false, refs: 'toolbarPopover', ref: 'lineStringPopover' }, // 13
|
|
3882
|
+
{ value: false, refs: 'toolbarPopover', ref: 'polygonPopover' }, // 14
|
|
3883
|
+
{ value: false, refs: 'toolbarPopover', ref: 'connectionPopover' }, // 15
|
|
3884
|
+
{ value: false, ref: 'simulationPopover' }, // 16
|
|
3447
3885
|
],
|
|
3448
3886
|
helpModeActiveIndex: this.helpModeInitialIndex,
|
|
3449
3887
|
yellowstar: yellowstar,
|
|
@@ -3468,9 +3906,14 @@ export default {
|
|
|
3468
3906
|
currentHover: '',
|
|
3469
3907
|
viewingMode: 'Exploration',
|
|
3470
3908
|
viewingModes: {
|
|
3471
|
-
|
|
3472
|
-
|
|
3473
|
-
'
|
|
3909
|
+
Exploration:
|
|
3910
|
+
'Find relevant research and view detail of neural pathways by selecting a pathway to view its connections and data sources',
|
|
3911
|
+
'Neuron Connection':
|
|
3912
|
+
'Discover Neuron connections by selecting a neuron and viewing its associated network connections',
|
|
3913
|
+
Annotation: [
|
|
3914
|
+
'View feature annotations',
|
|
3915
|
+
'Add, comment on and view feature annotations',
|
|
3916
|
+
],
|
|
3474
3917
|
},
|
|
3475
3918
|
connectionType: 'All',
|
|
3476
3919
|
offlineAnnotationEnabled: false,
|
|
@@ -3480,12 +3923,12 @@ export default {
|
|
|
3480
3923
|
openMapRef: undefined,
|
|
3481
3924
|
backgroundIconRef: undefined,
|
|
3482
3925
|
toolbarOptions: [
|
|
3483
|
-
|
|
3484
|
-
|
|
3485
|
-
|
|
3486
|
-
|
|
3487
|
-
|
|
3488
|
-
|
|
3926
|
+
'Edit',
|
|
3927
|
+
'Delete',
|
|
3928
|
+
'Point',
|
|
3929
|
+
'LineString',
|
|
3930
|
+
'Polygon',
|
|
3931
|
+
'Connection',
|
|
3489
3932
|
],
|
|
3490
3933
|
annotator: undefined,
|
|
3491
3934
|
authorisedUser: undefined,
|
|
@@ -3515,13 +3958,17 @@ export default {
|
|
|
3515
3958
|
alert: {
|
|
3516
3959
|
with: true,
|
|
3517
3960
|
without: true,
|
|
3518
|
-
}
|
|
3961
|
+
},
|
|
3519
3962
|
}),
|
|
3520
|
-
searchTerm:
|
|
3963
|
+
searchTerm: '',
|
|
3521
3964
|
taxonLeaveDelay: undefined,
|
|
3522
3965
|
connectivityFilters: [],
|
|
3523
3966
|
flatmapLegends: [],
|
|
3524
3967
|
lastViewport: undefined,
|
|
3968
|
+
simulationInfo: [],
|
|
3969
|
+
datasetInfo: null,
|
|
3970
|
+
simulationDrawerOpen: false,
|
|
3971
|
+
selectedSimulation: null,
|
|
3525
3972
|
}
|
|
3526
3973
|
},
|
|
3527
3974
|
computed: {
|
|
@@ -3529,16 +3976,17 @@ export default {
|
|
|
3529
3976
|
isValidDrawnCreated: function () {
|
|
3530
3977
|
return Object.keys(this.drawnCreatedEvent).length > 0
|
|
3531
3978
|
},
|
|
3532
|
-
requiresDrawer: function() {
|
|
3979
|
+
requiresDrawer: function () {
|
|
3533
3980
|
if (this.loading) {
|
|
3534
3981
|
this.drawerOpen = false
|
|
3535
3982
|
return false
|
|
3536
3983
|
}
|
|
3537
|
-
if (
|
|
3984
|
+
if (
|
|
3985
|
+
this.systems?.length > 0 ||
|
|
3538
3986
|
(this.containsAlert && this.alertOptions) ||
|
|
3539
|
-
|
|
3540
|
-
|
|
3541
|
-
|
|
3987
|
+
this.pathways?.length > 0 ||
|
|
3988
|
+
this.taxonConnectivity?.length > 0 ||
|
|
3989
|
+
this.legendEntry?.length > 0
|
|
3542
3990
|
) {
|
|
3543
3991
|
this.drawerOpen = true
|
|
3544
3992
|
return true
|
|
@@ -3560,7 +4008,7 @@ export default {
|
|
|
3560
4008
|
return [...this.flatmapLegends, ...this.externalLegends]
|
|
3561
4009
|
},
|
|
3562
4010
|
showDatasetMarkerTooltip: function () {
|
|
3563
|
-
return this.hoverVisibilities[9].value
|
|
4011
|
+
return this.hoverVisibilities[9].value
|
|
3564
4012
|
},
|
|
3565
4013
|
},
|
|
3566
4014
|
watch: {
|
|
@@ -3576,11 +4024,11 @@ export default {
|
|
|
3576
4024
|
// just take the action from helpModeActiveItem
|
|
3577
4025
|
// work with local value since the indexing is different
|
|
3578
4026
|
if (this.helpMode) {
|
|
3579
|
-
this.helpModeActiveIndex += 1
|
|
3580
|
-
this.setHelpMode(this.helpMode)
|
|
4027
|
+
this.helpModeActiveIndex += 1
|
|
4028
|
+
this.setHelpMode(this.helpMode)
|
|
3581
4029
|
}
|
|
3582
4030
|
},
|
|
3583
|
-
render: function(val) {
|
|
4031
|
+
render: function (val) {
|
|
3584
4032
|
if (val) {
|
|
3585
4033
|
if (this.mapImp && this.mapImp.contextLost && !this.loading) {
|
|
3586
4034
|
this.$nextTick(() => {
|
|
@@ -3615,7 +4063,7 @@ export default {
|
|
|
3615
4063
|
this.authorisedUser = undefined
|
|
3616
4064
|
this.offlineAnnotationEnabled = true
|
|
3617
4065
|
}
|
|
3618
|
-
this.emitOfflineAnnotationUpdate()
|
|
4066
|
+
this.emitOfflineAnnotationUpdate()
|
|
3619
4067
|
this.setFeatureAnnotated()
|
|
3620
4068
|
this.addAnnotationFeature()
|
|
3621
4069
|
this.loading = false
|
|
@@ -3628,54 +4076,67 @@ export default {
|
|
|
3628
4076
|
}
|
|
3629
4077
|
},
|
|
3630
4078
|
activeDrawTool: function (tool) {
|
|
3631
|
-
let coordinates = []
|
|
3632
|
-
let lastClick = { x: null, y: null }
|
|
3633
|
-
const canvas = this.$el.querySelector('.maplibregl-canvas')
|
|
4079
|
+
let coordinates = []
|
|
4080
|
+
let lastClick = { x: null, y: null }
|
|
4081
|
+
const canvas = this.$el.querySelector('.maplibregl-canvas')
|
|
3634
4082
|
const removeListeners = () => {
|
|
3635
|
-
canvas.removeEventListener('keydown', handleKeyboardEvent)
|
|
3636
|
-
canvas.removeEventListener('click', handleMouseEvent)
|
|
3637
|
-
}
|
|
4083
|
+
canvas.removeEventListener('keydown', handleKeyboardEvent)
|
|
4084
|
+
canvas.removeEventListener('click', handleMouseEvent)
|
|
4085
|
+
}
|
|
3638
4086
|
const handleKeyboardEvent = (event) => {
|
|
3639
|
-
if (!['Escape', 'Enter'].includes(event.key)) return
|
|
4087
|
+
if (!['Escape', 'Enter'].includes(event.key)) return
|
|
3640
4088
|
const isValidDraw =
|
|
3641
4089
|
(tool === 'Point' && coordinates.length === 1) ||
|
|
3642
4090
|
(tool === 'LineString' && coordinates.length >= 2) ||
|
|
3643
|
-
(tool === 'Polygon' && coordinates.length >= 3)
|
|
4091
|
+
(tool === 'Polygon' && coordinates.length >= 3)
|
|
3644
4092
|
if (event.key === 'Escape' || (event.key === 'Enter' && !isValidDraw)) {
|
|
3645
|
-
this.activeDrawTool = undefined
|
|
4093
|
+
this.activeDrawTool = undefined
|
|
3646
4094
|
}
|
|
3647
|
-
removeListeners()
|
|
3648
|
-
}
|
|
4095
|
+
removeListeners()
|
|
4096
|
+
}
|
|
3649
4097
|
const handleMouseEvent = (event) => {
|
|
3650
|
-
const rect = canvas.getBoundingClientRect()
|
|
3651
|
-
const x = event.clientX - rect.left
|
|
3652
|
-
const y = event.clientY - rect.top
|
|
3653
|
-
const distance = Math.sqrt(
|
|
4098
|
+
const rect = canvas.getBoundingClientRect()
|
|
4099
|
+
const x = event.clientX - rect.left
|
|
4100
|
+
const y = event.clientY - rect.top
|
|
4101
|
+
const distance = Math.sqrt(
|
|
4102
|
+
(x - lastClick.x) ** 2 + (y - lastClick.y) ** 2
|
|
4103
|
+
)
|
|
3654
4104
|
if (distance < 8) {
|
|
3655
|
-
if (!this.isValidDrawnCreated) this.activeDrawTool = undefined
|
|
3656
|
-
removeListeners()
|
|
3657
|
-
return
|
|
4105
|
+
if (!this.isValidDrawnCreated) this.activeDrawTool = undefined
|
|
4106
|
+
removeListeners()
|
|
4107
|
+
return
|
|
3658
4108
|
}
|
|
3659
|
-
lastClick = { x, y }
|
|
3660
|
-
coordinates.push(lastClick)
|
|
3661
|
-
}
|
|
4109
|
+
lastClick = { x, y }
|
|
4110
|
+
coordinates.push(lastClick)
|
|
4111
|
+
}
|
|
3662
4112
|
if (tool) {
|
|
3663
|
-
removeListeners()
|
|
3664
|
-
canvas.addEventListener('keydown', handleKeyboardEvent)
|
|
3665
|
-
canvas.addEventListener('click', handleMouseEvent)
|
|
4113
|
+
removeListeners()
|
|
4114
|
+
canvas.addEventListener('keydown', handleKeyboardEvent)
|
|
4115
|
+
canvas.addEventListener('click', handleMouseEvent)
|
|
3666
4116
|
}
|
|
3667
|
-
}
|
|
4117
|
+
},
|
|
4118
|
+
currentFlatmapUuid: {
|
|
4119
|
+
handler(newUuid) {
|
|
4120
|
+
if (newUuid) {
|
|
4121
|
+
// console.log('New map loaded with uuid:', newUuid)
|
|
4122
|
+
this.fetchFlatmapProtocols(newUuid)
|
|
4123
|
+
}
|
|
4124
|
+
},
|
|
4125
|
+
// immediate: true,
|
|
4126
|
+
},
|
|
3668
4127
|
},
|
|
3669
4128
|
created: function () {
|
|
3670
4129
|
if (this.mapManager) {
|
|
3671
|
-
this.mapManagerRef = this.mapManager
|
|
4130
|
+
this.mapManagerRef = this.mapManager
|
|
3672
4131
|
} else {
|
|
3673
|
-
this.mapManagerRef = markRaw(
|
|
4132
|
+
this.mapManagerRef = markRaw(
|
|
4133
|
+
new flatmap.MapViewer(this.flatmapAPI, { container: undefined })
|
|
4134
|
+
)
|
|
3674
4135
|
/**
|
|
3675
4136
|
* The event emitted after a new mapManager is loaded.
|
|
3676
4137
|
* This mapManager can be used to create new flatmaps.
|
|
3677
4138
|
*/
|
|
3678
|
-
this.$emit('mapmanager-loaded', this.mapManagerRef)
|
|
4139
|
+
this.$emit('mapmanager-loaded', this.mapManagerRef)
|
|
3679
4140
|
}
|
|
3680
4141
|
},
|
|
3681
4142
|
mounted: function () {
|
|
@@ -3692,17 +4153,16 @@ export default {
|
|
|
3692
4153
|
} else if (this.renderAtMounted) {
|
|
3693
4154
|
this.createFlatmap()
|
|
3694
4155
|
}
|
|
3695
|
-
refreshFlatmapKnowledgeCache()
|
|
4156
|
+
refreshFlatmapKnowledgeCache()
|
|
3696
4157
|
},
|
|
3697
4158
|
}
|
|
3698
4159
|
</script>
|
|
3699
4160
|
|
|
3700
4161
|
<style lang="scss" scoped>
|
|
3701
|
-
|
|
3702
4162
|
.beta-popovers {
|
|
3703
4163
|
position: absolute;
|
|
3704
|
-
top:
|
|
3705
|
-
left:
|
|
4164
|
+
top: 0px;
|
|
4165
|
+
left: 50%;
|
|
3706
4166
|
text-align: left;
|
|
3707
4167
|
font-size: 25px;
|
|
3708
4168
|
}
|
|
@@ -3758,6 +4218,32 @@ export default {
|
|
|
3758
4218
|
width: 100%;
|
|
3759
4219
|
}
|
|
3760
4220
|
|
|
4221
|
+
.popover-location {
|
|
4222
|
+
position: absolute;
|
|
4223
|
+
left: 0px;
|
|
4224
|
+
transform: translateX(0);
|
|
4225
|
+
transition: all var(--el-transition-duration);
|
|
4226
|
+
z-index: 99;
|
|
4227
|
+
display: flex;
|
|
4228
|
+
flex-direction: row;
|
|
4229
|
+
align-items: center;
|
|
4230
|
+
|
|
4231
|
+
&.open {
|
|
4232
|
+
transform: translateX(0);
|
|
4233
|
+
}
|
|
4234
|
+
&.close {
|
|
4235
|
+
transform: translateX(-100%);
|
|
4236
|
+
}
|
|
4237
|
+
}
|
|
4238
|
+
|
|
4239
|
+
.popover-location.top {
|
|
4240
|
+
top: 5px;
|
|
4241
|
+
}
|
|
4242
|
+
|
|
4243
|
+
.popover-location.bottom {
|
|
4244
|
+
bottom: 0px;
|
|
4245
|
+
}
|
|
4246
|
+
|
|
3761
4247
|
.pathway-location {
|
|
3762
4248
|
position: absolute;
|
|
3763
4249
|
bottom: 0px;
|
|
@@ -4004,7 +4490,7 @@ export default {
|
|
|
4004
4490
|
}
|
|
4005
4491
|
}
|
|
4006
4492
|
|
|
4007
|
-
:deep(.flatmap-marker-popup){
|
|
4493
|
+
:deep(.flatmap-marker-popup) {
|
|
4008
4494
|
.maplibregl-popup-content {
|
|
4009
4495
|
padding: 0px;
|
|
4010
4496
|
}
|
|
@@ -4029,7 +4515,9 @@ export default {
|
|
|
4029
4515
|
}
|
|
4030
4516
|
}
|
|
4031
4517
|
|
|
4032
|
-
.zoomIn,
|
|
4518
|
+
.zoomIn,
|
|
4519
|
+
.zoomOut,
|
|
4520
|
+
.fitWindow {
|
|
4033
4521
|
padding: 4px;
|
|
4034
4522
|
}
|
|
4035
4523
|
|
|
@@ -4144,7 +4632,7 @@ export default {
|
|
|
4144
4632
|
color: $app-primary-color;
|
|
4145
4633
|
|
|
4146
4634
|
&.open-map-button {
|
|
4147
|
-
margin-bottom:4px;
|
|
4635
|
+
margin-bottom: 4px;
|
|
4148
4636
|
}
|
|
4149
4637
|
|
|
4150
4638
|
&:hover {
|
|
@@ -4268,7 +4756,7 @@ export default {
|
|
|
4268
4756
|
position: relative;
|
|
4269
4757
|
|
|
4270
4758
|
&::before {
|
|
4271
|
-
content:
|
|
4759
|
+
content: '';
|
|
4272
4760
|
display: block;
|
|
4273
4761
|
width: 0;
|
|
4274
4762
|
height: 0;
|
|
@@ -4397,7 +4885,7 @@ export default {
|
|
|
4397
4885
|
background-color: var(--white);
|
|
4398
4886
|
font-weight: 500;
|
|
4399
4887
|
color: rgb(48, 49, 51);
|
|
4400
|
-
width: 150px!important;
|
|
4888
|
+
width: 150px !important;
|
|
4401
4889
|
}
|
|
4402
4890
|
|
|
4403
4891
|
:deep(.flatmap_dropdown) {
|
|
@@ -4421,11 +4909,10 @@ export default {
|
|
|
4421
4909
|
</style>
|
|
4422
4910
|
|
|
4423
4911
|
<style lang="scss">
|
|
4424
|
-
|
|
4425
4912
|
.flatmap-container {
|
|
4426
|
-
--el-color-primary: #
|
|
4427
|
-
--el-color-primary-light-5: #
|
|
4428
|
-
--el-color-primary-light-9: #
|
|
4913
|
+
--el-color-primary: #8300bf;
|
|
4914
|
+
--el-color-primary-light-5: #cd99e5;
|
|
4915
|
+
--el-color-primary-light-9: #f3e6f9;
|
|
4429
4916
|
--el-color-primary-dark-2: var(--el-color-primary);
|
|
4430
4917
|
}
|
|
4431
4918
|
|
|
@@ -4448,5 +4935,4 @@ export default {
|
|
|
4448
4935
|
}
|
|
4449
4936
|
}
|
|
4450
4937
|
}
|
|
4451
|
-
|
|
4452
4938
|
</style>
|