@abi-software/mapintegratedvuer 1.16.2 → 1.16.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.
- package/dist/{ContentMixin-DiDiS2Ct.js → ContentMixin-CN4E1Tcm.js} +224 -455
- package/dist/{style-t77Cw_0W.js → DynamicMarkerMixin-ToiTtIcj.js} +1 -1
- package/dist/Flatmap-D7eEw_Q5.js +103398 -0
- package/dist/{Iframe-Drf0INka.js → Iframe-NY9zAQZz.js} +2 -2
- package/dist/{MultiFlatmap-ZODnXOPU.js → MultiFlatmap-C8gAg-MI.js} +15 -15
- package/dist/{Plot-DrEUpK5N.js → Plot-DH_Px9IB.js} +2 -2
- package/dist/{Scaffold-BiDz1Mwi.js → Scaffold-C6XY3IQb.js} +79 -53
- package/dist/Simulation-Bb3HbeD4.js +72 -0
- package/dist/{index-C753e18_.js → index-DaB85Tpy.js} +19768 -20046
- package/dist/mapintegratedvuer.js +1 -1
- package/dist/mapintegratedvuer.umd.cjs +4271 -231
- package/dist/style.css +1 -1
- package/package.json +9 -4
- package/src/App.vue +283 -260
- package/src/assets/styles.scss +1 -1
- package/src/components/ContentBar.vue +0 -1
- package/src/components/ContentVuer.vue +0 -2
- package/src/components/ContextCard.vue +0 -1
- package/src/components/DummyRouteComponent.vue +1 -0
- package/src/components/EventBus.ts +13 -0
- package/src/components/FloatingWindow.vue +125 -0
- package/src/components/MapContent.vue +8 -5
- package/src/components/PlotComponent.vue +56 -0
- package/src/components/SplitFlow.vue +470 -439
- package/src/components/scripts/utilities.js +1 -1
- package/src/components/viewers/Flatmap.vue +136 -84
- package/src/components/viewers/MultiFlatmap.vue +1 -1
- package/src/components/viewers/Simulation.vue +66 -15
- package/src/components.d.ts +3 -0
- package/src/main.js +9 -3
- package/src/mixins/ContentMixin.js +419 -390
- package/src/services/mapping.js +69 -0
- package/src/stores/entries.js +1 -1
- package/src/stores/mapping.js +29 -0
- package/src/stores/settings.js +0 -4
- package/src/stores/simulationPlotStore.js +104 -0
- package/src/stores/splitFlow.js +427 -362
- package/src/types/simulation.js +18 -0
- package/dist/Flatmap-Dh0ybLSL.js +0 -202
- package/dist/Simulation-lEXXSWRc.js +0 -28
- package/src/components/EventBus.js +0 -3
package/src/assets/styles.scss
CHANGED
|
@@ -148,7 +148,6 @@ export default {
|
|
|
148
148
|
ALGOLIA_KEY: this.settingsStore.algoliaKey,
|
|
149
149
|
ALGOLIA_ID: this.settingsStore.algoliaId,
|
|
150
150
|
PENNSIEVE_API_LOCATION: this.settingsStore.pennsieveApi,
|
|
151
|
-
NL_LINK_PREFIX: this.settingsStore.nlLinkPrefix,
|
|
152
151
|
ROOT_URL: this.settingsStore.rootUrl,
|
|
153
152
|
};
|
|
154
153
|
},
|
|
@@ -173,9 +173,7 @@ export default {
|
|
|
173
173
|
...mapStores(useEntriesStore, useSplitFlowStore),
|
|
174
174
|
viewerType() {
|
|
175
175
|
switch (this.entry.type) {
|
|
176
|
-
case "Biolucida":
|
|
177
176
|
case "Iframe":
|
|
178
|
-
case "Segmentation":
|
|
179
177
|
return 'Iframe';
|
|
180
178
|
default:
|
|
181
179
|
return this.entry.type;
|
|
@@ -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,125 @@
|
|
|
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
|
+
watch(
|
|
22
|
+
[() => props.offsetX, () => props.offsetY],
|
|
23
|
+
([newX, newY]) => {
|
|
24
|
+
transform.value = `translate(-${newX}px, -${newY}px)`
|
|
25
|
+
},
|
|
26
|
+
{ immediate: true }
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
// 3. Activate draggable logic
|
|
30
|
+
// We set initialValue to the props so it opens where we want
|
|
31
|
+
const { x, y, style } = useDraggable(el, {
|
|
32
|
+
initialValue: { x: windowData.value.x, y: windowData.value.y },
|
|
33
|
+
handle: handle, // Only drag when clicking the header
|
|
34
|
+
preventDefault: true,
|
|
35
|
+
})
|
|
36
|
+
</script>
|
|
37
|
+
|
|
38
|
+
<template>
|
|
39
|
+
<div
|
|
40
|
+
ref="el"
|
|
41
|
+
class="floating-window"
|
|
42
|
+
:class="{ 'is-minimized': isMinimized }"
|
|
43
|
+
:style="[style, { zIndex: windowData.zIndex, transform: transform }]"
|
|
44
|
+
@mousedown="emit('mouseDown', windowData.id)"
|
|
45
|
+
>
|
|
46
|
+
<div ref="handle" class="window-header">
|
|
47
|
+
<span>{{ windowData.data?.title }}</span>
|
|
48
|
+
<div class="window-controls">
|
|
49
|
+
<button @click.stop="toggleMinimize" class="control-btn">
|
|
50
|
+
{{ isMinimized ? '□' : '_' }}
|
|
51
|
+
</button>
|
|
52
|
+
<button @click.stop="emit('closeWindow', windowData.id)">×</button>
|
|
53
|
+
</div>
|
|
54
|
+
</div>
|
|
55
|
+
|
|
56
|
+
<div class="window-body" v-show="!isMinimized">
|
|
57
|
+
<slot></slot>
|
|
58
|
+
</div>
|
|
59
|
+
</div>
|
|
60
|
+
</template>
|
|
61
|
+
|
|
62
|
+
<style scoped>
|
|
63
|
+
.floating-window {
|
|
64
|
+
position: absolute; /* Fixed relative to viewport */
|
|
65
|
+
width: 400px;
|
|
66
|
+
min-width: 200px;
|
|
67
|
+
height: 300px;
|
|
68
|
+
min-height: 150px;
|
|
69
|
+
background: white;
|
|
70
|
+
border: 1px solid #ccc;
|
|
71
|
+
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
|
|
72
|
+
display: flex;
|
|
73
|
+
flex-direction: column;
|
|
74
|
+
resize: both; /* Allow resizing */
|
|
75
|
+
overflow: hidden; /* Prevent content overflow */
|
|
76
|
+
transition: height 0.2s ease, width 0.2s ease;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
.window-header {
|
|
80
|
+
background: #f0f0f0;
|
|
81
|
+
padding: 8px;
|
|
82
|
+
cursor: grab; /* Shows user it is draggable */
|
|
83
|
+
display: flex;
|
|
84
|
+
justify-content: space-between;
|
|
85
|
+
border-bottom: 1px solid #ddd;
|
|
86
|
+
user-select: none;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
.window-header:active {
|
|
90
|
+
cursor: grabbing;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
.window-body {
|
|
94
|
+
flex-grow: 1;
|
|
95
|
+
width: 100%;
|
|
96
|
+
height: 100%;
|
|
97
|
+
position: relative;
|
|
98
|
+
padding: 10px;
|
|
99
|
+
/* overflow: hidden; Important for Plotly resizing */
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
.floating-window.is-minimized {
|
|
103
|
+
height: auto !important;
|
|
104
|
+
min-height: 0 !important;
|
|
105
|
+
resize: none; /* Disable resizing when minimized */
|
|
106
|
+
width: 250px; /* Optional: shrink the width to make a neat little bar */
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
.window-controls {
|
|
110
|
+
display: flex;
|
|
111
|
+
gap: 5px;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
.control-btn {
|
|
115
|
+
background: transparent;
|
|
116
|
+
border: 1px solid #ccc;
|
|
117
|
+
cursor: pointer;
|
|
118
|
+
padding: 0 5px;
|
|
119
|
+
border-radius: 3px;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
.control-btn:hover {
|
|
123
|
+
background: #e0e0e0;
|
|
124
|
+
}
|
|
125
|
+
</style>
|
|
@@ -24,6 +24,7 @@ import SplitFlow from './SplitFlow.vue';
|
|
|
24
24
|
import EventBus from './EventBus';
|
|
25
25
|
import { mapStores } from 'pinia';
|
|
26
26
|
import { useSettingsStore } from '../stores/settings';
|
|
27
|
+
import { useSimulationPlotStore } from '../stores/simulationPlotStore'
|
|
27
28
|
import { useSplitFlowStore } from '../stores/splitFlow';
|
|
28
29
|
import { defaultSpecies, findSpeciesKey } from './scripts/utilities.js';
|
|
29
30
|
import { MapSvgSpriteColor} from '@abi-software/svg-sprite';
|
|
@@ -329,7 +330,7 @@ export default {
|
|
|
329
330
|
this.$refs.flow.setState(currentState);
|
|
330
331
|
//Do not create a new entry, instead set the multiflatmap viewer
|
|
331
332
|
//to the primary slot
|
|
332
|
-
this.$refs.flow.
|
|
333
|
+
this.$refs.flow.setIdToPane(entry.id);
|
|
333
334
|
break;
|
|
334
335
|
}
|
|
335
336
|
}
|
|
@@ -384,7 +385,7 @@ export default {
|
|
|
384
385
|
},
|
|
385
386
|
},
|
|
386
387
|
computed: {
|
|
387
|
-
...mapStores(useSettingsStore, useSplitFlowStore),
|
|
388
|
+
...mapStores(useSettingsStore, useSimulationPlotStore, useSplitFlowStore),
|
|
388
389
|
stateToSet() {
|
|
389
390
|
return this.state ? this.state : this.initialState;
|
|
390
391
|
},
|
|
@@ -406,7 +407,6 @@ export default {
|
|
|
406
407
|
this.options.algoliaId ? this.settingsStore.updateAlgoliaId(this.options.algoliaId) : null;
|
|
407
408
|
this.options.pennsieveApi ? this.settingsStore.updatePennsieveApi(this.options.pennsieveApi) : null;
|
|
408
409
|
this.options.flatmapAPI ? this.settingsStore.updateFlatmapAPI(this.options.flatmapAPI) : null;
|
|
409
|
-
this.options.nlLinkPrefix ? this.settingsStore.updateNLLinkPrefix(this.options.nlLinkPrefix) : null;
|
|
410
410
|
this.options.rootUrl ? this.settingsStore.updateRootUrl(this.options.rootUrl) : null;
|
|
411
411
|
}
|
|
412
412
|
this.settingsStore.updateAllClosable(this.allClosable);
|
|
@@ -446,13 +446,16 @@ export default {
|
|
|
446
446
|
this.settingsStore.updateUseHelpModeDialog(this.useHelpModeDialog);
|
|
447
447
|
this.settingsStore.updateConnectivityInfoSidebar(this.connectivityInfoSidebar);
|
|
448
448
|
this.settingsStore.updateAnnotationSidebar(this.annotationSidebar);
|
|
449
|
-
|
|
449
|
+
this.simulationPlotStore.initListeners();
|
|
450
|
+
},
|
|
451
|
+
beforeUnmount: function () {
|
|
452
|
+
this.simulationPlotStore.cleanupListeners();
|
|
453
|
+
},
|
|
450
454
|
}
|
|
451
455
|
|
|
452
456
|
</script>
|
|
453
457
|
|
|
454
458
|
<style scoped lang="scss">
|
|
455
|
-
|
|
456
459
|
:deep(.el-loading-spinner) {
|
|
457
460
|
.path {
|
|
458
461
|
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>
|