Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
172 changes: 172 additions & 0 deletions app/components/ShrinkFilter.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
<script setup>
import ToolPanel from "@ogw_front/components/ToolPanel";
import { useDataStore } from "@ogw_front/stores/data";
import { useDebounceFn } from "@vueuse/core";
import { useHybridViewerStore } from "@ogw_front/stores/hybrid_viewer";

const DEFAULT_SHRINK_VALUE = 0.8;
const MAX_SHRINK_VALUE = 1;
const DEBOUNCE_DELAY = 100;

const show = defineModel("show", { type: Boolean, default: false });
const dataStore = useDataStore();
const hybridViewerStore = useHybridViewerStore();
const targetAllVisible = ref(true);
const selectedDatasetIds = ref([]);
const shrinkFactor = ref(DEFAULT_SHRINK_VALUE);

const allItems = dataStore.refAllItems();
const availableDatasets = computed(() =>
allItems.value.map((item) => ({ title: item.name || item.id, value: item.id })),
);

const debouncedApply = useDebounceFn(() => applyShrink(), DEBOUNCE_DELAY);

async function applyShrink() {
const allIds = allItems.value.map((item) => item.id);
if (allIds.length === 0) {
return;
}
const targetIds = targetAllVisible.value ? allIds : selectedDatasetIds.value;
const untargetedIds = allIds.filter((id) => !targetIds.includes(id));

if (targetIds.length > 0) {
await hybridViewerStore.setShrink(targetIds, Number(shrinkFactor.value));
}
if (untargetedIds.length > 0) {
await hybridViewerStore.setShrink(untargetedIds, MAX_SHRINK_VALUE);
}
}

async function resetShrink() {
shrinkFactor.value = DEFAULT_SHRINK_VALUE;
await applyShrink();
}

async function removeShrink() {
shrinkFactor.value = MAX_SHRINK_VALUE;
const allIds = allItems.value.map((item) => item.id);
if (allIds.length > 0) {
await hybridViewerStore.setShrink(allIds, MAX_SHRINK_VALUE);
}
}

watch(shrinkFactor, () => {
debouncedApply();
});

watch(show, (visible) => {
if (visible) {
applyShrink();
}
});

watch(
[targetAllVisible, selectedDatasetIds],
() => {
if (show.value) {
applyShrink();
}
},
{ deep: true },
);

watch(allItems, () => {
if (show.value) {
applyShrink();
}
});

watch(
() => Object.values(hybridViewerStore.hybridDb).filter((entry) => entry && entry.actor).length,
(actorCount) => {
if (show.value && actorCount > 0) {
applyShrink();
}
},
);
</script>

<template>
<ToolPanel v-model="show" title="Shrink Filter" :width="340" :click-outside="false">
<v-card-text class="pa-3 max-panel-height overflow-y-auto overflow-x-hidden">
<v-switch
v-model="targetAllVisible"
data-testid="shrinkTargetAllVisibleSwitch"
label="Apply to all visible datasets"
color="primary"
density="compact"
hide-details
class="mb-2 text-caption"
/>

<v-select
v-if="!targetAllVisible"
v-model="selectedDatasetIds"
data-testid="shrinkSelectedDatasetsSelect"
:items="availableDatasets"
label="Select datasets"
multiple
chips
closable-chips
variant="outlined"
density="compact"
hide-details
class="mb-3 text-caption"
/>

<v-divider class="my-3" />

<div class="d-flex align-center justify-space-between mb-1">
<span class="text-caption font-weight-bold">Shrink Factor</span>
<span class="text-caption text-primary font-weight-bold">
{{ (shrinkFactor * 100).toFixed(0) }}% ({{ shrinkFactor.toFixed(2) }})
</span>
</div>

<v-slider
v-model="shrinkFactor"
data-testid="shrinkFactorSlider"
min="0.0"
max="1.0"
step="0.01"
color="primary"
track-color="grey-lighten-2"
density="compact"
hide-details
class="my-2 px-1"
/>
</v-card-text>

<template #actions>
<v-card-actions class="justify-space-between px-3 pb-3 pt-0">
<v-btn
data-testid="removeShrinkButton"
variant="text"
size="small"
color="error"
class="text-caption text-none"
@click="removeShrink"
>
Remove Shrink
</v-btn>
<v-btn
data-testid="resetShrinkButton"
variant="tonal"
size="small"
color="secondary"
class="text-caption text-none"
@click="resetShrink"
>
Reset
</v-btn>
</v-card-actions>
</template>
</ToolPanel>
</template>

<style scoped>
.max-panel-height {
max-height: 520px;
}
</style>
12 changes: 12 additions & 0 deletions app/components/ViewToolbar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import CameraManager from "@ogw_front/components/CameraManager";
import CameraOrientation from "@ogw_front/components/CameraOrientation";
import ClippingPlanes from "@ogw_front/components/ClippingPlanes";
import Screenshot from "@ogw_front/components/Screenshot";
import ShrinkFilter from "@ogw_front/components/ShrinkFilter";
import ZScaling from "@ogw_front/components/ZScaling";
import schemas from "@geode/opengeodeweb-viewer/opengeodeweb_viewer_schemas.json";
import { useHybridViewerStore } from "@ogw_front/stores/hybrid_viewer";
Expand All @@ -17,6 +18,7 @@ const show_camera_manager = ref(false);
const showCameraOrientation = ref(false);
const showZScaling = ref(false);
const showClippingPlanes = ref(false);
const showShrinkFilter = ref(false);
const grid_scale = ref(false);
const zScale = ref(hybridViewerStore.zScale);

Expand Down Expand Up @@ -162,6 +164,15 @@ const camera_options = computed(() => [
showClippingPlanes.value = !showClippingPlanes.value;
},
},
{
testId: "shrinkFilterButton",
tooltip: "Shrink Filter",
icon: "mdi-arrow-collapse-all",
color: showShrinkFilter.value ? "primary" : undefined,
action: () => {
showShrinkFilter.value = !showShrinkFilter.value;
},
},
]);
</script>

Expand Down Expand Up @@ -235,6 +246,7 @@ const camera_options = computed(() => [
@apply="handleZScalingClose"
/>
<ClippingPlanes v-model:show="showClippingPlanes" />
<ShrinkFilter v-model:show="showShrinkFilter" />
</template>

<style module>
Expand Down
9 changes: 9 additions & 0 deletions app/stores/hybrid_viewer.js
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,13 @@
await remoteRender();
}

async function setShrink(ids, shrink_factor) {
const schema = viewer_schemas.opengeodeweb_viewer.viewer.shrink;
const params = { ids, shrink_factor };
await viewerStore.request({ schema, params });
await remoteRender();
}

function resetCamera() {
genericRenderWindow.value.getRenderer().resetCamera();
genericRenderWindow.value.getRenderWindow().render();
Expand Down Expand Up @@ -315,7 +322,9 @@
setVisibility,
setZScaling,
setClippingPlanes,
setShrink,
syncRemoteCamera,

setCamera,
initHybridViewer,
remoteRender,
Expand All @@ -338,4 +347,4 @@
latestImage,
getAverageBrightness,
};
});

Check failure on line 350 in app/stores/hybrid_viewer.js

View workflow job for this annotation

GitHub Actions / test / oxlint

eslint(max-lines)

app/stores/hybrid_viewer.js:350:4: File has too many lines (317).
Loading