in src/reducers/vis-state-updaters.js [470:592]
export function setFilterUpdater(state, action) {
const {idx, prop, value, valueIndex = 0} = action;
const oldFilter = state.filters[idx];
let newFilter = set([prop], value, oldFilter);
let newState = state;
const {dataId} = newFilter;
// Ensuring backward compatibility
let datasetIds = toArray(dataId);
switch (prop) {
// TODO: Next PR for UI if we update dataId, we need to consider two cases:
// 1. dataId is empty: create a default filter
// 2. Add a new dataset id
case FILTER_UPDATER_PROPS.dataId:
// if trying to update filter dataId. create an empty new filter
newFilter = updateFilterDataId(dataId);
break;
case FILTER_UPDATER_PROPS.name:
// we are supporting the current functionality
// TODO: Next PR for UI filter name will only update filter name but it won't have side effects
// we are gonna use pair of datasets and fieldIdx to update the filter
const datasetId = newFilter.dataId[valueIndex];
const {filter: updatedFilter, dataset: newDataset} = applyFilterFieldName(
newFilter,
state.datasets[datasetId],
value,
valueIndex,
{mergeDomain: false}
);
if (!updatedFilter) {
return state;
}
newFilter = updatedFilter;
if (newFilter.gpu) {
newFilter = setFilterGpuMode(newFilter, state.filters);
newFilter = assignGpuChannel(newFilter, state.filters);
}
newState = set(['datasets', datasetId], newDataset, state);
// only filter the current dataset
break;
case FILTER_UPDATER_PROPS.layerId:
// We need to update only datasetId/s if we have added/removed layers
// - check for layerId changes (XOR works because of string values)
// if no differences between layerIds, don't do any filtering
// @ts-ignore
const layerIdDifference = xor(newFilter.layerId, oldFilter.layerId);
const layerDataIds = uniq(
layerIdDifference
.map(lid =>
get(
state.layers.find(l => l.id === lid),
['config', 'dataId']
)
)
.filter(d => d)
);
// only filter datasetsIds
datasetIds = layerDataIds;
// Update newFilter dataIds
const newDataIds = uniq(
newFilter.layerId
.map(lid =>
get(
state.layers.find(l => l.id === lid),
['config', 'dataId']
)
)
.filter(d => d)
);
newFilter = {
...newFilter,
dataId: newDataIds
};
break;
default:
break;
}
const enlargedFilter = state.filters.find(f => f.enlarged);
if (enlargedFilter && enlargedFilter.id !== newFilter.id) {
// there should be only one enlarged filter
newFilter.enlarged = false;
}
// save new filters to newState
newState = set(['filters', idx], newFilter, newState);
// if we are currently setting a prop that only requires to filter the current
// dataset we will pass only the current dataset to applyFiltersToDatasets and
// updateAllLayerDomainData otherwise we pass the all list of datasets as defined in dataId
const datasetIdsToFilter = LIMITED_FILTER_EFFECT_PROPS[prop]
? [datasetIds[valueIndex]]
: datasetIds;
// filter data
const filteredDatasets = applyFiltersToDatasets(
datasetIdsToFilter,
newState.datasets,
newState.filters,
newState.layers
);
newState = set(['datasets'], filteredDatasets, newState);
// dataId is an array
// pass only the dataset we need to update
newState = updateAllLayerDomainData(newState, datasetIdsToFilter, newFilter);
return newState;
}