Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

1134 refresh timeseries #1136

Draft
wants to merge 13 commits into
base: main
Choose a base branch
from
Draft
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
40 changes: 30 additions & 10 deletions src/components/charts/ElevationChart.vue
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
<template>
<div class="chart-with-chips">
<LoadingOverlay v-if="isLoading" :offsets="margin" height="90%" />
<div ref="chartContainer" class="chart-container" v-show="!isLoading"></div>
<div ref="chartContainer" class="chart-container"></div>
<v-sheet
class="chart-controls"
rounded
Expand Down Expand Up @@ -57,7 +56,6 @@ import {
VerticalMouseOver,
ZoomHandler,
} from '@deltares/fews-web-oc-charts'
import LoadingOverlay from '@/components/charts/LoadingOverlay.vue'
import type { ChartConfig } from '../../lib/charts/types/ChartConfig.js'
import type { ChartSeries } from '../../lib/charts/types/ChartSeries.js'
import { Series } from '../../lib/timeseries/timeSeries.js'
Expand Down Expand Up @@ -88,6 +86,7 @@ interface Tag {
const props = withDefaults(defineProps<Props>(), {
config: () => {
return {
id: '',
title: '',
series: [],
}
Expand Down Expand Up @@ -153,10 +152,7 @@ onMounted(() => {
axis.accept(zoom)
axis.accept(mouseOver)
resize()
if (props.config !== undefined) {
refreshChart()
setTags()
}
if (props.config !== undefined) onValueChange()
window.addEventListener('resize', resize)
}
})
Expand Down Expand Up @@ -252,6 +248,30 @@ const refreshChart = () => {
})
}

const updateChartData = (series: ChartSeries[]) => {
series.forEach((series) => {
const chart = axis.charts.find((chart) => chart.id == series.id)
if (chart !== undefined) {
const rawData = dataFromResources(series.dataResources, props.series)
const data = removeUnreliableData(rawData)
chart.data = data
}
})
// Ensure the current zoom, which might be user-selected, does not change
axis.redraw({
x: {
nice: false,
domain: undefined,
fullExtent: false,
},
y: {
nice: false,
domain: undefined,
fullExtent: false,
},
})
}

const setTags = () => {
const s = new XMLSerializer()
const seriesData = props.config?.series
Expand Down Expand Up @@ -340,11 +360,11 @@ watch(
),
(newValue, oldValue) => {
const newSeriesIds = difference(newValue, oldValue)
const requiredSeriesIds = props.config?.series.filter((s) =>
const requiredSeries = props.config?.series.filter((s) =>
newSeriesIds.map((id) => id.split('-')[0]).includes(s.id),
)
if (requiredSeriesIds.length > 0) {
onValueChange()
if (requiredSeries.length > 0) {
updateChartData(requiredSeries)
}
},
)
Expand Down
55 changes: 47 additions & 8 deletions src/components/charts/TimeSeriesChart.vue
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
<template>
<div class="chart-with-chips">
<LoadingOverlay v-if="isLoading" :offsets="margin" height="80%" />
<div ref="chartContainer" class="chart-container" v-show="!isLoading"></div>
<div ref="chartContainer" class="chart-container"></div>
<v-sheet
class="chart-controls"
rounded
Expand Down Expand Up @@ -65,7 +64,6 @@ import {
CurrentTime,
MouseOver,
} from '@deltares/fews-web-oc-charts'
import LoadingOverlay from '@/components/charts/LoadingOverlay.vue'
import type { ChartConfig } from '../../lib/charts/types/ChartConfig.js'
import type { ChartSeries } from '../../lib/charts/types/ChartSeries.js'
import type { ThresholdLine } from '../../lib/charts/types/ThresholdLine.js'
Expand Down Expand Up @@ -99,6 +97,7 @@ interface Tag {
const props = withDefaults(defineProps<Props>(), {
config: () => {
return {
id: '',
title: '',
series: [],
}
Expand All @@ -120,6 +119,7 @@ const chipGroup = ref<VChipGroup>()
const expanded = ref(false)
const requiresExpand = ref(false)
const axisTime = ref<CurrentTime>()
const hasLoadedOnce = ref(false)

const margin = {
top: 110,
Expand Down Expand Up @@ -177,7 +177,7 @@ onMounted(() => {
axis.accept(mouseOver)
axis.accept(axisTime.value)
resize()
if (props.config !== undefined) refreshChart()
if (props.config !== undefined) onValueChange()
window.addEventListener('resize', resize)
}
})
Expand All @@ -187,7 +187,7 @@ watch(
(newValue) => {
if (axisTime.value) {
axisTime.value.setDateTime(newValue)
onValueChange()
axisTime.value.redraw()
}
},
)
Expand Down Expand Up @@ -303,6 +303,7 @@ const clearChart = () => {
}

const refreshChart = () => {
/* Adds charts to the axis if not yet present, and removes charts that should no longer be there */
const ids: string[] = axis.charts.map((c: any) => c.id)
const removeIds: string[] = axis.charts.map((c: any) => c.id)
if (props.config?.series === undefined) return
Expand Down Expand Up @@ -342,6 +343,30 @@ const refreshChart = () => {
})
}

const updateChartData = (series: ChartSeries[]) => {
series.forEach((series) => {
const chart = axis.charts.find((chart) => chart.id == series.id)
if (chart !== undefined) {
const rawData = dataFromResources(series.dataResources, props.series)
const data = removeUnreliableData(rawData)
chart.data = data
}
})
// Ensure the current zoom, which might be user-selected, does not change
axis.redraw({
x: {
nice: false,
domain: undefined,
fullExtent: false,
},
y: {
nice: false,
domain: undefined,
fullExtent: false,
},
})
}

const setTags = () => {
const s = new XMLSerializer()
const seriesData = props.config?.series
Expand Down Expand Up @@ -448,15 +473,29 @@ watch(
),
(newValue, oldValue) => {
const newSeriesIds = difference(newValue, oldValue)
const requiredSeriesIds = props.config?.series.filter((s) =>
const requiredSeries = props.config?.series.filter((s) =>
newSeriesIds.map((id) => id.split('-')[0]).includes(s.id),
)
if (requiredSeriesIds.length > 0) {
onValueChange()
if (requiredSeries.length > 0) {
updateChartData(requiredSeries)
}
},
)
watch(props.config, onValueChange)
watch(
() => props.isLoading,
(newValue, oldValue) => {
// isLoading changes every time the data is requested again.
// We need to keep track of the first time the data has been loaded, in order to fully draw the chart once
if (!newValue) {
hasLoadedOnce.value = true
}
},
)

watch(hasLoadedOnce, onValueChange, {
once: true,
})

onBeforeUnmount(() => {
beforeDestroy()
Expand Down
7 changes: 4 additions & 3 deletions src/components/timeseries/TimeSeriesComponent.vue
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@
>
<KeepAlive>
<TimeSeriesChart
v-for="(subplot, i) in subplots"
v-for="subplot in subplots"
:config="subplot"
:series="series"
:key="`${subplot.title}-${i}`"
:key="subplot.id"
:currentTime="props.currentTime"
:isLoading="isLoading(subplot, loadingSeriesIds)"
:zoomHandler="sharedZoomHandler"
Expand Down Expand Up @@ -199,7 +199,7 @@ const elevationChartSubplots = computed(() => {
}
})

const tableConfig = ref<ChartConfig>({ title: '', series: [] })
const tableConfig = ref<ChartConfig>({ id: '', title: '', series: [] })

watch(
() => props.config.subplots,
Expand All @@ -215,6 +215,7 @@ watch(
})

tableConfig.value = {
id: 'table',
title: props.config.title,
series,
}
Expand Down
5 changes: 3 additions & 2 deletions src/lib/charts/timeSeriesDisplayToChartConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ import {

export function timeSeriesDisplayToChartConfig(
subplot: TimeSeriesDisplaySubplot,
title: string,
domain?: [Date, Date],
): ChartConfig {
const xAxis = subplot.xAxis ? xAxisFromPlotItemXAxis(subplot.xAxis) : []
Expand All @@ -34,8 +33,10 @@ export function timeSeriesDisplayToChartConfig(
}
}

const subplotId = subplot.items.map((plot) => plot.request).toString()
const config: ChartConfig = {
title: title,
id: subplotId,
title: '',
xAxis,
yAxis: yAxisFromSubplot(subplot),
series: [],
Expand Down
1 change: 1 addition & 0 deletions src/lib/charts/types/ChartConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { ThresholdLine } from './ThresholdLine'
import { AxisOptions } from '@deltares/fews-web-oc-charts'

export interface ChartConfig {
id: string
title: string
xAxis?: AxisOptions[]
yAxis?: AxisOptions[]
Expand Down
2 changes: 1 addition & 1 deletion src/services/useDisplayConfig/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ function actionsResponseToDisplayConfig(

const subplots =
result.config.timeSeriesDisplay.subplots?.map((subPlot) => {
return timeSeriesDisplayToChartConfig(subPlot, title, configPeriod)
return timeSeriesDisplayToChartConfig(subPlot, configPeriod)
}) ?? []
const display: DisplayConfig = {
id: title,
Expand Down
2 changes: 1 addition & 1 deletion src/services/useSsdPi/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ export function useSsdPi(
subplots = result.config.timeSeriesDisplay.subplots?.map((subPlot) => {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
return timeSeriesDisplayToChartConfig(subPlot, title)
return timeSeriesDisplayToChartConfig(subPlot)
})
}
const display: DisplayConfig = {
Expand Down
23 changes: 19 additions & 4 deletions src/services/useTimeSeries/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,19 @@ import { difference } from 'lodash-es'
import { SeriesData } from '@/lib/timeseries/types/SeriesData'
import { convertFewsPiDateTimeToJsDate } from '@/lib/date'
import { debouncedRef } from '@vueuse/core'
import { type Pausable, useIntervalFn } from '@vueuse/core'

export interface UseTimeSeriesReturn {
error: Ref<any>
series: Ref<Record<string, Series>>
isReady: Ref<boolean>
isLoading: Ref<boolean>
loadingSeriesIds: Ref<string[]>
interval: Pausable
}

const TIMESERIES_POLLING_INTERVAL = 1000 * 30

export interface UseTimeSeriesOptions {
startTime?: Date | null
endTime?: Date | null
Expand Down Expand Up @@ -65,6 +69,10 @@ export function useTimeSeries(
const isLoading = computed(() => debouncedLoadingSeriesIds.value.length > 0)

watch([lastUpdated, selectedTime ?? ref(), requests, options], () => {
loadTimeSeries()
})

function loadTimeSeries() {
controller.abort('Timeseries request triggered again before finishing.')
controller = new AbortController()
const piProvider = new PiWebserviceProvider(baseUrl, {
Expand Down Expand Up @@ -135,7 +143,10 @@ export function useTimeSeries(
? `${request.key}[${index}]`
: (request.key ?? '')
updatedSeriesIds.push(resourceId)
const resource = new SeriesUrlRequest('fews-pi', 'dummyUrl')
const resource = new SeriesUrlRequest(
'fews-pi',
`dummyUrl-for-resource-${resourceId}`,
)
const _series = new Series(resource)
const header = timeSeries.header
if (header !== undefined) {
Expand Down Expand Up @@ -190,21 +201,25 @@ export function useTimeSeries(
delete series.value[seriesId]
}
}
}

const interval = useIntervalFn(loadTimeSeries, TIMESERIES_POLLING_INTERVAL, {
immediate: true,
immediateCallback: true,
})

onUnmounted(() => {
controller.abort('useTimeSeries unmounted.')
})

const shell = {
return {
series,
isReady,
isLoading,
loadingSeriesIds: debouncedLoadingSeriesIds,
error,
interval,
}

return shell
}

export async function postTimeSeriesEdit(
Expand Down
Loading