@abi-software/flatmapvuer 0.4.2 → 0.4.4

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.
@@ -1,509 +1,509 @@
1
- <template>
2
- <div class="multi-container" ref="multiContainer">
3
- <div style="position:absolute;z-index:10;">
4
- <div class="species-display-text">
5
- Species
6
- </div>
7
- <el-popover content="Select a species" placement="right"
8
- :appendToBody=false trigger="manual" popper-class="flatmap-popper right-popper" v-model="helpMode" ref="selectPopover">
9
- </el-popover>
10
- <el-select
11
- id="flatmap-select"
12
- :popper-append-to-body="appendToBody"
13
- v-model="activeSpecies"
14
- placeholder="Select"
15
- class="select-box"
16
- popper-class="flatmap_dropdown"
17
- @change="setSpecies"
18
- v-popover:selectPopover
19
- >
20
- <el-option v-for="(item, key) in speciesList" :key="key" :label="key" :value="key">
21
- <el-row>
22
- <el-col :span="8"><i :class="item.iconClass"></i></el-col>
23
- <el-col :span="12">{{ key }}</el-col>
24
- </el-row>
25
- </el-option>
26
- </el-select>
27
- </div>
28
- <FlatmapVuer
29
- v-for="(item, key) in speciesList"
30
- :key="key"
31
- :showLayer="showLayer"
32
- v-show="activeSpecies==key"
33
- :entry="item.taxo"
34
- :biologicalSex="item.biologicalSex"
35
- :displayWarning="item.displayWarning"
36
- :displayLatestChanges="item.displayLatestChanges"
37
- :latestChangesMessage="item.latestChangesMessage"
38
- :isLegacy="item.isLegacy"
39
- :ref="key"
40
- @view-latest-map="viewLatestMap"
41
- @resource-selected="FlatmapSelected"
42
- @ready="FlatmapReady"
43
- @pan-zoom-callback="panZoomCallback"
44
- :featureInfo="featureInfo"
45
- :minZoom="minZoom"
46
- :pathControls="pathControls"
47
- :searchable="searchable"
48
- :layerControl="layerControl"
49
- :helpMode="helpMode"
50
- :renderAtMounted="renderAtMounted"
51
- :displayMinimap="displayMinimap"
52
- style="height:100%"
53
- :flatmapAPI="flatmapAPI"
54
- :sparcAPI="sparcAPI"
55
- />
56
- </div>
57
- </template>
58
-
59
-
60
- <script>
61
- /* eslint-disable no-alert, no-console */
62
- import EventBus from './EventBus'
63
- import Vue from "vue";
64
- import FlatmapVuer from "./FlatmapVuer.vue";
65
- import { Col, Option, Select, Row, Popover } from "element-ui";
66
- import lang from "element-ui/lib/locale/lang/en";
67
- import locale from "element-ui/lib/locale";
68
- locale.use(lang);
69
- Vue.use(Col);
70
- Vue.use(Row);
71
- Vue.use(Option);
72
- Vue.use(Select);
73
- Vue.use(Popover)
74
-
75
- const TAXON_UUID = {
76
- "NCBITaxon:10114": "01fedbf9-d783-509c-a10c-827941ab13da",
77
- "NCBITaxon:9823": "a336ac04-24db-561f-a25f-1c994fe17410",
78
- "NCBITaxon:9606": "42ed6323-f645-5fbe-bada-9581819cf689",
79
- "NCBITaxon:10090": "25285fab-48a0-5620-a6a0-f9a0374837d5",
80
- "NCBITaxon:9685": "73060497-46a6-52bf-b975-cac511c127cb"
81
- }
82
-
83
- export default {
84
- name: "MultiFlatmapVuer",
85
- components: {
86
- FlatmapVuer
87
- },
88
- beforeMount() {
89
- //List for resolving the promise in initialise
90
- //if initialise is called multiple times
91
- this._resolveList = [];
92
- this._initialised = false;
93
- },
94
- mounted: function() {
95
- this.initialise();
96
- EventBus.$on('onActionClick', (action) =>{
97
- this.FlatmapSelected(action)
98
- })
99
- },
100
- methods: {
101
- initialise: function() {
102
- return new Promise(resolve => {
103
- if (this.requireInitialisation) {
104
- //It has not been initialised yet
105
- this.requireInitialisation = false;
106
- fetch(this.flatmapAPI)
107
- .then(response => response.json())
108
- .then(data => {
109
- //Check each key in the provided availableSpecies against the one
110
- //on the server, add them to the Select if the key is found
111
- Object.keys(this.availableSpecies).forEach(key => {
112
- for (let i = 0; i < data.length; i++) {
113
- if (this.availableSpecies[key].taxo === data[i].taxon) {
114
- if (this.availableSpecies[key].biologicalSex) {
115
- if (data[i].biologicalSex &&
116
- data[i].biologicalSex === this.availableSpecies[key].biologicalSex) {
117
- this.$set(this.speciesList, key, this.availableSpecies[key]);
118
- break;
119
- }
120
- } else {
121
- this.$set(this.speciesList, key, this.availableSpecies[key]);
122
- break;
123
- }
124
- }
125
- }
126
- });
127
- //Use the state species if it does not have any other species information
128
- let species = this.initial;
129
- if (this.state) {
130
- const mapState = this.state.state;
131
- if ((!mapState || ( !mapState.uuid && !mapState.entry )) && this.state.species)
132
- species = this.state.species;
133
- else
134
- species = undefined;
135
- }
136
- if (species) {
137
- //No state resuming, set the current flatmap to {this.initial}
138
- if (species && this.speciesList[species] !== undefined) {
139
- this.activeSpecies = species;
140
- } else {
141
- this.activeSpecies = Object.keys(this.speciesList)[0];
142
- }
143
- this.setSpecies(this.activeSpecies, this.state ? this.state.state : undefined, 5);
144
- }
145
- this._initialised = true;
146
- resolve();
147
- //Resolve all other promises resolve in the list
148
- this._resolveList.forEach(other => { other(); });
149
- });
150
- } else if (this._initialised) {
151
- //resolve as it has been initialised
152
- resolve();
153
- } else {
154
- //resolve when the async initialisation is finished
155
- this._resolveList.push(resolve);
156
- }
157
- })
158
- },
159
- FlatmapSelected: function(resource) {
160
- this.$emit("resource-selected", resource);
161
- },
162
- FlatmapReady: function(component) {
163
- this.$emit("ready", component);
164
- },
165
- getCoordinatesOfLastClick: function() {
166
- const flatmap = this.$refs[this.activeSpecies];
167
- if (flatmap && flatmap[0]) {
168
- return flatmap[0].getCoordinatesOfLastClick();
169
- }
170
- return undefined;
171
- },
172
- getCurrentFlatmap: function() {
173
- return this.$refs[this.activeSpecies][0];
174
- },
175
- panZoomCallback: function(payload) {
176
- this.$emit("pan-zoom-callback", payload);
177
- },
178
- showPopup: function(featureId, node, options) {
179
- let map = this.getCurrentFlatmap();
180
- map.showPopup(featureId, node, options);
181
- },
182
- showMarkerPopup: function(featureId, node, options) {
183
- let map = this.getCurrentFlatmap();
184
- map.showMarkerPopup(featureId, node, options);
185
- },
186
- setSpecies: function(species, state, numberOfRetry) {
187
- if (this.$refs && species in this.$refs) {
188
- this.activeSpecies = species;
189
- this.$refs[this.activeSpecies][0].createFlatmap(state);
190
- this.$emit('flatmapChanged', this.activeSpecies);
191
- } else if (numberOfRetry) {
192
- const retry = numberOfRetry - 1;
193
- if (retry >= 0) {
194
- Vue.nextTick(() => {
195
- this.setSpecies(species, state, retry);
196
- });
197
- }
198
- }
199
- },
200
- /**
201
- * Function to switch to the latest existing map from
202
- * a legacy map of the same species.
203
- *
204
- * @private
205
- */
206
- viewLatestMap: function(state) {
207
- const keys = Object.keys(this.speciesList);
208
- for (let i = 0; i < keys.length; i++) {
209
- const species = this.speciesList[keys[i]];
210
- if (!species.isLegacy &&
211
- (species.taxo === state.entry) &&
212
- (species.biologicalSex === state.biologicalSex)) {
213
- this.setSpecies(keys[i], state, 0);
214
- return;
215
- }
216
- }
217
- },
218
- /**
219
- * Create a legacy entry with the provided information
220
- *
221
- * @private
222
- */
223
- createLegacyEntry: function(state, taxo, uuid) {
224
- if (uuid && taxo) {
225
- let name = "Legacy";
226
- if (state.species) {
227
- if (state.species.slice(0, 6) === "Legacy")
228
- name = state.species;
229
- else
230
- name = name + ` ${state.species}`;
231
- }
232
- this.$set(
233
- this.speciesList,
234
- name,
235
- {
236
- taxo: taxo,
237
- isLegacy: true,
238
- displayWarning: true
239
- }
240
- );
241
- return {
242
- species: name,
243
- state: {
244
- entry: taxo,
245
- uuid: uuid,
246
- viewport: state.state.viewport,
247
- searchTerm: state.state.searchTerm
248
- },
249
- }
250
- }
251
- },
252
- /**
253
- * Function used to translate the legacy map state to one that can be used in current
254
- * flatmap if required. If it is a legacy, an Select entry will be added
255
- *
256
- * @private
257
- */
258
- updateState: function(state) {
259
- return new Promise((resolve) => {
260
- if (state && state.state) {
261
- const mapState = state.state;
262
- //uuid is not in the state, this is a legacy map
263
- if (!mapState.uuid) {
264
- if (mapState.entry) {
265
- const uuid = mapState.entry in TAXON_UUID ? TAXON_UUID[mapState.entry] : undefined;
266
- const newState = this.createLegacyEntry(state, mapState.entry, uuid);
267
- resolve(newState ? newState : state);
268
- }
269
- } else if (mapState.entry) {
270
- //uuid is in the state but should be checked if it is the latest map
271
- //for that taxon
272
- return new Promise(() => {
273
- const mapManager = new (require("@abi-software/flatmap-viewer")).MapManager(this.flatmapAPI);
274
- //mapManager.findMap_ is an async function so we need to wrap this with a promise
275
- const identifier = { taxon: mapState.entry };
276
- if (mapState.biologicalSex)
277
- identifier['biologicalSex'] = mapState.biologicalSex;
278
- mapManager.findMap_(identifier).then(map => {
279
- if (map.uuid !== mapState.uuid) {
280
- return this.createLegacyEntry(state, mapState.entry, mapState.uuid);
281
- }
282
- }).then(newState => {
283
- resolve(newState ? newState : state);
284
- })
285
- .catch(() => {
286
- resolve(state);
287
- });
288
- });
289
- }
290
- //Create a new state and add the legacy map to the select
291
- }
292
- resolve(state);
293
- });
294
- },
295
- /**
296
- * Function used for getting the current states of the scene. This exported states
297
- * can be imported using the importStates method.
298
- *
299
- * @public
300
- */
301
- getState: function() {
302
- let state = {
303
- species: this.activeSpecies,
304
- state: undefined,
305
- };
306
- let map = this.getCurrentFlatmap();
307
- state.state = map.getState();
308
- return state;
309
- },
310
- /**
311
- * Function used for importing the states of the scene. This exported states
312
- * can be imported using the read states method.
313
- *
314
- * @public
315
- */
316
- setState: function(state) {
317
- if (state) {
318
- //Update state if required
319
- this.updateState(state).then(currentState => {
320
- this.initialise().then(() => {
321
- if (currentState.species && (currentState.species !== this.activeSpecies)) {
322
- this.setSpecies(currentState.species, currentState.state, 5);
323
- } else if (currentState.state) {
324
- let map = this.getCurrentFlatmap();
325
- map.setState(currentState.state);
326
- }
327
- });
328
- });
329
- }
330
- },
331
- resourceSelected: function(action) {
332
- this.$emit("resource-selected", action);
333
- },
334
- },
335
- props: {
336
- showLayer: {
337
- type: Boolean,
338
- default: false
339
- },
340
- featureInfo: {
341
- type: Boolean,
342
- default: false
343
- },
344
- pathControls: {
345
- type: Boolean,
346
- default: true
347
- },
348
- searchable: {
349
- type: Boolean,
350
- default: false
351
- },
352
- layerControl: {
353
- type: Boolean,
354
- default: false
355
- },
356
- /**
357
- * Initial species for the flatmap.
358
- * This value will be ignored if a valid state object is provided.
359
- */
360
- initial: {
361
- type: String,
362
- default: ""
363
- },
364
- minZoom: {
365
- type: Number,
366
- default: 4
367
- },
368
- renderAtMounted: {
369
- type: Boolean,
370
- default: false
371
- },
372
- helpMode: {
373
- type: Boolean,
374
- default: false
375
- },
376
- displayMinimap: {
377
- type: Boolean,
378
- default: false
379
- },
380
- availableSpecies: {
381
- type: Object,
382
- default: function() {
383
- return {
384
- "Human Female":{taxo: "NCBITaxon:9606", biologicalSex: "PATO:0000383", iconClass:"mapicon-icon_human", displayWarning:true},
385
- "Human Male":{taxo: "NCBITaxon:9606", biologicalSex: "PATO:0000384", iconClass:"mapicon-icon_human", displayWarning:true},
386
- "Rat":{taxo: "NCBITaxon:10114", iconClass:"mapicon-icon_rat", displayLatestChanges: true},
387
- "Mouse":{taxo: "NCBITaxon:10090", iconClass:"mapicon-icon_mouse", displayWarning: true},
388
- "Pig":{taxo: "NCBITaxon:9823", iconClass:"mapicon-icon_pig", displayWarning: true},
389
- "Cat":{taxo: "NCBITaxon:9685", iconClass:"mapicon-icon_cat", displayWarning: true},
390
- }
391
- }
392
- },
393
- /**
394
- * State containing state of the flatmap.
395
- */
396
- state: {
397
- type: Object,
398
- default: undefined,
399
- },
400
- /**
401
- * Specify the endpoint of the flatmap server.
402
- */
403
- flatmapAPI: {
404
- type: String,
405
- default: "https://mapcore-demo.org/current/flatmap/v3/"
406
- },
407
- sparcAPI: {
408
- type: String,
409
- default: "https://api.sparc.science/"
410
- }
411
- },
412
- data: function() {
413
- return {
414
- activeSpecies: undefined,
415
- appendToBody: false,
416
- speciesList: {},
417
- requireInitialisation: true
418
- };
419
- },
420
- watch: {
421
- state: {
422
- handler: function(state) {
423
- this.setState(state);
424
- },
425
- immediate: true,
426
- deep: true,
427
- }
428
- }
429
- };
430
- </script>
431
-
432
- <style scoped lang="scss">
433
- @import "~element-ui/packages/theme-chalk/src/select";
434
- @import "~element-ui/packages/theme-chalk/src/option";
435
-
436
- .multi-container {
437
- height: 100%;
438
- width: 100%;
439
- }
440
-
441
- .species-display-text {
442
- width: 47px;
443
- height: 20px;
444
- color: rgb(48, 49, 51);
445
- font-size: 14px;
446
- font-weight: normal;
447
- line-height: 20px;
448
- left:24px;
449
- top:16px;
450
- position: absolute;
451
- }
452
-
453
- .select-box {
454
- width: 120px;
455
- border-radius: 4px;
456
- border: 1px solid rgb(144, 147, 153);
457
- background-color: var(--white);
458
- font-weight: 500;
459
- color:rgb(48, 49, 51);;
460
- left: 16px;
461
- top: 44px;
462
- position: absolute;
463
- ::v-deep .el-input__inner {
464
- color: rgb(48, 49, 51);
465
- padding-top: 0.25em;
466
- .is-focus {
467
- border: 1px solid $app-primary-color;
468
- }
469
- }
470
- }
471
-
472
-
473
- ::v-deep .flatmap_dropdown {
474
- min-width: 160px!important;
475
- .el-select-dropdown__item {
476
- white-space: nowrap;
477
- text-align: left;
478
- &.selected {
479
- color: $app-primary-color;
480
- font-weight: normal;
481
- }
482
- }
483
- }
484
-
485
- ::v-deep .flatmap-popper {
486
- padding: 6px 4px;
487
- font-size:12px;
488
- color: rgb(48, 49, 51);
489
- background-color: #f3ecf6;
490
- border: 1px solid $app-primary-color;
491
- white-space: nowrap;
492
- min-width: unset;
493
- &.right-popper {
494
- .popper__arrow {
495
- border-right-color: $app-primary-color !important;
496
- &:after {
497
- border-right-color: #f3ecf6 !important;
498
- }
499
- }
500
- }
501
- }
502
-
503
- ::v-deep .flatmap-marker-popup{
504
- background-color: #f0f0f000 !important;
505
- box-shadow: none !important;
506
- }
507
-
508
- </style>
509
-
1
+ <template>
2
+ <div class="multi-container" ref="multiContainer">
3
+ <div style="position:absolute;z-index:10;">
4
+ <div class="species-display-text">
5
+ Species
6
+ </div>
7
+ <el-popover content="Select a species" placement="right"
8
+ :appendToBody=false trigger="manual" popper-class="flatmap-popper right-popper" v-model="helpMode" ref="selectPopover">
9
+ </el-popover>
10
+ <el-select
11
+ id="flatmap-select"
12
+ :popper-append-to-body="appendToBody"
13
+ v-model="activeSpecies"
14
+ placeholder="Select"
15
+ class="select-box"
16
+ popper-class="flatmap_dropdown"
17
+ @change="setSpecies"
18
+ v-popover:selectPopover
19
+ >
20
+ <el-option v-for="(item, key) in speciesList" :key="key" :label="key" :value="key">
21
+ <el-row>
22
+ <el-col :span="8"><i :class="item.iconClass"></i></el-col>
23
+ <el-col :span="12">{{ key }}</el-col>
24
+ </el-row>
25
+ </el-option>
26
+ </el-select>
27
+ </div>
28
+ <FlatmapVuer
29
+ v-for="(item, key) in speciesList"
30
+ :key="key"
31
+ :showLayer="showLayer"
32
+ v-show="activeSpecies==key"
33
+ :entry="item.taxo"
34
+ :biologicalSex="item.biologicalSex"
35
+ :displayWarning="item.displayWarning"
36
+ :displayLatestChanges="item.displayLatestChanges"
37
+ :latestChangesMessage="item.latestChangesMessage"
38
+ :isLegacy="item.isLegacy"
39
+ :ref="key"
40
+ @view-latest-map="viewLatestMap"
41
+ @resource-selected="FlatmapSelected"
42
+ @ready="FlatmapReady"
43
+ @pan-zoom-callback="panZoomCallback"
44
+ :featureInfo="featureInfo"
45
+ :minZoom="minZoom"
46
+ :pathControls="pathControls"
47
+ :searchable="searchable"
48
+ :layerControl="layerControl"
49
+ :helpMode="helpMode"
50
+ :renderAtMounted="renderAtMounted"
51
+ :displayMinimap="displayMinimap"
52
+ style="height:100%"
53
+ :flatmapAPI="flatmapAPI"
54
+ :sparcAPI="sparcAPI"
55
+ />
56
+ </div>
57
+ </template>
58
+
59
+
60
+ <script>
61
+ /* eslint-disable no-alert, no-console */
62
+ import EventBus from './EventBus'
63
+ import Vue from "vue";
64
+ import FlatmapVuer from "./FlatmapVuer.vue";
65
+ import { Col, Option, Select, Row, Popover } from "element-ui";
66
+ import lang from "element-ui/lib/locale/lang/en";
67
+ import locale from "element-ui/lib/locale";
68
+ locale.use(lang);
69
+ Vue.use(Col);
70
+ Vue.use(Row);
71
+ Vue.use(Option);
72
+ Vue.use(Select);
73
+ Vue.use(Popover)
74
+
75
+ const TAXON_UUID = {
76
+ "NCBITaxon:10114": "01fedbf9-d783-509c-a10c-827941ab13da",
77
+ "NCBITaxon:9823": "a336ac04-24db-561f-a25f-1c994fe17410",
78
+ "NCBITaxon:9606": "42ed6323-f645-5fbe-bada-9581819cf689",
79
+ "NCBITaxon:10090": "25285fab-48a0-5620-a6a0-f9a0374837d5",
80
+ "NCBITaxon:9685": "73060497-46a6-52bf-b975-cac511c127cb"
81
+ }
82
+
83
+ export default {
84
+ name: "MultiFlatmapVuer",
85
+ components: {
86
+ FlatmapVuer
87
+ },
88
+ beforeMount() {
89
+ //List for resolving the promise in initialise
90
+ //if initialise is called multiple times
91
+ this._resolveList = [];
92
+ this._initialised = false;
93
+ },
94
+ mounted: function() {
95
+ this.initialise();
96
+ EventBus.$on('onActionClick', (action) =>{
97
+ this.FlatmapSelected(action)
98
+ })
99
+ },
100
+ methods: {
101
+ initialise: function() {
102
+ return new Promise(resolve => {
103
+ if (this.requireInitialisation) {
104
+ //It has not been initialised yet
105
+ this.requireInitialisation = false;
106
+ fetch(this.flatmapAPI)
107
+ .then(response => response.json())
108
+ .then(data => {
109
+ //Check each key in the provided availableSpecies against the one
110
+ //on the server, add them to the Select if the key is found
111
+ Object.keys(this.availableSpecies).forEach(key => {
112
+ for (let i = 0; i < data.length; i++) {
113
+ if (this.availableSpecies[key].taxo === data[i].taxon) {
114
+ if (this.availableSpecies[key].biologicalSex) {
115
+ if (data[i].biologicalSex &&
116
+ data[i].biologicalSex === this.availableSpecies[key].biologicalSex) {
117
+ this.$set(this.speciesList, key, this.availableSpecies[key]);
118
+ break;
119
+ }
120
+ } else {
121
+ this.$set(this.speciesList, key, this.availableSpecies[key]);
122
+ break;
123
+ }
124
+ }
125
+ }
126
+ });
127
+ //Use the state species if it does not have any other species information
128
+ let species = this.initial;
129
+ if (this.state) {
130
+ const mapState = this.state.state;
131
+ if ((!mapState || ( !mapState.uuid && !mapState.entry )) && this.state.species)
132
+ species = this.state.species;
133
+ else
134
+ species = undefined;
135
+ }
136
+ if (species) {
137
+ //No state resuming, set the current flatmap to {this.initial}
138
+ if (species && this.speciesList[species] !== undefined) {
139
+ this.activeSpecies = species;
140
+ } else {
141
+ this.activeSpecies = Object.keys(this.speciesList)[0];
142
+ }
143
+ this.setSpecies(this.activeSpecies, this.state ? this.state.state : undefined, 5);
144
+ }
145
+ this._initialised = true;
146
+ resolve();
147
+ //Resolve all other promises resolve in the list
148
+ this._resolveList.forEach(other => { other(); });
149
+ });
150
+ } else if (this._initialised) {
151
+ //resolve as it has been initialised
152
+ resolve();
153
+ } else {
154
+ //resolve when the async initialisation is finished
155
+ this._resolveList.push(resolve);
156
+ }
157
+ })
158
+ },
159
+ FlatmapSelected: function(resource) {
160
+ this.$emit("resource-selected", resource);
161
+ },
162
+ FlatmapReady: function(component) {
163
+ this.$emit("ready", component);
164
+ },
165
+ getCoordinatesOfLastClick: function() {
166
+ const flatmap = this.$refs[this.activeSpecies];
167
+ if (flatmap && flatmap[0]) {
168
+ return flatmap[0].getCoordinatesOfLastClick();
169
+ }
170
+ return undefined;
171
+ },
172
+ getCurrentFlatmap: function() {
173
+ return this.$refs[this.activeSpecies][0];
174
+ },
175
+ panZoomCallback: function(payload) {
176
+ this.$emit("pan-zoom-callback", payload);
177
+ },
178
+ showPopup: function(featureId, node, options) {
179
+ let map = this.getCurrentFlatmap();
180
+ map.showPopup(featureId, node, options);
181
+ },
182
+ showMarkerPopup: function(featureId, node, options) {
183
+ let map = this.getCurrentFlatmap();
184
+ map.showMarkerPopup(featureId, node, options);
185
+ },
186
+ setSpecies: function(species, state, numberOfRetry) {
187
+ if (this.$refs && species in this.$refs) {
188
+ this.activeSpecies = species;
189
+ this.$refs[this.activeSpecies][0].createFlatmap(state);
190
+ this.$emit('flatmapChanged', this.activeSpecies);
191
+ } else if (numberOfRetry) {
192
+ const retry = numberOfRetry - 1;
193
+ if (retry >= 0) {
194
+ Vue.nextTick(() => {
195
+ this.setSpecies(species, state, retry);
196
+ });
197
+ }
198
+ }
199
+ },
200
+ /**
201
+ * Function to switch to the latest existing map from
202
+ * a legacy map of the same species.
203
+ *
204
+ * @private
205
+ */
206
+ viewLatestMap: function(state) {
207
+ const keys = Object.keys(this.speciesList);
208
+ for (let i = 0; i < keys.length; i++) {
209
+ const species = this.speciesList[keys[i]];
210
+ if (!species.isLegacy &&
211
+ (species.taxo === state.entry) &&
212
+ (species.biologicalSex === state.biologicalSex)) {
213
+ this.setSpecies(keys[i], state, 0);
214
+ return;
215
+ }
216
+ }
217
+ },
218
+ /**
219
+ * Create a legacy entry with the provided information
220
+ *
221
+ * @private
222
+ */
223
+ createLegacyEntry: function(state, taxo, uuid) {
224
+ if (uuid && taxo) {
225
+ let name = "Legacy";
226
+ if (state.species) {
227
+ if (state.species.slice(0, 6) === "Legacy")
228
+ name = state.species;
229
+ else
230
+ name = name + ` ${state.species}`;
231
+ }
232
+ this.$set(
233
+ this.speciesList,
234
+ name,
235
+ {
236
+ taxo: taxo,
237
+ isLegacy: true,
238
+ displayWarning: true
239
+ }
240
+ );
241
+ return {
242
+ species: name,
243
+ state: {
244
+ entry: taxo,
245
+ uuid: uuid,
246
+ viewport: state.state.viewport,
247
+ searchTerm: state.state.searchTerm
248
+ },
249
+ }
250
+ }
251
+ },
252
+ /**
253
+ * Function used to translate the legacy map state to one that can be used in current
254
+ * flatmap if required. If it is a legacy, an Select entry will be added
255
+ *
256
+ * @private
257
+ */
258
+ updateState: function(state) {
259
+ return new Promise((resolve) => {
260
+ if (state && state.state) {
261
+ const mapState = state.state;
262
+ //uuid is not in the state, this is a legacy map
263
+ if (!mapState.uuid) {
264
+ if (mapState.entry) {
265
+ const uuid = mapState.entry in TAXON_UUID ? TAXON_UUID[mapState.entry] : undefined;
266
+ const newState = this.createLegacyEntry(state, mapState.entry, uuid);
267
+ resolve(newState ? newState : state);
268
+ }
269
+ } else if (mapState.entry) {
270
+ //uuid is in the state but should be checked if it is the latest map
271
+ //for that taxon
272
+ return new Promise(() => {
273
+ const mapManager = new (require("@abi-software/flatmap-viewer")).MapManager(this.flatmapAPI);
274
+ //mapManager.findMap_ is an async function so we need to wrap this with a promise
275
+ const identifier = { taxon: mapState.entry };
276
+ if (mapState.biologicalSex)
277
+ identifier['biologicalSex'] = mapState.biologicalSex;
278
+ mapManager.findMap_(identifier).then(map => {
279
+ if (map.uuid !== mapState.uuid) {
280
+ return this.createLegacyEntry(state, mapState.entry, mapState.uuid);
281
+ }
282
+ }).then(newState => {
283
+ resolve(newState ? newState : state);
284
+ })
285
+ .catch(() => {
286
+ resolve(state);
287
+ });
288
+ });
289
+ }
290
+ //Create a new state and add the legacy map to the select
291
+ }
292
+ resolve(state);
293
+ });
294
+ },
295
+ /**
296
+ * Function used for getting the current states of the scene. This exported states
297
+ * can be imported using the importStates method.
298
+ *
299
+ * @public
300
+ */
301
+ getState: function() {
302
+ let state = {
303
+ species: this.activeSpecies,
304
+ state: undefined,
305
+ };
306
+ let map = this.getCurrentFlatmap();
307
+ state.state = map.getState();
308
+ return state;
309
+ },
310
+ /**
311
+ * Function used for importing the states of the scene. This exported states
312
+ * can be imported using the read states method.
313
+ *
314
+ * @public
315
+ */
316
+ setState: function(state) {
317
+ if (state) {
318
+ //Update state if required
319
+ this.updateState(state).then(currentState => {
320
+ this.initialise().then(() => {
321
+ if (currentState.species && (currentState.species !== this.activeSpecies)) {
322
+ this.setSpecies(currentState.species, currentState.state, 5);
323
+ } else if (currentState.state) {
324
+ let map = this.getCurrentFlatmap();
325
+ map.setState(currentState.state);
326
+ }
327
+ });
328
+ });
329
+ }
330
+ },
331
+ resourceSelected: function(action) {
332
+ this.$emit("resource-selected", action);
333
+ },
334
+ },
335
+ props: {
336
+ showLayer: {
337
+ type: Boolean,
338
+ default: false
339
+ },
340
+ featureInfo: {
341
+ type: Boolean,
342
+ default: false
343
+ },
344
+ pathControls: {
345
+ type: Boolean,
346
+ default: true
347
+ },
348
+ searchable: {
349
+ type: Boolean,
350
+ default: false
351
+ },
352
+ layerControl: {
353
+ type: Boolean,
354
+ default: false
355
+ },
356
+ /**
357
+ * Initial species for the flatmap.
358
+ * This value will be ignored if a valid state object is provided.
359
+ */
360
+ initial: {
361
+ type: String,
362
+ default: ""
363
+ },
364
+ minZoom: {
365
+ type: Number,
366
+ default: 4
367
+ },
368
+ renderAtMounted: {
369
+ type: Boolean,
370
+ default: false
371
+ },
372
+ helpMode: {
373
+ type: Boolean,
374
+ default: false
375
+ },
376
+ displayMinimap: {
377
+ type: Boolean,
378
+ default: false
379
+ },
380
+ availableSpecies: {
381
+ type: Object,
382
+ default: function() {
383
+ return {
384
+ "Human Female":{taxo: "NCBITaxon:9606", biologicalSex: "PATO:0000383", iconClass:"mapicon-icon_human", displayWarning:true},
385
+ "Human Male":{taxo: "NCBITaxon:9606", biologicalSex: "PATO:0000384", iconClass:"mapicon-icon_human", displayWarning:true},
386
+ "Rat":{taxo: "NCBITaxon:10114", iconClass:"mapicon-icon_rat", displayLatestChanges: true},
387
+ "Mouse":{taxo: "NCBITaxon:10090", iconClass:"mapicon-icon_mouse", displayWarning: true},
388
+ "Pig":{taxo: "NCBITaxon:9823", iconClass:"mapicon-icon_pig", displayWarning: true},
389
+ "Cat":{taxo: "NCBITaxon:9685", iconClass:"mapicon-icon_cat", displayWarning: true},
390
+ }
391
+ }
392
+ },
393
+ /**
394
+ * State containing state of the flatmap.
395
+ */
396
+ state: {
397
+ type: Object,
398
+ default: undefined,
399
+ },
400
+ /**
401
+ * Specify the endpoint of the flatmap server.
402
+ */
403
+ flatmapAPI: {
404
+ type: String,
405
+ default: "https://mapcore-demo.org/current/flatmap/v3/"
406
+ },
407
+ sparcAPI: {
408
+ type: String,
409
+ default: "https://api.sparc.science/"
410
+ }
411
+ },
412
+ data: function() {
413
+ return {
414
+ activeSpecies: undefined,
415
+ appendToBody: false,
416
+ speciesList: {},
417
+ requireInitialisation: true
418
+ };
419
+ },
420
+ watch: {
421
+ state: {
422
+ handler: function(state) {
423
+ this.setState(state);
424
+ },
425
+ immediate: true,
426
+ deep: true,
427
+ }
428
+ }
429
+ };
430
+ </script>
431
+
432
+ <style scoped lang="scss">
433
+ @import "~element-ui/packages/theme-chalk/src/select";
434
+ @import "~element-ui/packages/theme-chalk/src/option";
435
+
436
+ .multi-container {
437
+ height: 100%;
438
+ width: 100%;
439
+ }
440
+
441
+ .species-display-text {
442
+ width: 47px;
443
+ height: 20px;
444
+ color: rgb(48, 49, 51);
445
+ font-size: 14px;
446
+ font-weight: normal;
447
+ line-height: 20px;
448
+ left:24px;
449
+ top:16px;
450
+ position: absolute;
451
+ }
452
+
453
+ .select-box {
454
+ width: 120px;
455
+ border-radius: 4px;
456
+ border: 1px solid rgb(144, 147, 153);
457
+ background-color: var(--white);
458
+ font-weight: 500;
459
+ color:rgb(48, 49, 51);;
460
+ left: 16px;
461
+ top: 44px;
462
+ position: absolute;
463
+ ::v-deep .el-input__inner {
464
+ color: rgb(48, 49, 51);
465
+ padding-top: 0.25em;
466
+ .is-focus {
467
+ border: 1px solid $app-primary-color;
468
+ }
469
+ }
470
+ }
471
+
472
+
473
+ ::v-deep .flatmap_dropdown {
474
+ min-width: 160px!important;
475
+ .el-select-dropdown__item {
476
+ white-space: nowrap;
477
+ text-align: left;
478
+ &.selected {
479
+ color: $app-primary-color;
480
+ font-weight: normal;
481
+ }
482
+ }
483
+ }
484
+
485
+ ::v-deep .flatmap-popper {
486
+ padding: 6px 4px;
487
+ font-size:12px;
488
+ color: rgb(48, 49, 51);
489
+ background-color: #f3ecf6;
490
+ border: 1px solid $app-primary-color;
491
+ white-space: nowrap;
492
+ min-width: unset;
493
+ &.right-popper {
494
+ .popper__arrow {
495
+ border-right-color: $app-primary-color !important;
496
+ &:after {
497
+ border-right-color: #f3ecf6 !important;
498
+ }
499
+ }
500
+ }
501
+ }
502
+
503
+ ::v-deep .flatmap-marker-popup{
504
+ background-color: #f0f0f000 !important;
505
+ box-shadow: none !important;
506
+ }
507
+
508
+ </style>
509
+