@geode/opengeodeweb-front 10.17.0 → 10.18.0-rc.2
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/app/assets/scientific_colormaps.json +5881 -0
- package/app/components/HybridRenderingView.vue +17 -3
- package/app/components/Viewer/Options/AttributeSelector.vue +1 -1
- package/app/components/Viewer/Options/ColorMapList.vue +7 -8
- package/app/components/Viewer/Options/ColorMapPicker.vue +12 -41
- package/app/components/Viewer/Ui.vue +48 -1
- package/app/stores/viewer.js +6 -8
- package/app/utils/colormap.js +7 -3
- package/package.json +3 -3
|
@@ -42,6 +42,17 @@ function debounce(func, wait) {
|
|
|
42
42
|
timeout = setTimeout(later, wait);
|
|
43
43
|
};
|
|
44
44
|
}
|
|
45
|
+
|
|
46
|
+
async function handleClick(event) {
|
|
47
|
+
if (viewerStore.picking_mode) {
|
|
48
|
+
const rect = container.value.$el.getBoundingClientRect();
|
|
49
|
+
const x = event.clientX - rect.left;
|
|
50
|
+
const y = elementHeight.value - (event.clientY - rect.top);
|
|
51
|
+
await viewerStore.set_picked_point(x, y);
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
emit("click", event);
|
|
55
|
+
}
|
|
45
56
|
</script>
|
|
46
57
|
|
|
47
58
|
<template>
|
|
@@ -52,16 +63,19 @@ function debounce(func, wait) {
|
|
|
52
63
|
<v-col
|
|
53
64
|
class="pa-0"
|
|
54
65
|
ref="viewer"
|
|
66
|
+
:class="{ 'picking-cursor': viewerStore.picking_mode }"
|
|
55
67
|
style="height: 100%; overflow: hidden; position: relative; z-index: 0"
|
|
56
|
-
@click="
|
|
57
|
-
@keydown.esc="viewerStore.toggle_picking_mode(false)"
|
|
68
|
+
@click="handleClick"
|
|
58
69
|
/>
|
|
59
70
|
</div>
|
|
60
71
|
</ClientOnly>
|
|
61
72
|
</template>
|
|
62
73
|
|
|
63
|
-
<style>
|
|
74
|
+
<style scoped>
|
|
64
75
|
img {
|
|
65
76
|
pointer-events: none;
|
|
66
77
|
}
|
|
78
|
+
.picking-cursor {
|
|
79
|
+
cursor: crosshair !important;
|
|
80
|
+
}
|
|
67
81
|
</style>
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<script setup>
|
|
2
|
-
import
|
|
2
|
+
import { getRGBPointsFromPreset } from "@ogw_front/utils/colormap";
|
|
3
3
|
import { newInstance as vtkColorTransferFunction } from "@kitware/vtk.js/Rendering/Core/ColorTransferFunction";
|
|
4
4
|
|
|
5
5
|
const LAST_POINT_OFFSET = 4;
|
|
@@ -50,14 +50,13 @@ function drawPresetCanvas(presetName, canvas) {
|
|
|
50
50
|
if (!canvas) {
|
|
51
51
|
return;
|
|
52
52
|
}
|
|
53
|
-
const
|
|
54
|
-
if (!
|
|
53
|
+
const rgbPoints = getRGBPointsFromPreset(presetName);
|
|
54
|
+
if (!rgbPoints || rgbPoints.length === 0) {
|
|
55
55
|
return;
|
|
56
56
|
}
|
|
57
57
|
const ctx = canvas.getContext("2d");
|
|
58
58
|
const { height, width } = canvas;
|
|
59
59
|
const lut = vtkColorTransferFunction();
|
|
60
|
-
const rgbPoints = preset.RGBPoints;
|
|
61
60
|
for (let pointIdx = 0; pointIdx < rgbPoints.length; pointIdx += 4) {
|
|
62
61
|
lut.addRGBPoint(
|
|
63
62
|
rgbPoints[pointIdx],
|
|
@@ -161,8 +160,8 @@ watch(filteredPresets, drawAllCanvases);
|
|
|
161
160
|
</template>
|
|
162
161
|
|
|
163
162
|
<v-list-item
|
|
164
|
-
v-for="(child,
|
|
165
|
-
:key="
|
|
163
|
+
v-for="(child, childIdx) in item.Children"
|
|
164
|
+
:key="childIdx"
|
|
166
165
|
:active="child.Name === selectedPresetName"
|
|
167
166
|
@click="emit('select', child)"
|
|
168
167
|
class="px-2 mb-1"
|
|
@@ -171,7 +170,7 @@ watch(filteredPresets, drawAllCanvases);
|
|
|
171
170
|
<div class="d-flex flex-column py-1">
|
|
172
171
|
<span class="text-caption text-grey-lighten-1 mb-1">{{ child.Name }}</span>
|
|
173
172
|
<canvas
|
|
174
|
-
:ref="(
|
|
173
|
+
:ref="(element) => setCanvasRef(child.Name, element, `g-${index}-${childIdx}`)"
|
|
175
174
|
width="200"
|
|
176
175
|
height="18"
|
|
177
176
|
class="w-100 rounded-xs border-thin"
|
|
@@ -191,7 +190,7 @@ watch(filteredPresets, drawAllCanvases);
|
|
|
191
190
|
<div class="d-flex flex-column py-1">
|
|
192
191
|
<span class="text-caption text-grey-lighten-1 mb-1">{{ item.Name }}</span>
|
|
193
192
|
<canvas
|
|
194
|
-
:ref="(
|
|
193
|
+
:ref="(element) => setCanvasRef(item.Name, element, `s-${index}`)"
|
|
195
194
|
width="200"
|
|
196
195
|
height="18"
|
|
197
196
|
class="w-100 rounded-xs border-thin"
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<script setup>
|
|
2
|
+
import { getRGBPointsFromPreset, scientificPresets } from "@ogw_front/utils/colormap";
|
|
2
3
|
import ColorMapList from "./ColorMapList.vue";
|
|
3
4
|
import { newInstance } from "@kitware/vtk.js/Rendering/Core/ColorTransferFunction";
|
|
4
|
-
import vtkColorMaps from "@kitware/vtk.js/Rendering/Core/ColorTransferFunction/ColorMaps";
|
|
5
5
|
|
|
6
6
|
const LAST_POINT_OFFSET = 4;
|
|
7
7
|
const THREE = 3;
|
|
@@ -11,56 +11,28 @@ const { max, min } = defineProps({
|
|
|
11
11
|
max: { type: Number, required: true },
|
|
12
12
|
});
|
|
13
13
|
|
|
14
|
-
const selectedPresetName = defineModel("selectedPresetName", { default: "
|
|
14
|
+
const selectedPresetName = defineModel("selectedPresetName", { default: "batlow" });
|
|
15
15
|
|
|
16
16
|
const menuOpen = ref(false);
|
|
17
17
|
const lutCanvas = ref();
|
|
18
18
|
|
|
19
19
|
const presets = computed(() => {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
"Black-Body Radiation",
|
|
29
|
-
"erdc_rainbow_bright",
|
|
30
|
-
];
|
|
31
|
-
const matplotlibNames = [
|
|
32
|
-
"Viridis (matplotlib)",
|
|
33
|
-
"Plasma (matplotlib)",
|
|
34
|
-
"Inferno (matplotlib)",
|
|
35
|
-
"Magma (matplotlib)",
|
|
36
|
-
];
|
|
37
|
-
|
|
38
|
-
const paraviewPresets = paraviewNames
|
|
39
|
-
.map((name) => vtkColorMaps.getPresetByName(name))
|
|
40
|
-
.filter(Boolean);
|
|
41
|
-
const matplotlibPresets = matplotlibNames
|
|
42
|
-
.map((name) => vtkColorMaps.getPresetByName(name))
|
|
43
|
-
.filter(Boolean);
|
|
44
|
-
const otherPresets = allPresets.filter(
|
|
45
|
-
(preset) => !paraviewNames.includes(preset.Name) && !matplotlibNames.includes(preset.Name),
|
|
46
|
-
);
|
|
47
|
-
|
|
48
|
-
const currentPreset = vtkColorMaps.getPresetByName(selectedPresetName.value);
|
|
49
|
-
|
|
50
|
-
return [
|
|
51
|
-
currentPreset,
|
|
52
|
-
{ Name: "ParaView", Children: paraviewPresets },
|
|
53
|
-
{ Name: "Matplotlib", Children: matplotlibPresets },
|
|
54
|
-
{ Name: "Others", Children: otherPresets },
|
|
55
|
-
].filter(Boolean);
|
|
20
|
+
let currentPreset = undefined;
|
|
21
|
+
for (const category of scientificPresets) {
|
|
22
|
+
currentPreset = category.Children.find((preset) => preset.Name === selectedPresetName.value);
|
|
23
|
+
if (currentPreset) {
|
|
24
|
+
break;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
return [currentPreset, ...scientificPresets].filter(Boolean);
|
|
56
28
|
});
|
|
57
29
|
|
|
58
30
|
function drawLutCanvas() {
|
|
59
31
|
if (!lutCanvas.value) {
|
|
60
32
|
return;
|
|
61
33
|
}
|
|
62
|
-
const
|
|
63
|
-
if (!
|
|
34
|
+
const rgbPoints = getRGBPointsFromPreset(selectedPresetName.value);
|
|
35
|
+
if (!rgbPoints || rgbPoints.length === 0) {
|
|
64
36
|
return;
|
|
65
37
|
}
|
|
66
38
|
|
|
@@ -69,7 +41,6 @@ function drawLutCanvas() {
|
|
|
69
41
|
const { height, width } = canvas;
|
|
70
42
|
|
|
71
43
|
const lut = newInstance();
|
|
72
|
-
const rgbPoints = preset.RGBPoints;
|
|
73
44
|
|
|
74
45
|
for (let pointIdx = 0; pointIdx < rgbPoints.length; pointIdx += 4) {
|
|
75
46
|
lut.addRGBPoint(
|
|
@@ -14,7 +14,6 @@ const { displayMenu, containerWidth, containerHeight } = defineProps({
|
|
|
14
14
|
});
|
|
15
15
|
|
|
16
16
|
const emit = defineEmits(["show-menu"]);
|
|
17
|
-
|
|
18
17
|
const dataStore = useDataStore();
|
|
19
18
|
const dataStyleStore = useDataStyleStore();
|
|
20
19
|
const viewerStore = useViewerStore();
|
|
@@ -56,4 +55,52 @@ defineExpose({ get_viewer_id });
|
|
|
56
55
|
:container-width="containerWidth"
|
|
57
56
|
:container-height="containerHeight"
|
|
58
57
|
/>
|
|
58
|
+
|
|
59
|
+
<v-fade-transition>
|
|
60
|
+
<div
|
|
61
|
+
v-if="viewerStore.picking_mode"
|
|
62
|
+
class="picking-message-container d-flex justify-center w-100 pa-4"
|
|
63
|
+
>
|
|
64
|
+
<v-chip
|
|
65
|
+
color="secondary"
|
|
66
|
+
elevation="8"
|
|
67
|
+
size="large"
|
|
68
|
+
variant="flat"
|
|
69
|
+
prepend-icon="mdi-crosshairs-gps"
|
|
70
|
+
class="pick-pulse"
|
|
71
|
+
style="pointer-events: auto"
|
|
72
|
+
@click="viewerStore.toggle_picking_mode(false)"
|
|
73
|
+
>
|
|
74
|
+
Picking active — click in the viewer · Esc to stop
|
|
75
|
+
<v-divider vertical class="mx-2 my-1" opacity="0.3" />
|
|
76
|
+
<v-icon icon="mdi-close" size="small" />
|
|
77
|
+
</v-chip>
|
|
78
|
+
</div>
|
|
79
|
+
</v-fade-transition>
|
|
59
80
|
</template>
|
|
81
|
+
|
|
82
|
+
<style scoped>
|
|
83
|
+
.picking-message-container {
|
|
84
|
+
position: absolute;
|
|
85
|
+
top: 20px;
|
|
86
|
+
left: 0;
|
|
87
|
+
pointer-events: none;
|
|
88
|
+
z-index: 100;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
@keyframes pulse-ring {
|
|
92
|
+
0% {
|
|
93
|
+
box-shadow: 0 0 0 0 rgba(var(--v-theme-secondary), 0.7);
|
|
94
|
+
}
|
|
95
|
+
70% {
|
|
96
|
+
box-shadow: 0 0 0 10px rgba(var(--v-theme-secondary), 0);
|
|
97
|
+
}
|
|
98
|
+
100% {
|
|
99
|
+
box-shadow: 0 0 0 0 rgba(var(--v-theme-secondary), 0);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
.pick-pulse {
|
|
104
|
+
animation: pulse-ring 1.5s ease-out infinite;
|
|
105
|
+
}
|
|
106
|
+
</style>
|
package/app/stores/viewer.js
CHANGED
|
@@ -27,7 +27,7 @@ export const useViewerStore = defineStore(
|
|
|
27
27
|
const client = ref({});
|
|
28
28
|
const config = ref(undefined);
|
|
29
29
|
const picking_mode = ref(false);
|
|
30
|
-
const picked_point = ref({ x: undefined, y: undefined });
|
|
30
|
+
const picked_point = ref({ x: undefined, y: undefined, z: undefined });
|
|
31
31
|
const request_counter = ref(0);
|
|
32
32
|
const status = ref(Status.NOT_CONNECTED);
|
|
33
33
|
const buzy = ref(0);
|
|
@@ -62,14 +62,12 @@ export const useViewerStore = defineStore(
|
|
|
62
62
|
}
|
|
63
63
|
|
|
64
64
|
async function set_picked_point(x, y) {
|
|
65
|
-
const response = await request(schemas.opengeodeweb_viewer.
|
|
66
|
-
x,
|
|
67
|
-
y,
|
|
65
|
+
const response = await request(schemas.opengeodeweb_viewer.viewer.get_point_position, {
|
|
66
|
+
x: Math.round(x),
|
|
67
|
+
y: Math.round(y),
|
|
68
68
|
});
|
|
69
|
-
const { x: world_x, y: world_y } = response;
|
|
70
|
-
picked_point.value
|
|
71
|
-
picked_point.value.y = world_y;
|
|
72
|
-
picking_mode.value = false;
|
|
69
|
+
const { x: world_x, y: world_y, z: world_z } = response;
|
|
70
|
+
picked_point.value = { x: world_x, y: world_y, z: world_z };
|
|
73
71
|
}
|
|
74
72
|
|
|
75
73
|
function ws_connect() {
|
package/app/utils/colormap.js
CHANGED
|
@@ -1,7 +1,11 @@
|
|
|
1
|
-
import
|
|
1
|
+
import scientificPresets from "@ogw_front/assets/scientific_colormaps.json";
|
|
2
2
|
|
|
3
3
|
function getRGBPointsFromPreset(presetName) {
|
|
4
|
-
return
|
|
4
|
+
return (
|
|
5
|
+
scientificPresets
|
|
6
|
+
.flatMap((category) => category.Children)
|
|
7
|
+
.find((preset) => preset.Name === presetName)?.RGBPoints ?? []
|
|
8
|
+
);
|
|
5
9
|
}
|
|
6
10
|
|
|
7
|
-
export { getRGBPointsFromPreset };
|
|
11
|
+
export { getRGBPointsFromPreset, scientificPresets };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@geode/opengeodeweb-front",
|
|
3
|
-
"version": "10.
|
|
3
|
+
"version": "10.18.0-rc.2",
|
|
4
4
|
"description": "OpenSource Vue/Nuxt/Pinia/Vuetify framework for web applications",
|
|
5
5
|
"homepage": "https://github.com/Geode-solutions/OpenGeodeWeb-Front",
|
|
6
6
|
"bugs": {
|
|
@@ -34,8 +34,8 @@
|
|
|
34
34
|
"build": ""
|
|
35
35
|
},
|
|
36
36
|
"dependencies": {
|
|
37
|
-
"@geode/opengeodeweb-back": "
|
|
38
|
-
"@geode/opengeodeweb-viewer": "
|
|
37
|
+
"@geode/opengeodeweb-back": "next",
|
|
38
|
+
"@geode/opengeodeweb-viewer": "next",
|
|
39
39
|
"@google-cloud/run": "3.2.0",
|
|
40
40
|
"@kitware/vtk.js": "33.3.0",
|
|
41
41
|
"@mdi/font": "7.4.47",
|