@abi-software/flatmapvuer 0.3.13-beta-2 → 0.3.14

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