@abi-software/mapintegratedvuer 1.23.0 → 1.24.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 (34) hide show
  1. package/dist/{ConnectivityGraph-Cao0C1-G.js → ConnectivityGraph-Cye6QvZR.js} +6 -6
  2. package/dist/{ContentMixin-4t04VWoF.js → ContentMixin-SBI5HTPO.js} +295 -244
  3. package/dist/{DynamicMarkerMixin-tATj70ym.js → DynamicMarkerMixin-LB2RYdSY.js} +1 -1
  4. package/dist/{Flatmap-DF4FAwLY.js → Flatmap-TcOqOyD5.js} +5 -5
  5. package/dist/{Iframe-DbQ22y53.js → Iframe-D-Eq3G6T.js} +2 -2
  6. package/dist/{MultiFlatmap-Dwy9gbWC.js → MultiFlatmap-C122IUmB.js} +6 -6
  7. package/dist/{Plot-COXE_H78.js → Plot-DTv-vd63.js} +2 -2
  8. package/dist/{Scaffold-9ubjNzcD.js → Scaffold-B2g3O1xF.js} +46 -36
  9. package/dist/{Simulation-CR-yKjxu.js → Simulation-ClMZ5HHt.js} +2 -2
  10. package/dist/{connectivities-DhBMlBSj.js → connectivities-LtlFwLOp.js} +6399 -5790
  11. package/dist/es-D-YkSGXX.js +436 -0
  12. package/dist/mapintegratedvuer.js +12994 -11652
  13. package/dist/mapintegratedvuer.umd.cjs +191 -190
  14. package/dist/style.css +1 -1
  15. package/package.json +4 -4
  16. package/src/assets/header-icon.scss +9 -3
  17. package/src/components/ContentBar.vue +172 -92
  18. package/src/components/ContentVuer.vue +41 -1
  19. package/src/components/DialogToolbarContent.vue +45 -4
  20. package/src/components/EventBus.js +8 -0
  21. package/src/components/MapContent.vue +77 -31
  22. package/src/components/ResizeSensor.vue +7 -9
  23. package/src/components/ScreenshotPopover.vue +526 -0
  24. package/src/components/SplitDialog.vue +94 -93
  25. package/src/components/SplitFlow.vue +158 -96
  26. package/src/components/scripts/utilities.js +56 -1
  27. package/src/components/viewers/Flatmap.vue +1 -0
  28. package/src/components/viewers/MultiFlatmap.vue +3 -0
  29. package/src/components/viewers/Scaffold.vue +25 -13
  30. package/src/components.d.ts +2 -0
  31. package/src/mixins/ContentMixin.js +32 -21
  32. package/src/services/screenshot.js +1186 -0
  33. package/src/stores/connectivities.js +38 -5
  34. package/src/stores/settings.js +18 -0
@@ -57,6 +57,7 @@
57
57
  import { markRaw } from 'vue';
58
58
  import EventBus from '../EventBus';
59
59
  import ContentMixin from '../../mixins/ContentMixin';
60
+ import { snapshotThreeRenderer } from '../../services/screenshot.js';
60
61
 
61
62
  import { ScaffoldVuer } from '@abi-software/scaffoldvuer';
62
63
  import '@abi-software/scaffoldvuer/dist/style.css';
@@ -150,7 +151,10 @@ export default {
150
151
  // Both EventBus.emit and getKnowledgeTooltip will trigger sidebar content update
151
152
  // Then setVisibilityFilter will be called to zoom to the clicked nerve.
152
153
  if (resource.length === 1) {
153
- this.clickedObject = resource[0].data;
154
+ // Keep only the fields needed here; resource data carries the live
155
+ // zincObject, which should not be made reactive or retained.
156
+ const { id, isNerves, anatomicalId } = resource[0].data;
157
+ this.clickedObject = { id, isNerves, anatomicalId };
154
158
  if (this.clickedObject.isNerves || this.clickedObject.anatomicalId) {
155
159
  const label = this.clickedObject.id.toLowerCase();
156
160
  if (this.$refs.scaffold.viewingMode === 'Neuron Connection') {
@@ -245,6 +249,11 @@ export default {
245
249
  this.scaffoldCamera.onResize();
246
250
  }
247
251
  },
252
+ getScreenshotSources: async function (pixelRatio) {
253
+ const zincRenderer = this.$refs.scaffold?.$module?.zincRenderer;
254
+ if (!zincRenderer) return [];
255
+ return [snapshotThreeRenderer(zincRenderer, pixelRatio)];
256
+ },
248
257
  getState: function () {
249
258
  if (this.$refs.scaffold) {
250
259
  return this.$refs.scaffold.getState();
@@ -297,6 +306,7 @@ export default {
297
306
  },
298
307
  scaffoldIsReady: function () {
299
308
  this.scaffoldLoaded = true;
309
+ this.$emit('viewer-ready', true);
300
310
  this.$refs.scaffold.$module.graphicsHighlight.highlightColour = [1, 0, 1];
301
311
  if (!this.scaffoldRef) {
302
312
  this.scaffoldRef = markRaw(this.$refs.scaffold);
@@ -309,7 +319,7 @@ export default {
309
319
  }
310
320
  this.updateViewerSettings();
311
321
  EventBus.emit('mapLoaded', this.$refs.scaffold);
312
- setTimeout(() => {
322
+ this._greyScaleTimer = setTimeout(() => {
313
323
  this.setNerveGreyScale();
314
324
  }, 500);
315
325
  },
@@ -383,6 +393,9 @@ export default {
383
393
  ? this.settingsStore.numberOfDatasetsForFacets
384
394
  : {};
385
395
  },
396
+ scaffoldKnowledge: function () {
397
+ return this.connectivityKnowledge?.[this.entry.resource];
398
+ },
386
399
  },
387
400
  watch: {
388
401
  visible: {
@@ -403,23 +416,19 @@ export default {
403
416
  });
404
417
  }
405
418
  },
406
- deep: true,
407
419
  immediate: true,
408
420
  },
409
- connectivityKnowledge: {
410
- handler(newVal, _oldVal) {
421
+ // Knowledge entries are replaced so a shallow watch on this scaffold's entry is sufficient
422
+ scaffoldKnowledge: {
423
+ handler(scaffoldKnowledge) {
411
424
  // Store scaffold knowledge locally
412
- if (this.entry.resource in newVal) {
413
- const scaffoldKnowledge = newVal[this.entry.resource];
414
- if (scaffoldKnowledge.length !== this.nervesKnowledge.length) {
415
- this.nervesKnowledge = scaffoldKnowledge;
416
- if (this.scaffoldLoaded) {
417
- this.setNerveGreyScale();
418
- }
425
+ if (scaffoldKnowledge && scaffoldKnowledge.length !== this.nervesKnowledge.length) {
426
+ this.nervesKnowledge = scaffoldKnowledge;
427
+ if (this.scaffoldLoaded) {
428
+ this.setNerveGreyScale();
419
429
  }
420
430
  }
421
431
  },
422
- deep: true,
423
432
  immediate: true,
424
433
  },
425
434
  },
@@ -435,6 +444,9 @@ export default {
435
444
  query: '',
436
445
  };
437
446
  },
447
+ beforeUnmount: function () {
448
+ clearTimeout(this._greyScaleTimer);
449
+ },
438
450
  };
439
451
  </script>
440
452
 
@@ -34,6 +34,7 @@ declare module 'vue' {
34
34
  ElIcon: typeof import('element-plus/es')['ElIcon']
35
35
  ElIconArrowDown: typeof import('@element-plus/icons-vue')['ArrowDown']
36
36
  ElIconArrowUp: typeof import('@element-plus/icons-vue')['ArrowUp']
37
+ ElIconCamera: typeof import('@element-plus/icons-vue')['Camera']
37
38
  ElIconCompass: typeof import('@element-plus/icons-vue')['Compass']
38
39
  ElIconEditPen: typeof import('@element-plus/icons-vue')['EditPen']
39
40
  ElIconMoreFilled: typeof import('@element-plus/icons-vue')['MoreFilled']
@@ -57,6 +58,7 @@ declare module 'vue' {
57
58
  RouterLink: typeof import('vue-router')['RouterLink']
58
59
  RouterView: typeof import('vue-router')['RouterView']
59
60
  Scaffold: typeof import('./components/viewers/Scaffold.vue')['default']
61
+ ScreenshotPopover: typeof import('./components/ScreenshotPopover.vue')['default']
60
62
  SearchControls: typeof import('./components/SearchControls.vue')['default']
61
63
  Simulation: typeof import('./components/viewers/Simulation.vue')['default']
62
64
  SplitDialog: typeof import('./components/SplitDialog.vue')['default']
@@ -6,6 +6,7 @@ import { useSettingsStore } from '../stores/settings';
6
6
  import { useSplitFlowStore } from '../stores/splitFlow';
7
7
  import { useConnectivitiesStore } from '../stores/connectivities';
8
8
  import Tagging from '../services/tagging.js';
9
+ import { snapshotMaplibre } from '../services/screenshot.js';
9
10
 
10
11
  import { getFlatmapFilterOptions } from '@abi-software/map-utilities';
11
12
  import { FlatmapQueries } from '@abi-software/flatmapvuer/src/services/flatmapQueries.js';
@@ -17,14 +18,18 @@ import {
17
18
  getTermNerveMaps,
18
19
  getFilterOptions as getScaffoldFilterOptions,
19
20
  } from '@abi-software/scaffoldvuer/src/scripts/MappedNerves.js';
20
- import { defaultSpecies } from '../components/scripts/utilities.js';
21
+ import {
22
+ defaultSpecies,
23
+ getLatestFlatmap,
24
+ getFlatmapPathways,
25
+ } from '../components/scripts/utilities.js';
21
26
 
22
27
  function capitalise(text) {
23
28
  return text[0].toUpperCase() + text.substring(1);
24
29
  }
25
30
 
26
31
  export default {
27
- emits: ['flatmap-provenance-ready', 'resource-selected', 'species-changed'],
32
+ emits: ['flatmap-provenance-ready', 'resource-selected', 'species-changed', 'viewer-ready'],
28
33
  props: {
29
34
  /**
30
35
  * Object containing information for
@@ -78,6 +83,8 @@ export default {
78
83
  },
79
84
  beforeUnmount: function () {
80
85
  this.alive = false;
86
+ window.removeEventListener('mousedown', this.checkEndHelpMouseDown);
87
+ clearTimeout(this.highlightDelay);
81
88
  },
82
89
  mounted: function () {
83
90
  if (this.$refs.multiflatmap) {
@@ -139,6 +146,17 @@ export default {
139
146
  getState: function () {
140
147
  return undefined;
141
148
  },
149
+ /**
150
+ * Return snapshots of WebGL canvases rendered at `pixelRatio`,
151
+ * used by the screenshot service. Defaults to the flatmap canvas.
152
+ */
153
+ getScreenshotSources: async function (pixelRatio) {
154
+ const map = this.getFlatmapImp?.()?.map;
155
+ if (map) {
156
+ return [await snapshotMaplibre(map, pixelRatio)];
157
+ }
158
+ return [];
159
+ },
142
160
  openMap: function (type) {
143
161
  EventBus.emit('OpenNewMap', type);
144
162
  this.trackOpenMap(`open_new_${type}_map`);
@@ -612,19 +630,14 @@ export default {
612
630
  return;
613
631
  },
614
632
  loadExplorerConfig: async function () {
615
- this.flatmapService = await this.mockUpFlatmapService();
633
+ this.flatmapService = markRaw(await this.mockUpFlatmapService());
616
634
  this.loadConnectivityExplorerConfig(this.flatmapService);
617
635
  },
618
636
  mockUpFlatmapService: async function () {
619
- const flatmapResponse = await fetch(this.flatmapAPI);
620
- const flatmapJson = await flatmapResponse.json();
621
- const latestFlatmap = flatmapJson
622
- .filter((f) => f.id === 'human-flatmap_male')
623
- .sort((a, b) => b.created.localeCompare(a.created))[0];
637
+ const latestFlatmap = await getLatestFlatmap(this.flatmapAPI, 'human-flatmap_male');
624
638
  const flatmapUuid = latestFlatmap.uuid;
625
639
  const flatmapSource = latestFlatmap.sckan['knowledge-source'];
626
- const pathwaysResponse = await fetch(`${this.flatmapAPI}/flatmap/${flatmapUuid}/pathways`);
627
- const pathwaysJson = await pathwaysResponse.json();
640
+ const pathwaysJson = await getFlatmapPathways(this.flatmapAPI, flatmapUuid);
628
641
 
629
642
  this.flatmapQueries = markRaw(new FlatmapQueries());
630
643
  this.flatmapQueries.initialise(this.flatmapAPI);
@@ -692,8 +705,10 @@ export default {
692
705
  let validNerves = [];
693
706
 
694
707
  if (!this.connectivityKnowledge[sckanVersion]) {
695
- this.flatmapQueries = markRaw(new FlatmapQueries());
696
- this.flatmapQueries.initialise(this.flatmapAPI);
708
+ if (!this.flatmapQueries) {
709
+ this.flatmapQueries = markRaw(new FlatmapQueries());
710
+ this.flatmapQueries.initialise(this.flatmapAPI);
711
+ }
697
712
  const knowledge = await loadAndStoreKnowledge(flatmapImp, this.flatmapQueries);
698
713
  this.connectivityKnowledge[sckanVersion] = knowledge
699
714
  .filter((item) => item.connectivity?.length)
@@ -770,10 +785,8 @@ export default {
770
785
  EventBus.emit('species-layout-connectivity-update');
771
786
  },
772
787
  knowledgeTooltipQuery: async function (data) {
773
- await this.flatmapQueries.retrieveFlatmapKnowledgeForEvent(this.flatmapService.mapImp, {
774
- resource: [data.id],
775
- });
776
- let tooltip = await this.flatmapQueries.createTooltipData(this.flatmapService.mapImp, {
788
+ // queryTooltipData does not share state between queries, so it can run in parallel
789
+ let tooltip = await this.flatmapQueries.queryTooltipData(this.flatmapService.mapImp, {
777
790
  resource: [data.id],
778
791
  label: data.label,
779
792
  provenanceTaxonomy: data.taxons,
@@ -793,12 +806,10 @@ export default {
793
806
  );
794
807
  EventBus.emit('connectivity-info-open', this.tooltipEntry);
795
808
 
796
- let prom1 = [];
797
809
  // While having placeholders displayed, get details for all paths and then replace.
798
- for (let index = 0; index < payload.data.length; index++) {
799
- prom1.push(await this.knowledgeTooltipQuery(payload.data[index]));
800
- }
801
- this.tooltipEntry = await Promise.all(prom1);
810
+ this.tooltipEntry = await Promise.all(
811
+ payload.data.map((data) => this.knowledgeTooltipQuery(data)),
812
+ );
802
813
  const featureIds = this.tooltipEntry.map((tooltip) => tooltip.featureId[0]);
803
814
  if (featureIds.length > 0) {
804
815
  EventBus.emit('connectivity-info-open', this.tooltipEntry);