Skip to content

Commit

Permalink
Merge pull request #904 from Deltares/dwo-680-default-period
Browse files Browse the repository at this point in the history
Use period from display configuration as x-axis domain
  • Loading branch information
hvangeffen authored Jun 11, 2024
2 parents 716791f + d6cc470 commit 41019db
Show file tree
Hide file tree
Showing 5 changed files with 70 additions and 22 deletions.
23 changes: 22 additions & 1 deletion src/lib/charts/timeSeriesDisplayToChartConfig.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import type { ChartConfig } from './types/ChartConfig.js'
import type { ChartSeries } from './types/ChartSeries.js'
import type {
ActionPeriod,
TimeSeriesDisplayPlotItemXAxis,
TimeSeriesDisplaySubplot,
TimeSeriesDisplaySubplotItem,
Expand All @@ -16,14 +17,34 @@ import {
AxisPosition,
AxisType,
} from '@deltares/fews-web-oc-charts'
import { convertFewsPiDateTimeToJsDate } from '@/lib/date/index.js'

export function timeSeriesDisplayToChartConfig(
subplot: TimeSeriesDisplaySubplot,
title: string,
period?: ActionPeriod,
): ChartConfig {
const xAxis = subplot.xAxis ? xAxisFromPlotItemXAxis(subplot.xAxis) : []
if (period) {
// The period is always specified in UTC.
const timeZoneOffsetString = 'Z'
const domain: [Date, Date] = [
convertFewsPiDateTimeToJsDate(period.startDate, timeZoneOffsetString),
convertFewsPiDateTimeToJsDate(period.endDate, timeZoneOffsetString),
]
// Set the domain of the x-axis to be equal to the period, even if there are
// no data points in parts of the period.
if (xAxis.length === 0) {
xAxis.push({ domain })
} else {
// Time series charts always have just a single x-axis.
xAxis[0].domain = domain
}
}

const config: ChartConfig = {
title: title,
xAxis: subplot.xAxis ? xAxisFromPlotItemXAxis(subplot.xAxis) : [],
xAxis,
yAxis: yAxisFromSubplot(subplot),
series: [],
}
Expand Down
15 changes: 15 additions & 0 deletions src/lib/date/convertFewsPiDateTimeToJsDate.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { expect, test } from 'vitest'

import { convertFewsPiDateTimeToJsDate } from '.'

test('parses a FEWS PI date/time object to a Date object without timezone offset', () => {
const fewsDatetime = { date: '2021-07-01', time: '12:00:00' }
const result = convertFewsPiDateTimeToJsDate(fewsDatetime, 'Z')
expect(result).toEqual(new Date('2021-07-01T12:00:00Z'))
})

test('parses a FEWS PI date/time object to a Date object with a timezone offset', () => {
const fewsDatetime = { date: '2021-07-01', time: '12:00:00' }
const result = convertFewsPiDateTimeToJsDate(fewsDatetime, '+02:00')
expect(result).toEqual(new Date('2021-07-01T12:00:00+02:00'))
})
17 changes: 17 additions & 0 deletions src/lib/date/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,20 @@ export function getDateWithMinutesOffset(date: Date, minutesOffset: number) {
result.setMinutes(result.getMinutes() + minutesOffset)
return result
}

/**
* Converts a FEWS PI date/time object to a Date object.
*
* @param fewsDatetime - The FEWS date/time object to convert.
* @param timeZoneOffsetString - Timezone offset string to apply to the date.
* E.g., '+02:00' or 'Z'.
* @returns The date/time as a Date object.
*/
export function convertFewsPiDateTimeToJsDate(
fewsDatetime: { date: string; time: string },
timeZoneOffsetString: string,
): Date {
return new Date(
`${fewsDatetime.date}T${fewsDatetime.time}${timeZoneOffsetString}`,
)
}
15 changes: 6 additions & 9 deletions src/services/useDisplayConfig/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import { ref, toValue, watchEffect } from 'vue'
import type { MaybeRefOrGetter, Ref } from 'vue'
import { DisplayConfig } from '../../lib/display/DisplayConfig.js'
import { timeSeriesDisplayToChartConfig } from '../../lib/charts/timeSeriesDisplayToChartConfig.js'
import { ChartConfig } from '../../lib/charts/types/ChartConfig.js'
import { createTransformRequestFn } from '@/lib/requests/transformRequest.js'
import { MD5 } from 'crypto-js'

Expand Down Expand Up @@ -47,14 +46,12 @@ function actionsResponseToDisplayConfig(
for (const result of actionsResponse.results) {
if (result.config === undefined) continue
const title = result.config.timeSeriesDisplay.title ?? ''
const timeSeriesDisplayIndex: number | undefined =
result.config.timeSeriesDisplay.index ?? undefined
let subplots: ChartConfig[] = []
if (result.config.timeSeriesDisplay.subplots) {
subplots = result.config.timeSeriesDisplay.subplots?.map((subPlot) => {
return timeSeriesDisplayToChartConfig(subPlot, title)
})
}
const timeSeriesDisplayIndex = result.config.timeSeriesDisplay.index
const period = result.config.timeSeriesDisplay.period
const subplots =
result.config.timeSeriesDisplay.subplots?.map((subPlot) => {
return timeSeriesDisplayToChartConfig(subPlot, title, period)
}) ?? []
const display: DisplayConfig = {
id: title,
title,
Expand Down
22 changes: 10 additions & 12 deletions src/services/useTimeSeries/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { SeriesUrlRequest } from '../../lib/timeseries/timeSeriesResource'
import { createTransformRequestFn } from '@/lib/requests/transformRequest'
import { difference } from 'lodash-es'
import { SeriesData } from '@/lib/timeseries/types/SeriesData'
import { convertFewsPiDateTimeToJsDate } from '@/lib/date'

export interface UseTimeSeriesReturn {
error: Ref<any>
Expand All @@ -38,13 +39,6 @@ function timeZoneOffsetString(offset: number): string {
.padStart(2, '0')}`
}

function parsePiDateTime(
event: { date: string; time: string },
timeZone: string,
) {
return `${event.date}T${event.time}${timeZone}`
}

/**
* Reactive async state. Will not block your setup function and will trigger changes once
* the promise is ready.
Expand Down Expand Up @@ -152,14 +146,18 @@ export function useTimeSeries(
_series.header.parameter = header.parameterId
_series.header.location = header.stationName
_series.header.source = header.moduleInstanceId
_series.start = new Date(
parsePiDateTime(header.startDate, timeZone),
_series.start = convertFewsPiDateTimeToJsDate(
header.startDate,
timeZone,
)
_series.end = convertFewsPiDateTimeToJsDate(
header.endDate,
timeZone,
)
_series.end = new Date(parsePiDateTime(header.endDate, timeZone))
if (timeSeries.events) {
_series.data = timeSeries.events.map((event) => {
return {
x: new Date(parsePiDateTime(event, timeZone)),
x: convertFewsPiDateTimeToJsDate(event, timeZone),
y:
event.value === _series.missingValue
? null
Expand Down Expand Up @@ -264,7 +262,7 @@ function fillSeriesForElevation(
if (time === undefined || date === undefined) {
return false
}
const eventDate = new Date(parsePiDateTime({ date, time }, timeZone))
const eventDate = convertFewsPiDateTimeToJsDate({ date, time }, timeZone)
return eventDate.getTime() === currentDate.getTime()
})

Expand Down

0 comments on commit 41019db

Please sign in to comment.