diff --git a/client/src/api/UVDATApi.ts b/client/src/api/UVDATApi.ts index 197eeda..e511268 100644 --- a/client/src/api/UVDATApi.ts +++ b/client/src/api/UVDATApi.ts @@ -8,6 +8,7 @@ import { ContextWithIds, Dataset, DerivedRegion, + FeatureGraphData, FileItem, LayerCollection, LayerCollectionLayer, @@ -21,6 +22,7 @@ import { RasterData, RasterMapLayer, SimulationType, + TableSummary, VectorMapLayer, } from '../types'; @@ -494,4 +496,29 @@ export default class UVdatApi { public static async deleteContext(contextId: number): Promise<{ detail: string }> { return (await UVdatApi.apiClient.delete(`/contexts/${contextId}/`)).data; } + + public static async getVectorTableSummary(layerId: number): Promise { + return (await UVdatApi.apiClient.get('/vectorfeature/tabledata/table-summary/', { params: { layerId } })).data; + } + + public static async getFeatureGraphData( + tableType: string, + vectorFeatureId: number, + xAxis: string = 'index', + yAxis: string = 'mean_va', + filter?: string, + filterVal?: string, + ): Promise { + const response = await UVdatApi.apiClient.get('/vectorfeature/tabledata/feature-graph/', { + params: { + tableType, + vectorFeatureId, + xAxis, + yAxis, + filter, + filterVal, + }, + }); + return response.data; + } } diff --git a/client/src/components/DataSelection/NetCDFDataConfigurator.vue b/client/src/components/DataSelection/NetCDFDataConfigurator.vue index 29a3d47..81d34d0 100644 --- a/client/src/components/DataSelection/NetCDFDataConfigurator.vue +++ b/client/src/components/DataSelection/NetCDFDataConfigurator.vue @@ -194,12 +194,12 @@ export default defineComponent({ } const data = getVariableInformation(newLayerSlice.value); if (data.startDate) { - sliceLayerRangeStep.value = (data.max / 1e6 - data.min / 1e6) / (data.steps || 1); - const startDate = new Date(data.min / 1e6); - const endDate = new Date(data.max / 1e6); + sliceLayerRangeStep.value = (data.max - data.min) / (data.steps || 1); + const startDate = new Date(data.min); + const endDate = new Date(data.max); const diffMilli = endDate.getTime() - startDate.getTime(); const differenceInHours = diffMilli / (1000 * 60 * 60); - sliceLayerRange.value = [data.min / 1e6, data.max / 1e6]; + sliceLayerRange.value = [data.min, data.max]; sliceLayerRangeStep.value = Math.round(differenceInHours / (data.steps || 1)) * (1000 * 60 * 60); } else { sliceLayerRange.value = [data.min, data.max]; @@ -565,10 +565,10 @@ export default defineComponent({ {{ modelValue.toFixed(2) }} @@ -589,10 +589,10 @@ export default defineComponent({ {{ modelValue.toFixed(2) }} @@ -654,8 +654,8 @@ export default defineComponent({ @@ -664,10 +664,10 @@ export default defineComponent({ diff --git a/client/src/components/FeatureSelection/RenderFeatureChart.vue b/client/src/components/FeatureSelection/PropertyFeatureChart.vue similarity index 98% rename from client/src/components/FeatureSelection/RenderFeatureChart.vue rename to client/src/components/FeatureSelection/PropertyFeatureChart.vue index 5fd08b3..80e285e 100644 --- a/client/src/components/FeatureSelection/RenderFeatureChart.vue +++ b/client/src/components/FeatureSelection/PropertyFeatureChart.vue @@ -7,7 +7,7 @@ import { drawBarChart } from '../Metadata/drawChart'; // FeatureChart TypeScript interface (as provided) export default defineComponent({ - name: 'RenderFeatureChart', + name: 'PropertyFeatureChart', props: { featureChart: { type: Object as PropType, diff --git a/client/src/components/FeatureSelection/SelectedFeature.vue b/client/src/components/FeatureSelection/SelectedFeature.vue index 1838195..6b30e08 100644 --- a/client/src/components/FeatureSelection/SelectedFeature.vue +++ b/client/src/components/FeatureSelection/SelectedFeature.vue @@ -3,13 +3,15 @@ import { PropType, Ref, computed, defineComponent, onMounted, ref, } from 'vue'; import MapStore from '../../MapStore'; -import { ClickedProps, FeatureChartWithData } from '../../types'; +import { ClickedProps, FeatureChartWithData, VectorFeatureTableGraph } from '../../types'; import { colorGenerator } from '../../map/mapColors'; -import RenderFeatureChart from './RenderFeatureChart.vue'; +import PropertyFeatureChart from './PropertyFeatureChart.vue'; +import VectorFeatureChart from './VectorFeatureChart.vue'; export default defineComponent({ components: { - RenderFeatureChart, + PropertyFeatureChart, + VectorFeatureChart, }, props: { data: { @@ -28,6 +30,8 @@ export default defineComponent({ const mapLayerId = ref(props.data.layerId); const featureId = ref(props.data.id as number); const enabledChartPanels: Ref = ref([]); + const enabledVectorChartPanel: Ref = ref([]); + const vectorGraphs: Ref = ref([]); const processLayerProps = () => { const found = MapStore.selectedVectorMapLayers.value.find((item) => item.id === props.data.layerId); if (found?.default_style.properties) { @@ -65,6 +69,9 @@ export default defineComponent({ }); } } + if (found?.default_style.vectorFeatureTableGraphs) { + vectorGraphs.value = found.default_style.vectorFeatureTableGraphs; + } }; onMounted(() => processLayerProps()); @@ -81,8 +88,10 @@ export default defineComponent({ featureId, featureCharts, enabledChartPanels, + enabledVectorChartPanel, selectedFeatureExpanded, toggleFeatureExpaned, + vectorGraphs, }; }, }); @@ -137,7 +146,24 @@ export default defineComponent({ {{ featureChart.name }} - + + + + + + + + + mdi-chart-line + {{ vectorGraph.name }} + + + @@ -146,4 +172,7 @@ export default defineComponent({ diff --git a/client/src/components/FeatureSelection/VectorFeatureChart.vue b/client/src/components/FeatureSelection/VectorFeatureChart.vue new file mode 100644 index 0000000..9a21f09 --- /dev/null +++ b/client/src/components/FeatureSelection/VectorFeatureChart.vue @@ -0,0 +1,191 @@ + + + + + diff --git a/client/src/components/Metadata/FeatureChartEditor.vue b/client/src/components/Metadata/FeatureChartEditor.vue index 03045ac..b160a4f 100644 --- a/client/src/components/Metadata/FeatureChartEditor.vue +++ b/client/src/components/Metadata/FeatureChartEditor.vue @@ -7,13 +7,13 @@ import { FeatureChart } from '../../types'; import MapStore from '../../MapStore'; import { drawBarChart } from './drawChart'; // Separate drawChart function import { colorGenerator } from '../../map/mapColors'; -import RenderFeatureChart from '../FeatureSelection/RenderFeatureChart.vue'; +import PropertyFeatureChart from '../FeatureSelection/PropertyFeatureChart.vue'; export default defineComponent({ name: 'FeatureChartEditor', components: { draggable, - RenderFeatureChart, + PropertyFeatureChart, }, props: { layerId: { @@ -278,7 +278,7 @@ export default defineComponent({ {{ chart.name }} - + diff --git a/client/src/components/NetCDFLayerConfig.vue b/client/src/components/NetCDFLayerConfig.vue index 28972df..a2c89fd 100644 --- a/client/src/components/NetCDFLayerConfig.vue +++ b/client/src/components/NetCDFLayerConfig.vue @@ -27,6 +27,36 @@ export default defineComponent({ const found = visibleNetCDFLayers.find((item) => item.netCDFLayer === props.layer.id); return found?.images.length || 0; }); + const stepMapping = computed(() => { + const found = visibleNetCDFLayers.find((item) => item.netCDFLayer === props.layer.id); + const mapSlicer: Record = {}; + let unixTimeStamp = true; + if (found) { + if (found?.sliding) { + for (let i = 0; i < found.images.length; i += 1) { + mapSlicer[i] = found.sliding.min + i * found.sliding.step; + if (found.sliding.variable === 'time') { + // convert unix timestamp to human readable date YYYY-MM-DD + try { + const date = new Date((mapSlicer[i] as number) * 1000); + // eslint-disable-next-line prefer-destructuring + mapSlicer[i] = date.toISOString().split('T')[0]; + } catch (e) { + unixTimeStamp = false; + break; + } + } + } + if (unixTimeStamp) { + return mapSlicer; + } + } + for (let i = 0; i < found.images.length; i += 1) { + mapSlicer[i] = i; + } + } + return mapSlicer; + }); const updateIndex = () => { updateNetCDFLayer(props.layer.id, currentIndex.value); }; @@ -43,6 +73,7 @@ export default defineComponent({ layerOpacity, currentIndex, totalIndex, + stepMapping, }; }, }); @@ -72,9 +103,9 @@ export default defineComponent({ mdi-checkbox-marked - Step + {{ - currentIndex + stepMapping[currentIndex] }} diff --git a/client/src/components/PropertiesConfig.vue b/client/src/components/PropertiesConfig.vue index 9bf2540..149707b 100644 --- a/client/src/components/PropertiesConfig.vue +++ b/client/src/components/PropertiesConfig.vue @@ -5,12 +5,14 @@ import { import AvailableProperties from './Metadata/AvailableProperties.vue'; import MetadataSettings from './Metadata/MetadataSettings.vue'; import SelectedFeatureChartCard from './Metadata/SelectedFeatureChartCard.vue'; +import TableSummary from './TabularData/TableSummary.vue'; export default defineComponent({ components: { AvailableProperties, MetadataSettings, SelectedFeatureChartCard, + TableSummary, }, props: { layerId: { @@ -19,7 +21,7 @@ export default defineComponent({ }, }, setup() { - const tab: Ref<'availableProperties' | 'settings' | 'charts'> = ref('availableProperties'); + const tab: Ref<'availableProperties' | 'settings' | 'charts' | 'tabularData'> = ref('availableProperties'); return { tab, @@ -72,12 +74,27 @@ export default defineComponent({ + + + +