@abi-software/mapintegratedvuer 1.7.2 → 1.8.0-isan.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (31) hide show
  1. package/dist/ContentMixin-CthZZNjI.js +706 -0
  2. package/dist/{Flatmap-fO2lvKFX.js → Flatmap-Bi9esI2v.js} +24 -19
  3. package/dist/{Iframe-C8wxLuOy.js → Iframe-bsYxppii.js} +2 -2
  4. package/dist/{MultiFlatmap-Dijv5l_F.js → MultiFlatmap-BWFsdMgS.js} +49 -35
  5. package/dist/{Plot-iXTevaO7.js → Plot-gX8radCI.js} +2 -2
  6. package/dist/{Scaffold-_QafxYws.js → Scaffold-Dn3GeNi0.js} +10241 -10168
  7. package/dist/Simulation-Zgs0MXh1.js +30 -0
  8. package/dist/{index-DcTjoXV1.js → index-DFkMrKek.js} +22249 -19928
  9. package/dist/mapintegratedvuer.js +1 -1
  10. package/dist/mapintegratedvuer.umd.cjs +1667 -1009
  11. package/dist/{style-C2GyLbPa.js → style-DlUxkFU-.js} +75606 -75481
  12. package/dist/style.css +1 -1
  13. package/package.json +8 -7
  14. package/src/App.vue +39 -18
  15. package/src/assets/header-icon.scss +7 -0
  16. package/src/components/ContentBar.vue +5 -1
  17. package/src/components/DialogToolbarContent.vue +91 -6
  18. package/src/components/FlatmapContextCard.vue +11 -8
  19. package/src/components/MapContent.vue +62 -46
  20. package/src/components/SplitFlow.vue +188 -112
  21. package/src/components/scripts/utilities.js +1 -1
  22. package/src/components/viewers/Flatmap.vue +12 -7
  23. package/src/components/viewers/MultiFlatmap.vue +34 -7
  24. package/src/components/viewers/Scaffold.vue +2 -2
  25. package/src/components/viewers/Simulation.vue +19 -1
  26. package/src/components.d.ts +4 -0
  27. package/src/mixins/ContentMixin.js +155 -47
  28. package/src/mixins/DynamicMarkerMixin.js +3 -1
  29. package/src/stores/settings.js +31 -5
  30. package/dist/ContentMixin-CdE8AlUJ.js +0 -339
  31. package/dist/Simulation-CJ-9g74P.js +0 -22
@@ -1,7 +1,7 @@
1
1
  <template>
2
2
  <SimulationVuer
3
3
  :apiLocation="apiLocation"
4
- :id="entry.discoverId"
4
+ :id="id"
5
5
  />
6
6
  </template>
7
7
 
@@ -13,9 +13,27 @@ import "@abi-software/simulationvuer/dist/style.css";
13
13
 
14
14
  export default {
15
15
  name: "Simulation",
16
+ data: function() {
17
+ return {
18
+ id: undefined,
19
+ };
20
+ },
16
21
  mixins: [ ContentMixin ],
17
22
  components: {
18
23
  SimulationVuer,
19
24
  },
25
+ created: function() {
26
+ if (this.entry) {
27
+ if (this.entry.discoverId) {
28
+ this.id = this.entry.discoverId;
29
+ } else if (this.entry.resource) {
30
+ if (this.settingsStore.pmrHost) {
31
+ this.id = this.entry.resource.replace(this.settingsStore.pmrHost, '');
32
+ } else {
33
+ this.id = this.entry.resource;
34
+ }
35
+ }
36
+ }
37
+ }
20
38
  };
21
39
  </script>
@@ -16,16 +16,20 @@ declare module 'vue' {
16
16
  DialogToolbarContent: typeof import('./components/DialogToolbarContent.vue')['default']
17
17
  ElAutocomplete: typeof import('element-plus/es')['ElAutocomplete']
18
18
  ElButton: typeof import('element-plus/es')['ElButton']
19
+ ElCheckbox: typeof import('element-plus/es')['ElCheckbox']
19
20
  ElCol: typeof import('element-plus/es')['ElCol']
20
21
  ElContainer: typeof import('element-plus/es')['ElContainer']
21
22
  ElHeader: typeof import('element-plus/es')['ElHeader']
22
23
  ElIcon: typeof import('element-plus/es')['ElIcon']
23
24
  ElIconArrowDown: typeof import('@element-plus/icons-vue')['ArrowDown']
24
25
  ElIconArrowUp: typeof import('@element-plus/icons-vue')['ArrowUp']
26
+ ElIconMoreFilled: typeof import('@element-plus/icons-vue')['MoreFilled']
25
27
  ElInput: typeof import('element-plus/es')['ElInput']
26
28
  ElMain: typeof import('element-plus/es')['ElMain']
27
29
  ElOption: typeof import('element-plus/es')['ElOption']
28
30
  ElPopover: typeof import('element-plus/es')['ElPopover']
31
+ ElRadio: typeof import('element-plus/es')['ElRadio']
32
+ ElRadioGroup: typeof import('element-plus/es')['ElRadioGroup']
29
33
  ElRow: typeof import('element-plus/es')['ElRow']
30
34
  ElSelect: typeof import('element-plus/es')['ElSelect']
31
35
  ElSwitch: typeof import('element-plus/es')['ElSwitch']
@@ -9,6 +9,9 @@ import { useSettingsStore } from '../stores/settings';
9
9
  import { useSplitFlowStore } from '../stores/splitFlow';
10
10
  import Tagging from '../services/tagging.js';
11
11
 
12
+ import { FlatmapQueries } from "@abi-software/flatmapvuer/src/services/flatmapQueries.js";
13
+ import { getKnowledgeSource, loadAndStoreKnowledge } from "@abi-software/flatmapvuer/src/services/flatmapKnowledge.js";
14
+
12
15
  function capitalise(text) {
13
16
  return text[0].toUpperCase() + text.substring(1)
14
17
  }
@@ -73,8 +76,6 @@ export default {
73
76
  EventBus.emit("OpenNewMap", type);
74
77
  this.trackOpenMap(`open_new_${type}_map`);
75
78
  }
76
-
77
- this.onConnectivityInfoClose();
78
79
  },
79
80
  onMapmanagerLoaded: function (mapManager) {
80
81
  this.settingsStore.updateMapManager(mapManager);
@@ -107,42 +108,37 @@ export default {
107
108
  /**
108
109
  * Callback when the vuers emit a selected event.
109
110
  */
110
- resourceSelected: function (type, resource) {
111
+ resourceSelected: function (type, resources) {
112
+ const resource = resources[0]
111
113
  // Skip processing if resources already has actions
112
- if (this.resourceHasAction(resource)) {
114
+ if (resource && this.resourceHasAction(resource)) {
113
115
  EventBus.emit("PopoverActionClick", resource);
114
116
  return;
115
117
  }
116
-
117
118
  let returnedAction = undefined;
118
119
  let action = "none";
119
120
  let fireResourceSelected = false;
120
121
  const result = {
121
122
  paneIndex: this.entry.id,
122
123
  type: type,
123
- resource: resource,
124
+ resource: resources,
124
125
  internalName: undefined,
125
126
  eventType: undefined,
126
127
  };
127
-
128
-
129
128
  if (type == "MultiFlatmap" || type == "Flatmap") {
130
- result.internalName = resource?.feature?.label ? resource.feature.label : this.idNamePair[resource.feature.models];
129
+ const flatmapImp = this.getFlatmapImp();
130
+ result.internalName = resource?.feature?.label ?
131
+ resource.feature.label : this.idNamePair[resource.feature.models];
131
132
  if (resource.eventType == "click") {
132
133
  result.eventType = "selected";
133
134
  if (resource.feature.type == "marker") {
135
+
134
136
  let label = result.internalName;
135
- if (
136
- this.settingsStore.isFeaturedMarkerIdentifier(
137
- resource.feature.id
138
- )
139
- ) {
137
+ if (this.settingsStore.isFeaturedMarkerIdentifier(resource.feature.id)) {
140
138
  // It is a featured dataset search for DOI.
141
139
  returnedAction = {
142
140
  type: "Search",
143
- term: this.settingsStore.featuredMarkerDoi(
144
- resource.feature.id
145
- ),
141
+ term: this.settingsStore.featuredMarkerDoi(resource.feature.id),
146
142
  featuredDataset: true,
147
143
  };
148
144
  } else {
@@ -151,17 +147,41 @@ export default {
151
147
  type: "Facet",
152
148
  facet: label,
153
149
  facetPropPath: "anatomy.organ.category.name",
150
+ facetSubPropPath: "anatomy.organ.name",
154
151
  term: "Anatomical structure",
155
152
  };
153
+ let labels = new Set();
154
+ if (resource?.feature['marker-terms']) {
155
+ resource.feature['marker-terms'].forEach((term) => {
156
+ labels.add(term.label)
157
+ });
158
+ labels.add(label)
159
+ if (labels.size > 0) {
160
+ returnedAction = {
161
+ type: "Facets",
162
+ labels: [...labels],
163
+ };
164
+ }
165
+ } else if (resource?.feature?.models) {
166
+ returnedAction = {
167
+ type: "PMRSearch",
168
+ term: resource.feature.models,
169
+ };
170
+ }
156
171
  }
157
-
158
172
  fireResourceSelected = true;
159
173
  if (type == "MultiFlatmap") {
160
- const flatmap =
161
- this.$refs.multiflatmap.getCurrentFlatmap().mapImp;
162
- flatmap.clearSearchResults();
174
+ flatmapImp.clearSearchResults();
163
175
  }
164
176
  } else if (resource.feature.type == "feature") {
177
+ if (flatmapImp.options && flatmapImp.options.style === 'functional') {
178
+ if (resource.feature?.hyperlinks?.pmr) {
179
+ returnedAction = {
180
+ type: "URL",
181
+ resource: resource.feature?.hyperlinks?.pmr,
182
+ };
183
+ }
184
+ }
165
185
  // Do no open scaffold in sync map
166
186
  if (this.syncMode) {
167
187
  fireResourceSelected = true;
@@ -174,16 +194,16 @@ export default {
174
194
  fireResourceSelected = true;
175
195
  }
176
196
  } else if (type == "Scaffold") {
177
- if (resource && resource[0]) {
178
- if (resource[0].data?.id === undefined || resource[0].data?.id === "") {
179
- resource[0].data.id = resource[0].data?.group;
197
+ if (resource) {
198
+ if (resource.data?.id === undefined || resource.data?.id === "") {
199
+ resource.data.id = resource.data?.group;
180
200
  }
181
- result.internalName = resource[0].data.id;
201
+ result.internalName = resource.data.id;
182
202
  // Facet search if marker is clicked
183
- if (resource[0].data.lastActionOnMarker === true) {
203
+ if (resource.data.lastActionOnMarker === true) {
184
204
  returnedAction = {
185
205
  type: "Facet",
186
- facet: capitalise(resource[0].data.id),
206
+ facet: capitalise(resource.data.id),
187
207
  facetPropPath: "anatomy.organ.category.name",
188
208
  term: "Anatomical structure",
189
209
  };
@@ -248,7 +268,7 @@ export default {
248
268
  return fetch(`${this.apiLocation}get-related-terms/${id}`)
249
269
  .then(response => response.json())
250
270
  .then(data => {
251
- if (data.uberon.array.length > 0) {
271
+ if (data.uberon?.array.length > 0) {
252
272
  name =
253
273
  data.uberon.array[0].name.charAt(0).toUpperCase() +
254
274
  data.uberon.array[0].name.slice(1);
@@ -458,25 +478,64 @@ export default {
458
478
  this.endHelp();
459
479
  }
460
480
  },
461
- mapHoverHighlight: function (mapImp) {
481
+ flatmapHighlight: async function (flatmap, hoverAnatomies, hoverDOI, hoverConnectivity) {
482
+ let toHighlight = [...hoverAnatomies, ...hoverConnectivity];
483
+ const globalSettings = this.settingsStore.globalSettings;
484
+
485
+
486
+ // to highlight connected paths
487
+ if (globalSettings.highlightConnectedPaths) {
488
+ const hoverEntry = hoverAnatomies.length ? hoverAnatomies :
489
+ hoverConnectivity.length ? hoverConnectivity :
490
+ []
491
+ const connectedPaths = await flatmap.retrieveConnectedPaths(hoverEntry);
492
+ if (connectedPaths) {
493
+ toHighlight.push(...connectedPaths);
494
+ }
495
+ }
496
+
497
+ // to highlight related paths from reference DOI
498
+ if (globalSettings.highlightDOIPaths) {
499
+ const connectionsFromDOI = await flatmap.searchConnectivitiesByReference(hoverDOI);
500
+ if (connectionsFromDOI) {
501
+ toHighlight.push(...connectionsFromDOI);
502
+ }
503
+ }
504
+ toHighlight = [...new Set(toHighlight)];
505
+ return toHighlight;
506
+ },
507
+ cardHoverHighlight: function () {
462
508
  if (this.visible) {
463
509
  const hoverAnatomies = this.settingsStore.hoverAnatomies;
464
510
  const hoverOrgans = this.settingsStore.hoverOrgans;
465
- if (hoverAnatomies.length || hoverOrgans.length) {
466
- clearTimeout(this.hoverDelay);
467
- if (this.multiflatmapRef || this.flatmapRef) {
468
- mapImp?.zoomToFeatures(hoverAnatomies, { noZoomIn: true });
469
- } else if (this.scaffoldRef) {
470
- mapImp?.changeHighlightedByName(hoverOrgans, "", false);
511
+ const hoverDOI = this.settingsStore.hoverDOI;
512
+ const hoverConnectivity = this.settingsStore.hoverConnectivity;
513
+
514
+ let flatmap = null;
515
+ let scaffold = null;
516
+ if (this.flatmapRef) flatmap = this.$flatmapRef;
517
+ if (this.multiflatmapRef) flatmap = this.$multiflatmapRef;
518
+ if (this.scaffoldRef) scaffold = this.$scaffoldRef;
519
+
520
+ // reset
521
+ if ((this.multiflatmapRef || this.flatmapRef) && flatmap) {
522
+ flatmap.mapImp.clearSearchResults();
523
+ } else if (this.scaffoldRef && scaffold) {
524
+ scaffold.changeHighlightedByName(hoverOrgans, "", false);
525
+ }
526
+
527
+ if (hoverAnatomies.length || hoverOrgans.length || hoverDOI || hoverConnectivity.length) {
528
+ if ((this.multiflatmapRef || this.flatmapRef) && flatmap) {
529
+ this.flatmapHighlight(flatmap, hoverAnatomies, hoverDOI, hoverConnectivity).then((paths) => {
530
+ try {
531
+ flatmap.zoomToFeatures(paths);
532
+ } catch (error) {
533
+ console.log(error)
534
+ }
535
+ });
536
+ } else if (this.scaffoldRef && scaffold) {
537
+ scaffold.changeHighlightedByName(hoverOrgans, "", false);
471
538
  }
472
- } else {
473
- this.hoverDelay = setTimeout(() => {
474
- if (this.multiflatmapRef || this.flatmapRef) {
475
- mapImp?.clearSearchResults();
476
- } else if (this.scaffoldRef) {
477
- mapImp?.changeHighlightedByName(hoverOrgans, "", false);
478
- }
479
- }, 500);
480
539
  }
481
540
  }
482
541
  },
@@ -489,12 +548,58 @@ export default {
489
548
  onConnectivityInfoOpen: function (connectivityInfoData) {
490
549
  EventBus.emit('connectivity-info-open', connectivityInfoData);
491
550
  },
492
- onConnectivityInfoClose: function () {
493
- EventBus.emit('connectivity-info-close');
494
- },
495
551
  onConnectivityGraphError: function (errorInfo) {
496
552
  EventBus.emit('connectivity-graph-error', errorInfo);
497
553
  },
554
+ loadConnectivityKnowledge: async function (flatmap) {
555
+ const sckanVersion = getKnowledgeSource(flatmap);
556
+ const flatmapQueries = markRaw(new FlatmapQueries());
557
+ flatmapQueries.initialise(this.flatmapAPI);
558
+ const knowledge = await loadAndStoreKnowledge(flatmap, flatmapQueries);
559
+ this.connectivityKnowledge = knowledge.filter((item) => {
560
+ if (item.source === sckanVersion && item.connectivity?.length) return true;
561
+ return false;
562
+ });
563
+ EventBus.emit("connectivity-knowledge", this.connectivityKnowledge);
564
+ },
565
+ connectivityQueryFilter: async function (flatmap, payload) {
566
+ let results = this.connectivityKnowledge;
567
+ if (payload.type === "query-update") {
568
+ if (this.query !== payload.value) this.target = [];
569
+ this.query = payload.value;
570
+ } else if (payload.type === "filter-update") {
571
+ this.filter = payload.value;
572
+ this.target = [];
573
+ } else if (payload.type === "query-filter-update") {
574
+ this.query = payload.query;
575
+ this.filter = payload.filter;
576
+ this.target = payload.data;
577
+ // restore connectivity explorer content
578
+ if (!this.query) {
579
+ EventBus.emit("connectivity-knowledge", [...results]);
580
+ }
581
+ return;
582
+ }
583
+ if (this.query) {
584
+ let flag = "", order = [], suggestions = [], paths = [];
585
+ this.searchSuggestions(this.query, suggestions);
586
+ const labels = [...new Set(suggestions)];
587
+ flag = 'label';
588
+ order = labels;
589
+ if (labels.length === 1) {
590
+ const options = {
591
+ type: this.filter.map(f => f.facet.toLowerCase()),
592
+ target: this.target.map(d => d.id),
593
+ };
594
+ paths = await flatmap.retrieveConnectedPaths([this.query], options);
595
+ flag = 'id';
596
+ order = [this.query, ...paths.filter(item => item !== this.query)];
597
+ }
598
+ results = results.filter(item => paths.includes(item.id) || labels.includes(item.label));
599
+ results.sort((a, b) => order.indexOf(a[flag]) - order.indexOf(b[flag]));
600
+ }
601
+ EventBus.emit("connectivity-knowledge", results);
602
+ }
498
603
  },
499
604
  data: function () {
500
605
  return {
@@ -514,8 +619,11 @@ export default {
514
619
  scaffoldRef: null,
515
620
  scaffoldLoaded: false,
516
621
  isInHelp: false,
517
- hoverDelay: undefined,
518
622
  mapManager: undefined,
623
+ connectivityKnowledge: [],
624
+ query: "",
625
+ filter: [],
626
+ target: [], // Support origins/components/destinations term search
519
627
  };
520
628
  },
521
629
  created: function () {
@@ -40,8 +40,9 @@ export default {
40
40
 
41
41
  if (flatmapImp) {
42
42
  // Set the dataset markers
43
- let markers = this.settingsStore.markers;
43
+ let markers = this.settingsStore.globalSettings.displayMarkers ? this.settingsStore.markers : [];
44
44
  markers = removeDuplicates(markers);
45
+ let multiMarkers = this.settingsStore.globalSettings.displayMarkers ? this.settingsStore.multiScaleMarkers : [];
45
46
  let fmMarkers = this.removeMarkersNotOnFlatmap(flatmapImp, markers);
46
47
  flatmapImp.clearMarkers();
47
48
  flatmapImp.clearDatasetMarkers();
@@ -54,6 +55,7 @@ export default {
54
55
  } else {
55
56
  flatmapImp.addDatasetMarkers(fmMarkers);
56
57
  }
58
+ flatmapImp.addMarkers(multiMarkers);
57
59
 
58
60
  // Set the featured markers
59
61
  if (this.entry.type === "MultiFlatmap") {
@@ -11,16 +11,19 @@ export const useSettingsStore = defineStore('settings', {
11
11
  algoliaKey: undefined,
12
12
  algoliaId: undefined,
13
13
  pennsieveApi: undefined,
14
+ pmrHost: "https://models.physiomeproject.org/",
14
15
  flatmapAPI: undefined,
15
16
  nlLinkPrefix: undefined,
16
- flatmapAPI2: "https://mapcore-demo.org/curation/flatmap/",
17
17
  mapManager: undefined,
18
18
  rootUrl: undefined,
19
19
  facets: { species: [], gender: [], organ: [] },
20
20
  numberOfDatasetsForFacets: [],
21
21
  markers: [],
22
+ multiScaleMarkers: ["cvs:functional.whole-body", "cvs:functional.tissue", "cvs:functional.cell"],
22
23
  hoverAnatomies: [],
23
24
  hoverOrgans: [],
25
+ hoverDOI: '',
26
+ hoverConnectivity: [],
24
27
  featuredMarkers: [],
25
28
  featuredMarkerIdentifiers: [],
26
29
  featuredMarkerDois: [],
@@ -30,6 +33,12 @@ export const useSettingsStore = defineStore('settings', {
30
33
  useHelpModeDialog: false,
31
34
  connectivityInfoSidebar: true,
32
35
  annotationSidebar: true,
36
+ globalSettings: {
37
+ displayMarkers: true,
38
+ highlightConnectedPaths: false,
39
+ highlightDOIPaths: false, // comment out to hide in settings
40
+ interactiveMode: 'dataset', // dataset, connectivity, multiscale
41
+ },
33
42
  }
34
43
  },
35
44
  getters: {
@@ -42,6 +51,16 @@ export const useSettingsStore = defineStore('settings', {
42
51
  );
43
52
  return state.featuredMarkerDois[index];
44
53
  },
54
+ getUpdatedGlobalSettingsKey: state => settings => {
55
+ let updatedSettings = [];
56
+ for (const [key, value] of Object.entries(settings)) {
57
+ const attribute = state.globalSettings[key];
58
+ if (attribute === undefined || (attribute !== value)) {
59
+ updatedSettings.push(key);
60
+ }
61
+ }
62
+ return updatedSettings;
63
+ },
45
64
  },
46
65
  actions: {
47
66
  updateShareLink(newLink) {
@@ -65,9 +84,6 @@ export const useSettingsStore = defineStore('settings', {
65
84
  updateFlatmapAPI(flatmapAPI) {
66
85
  this.flatmapAPI = flatmapAPI;
67
86
  },
68
- updateFlatmapAPI2(flatmapAPI2) {
69
- this.flatmapAPI2 = flatmapAPI2;
70
- },
71
87
  updateMapManager(mapManager) {
72
88
  this.mapManager = mapManager;
73
89
  },
@@ -77,12 +93,17 @@ export const useSettingsStore = defineStore('settings', {
77
93
  updateRootUrl(rootUrl) {
78
94
  this.rootUrl = rootUrl;
79
95
  },
96
+ updatePmrHost(pmrHost) {
97
+ this.pmrHost = pmrHost ? pmrHost : "https://models.physiomeproject.org/";
98
+ },
80
99
  updateMarkers(markers) {
81
100
  this.markers = markers;
82
101
  },
83
- updateHoverFeatures(anatomies, organs) {
102
+ updateHoverFeatures(anatomies, organs, doi, connectivity) {
84
103
  this.hoverAnatomies = anatomies;
85
104
  this.hoverOrgans = organs;
105
+ this.hoverDOI = doi;
106
+ this.hoverConnectivity = connectivity;
86
107
  },
87
108
  updateFeatured(datasetIdentifiers) {
88
109
  this.featuredMarkerIdentifiers = new Array(datasetIdentifiers.length);
@@ -166,5 +187,10 @@ export const useSettingsStore = defineStore('settings', {
166
187
  updateAnnotationSidebar(annotationSidebar) {
167
188
  this.annotationSidebar = annotationSidebar;
168
189
  },
190
+ updateGlobalSettings(globalSettings) {
191
+ for (const [key, value] of Object.entries(globalSettings)) {
192
+ this.globalSettings[key] = value;
193
+ }
194
+ },
169
195
  }
170
196
  });