Skip to content

Commit

Permalink
Removing a layer now removes it from the layerdataarray, the hoverdat…
Browse files Browse the repository at this point in the history
…aarray and the allfeaturesdataarray

Added subscriptions to better synch the featureinfo-geochart stores
  • Loading branch information
Alex-NRCan committed Feb 20, 2024
1 parent ce9bf2c commit 6f6456e
Show file tree
Hide file tree
Showing 2 changed files with 137 additions and 17 deletions.
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { GeoviewStoreType, IFeatureInfoState } from '@/core/stores';
import { TypeFeatureInfoResultsSet, EventType, TypeLayerData, TypeArrayOfLayerData } from '@/api/events/payloads/get-feature-info-payload';
import { IFeatureInfoState } from '@/core/stores';
import { logger } from '@/core/utils/logger';

import { GeochartEventProcessor } from './geochart-event-processor';
import { AbstractEventProcessor, BatchedPropagationLayerDataArrayByMap } from '../abstract-event-processor';
import { UIEventProcessor } from './ui-event-processor';

Expand All @@ -25,6 +25,45 @@ export class FeatureInfoEventProcessor extends AbstractEventProcessor {
// The longer the delay, the longer it'll take to update the UI. The delay can be bypassed using the layer path bypass method.
private static timeDelayBetweenPropagationsForBatch = 1000;

/**
* Overrides initialization of the Feature Info Event Processor
* @param {GeoviewStoreType} store The store associated with the Feature Info Event Processor
* @returns An array of the subscriptions callbacks which were created
*/
protected onInitialize(store: GeoviewStoreType): Array<() => void> | void {
// Checks for udpated layers in layer order
const unsubLayerRemoved = store.subscribe(
(state) => state.mapState.layerOrder,
(cur, prev) => {
// Log
logger.logTraceCoreStoreSubscription('FEATUREINFO EVENT PROCESSOR - layerOrder', cur);

// For each layer path in the layer data array
store
.getState()
.detailsState.layerDataArray.map((layerInfo) => layerInfo.layerPath)
.forEach((layerPath) => {
// If it was in the layer data array and is not anymore
if (prev.includes(layerPath) && !cur.includes(layerPath)) {
// Remove it
FeatureInfoEventProcessor.deleteFeatureInfo(store.getState().mapId, layerPath);

// Remove it
FeatureInfoEventProcessor.deleteFeatureHoverInfo(store.getState().mapId, layerPath);

// Remove it
FeatureInfoEventProcessor.deleteFeatureAllInfo(store.getState().mapId, layerPath);

// Log
logger.logDebug('Removed Feature Info for layer path:', layerPath);
}
});
}
);

return [unsubLayerRemoved];
}

/**
* Shortcut to get the Feature Info state for a given map id
* @param {string} mapId The mapId
Expand All @@ -36,15 +75,87 @@ export class FeatureInfoEventProcessor extends AbstractEventProcessor {
}

/**
* Static method used to propagate feature info layer sets to the store
* Deletes the specified layer path from the layer sets in the store
* @param {string} mapId The map identifier
* @param {string} layerPath The layer path to delete
*/
private static deleteFeatureInfo(mapId: string, layerPath: string) {
// The feature info state
const featureInfoState = this.getFeatureInfoState(mapId);

// Find the layer data info to delete from the array
const layerDataInfoToDelIndex = featureInfoState.layerDataArray.findIndex((layerInfo) => layerInfo.layerPath === layerPath);

// If found
if (layerDataInfoToDelIndex >= 0) {
// Remove from the array
featureInfoState.layerDataArray.splice(layerDataInfoToDelIndex, 1);

// Update the layer data array in the store
featureInfoState.actions.setLayerDataArray(featureInfoState.layerDataArray);

// Also propagate in the batched array
FeatureInfoEventProcessor.propagateFeatureInfoToStoreBatch(mapId, featureInfoState.layerDataArray);
}
}

/**
* Deletes the specified layer path from the hover layers sets in the store
* @param {string} mapId The map identifier
* @param {string} layerPath The layer path to delete
*/
private static deleteFeatureHoverInfo(mapId: string, layerPath: string) {
// The feature info state
const featureInfoState = this.getFeatureInfoState(mapId);

// Find the layer data info to delete from the array
const layerDataInfoToDelIndex = featureInfoState.hoverDataArray.findIndex((layerInfo) => layerInfo.layerPath === layerPath);

// If found
if (layerDataInfoToDelIndex >= 0) {
// Remove from the array
featureInfoState.hoverDataArray.splice(layerDataInfoToDelIndex, 1);

// Update the layer data array in the store
featureInfoState.actions.setHoverDataArray(featureInfoState.hoverDataArray);
}
}

/**
* Deletes the specified layer path from the all features layers sets in the store
* @param {string} mapId The map identifier
* @param {string} layerPath The layer path to delete
*/
private static deleteFeatureAllInfo(mapId: string, layerPath: string) {
// The feature info state
const featureInfoState = this.getFeatureInfoState(mapId);

// Find the layer data info to delete from the array
const layerDataInfoToDelIndex = featureInfoState.allFeaturesDataArray.findIndex((layerInfo) => layerInfo.layerPath === layerPath);

// If found
if (layerDataInfoToDelIndex >= 0) {
// Remove from the array
featureInfoState.allFeaturesDataArray.splice(layerDataInfoToDelIndex, 1);

// Update the layer data array in the store
featureInfoState.actions.setAllFeaturesDataArray(featureInfoState.allFeaturesDataArray);
}
}

/**
* Propagates feature info layer sets to the store
*
* @param {string} mapId The map identifier of the resul set modified.
* @param {string} mapId The map identifier of the modified result set.
* @param {string} layerPath The layer path that has changed.
* @param {EventType} eventType The event type that triggered the layer set update.
* @param {TypeFeatureInfoResultsSet} resultsSet The resul sets associated to the map.
*/
static propagateFeatureInfoToStore(mapId: string, layerPath: string, eventType: EventType, resultsSet: TypeFeatureInfoResultsSet) {
// The feature info state
const featureInfoState = this.getFeatureInfoState(mapId);

// Depending on the event type
if (eventType === 'click') {
/**
* Create a details object for each layer which is then used to render layers in details panel.
Expand All @@ -66,9 +177,6 @@ export class FeatureInfoEventProcessor extends AbstractEventProcessor {

// Also propagate in the batched array
FeatureInfoEventProcessor.propagateFeatureInfoToStoreBatch(mapId, layerDataArray);

// Also propagate in the geochart arrays
GeochartEventProcessor.propagateArrayDataToStore(mapId, layerDataArray);
} else if (eventType === 'hover') {
/**
* Create a hover object for each layer which is then used to render layers
Expand All @@ -91,7 +199,7 @@ export class FeatureInfoEventProcessor extends AbstractEventProcessor {
}

/**
* Propagate feature info layer sets to the store in a batched manner, every 'timeDelayBetweenPropagationsForBatch' millisecond.
* Propagates feature info layer sets to the store in a batched manner, every 'timeDelayBetweenPropagationsForBatch' millisecond.
* This is used to provide another 'layerDataArray', in the store, which updates less often so that we save a couple 'layerDataArray'
* update triggers in the components that are listening to the store array.
* The propagation can be bypassed using the store 'layerDataArrayBatchLayerPathBypass' state which tells the process to
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,28 +32,40 @@ export class GeochartEventProcessor extends AbstractEventProcessor {
* @returns An array of the subscriptions callbacks which were created
*/
protected onInitialize(store: GeoviewStoreType): Array<() => void> | void {
// Checks for added and removed layers with time dimension
// Checks for udpated layers in layer order
const unsubLayerRemoved = store.subscribe(
(state) => state.mapState.layerOrder,
(cur, prev) => {
// Log
logger.logTraceCoreStoreSubscription('GEOCHART EVENT PROCESSOR - layerOrder', cur);

// For each chart config keys
Object.keys(store.getState().geochartState.geochartChartsConfig).forEach((chartLayerPath: string) => {
Object.keys(store.getState().geochartState.geochartChartsConfig).forEach((layerPath: string) => {
// If it was in the layerdata array and is not anymore
if (prev.includes(chartLayerPath) && !cur.includes(chartLayerPath)) {
if (prev.includes(layerPath) && !cur.includes(layerPath)) {
// Remove it
GeochartEventProcessor.removeGeochartChart(store.getState().mapId, chartLayerPath);
GeochartEventProcessor.removeGeochartChart(store.getState().mapId, layerPath);

// Log
logger.logDebug('Removed GeoChart configs for layer path:', chartLayerPath);
logger.logDebug('Removed GeoChart configs for layer path:', layerPath);
}
});
}
);

return [unsubLayerRemoved];
// Checks for updated layers in layer data array
const layerDataArrayUpdate = store.subscribe(
(state) => state.detailsState.layerDataArray,
(cur) => {
// Log
logger.logTraceCoreStoreSubscription('GEOCHART EVENT PROCESSOR - layerDataArray', cur);

// Also propagate in the geochart arrays
GeochartEventProcessor.propagateArrayDataToStore(store.getState().mapId, cur);
}
);

return [unsubLayerRemoved, layerDataArrayUpdate];
}

/**
Expand Down Expand Up @@ -93,7 +105,7 @@ export class GeochartEventProcessor extends AbstractEventProcessor {
// set store charts config
this.getGeochartState(mapId)?.actions.setGeochartCharts(chartData);

// TODO: Also update the layer array in other store state to inform the later has a geochart attached to it (when code is done over there)
// TODO: Also update the layer array in other store state to inform the later has a geochart attached to it (when code is done over there)?
}

/**
Expand All @@ -114,7 +126,7 @@ export class GeochartEventProcessor extends AbstractEventProcessor {
// Update the layer data array in the store
this.getGeochartState(mapId)!.actions.setGeochartCharts({ ...this.getGeochartState(mapId)?.geochartChartsConfig, ...toAdd });

// TODO: Also update the layer array in other store state to inform the later has a geochart attached to it (when code is done over there)
// TODO: Also update the layer array in other store state to inform the later has a geochart attached to it (when code is done over there)?
}

/**
Expand All @@ -139,7 +151,7 @@ export class GeochartEventProcessor extends AbstractEventProcessor {
// Update the layer data array in the store
this.getGeochartState(mapId)!.actions.setGeochartCharts({ ...chartConfigs });

// TODO: Also update the layer array in other store state to inform the later has a geochart attached to it (when code is done over there)
// TODO: Also update the layer array in other store state to inform the later has a geochart attached to it (when code is done over there)?
}
}

Expand Down

0 comments on commit 6f6456e

Please sign in to comment.