@abi-software/mapintegratedvuer 1.17.1 → 1.17.3-simulation.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 (43) hide show
  1. package/dist/{ConnectivityGraph-BL4B9GZX.js → ConnectivityGraph-9pXPgFJR.js} +2 -2
  2. package/dist/{ContentMixin-Djmb_gqk.js → ContentMixin-DIqgKIz6.js} +279 -536
  3. package/dist/Flatmap-D7GVPV7o.js +103422 -0
  4. package/dist/{Iframe-ByYxT4Yq.js → Iframe-CCEA3d9c.js} +2 -2
  5. package/dist/{MultiFlatmap-DSkdlRiS.js → MultiFlatmap-Cuke1uNp.js} +3 -3
  6. package/dist/{Plot-ymkHVq_A.js → Plot-B4oTBVAT.js} +2 -2
  7. package/dist/{Scaffold-bw7posKm.js → Scaffold-Czz8X5kL.js} +79 -53
  8. package/dist/Simulation-BKmz8zwm.js +107 -0
  9. package/dist/{index-CwfUgFL1.js → index-_b4VBGHk.js} +30002 -25408
  10. package/dist/mapintegratedvuer.js +1 -1
  11. package/dist/mapintegratedvuer.umd.cjs +4291 -229
  12. package/dist/style-CM86xE3J.js +119 -0
  13. package/dist/style.css +1 -1
  14. package/package.json +10 -5
  15. package/src/App.vue +285 -258
  16. package/src/assets/styles.scss +1 -1
  17. package/src/components/ContextCard.vue +0 -1
  18. package/src/components/DummyRouteComponent.vue +1 -0
  19. package/src/components/EventBus.ts +13 -0
  20. package/src/components/FloatingWindow.vue +142 -0
  21. package/src/components/MapContent.vue +9 -4
  22. package/src/components/PlotComponent.vue +56 -0
  23. package/src/components/SplitDialog.vue +1 -6
  24. package/src/components/SplitFlow.vue +504 -444
  25. package/src/components/scripts/utilities.js +1 -1
  26. package/src/components/viewers/Flatmap.vue +166 -83
  27. package/src/components/viewers/Simulation.vue +118 -11
  28. package/src/components.d.ts +3 -0
  29. package/src/main.js +9 -3
  30. package/src/mixins/ContentMixin.js +467 -406
  31. package/src/mixins/DynamicMarkerMixin.js +50 -17
  32. package/src/services/mapping.js +69 -0
  33. package/src/services/testData.js +71 -0
  34. package/src/stores/entries.js +1 -1
  35. package/src/stores/mapping.js +29 -0
  36. package/src/stores/settings.js +4 -0
  37. package/src/stores/simulationPlotStore.js +124 -0
  38. package/src/stores/splitFlow.js +425 -352
  39. package/src/types/simulation.js +18 -0
  40. package/dist/Flatmap-uPEQNDkK.js +0 -202
  41. package/dist/Simulation-C_gdqDes.js +0 -28
  42. package/dist/style-Czqe2bTf.js +0 -57
  43. package/src/components/EventBus.js +0 -3
@@ -1,5 +1,5 @@
1
- @import '_variables';
2
1
 
2
+ @import '_variables.scss';
3
3
  @import url('https://fonts.googleapis.com/css?family=Asap:400,400i,500,600,700&display=swap');
4
4
 
5
5
  /* icon font path, required */
@@ -94,7 +94,6 @@
94
94
  </div>
95
95
  </template>
96
96
 
97
-
98
97
  <script>
99
98
  /* eslint-disable no-alert, no-console */
100
99
  import { CopyToClipboard } from "@abi-software/map-utilities";
@@ -0,0 +1 @@
1
+ <template></template>
@@ -0,0 +1,13 @@
1
+ import mitt from 'mitt';
2
+ import type { SimulationRequest, SimulationResponse } from '../types/simulation';
3
+
4
+ // Define the mapping of Event Name -> Event Payload
5
+ type Events = {
6
+ 'simulation-data-request': SimulationRequest;
7
+ 'simulation-data-ready': SimulationResponse;
8
+ [key: string]: any; // Allow for other events with any payload.
9
+ };
10
+
11
+ // Pass the type to mitt
12
+ const EventBus = mitt<Events>();
13
+ export default EventBus;
@@ -0,0 +1,142 @@
1
+ <script setup>
2
+ import { ref, toRefs, watch } from 'vue'
3
+ import { useDraggable } from '@vueuse/core'
4
+
5
+ const props = defineProps(['windowData', 'offsetX', 'offsetY'])
6
+ const emit = defineEmits(['closeWindow', 'mouseDown'])
7
+ const { windowData } = toRefs(props)
8
+
9
+ // 1. Create a template ref for the DOM element
10
+ const el = ref(null)
11
+
12
+ // 2. Create a "handle" ref so the user can only drag by the header
13
+ const handle = ref(null)
14
+
15
+ const transform = ref('translate(0px, 0px)')
16
+ const isMinimized = ref(false)
17
+ const toggleMinimize = () => {
18
+ isMinimized.value = !isMinimized.value
19
+ }
20
+
21
+ const getTitle = () => {
22
+ if (windowData.value.label) {
23
+ let title = windowData.value.label;
24
+ if (windowData.value.data?.title) {
25
+ title += ` (${windowData.value.data?.title})`;
26
+ }
27
+ return title;
28
+ } else {
29
+ return windowData.value.data?.title;
30
+ }
31
+ }
32
+
33
+ watch(
34
+ [() => props.offsetX, () => props.offsetY],
35
+ ([newX, newY]) => {
36
+ transform.value = `translate(-${newX}px, -${newY}px)`
37
+ },
38
+ { immediate: true }
39
+ )
40
+
41
+ // 3. Activate draggable logic
42
+ // We set initialValue to the props so it opens where we want
43
+ const { x, y, style } = useDraggable(el, {
44
+ initialValue: { x: windowData.value.x, y: windowData.value.y },
45
+ handle: handle, // Only drag when clicking the header
46
+ preventDefault: true,
47
+ })
48
+ </script>
49
+
50
+ <template>
51
+ <div
52
+ ref="el"
53
+ class="floating-window"
54
+ :class="{ 'is-minimized': isMinimized }"
55
+ :style="[style, { zIndex: windowData.zIndex, transform: transform }]"
56
+ @mousedown="emit('mouseDown', windowData.id)"
57
+ >
58
+ <div ref="handle" class="window-header">
59
+ <span class="title">{{ getTitle() }}</span>
60
+ <div class="window-controls">
61
+ <button @click.stop="toggleMinimize" class="control-btn">
62
+ {{ isMinimized ? '□' : '_' }}
63
+ </button>
64
+ <button @click.stop="emit('closeWindow', windowData.id)">×</button>
65
+ </div>
66
+ </div>
67
+
68
+ <div class="window-body" v-show="!isMinimized">
69
+ <slot></slot>
70
+ </div>
71
+ </div>
72
+ </template>
73
+
74
+ <style scoped>
75
+ .floating-window {
76
+ position: absolute; /* Fixed relative to viewport */
77
+ width: 400px;
78
+ min-width: 200px;
79
+ height: 300px;
80
+ min-height: 150px;
81
+ background: white;
82
+ border: 1px solid #ccc;
83
+ box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
84
+ display: flex;
85
+ flex-direction: column;
86
+ resize: both; /* Allow resizing */
87
+ overflow: hidden; /* Prevent content overflow */
88
+ transition: height 0.2s ease, width 0.2s ease;
89
+
90
+ .title {
91
+ align-content: center;
92
+ font-size: 12px;
93
+ }
94
+ }
95
+
96
+ .window-header {
97
+ background: #f0f0f0;
98
+ padding: 8px;
99
+ cursor: grab; /* Shows user it is draggable */
100
+ display: flex;
101
+ justify-content: space-between;
102
+ border-bottom: 1px solid #ddd;
103
+ user-select: none;
104
+ }
105
+
106
+ .window-header:active {
107
+ cursor: grabbing;
108
+ }
109
+
110
+ .window-body {
111
+ flex-grow: 1;
112
+ width: 100%;
113
+ height: 100%;
114
+ position: relative;
115
+ padding: 10px;
116
+ /* overflow: hidden; Important for Plotly resizing */
117
+ }
118
+
119
+ .floating-window.is-minimized {
120
+ height: auto !important;
121
+ min-height: 0 !important;
122
+ resize: none; /* Disable resizing when minimized */
123
+ width: 250px; /* Optional: shrink the width to make a neat little bar */
124
+ }
125
+
126
+ .window-controls {
127
+ display: flex;
128
+ gap: 5px;
129
+ }
130
+
131
+ .control-btn {
132
+ background: transparent;
133
+ border: 1px solid #ccc;
134
+ cursor: pointer;
135
+ padding: 0 5px;
136
+ border-radius: 3px;
137
+ }
138
+
139
+ .control-btn:hover {
140
+ background: #e0e0e0;
141
+ }
142
+ </style>
@@ -25,6 +25,7 @@ import SplitFlow from './SplitFlow.vue';
25
25
  import EventBus from './EventBus';
26
26
  import { mapStores } from 'pinia';
27
27
  import { useSettingsStore } from '../stores/settings';
28
+ import { useSimulationPlotStore } from '../stores/simulationPlotStore'
28
29
  import { useSplitFlowStore } from '../stores/splitFlow';
29
30
  import { defaultSpecies, findSpeciesKey } from './scripts/utilities.js';
30
31
  import { MapSvgSpriteColor} from '@abi-software/svg-sprite';
@@ -334,7 +335,7 @@ export default {
334
335
  this.$refs.flow.setState(currentState);
335
336
  //Do not create a new entry, instead set the multiflatmap viewer
336
337
  //to the primary slot
337
- this.$refs.flow.setIdToPrimaryPane(entry.id);
338
+ this.$refs.flow.setIdToPane(entry.id);
338
339
  break;
339
340
  }
340
341
  }
@@ -389,7 +390,7 @@ export default {
389
390
  },
390
391
  },
391
392
  computed: {
392
- ...mapStores(useSettingsStore, useSplitFlowStore),
393
+ ...mapStores(useSettingsStore, useSimulationPlotStore, useSplitFlowStore),
393
394
  stateToSet() {
394
395
  return this.state ? this.state : this.initialState;
395
396
  },
@@ -412,6 +413,7 @@ export default {
412
413
  this.options.pennsieveApi ? this.settingsStore.updatePennsieveApi(this.options.pennsieveApi) : null;
413
414
  this.options.flatmapAPI ? this.settingsStore.updateFlatmapAPI(this.options.flatmapAPI) : null;
414
415
  this.options.rootUrl ? this.settingsStore.updateRootUrl(this.options.rootUrl) : null;
416
+ this.options.testDataLocation ? this.settingsStore.updateTestDataLocation(this.options.testDataLocation) : null;
415
417
  }
416
418
  this.settingsStore.updateAllClosable(this.allClosable);
417
419
  this.splitFlowStore?.reset();
@@ -450,13 +452,16 @@ export default {
450
452
  this.settingsStore.updateUseHelpModeDialog(this.useHelpModeDialog);
451
453
  this.settingsStore.updateConnectivityInfoSidebar(this.connectivityInfoSidebar);
452
454
  this.settingsStore.updateAnnotationSidebar(this.annotationSidebar);
453
- }
455
+ this.simulationPlotStore.initListeners();
456
+ },
457
+ beforeUnmount: function () {
458
+ this.simulationPlotStore.cleanupListeners();
459
+ },
454
460
  }
455
461
 
456
462
  </script>
457
463
 
458
464
  <style scoped lang="scss">
459
-
460
465
  :deep(.el-loading-spinner) {
461
466
  .path {
462
467
  stroke: $app-primary-color;
@@ -0,0 +1,56 @@
1
+ <script setup>
2
+ import { ref, onMounted, watch } from 'vue';
3
+ import Plotly from 'plotly.js-dist-min';
4
+ import { useResizeObserver, useDebounceFn } from '@vueuse/core';
5
+
6
+ const props = defineProps(['data']);
7
+ const plotContainer = ref(null);
8
+
9
+ const drawPlot = () => {
10
+ if (!plotContainer.value) return;
11
+
12
+ const plotData = [{
13
+ x: props.data?.x || [],
14
+ y: props.data?.y || [],
15
+ type: 'scatter'
16
+ }];
17
+
18
+ const layout = {
19
+ margin: { t: 20, r: 20, b: 40, l: 40 }, // Tight margins for small windows
20
+ autosize: true
21
+ };
22
+
23
+ const config = { responsive: true }; // Helps with window resize, but not enough for container resize
24
+
25
+ Plotly.newPlot(plotContainer.value, plotData, layout, config);
26
+ };
27
+
28
+ // Debounce this so we don't spam Plotly while the user is actively dragging
29
+ const handleResize = useDebounceFn(() => {
30
+ if (plotContainer.value) {
31
+ Plotly.Plots.resize(plotContainer.value);
32
+ }
33
+ }, 50); // 50ms delay
34
+
35
+ // Observe resizes, useResizeObserver automatically cleans up when component unmounts
36
+ useResizeObserver(plotContainer, () => {
37
+ handleResize();
38
+ });
39
+
40
+ onMounted(() => {
41
+ drawPlot();
42
+ });
43
+
44
+ watch(() => props.data, drawPlot, { deep: true });
45
+ </script>
46
+
47
+ <template>
48
+ <div ref="plotContainer" class="plot-container"></div>
49
+ </template>
50
+
51
+ <style scoped>
52
+ .plot-container {
53
+ width: 100%;
54
+ height: 100%;
55
+ }
56
+ </style>
@@ -109,12 +109,7 @@ export default {
109
109
  return activeContents;
110
110
  },
111
111
  isIdVisible: function(id) {
112
- const paneName = this.splitFlowStore.getPaneNameById(id);
113
- let visible = false;
114
- if (paneName !== undefined) {
115
- visible = this.splitFlowStore.isPaneActive(paneName);
116
- }
117
- return visible;
112
+ return this.splitFlowStore.isIdVisible(id);
118
113
  },
119
114
  getContentsWithId: function(id) {
120
115
  let contents = this.$refs["content"];