From 1d90d8df1ed15846f8d273f413d5ebf774334c97 Mon Sep 17 00:00:00 2001 From: MaxNumerique Date: Mon, 18 May 2026 14:53:58 +0200 Subject: [PATCH 01/11] temp --- app/components/HybridRenderingView.vue | 95 ++++++++++++++++++++++++++ app/stores/hybrid_viewer.js | 43 +++++++++++- 2 files changed, 136 insertions(+), 2 deletions(-) diff --git a/app/components/HybridRenderingView.vue b/app/components/HybridRenderingView.vue index 1a6b8db68..53db404e3 100644 --- a/app/components/HybridRenderingView.vue +++ b/app/components/HybridRenderingView.vue @@ -60,6 +60,84 @@ async function handleClick(event) {
+ + + +
+ +
+ + + {{ hybridViewerStore.hoverData.component?.name || `${hybridViewerStore.hoverData.fieldType} #${hybridViewerStore.hoverData.pickedId}` }} + +
+ + +
+
+ Type: + {{ hybridViewerStore.hoverData.component.type }} +
+
+ ID: + + {{ hybridViewerStore.hoverData.component.id }} + +
+
+ + +
+ +
+ Position: +
+ X: {{ Number(hybridViewerStore.hoverData.attributes.coordinates[0]).toFixed(3) }} + Y: {{ Number(hybridViewerStore.hoverData.attributes.coordinates[1]).toFixed(3) }} + Z: {{ Number(hybridViewerStore.hoverData.attributes.coordinates[2]).toFixed(3) }} +
+
+ + + +
+
+
+ diff --git a/app/stores/hybrid_viewer.js b/app/stores/hybrid_viewer.js index bce5237fd..b4ca243a1 100644 --- a/app/stores/hybrid_viewer.js +++ b/app/stores/hybrid_viewer.js @@ -27,6 +27,7 @@ import { newInstance as vtkXMLPolyDataReader } from "@kitware/vtk.js/IO/XML/XMLP import { Status } from "@ogw_front/utils/status"; import { useDataStore } from "@ogw_front/stores/data"; import { useViewerStore } from "@ogw_front/stores/viewer"; +import { database } from "@ogw_internal/database/database.js"; import viewer_schemas from "@geode/opengeodeweb-viewer/opengeodeweb_viewer_schemas.json"; @@ -41,6 +42,8 @@ export const useHybridViewerStore = defineStore("hybridViewer", () => { const is_picking = ref(false); const is_hover_highlight = ref(false); const hover_highlight_field_type = ref("CELL"); + const hoverData = ref(null); + const hoverPosition = ref({ x: 0, y: 0 }); const zScale = ref(1); let imageStyle = undefined; let viewStream = undefined; @@ -185,7 +188,8 @@ export const useHybridViewerStore = defineStore("hybridViewer", () => { } const throttledHoverHighlight = useThrottleFn( - (event) => + (event) => { + hoverPosition.value = { x: event.clientX, y: event.clientY }; performHoverHighlight(event, { is_hover_highlight, genericRenderWindow: genericRenderWindow.value, @@ -193,11 +197,44 @@ export const useHybridViewerStore = defineStore("hybridViewer", () => { viewer_schemas, hover_highlight_field_type, hybridDb, - }), + onResponse: async (response) => { + if (!is_hover_highlight.value) { + hoverData.value = null; + return; + } + if (response && response.id && response.picked_id !== undefined && response.picked_id !== -1) { + let componentInfo = null; + if (response.geode_id) { + const component = await database.model_components + .where("[id+geode_id]") + .equals([response.id, response.geode_id]) + .first(); + if (component) { + componentInfo = { + name: component.name, + id: component.geode_id, + type: component.type, + }; + } + } + hoverData.value = { + modelId: response.id, + pickedId: response.picked_id, + fieldType: response.field_type, + component: componentInfo, + attributes: response.attributes || {}, + }; + } else { + hoverData.value = null; + } + }, + }); + }, HOVER_THROTTLE_MS, ); function clearHoverHighlight() { + hoverData.value = null; performClearHoverHighlight({ viewerStore, viewer_schemas, @@ -297,6 +334,8 @@ export const useHybridViewerStore = defineStore("hybridViewer", () => { is_hover_highlight, hover_highlight_field_type, clearHoverHighlight, + hoverData, + hoverPosition, clear, exportStores, importStores, From b3ef1e45d4468c53d636b6a1f0210838b61aaf1d Mon Sep 17 00:00:00 2001 From: MaxNumerique <144453705+MaxNumerique@users.noreply.github.com> Date: Mon, 18 May 2026 13:14:42 +0000 Subject: [PATCH 02/11] Apply prepare changes --- app/components/HybridRenderingView.vue | 63 ++++++++++++++---- app/stores/hybrid_viewer.js | 88 +++++++++++++------------- 2 files changed, 94 insertions(+), 57 deletions(-) diff --git a/app/components/HybridRenderingView.vue b/app/components/HybridRenderingView.vue index 53db404e3..3b607da5c 100644 --- a/app/components/HybridRenderingView.vue +++ b/app/components/HybridRenderingView.vue @@ -60,19 +60,22 @@ async function handleClick(event) {
- +
-
+
- {{ hybridViewerStore.hoverData.component?.name || `${hybridViewerStore.hoverData.fieldType} #${hybridViewerStore.hoverData.pickedId}` }} + {{ + hybridViewerStore.hoverData.component?.name || + `${hybridViewerStore.hoverData.fieldType} #${hybridViewerStore.hoverData.pickedId}` + }}
-
+
Type: - {{ hybridViewerStore.hoverData.component.type }} + {{ + hybridViewerStore.hoverData.component.type + }}
ID: - + {{ hybridViewerStore.hoverData.component.id }}
@@ -113,15 +127,36 @@ async function handleClick(event) {
-
+
Position: -
- X: {{ Number(hybridViewerStore.hoverData.attributes.coordinates[0]).toFixed(3) }} - Y: {{ Number(hybridViewerStore.hoverData.attributes.coordinates[1]).toFixed(3) }} - Z: {{ Number(hybridViewerStore.hoverData.attributes.coordinates[2]).toFixed(3) }} +
+ X: + {{ + Number(hybridViewerStore.hoverData.attributes.coordinates[0]).toFixed(3) + }} + Y: + {{ + Number(hybridViewerStore.hoverData.attributes.coordinates[1]).toFixed(3) + }} + Z: + {{ + Number(hybridViewerStore.hoverData.attributes.coordinates[2]).toFixed(3) + }}
@@ -130,7 +165,7 @@ async function handleClick(event) {
{{ name }}: - {{ typeof val === 'number' ? Number(val).toFixed(4) : val }} + {{ typeof val === "number" ? Number(val).toFixed(4) : val }}
diff --git a/app/stores/hybrid_viewer.js b/app/stores/hybrid_viewer.js index b4ca243a1..a9acdba83 100644 --- a/app/stores/hybrid_viewer.js +++ b/app/stores/hybrid_viewer.js @@ -187,51 +187,53 @@ export const useHybridViewerStore = defineStore("hybridViewer", () => { return viewerStore.request(viewer_schemas.opengeodeweb_viewer.viewer.render); } - const throttledHoverHighlight = useThrottleFn( - (event) => { - hoverPosition.value = { x: event.clientX, y: event.clientY }; - performHoverHighlight(event, { - is_hover_highlight, - genericRenderWindow: genericRenderWindow.value, - viewerStore, - viewer_schemas, - hover_highlight_field_type, - hybridDb, - onResponse: async (response) => { - if (!is_hover_highlight.value) { - hoverData.value = null; - return; - } - if (response && response.id && response.picked_id !== undefined && response.picked_id !== -1) { - let componentInfo = null; - if (response.geode_id) { - const component = await database.model_components - .where("[id+geode_id]") - .equals([response.id, response.geode_id]) - .first(); - if (component) { - componentInfo = { - name: component.name, - id: component.geode_id, - type: component.type, - }; - } + const throttledHoverHighlight = useThrottleFn((event) => { + hoverPosition.value = { x: event.clientX, y: event.clientY }; + performHoverHighlight(event, { + is_hover_highlight, + genericRenderWindow: genericRenderWindow.value, + viewerStore, + viewer_schemas, + hover_highlight_field_type, + hybridDb, + onResponse: async (response) => { + if (!is_hover_highlight.value) { + hoverData.value = null; + return; + } + if ( + response && + response.id && + response.picked_id !== undefined && + response.picked_id !== -1 + ) { + let componentInfo = null; + if (response.geode_id) { + const component = await database.model_components + .where("[id+geode_id]") + .equals([response.id, response.geode_id]) + .first(); + if (component) { + componentInfo = { + name: component.name, + id: component.geode_id, + type: component.type, + }; } - hoverData.value = { - modelId: response.id, - pickedId: response.picked_id, - fieldType: response.field_type, - component: componentInfo, - attributes: response.attributes || {}, - }; - } else { - hoverData.value = null; } - }, - }); - }, - HOVER_THROTTLE_MS, - ); + hoverData.value = { + modelId: response.id, + pickedId: response.picked_id, + fieldType: response.field_type, + component: componentInfo, + attributes: response.attributes || {}, + }; + } else { + hoverData.value = null; + } + }, + }); + }, HOVER_THROTTLE_MS); function clearHoverHighlight() { hoverData.value = null; From a54a7701e1c0d98ff878f21976994fd303a6dc87 Mon Sep 17 00:00:00 2001 From: MaxNumerique Date: Mon, 18 May 2026 17:18:26 +0200 Subject: [PATCH 03/11] feat(viewer): add a tooltip with infos on hover cells and nodes --- app/components/HybridRenderingView.vue | 236 +++++++++++++++++-------- app/stores/hybrid_viewer.js | 141 ++++++++++----- 2 files changed, 261 insertions(+), 116 deletions(-) diff --git a/app/components/HybridRenderingView.vue b/app/components/HybridRenderingView.vue index 53db404e3..d20266236 100644 --- a/app/components/HybridRenderingView.vue +++ b/app/components/HybridRenderingView.vue @@ -1,9 +1,11 @@ diff --git a/app/components/Inspector/InspectionButton.vue b/app/components/Inspector/InspectionButton.vue index 625c7894a..c9d9e7529 100644 --- a/app/components/Inspector/InspectionButton.vue +++ b/app/components/Inspector/InspectionButton.vue @@ -1,6 +1,7 @@ diff --git a/app/components/Viewer/Options/Sliders/Width.vue b/app/components/Viewer/Options/Sliders/Width.vue index c699b9d61..c0b81e991 100644 --- a/app/components/Viewer/Options/Sliders/Width.vue +++ b/app/components/Viewer/Options/Sliders/Width.vue @@ -1,5 +1,6 @@ diff --git a/app/composables/run_function_when_microservices_connected.js b/app/composables/run_function_when_microservices_connected.js index 0248f2208..e12371e56 100644 --- a/app/composables/run_function_when_microservices_connected.js +++ b/app/composables/run_function_when_microservices_connected.js @@ -1,4 +1,5 @@ import { useInfraStore } from "@ogw_front/stores/infra"; + export function run_function_when_microservices_connected(function_to_run) { const infraStore = useInfraStore(); const { microservices_connected } = storeToRefs(infraStore); diff --git a/app/stores/treeview.js b/app/stores/treeview.js index e3db57de0..2dc6443fc 100644 --- a/app/stores/treeview.js +++ b/app/stores/treeview.js @@ -3,6 +3,7 @@ import { defineStore } from "pinia"; import { ref, toRaw, watch } from "vue"; import { compareSelections } from "@ogw_front/utils/treeview"; import { database } from "@ogw_internal/database/database"; + const PANEL_WIDTH = 300; export const useTreeviewStore = defineStore("treeview", () => { From 59fc03d4e106693a653543fb69d8e87f21939ba4 Mon Sep 17 00:00:00 2001 From: MaxNumerique Date: Tue, 19 May 2026 11:28:51 +0200 Subject: [PATCH 09/11] refacto --- app/components/HybridRenderingView.vue | 111 +++++++++++++------------ 1 file changed, 58 insertions(+), 53 deletions(-) diff --git a/app/components/HybridRenderingView.vue b/app/components/HybridRenderingView.vue index 2e5bd37d1..dd4afb97b 100644 --- a/app/components/HybridRenderingView.vue +++ b/app/components/HybridRenderingView.vue @@ -16,7 +16,7 @@ const viewerStore = useViewerStore(); const { width: elementWidth, height: elementHeight } = useElementSize(container); const { width: windowWidth, height: windowHeight } = useWindowSize(); -const tooltipRef = ref(undefined); +const tooltipRef = useTemplateRef("tooltip"); const { width: tooltipWidth, height: tooltipHeight } = useElementSize(tooltipRef); const tooltipStyle = computed(() => { @@ -28,7 +28,6 @@ const tooltipStyle = computed(() => { const measuredTooltipWidth = tooltipWidth.value; const measuredTooltipHeight = tooltipHeight.value; const tooltipOffsetGap = 20; - let left = mouseX + tooltipOffsetGap; if (left + measuredTooltipWidth > elementWidth.value) { left = mouseX - measuredTooltipWidth - tooltipOffsetGap; @@ -36,7 +35,6 @@ const tooltipStyle = computed(() => { if (left < 0) { left = TOOLTIP_SCREEN_MARGIN; } - let top = mouseY - measuredTooltipHeight - tooltipOffsetGap; if (top < 0) { top = mouseY + tooltipOffsetGap; @@ -44,7 +42,6 @@ const tooltipStyle = computed(() => { if (top + measuredTooltipHeight > elementHeight.value) { top = elementHeight.value - measuredTooltipHeight - TOOLTIP_SCREEN_MARGIN; } - return { left: `${left}px`, top: `${top}px`, @@ -145,20 +142,18 @@ async function handleClick(event) { -
- -
- -
- Name: - + + + + Name: + {{ hybridViewerStore.hoverData.component?.name || hybridViewerStore.hoverData.component?.id || @@ -167,58 +162,44 @@ async function handleClick(event) { `${capitalize(hybridViewerStore.hoverData.fieldType.toLowerCase())} #${hybridViewerStore.hoverData.pickedId}` }} -
- - -
- Id: - + + + Id: + {{ hybridViewerStore.hoverData.component?.id || hybridViewerStore.hoverData.modelId }} -
- - -
- Index: - + + + Index: + {{ originalIndex }} -
- - -
- Type: - + + + Type: + {{ hybridViewerStore.hoverData.component.type }} -
-
- - -
+ + + + .tooltip-value { + margin-left: 0 !important; +} From c0775eef98b0353712bce28cbc9240f5ba8d460b Mon Sep 17 00:00:00 2001 From: MaxNumerique Date: Tue, 19 May 2026 14:07:28 +0200 Subject: [PATCH 10/11] refacto --- app/components/HybridRenderingView.vue | 195 +--------------------- app/components/HybridViewerTooltip.vue | 216 +++++++++++++++++++++++++ 2 files changed, 218 insertions(+), 193 deletions(-) create mode 100644 app/components/HybridViewerTooltip.vue diff --git a/app/components/HybridRenderingView.vue b/app/components/HybridRenderingView.vue index dd4afb97b..96a65c463 100644 --- a/app/components/HybridRenderingView.vue +++ b/app/components/HybridRenderingView.vue @@ -1,11 +1,10 @@ + + + + From f6a0b6db2e1db78eb9aa754617d5d3d3cbb6a539 Mon Sep 17 00:00:00 2001 From: MaxNumerique Date: Tue, 19 May 2026 14:12:46 +0200 Subject: [PATCH 11/11] refacto --- app/components/HybridViewerTooltip.vue | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/components/HybridViewerTooltip.vue b/app/components/HybridViewerTooltip.vue index b50c86b8c..b0eb74714 100644 --- a/app/components/HybridViewerTooltip.vue +++ b/app/components/HybridViewerTooltip.vue @@ -31,7 +31,7 @@ const tooltipStyle = computed(() => { const tooltipOffsetGap = 20; let left = mouseX + tooltipOffsetGap; - if (left + measuredTooltipWidth > props.containerWidth) { + if (left + measuredTooltipWidth > containerWidth) { left = mouseX - measuredTooltipWidth - tooltipOffsetGap; } if (left < 0) { @@ -42,8 +42,8 @@ const tooltipStyle = computed(() => { if (top < 0) { top = mouseY + tooltipOffsetGap; } - if (top + measuredTooltipHeight > props.containerHeight) { - top = props.containerHeight - measuredTooltipHeight - TOOLTIP_SCREEN_MARGIN; + if (top + measuredTooltipHeight > containerHeight) { + top = containerHeight - measuredTooltipHeight - TOOLTIP_SCREEN_MARGIN; } return {