@abi-software/flatmapvuer 0.5.9 → 0.5.10

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