Skip to content

Commit

Permalink
refactor to allow custom temporal dimension into time slider (#1799)
Browse files Browse the repository at this point in the history
* refactor to allow custom temporal dimension into time slider

* add time dimension config in custom config json

* code cleanup

* override time dimension with custom if preset

* fix warnings

* fix range items autogenerated using createRangeOGC util

* fix default value

* remove default value logic

* fix default value is array vs single value

* fix default value override from slider config

* fix layer data visibility on slider change

* fix default value data for spatiotemporal layer

* fix default filter for custom temporal dimension for time slider

* fix default filters applied for map

* override default value inside temporal dimension

* add doc & rename variable

* refactor to use custom config logic to time slider plugin
  • Loading branch information
mayurmarakana89 authored Feb 22, 2024
1 parent d8ab9da commit 9c931e2
Show file tree
Hide file tree
Showing 7 changed files with 83 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,16 @@
"en": "Custom description",
"fr": "Descriptif personnalisé"
},
"locked": true,
"reversed": true,
"defaultValue": ""
"locked": false,
"reversed": false,
"temporalDimension": {
"field": "time_slider_date",
"default": ["1940-01-01T05:00:00Z", "1960-01-01T05:00:00Z"],
"unitSymbol": "",
"range": "1900-01-01T05:00:00Z/2000-01-01T05:00:00Z/P1Y",
"nearestValues": "absolute",
"singleHandle": false
}
},
{
"layerPaths": ["wmsLYR1-spatiotemporel/RADAR_1KM_RSNO"],
Expand All @@ -26,10 +33,11 @@
},
"locked": true,
"reversed": true,
"defaultValue": ""
"defaultValue": "2024-02-21T14:54:00Z"
},
{
"layerPaths": ["MSI/msi-94-or-more"]
"layerPaths": ["MSI/msi-94-or-more"],
"defaultValue": "2011-08-15T00:00:00Z"
}
],
"suportedLanguages": ["en", "fr"]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ export class TimeSliderEventProcessor extends AbstractEventProcessor {
initialTimeSliderLayerPaths.forEach((layerPath) => {
const timeSliderLayer = TimeSliderEventProcessor.getInitialTimeSliderValues(mapId, layerPath);
store.getState().timeSliderState.actions.addTimeSliderLayer(timeSliderLayer);

const { defaultValue, field, filtering, minAndMax, values } = timeSliderLayer[layerPath];
TimeSliderEventProcessor.applyFilters(mapId, layerPath, defaultValue, field, filtering, minAndMax, values);
});
}
},
Expand Down Expand Up @@ -109,9 +112,11 @@ export class TimeSliderEventProcessor extends AbstractEventProcessor {
const name = getLocalizedValue(api.maps[mapId].layer.geoviewLayers[layerPath.split('/')[0]].geoviewLayerName, mapId) || layerPath;
const temporalDimensionInfo = api.maps[mapId].layer.geoviewLayer(layerPath).getTemporalDimension();
const { range } = temporalDimensionInfo.range;
const defaultValue = temporalDimensionInfo.default;
const defaultValueIsArray = Array.isArray(temporalDimensionInfo.default);
const defaultValue = defaultValueIsArray ? temporalDimensionInfo.default[0] : temporalDimensionInfo.default;
const minAndMax: number[] = [new Date(range[0]).getTime(), new Date(range[range.length - 1]).getTime()];
const { field, singleHandle } = temporalDimensionInfo;

// If the field type has an alias, use that as a label
let fieldAlias = field;
const { featureInfo } = api.maps[mapId].layer.registeredLayers[layerPath].source!;
Expand All @@ -121,7 +126,13 @@ export class TimeSliderEventProcessor extends AbstractEventProcessor {
const fieldIndex = localizedOutFields ? localizedOutFields.indexOf(field) : -1;
if (fieldIndex !== -1 && localizedAliasFields?.length === localizedOutFields?.length) fieldAlias = localizedAliasFields![fieldIndex];

const values = singleHandle ? [new Date(temporalDimensionInfo.default).getTime()] : [...minAndMax];
// eslint-disable-next-line no-nested-ternary
const values = singleHandle
? [new Date(temporalDimensionInfo.default).getTime()]
: defaultValueIsArray
? [new Date(temporalDimensionInfo.default[0]).getTime(), new Date(temporalDimensionInfo.default[1]).getTime()]
: [...minAndMax];

const sliderData: TimeSliderLayerSet = {
[layerPath]: {
name,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -166,5 +166,4 @@ export function initializeTimeSliderState(set: TypeSetStore, get: TypeGetStore):
// Layer state selectors
// **********************************************************
export const useTimeSliderLayers = () => useStore(useGeoViewStore(), (state) => state.timeSliderState.timeSliderLayers);

export const useTimeSliderStoreActions = () => useStore(useGeoViewStore(), (state) => state.timeSliderState.actions);
Original file line number Diff line number Diff line change
Expand Up @@ -1499,6 +1499,17 @@ export abstract class AbstractGeoViewLayer {
return this.layerTemporalDimension[layerPath];
}

/** ***************************************************************************************************************************
* Set the layerTemporalDimension for the layer identified by specified layerPath.
*
* @param {string} layerPath The layer path to the layer's configuration affected by the change.
* @param {TimeDimension} temporalDimension The value to assign to the layer temporal dimension property.
*/
setTemporalDimension(layerPath: string, temporalDimension: TimeDimension): void {
layerPath = layerPath || this.layerPathAssociatedToTheGeoviewLayer;
this.layerTemporalDimension[layerPath] = temporalDimension;
}

/** ***************************************************************************************************************************
* Get the bounds of the layer represented in the layerConfig pointed to by the cached layerPath, returns updated bounds
*
Expand Down
28 changes: 27 additions & 1 deletion packages/geoview-time-slider/src/index.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import { AnySchemaObject, Cast, toJsonObject, TypeJsonObject, TypeTabs } from 'geoview-core';
import { AnySchemaObject, api, Cast, TimeDimension, toJsonObject, TypeJsonObject, TypeTabs } from 'geoview-core';
import { TimeSliderIcon } from 'geoview-core/src/ui';
import { FooterPlugin } from 'geoview-core/src/api/plugin/footer-plugin';

import { TimeSliderPanel } from './time-slider-panel';
import schema from '../schema.json';
import defaultConfig from '../default-config-time-slider-panel.json';
import { SliderProps } from './time-slider-types';

export interface LayerProps {
layerPath: string;
Expand Down Expand Up @@ -96,6 +97,31 @@ class TimeSliderPlugin extends FooterPlugin {
});

onCreateContentProps = (): TypeTabs => {
// Set custom time dimension if applicable
this.configObj.sliders.forEach((obj: SliderProps) => {
if (obj.temporalDimension) {
const timeDimension: TimeDimension = {
field: obj.temporalDimension.field,
default: obj.temporalDimension.default,
unitSymbol: obj.temporalDimension.unitSymbol,
nearestValues: obj.temporalDimension.nearestValues,
range: api.dateUtilities.createRangeOGC(obj.temporalDimension.range as unknown as string),
singleHandle: obj.temporalDimension.singleHandle,
};
api.maps[this.pluginProps.mapId].layer.geoviewLayer(obj.layerPaths[0]).setTemporalDimension(obj.layerPaths[0], timeDimension);
}

// Set override default value under time dimension if applicable
if (obj.defaultValue) {
const layerPath = obj.layerPaths[0];
const timeDimension = api.maps[this.pluginProps.mapId].layer.geoviewLayer(layerPath).layerTemporalDimension[layerPath];
api.maps[this.pluginProps.mapId].layer.geoviewLayer(layerPath).setTemporalDimension(layerPath, {
...timeDimension,
default: obj.defaultValue,
});
}
});

return {
id: 'time-slider',
value: this.value!,
Expand Down
2 changes: 2 additions & 0 deletions packages/geoview-time-slider/src/time-slider-types.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { TimeDimension } from 'geoview-core';
import { TypeLocalizedString } from 'geoview-core/src/geo/map/map-schema-types';

export type SliderProps = {
Expand All @@ -7,6 +8,7 @@ export type SliderProps = {
locked: boolean;
reversed: boolean;
defaultValue: string;
temporalDimension: TimeDimension;
};

export type ConfigProps = {
Expand Down
21 changes: 17 additions & 4 deletions packages/geoview-time-slider/src/time-slider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ export function TimeSlider(TimeSliderPanelProps: TimeSliderPanelProps) {

// Get actions and states from store
// TODO: evaluate best option to set value by layer path.... trough a getter?
const { setTitle, setDescription, setDefaultValue, setValues, setLocked, setReversed, setDelay, setFiltering } =
const { setTitle, setDefaultValue, setDescription, setValues, setLocked, setReversed, setDelay, setFiltering } =
useTimeSliderStoreActions();

// TODO: check performance as we should technically have one selector by constant
Expand All @@ -78,14 +78,28 @@ export function TimeSlider(TimeSliderPanelProps: TimeSliderPanelProps) {
const sliderConfig = config?.sliders?.find((o: { layerPaths: string[] }) => o.layerPaths.includes(layerPath));
if (title === undefined) setTitle(layerPath, getLocalizedValue(sliderConfig?.title, mapId) || '');
if (description === undefined) setDescription(layerPath, getLocalizedValue(sliderConfig?.description, mapId) || '');
if (defaultValue === undefined) setDefaultValue(layerPath, sliderConfig?.defaultValue || '');
if (locked === undefined) setLocked(layerPath, sliderConfig?.locked !== undefined ? sliderConfig?.locked : false);
if (reversed === undefined) setReversed(layerPath, sliderConfig?.reversed !== undefined ? sliderConfig?.reversed : false);
if (defaultValue === undefined) setDefaultValue(layerPath, sliderConfig?.defaultValue || '');
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);

const timeStampRange = range.map((entry: string | number | Date) => new Date(entry).getTime());
useEffect(() => {
const sliderConfig = config?.sliders?.find((o: { layerPaths: string[] }) => o.layerPaths.includes(layerPath));
if (sliderConfig?.defaultValue) {
// update values based on slider's default value
const defaultValueIsArray = Array.isArray(sliderConfig?.defaultValue);
if (defaultValueIsArray) {
setValues(layerPath, [new Date(sliderConfig?.defaultValue[0]).getTime(), new Date(sliderConfig?.defaultValue[1]).getTime()]);
} else if (range.includes(sliderConfig?.defaultValue)) {
setValues(layerPath, [new Date(sliderConfig?.defaultValue).getTime()]);
} else {
setValues(layerPath, [new Date(range[0]).getTime()]);
}
}
}, [config, layerPath, range, setFiltering, setValues]);

const timeStampRange = range.map((entry: string | number | Date) => new Date(entry).getTime());
// Check if range occurs in a single day or year
const timeDelta = minAndMax[1] - minAndMax[0];
const dayDelta = new Date(minAndMax[1]).getDate() - new Date(minAndMax[0]).getDate();
Expand Down Expand Up @@ -332,7 +346,6 @@ export function TimeSlider(TimeSliderPanelProps: TimeSliderPanelProps) {
style={{ width: '80%', color: 'primary' }}
min={minAndMax[0]}
max={minAndMax[1]}
defaultValue={Number(defaultValue)}
value={values}
valueLabelFormat={(value) => valueLabelFormat(value)}
marks={sliderMarks}
Expand Down

0 comments on commit 9c931e2

Please sign in to comment.