kepler.gl
Version:
kepler.gl is a webgl based application to visualize large scale location data in the browser
1,063 lines (855 loc) • 110 kB
JavaScript
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.loadFilesErrUpdater = exports.loadFilesUpdater = exports.updateVisDataUpdater = exports.toggleLayerForMapUpdater = exports.setVisibleLayersForMapUpdater = exports.toggleSplitMapUpdater = exports.mapClickUpdater = exports.layerClickUpdater = exports.layerHoverUpdater = exports.receiveMapConfigUpdater = exports.resetMapConfigVisStateUpdater = exports.showDatasetTableUpdater = exports.updateLayerBlendingUpdater = exports.removeDatasetUpdater = exports.reorderLayerUpdater = exports.removeLayerUpdater = exports.addLayerUpdater = exports.removeFilterUpdater = exports.enlargeFilterUpdater = exports.updateAnimationSpeedUpdater = exports.toggleFilterAnimationUpdater = exports.addFilterUpdater = exports.setFilterPlotUpdater = exports.INITIAL_VIS_STATE = undefined;
var _toConsumableArray2 = require('babel-runtime/helpers/toConsumableArray');
var _toConsumableArray3 = _interopRequireDefault(_toConsumableArray2);
var _defineProperty2 = require('babel-runtime/helpers/defineProperty');
var _defineProperty3 = _interopRequireDefault(_defineProperty2);
var _objectWithoutProperties2 = require('babel-runtime/helpers/objectWithoutProperties');
var _objectWithoutProperties3 = _interopRequireDefault(_objectWithoutProperties2);
var _extends13 = require('babel-runtime/helpers/extends');
var _extends14 = _interopRequireDefault(_extends13);
exports.layerConfigChangeUpdater = layerConfigChangeUpdater;
exports.layerTypeChangeUpdater = layerTypeChangeUpdater;
exports.layerVisualChannelChangeUpdater = layerVisualChannelChangeUpdater;
exports.layerVisConfigChangeUpdater = layerVisConfigChangeUpdater;
exports.interactionConfigChangeUpdater = interactionConfigChangeUpdater;
exports.setFilterUpdater = setFilterUpdater;
exports.addDefaultLayers = addDefaultLayers;
exports.addDefaultTooltips = addDefaultTooltips;
exports.updateAllLayerDomainData = updateAllLayerDomainData;
var _window = require('global/window');
var _tasks = require('react-palm/tasks');
var _tasks2 = _interopRequireDefault(_tasks);
var _tasks3 = require('../tasks/tasks');
var _visStateActions = require('../actions/vis-state-actions');
var _actions = require('../actions');
var _utils = require('../utils/utils');
var _interactionUtils = require('../utils/interaction-utils');
var _filterUtils = require('../utils/filter-utils');
var _datasetUtils = require('../utils/dataset-utils');
var _layerUtils = require('../utils/layer-utils/layer-utils');
var _fileHandler = require('../processors/file-handler');
var _visStateMerger = require('./vis-state-merger');
var _layers = require('../layers');
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
// react-palm
// disable capture exception for react-palm call to withTask
// Utils
// Actions
(0, _tasks.disableStackCapturing)();
// LayerClasses contain ES6 Class, do not instatiate in iso rendering
// const {LayerClasses} = isBrowser || isTesting ?
// require('layers') : {
// LayerClasses: {}
// };
// Tasks
// Copyright (c) 2018 Uber Technologies, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
var INITIAL_VIS_STATE = exports.INITIAL_VIS_STATE = {
// layers
layers: [],
layerData: [],
layerToBeMerged: [],
layerOrder: [],
// filters
filters: [],
filterToBeMerged: [],
// a collection of multiple dataset
datasets: {},
editingDataset: undefined,
interactionConfig: (0, _interactionUtils.getDefaultInteraction)(),
interactionToBeMerged: undefined,
layerBlending: 'normal',
hoverInfo: undefined,
clicked: undefined,
fileLoading: false,
fileLoadingErr: null,
// this is used when user split maps
splitMaps: [
// this will contain a list of objects to
// describe the state of layer availability and visibility for each map
// [
// {
// layers: {
// layer_id: {
// isAvailable: true|false # this is driven by the left hand panel
// isVisible: true|false
// }
// }
// }
// ]
],
// defaults layer classes
layerClasses: _layers.LayerClasses
};
function updateStateWithLayerAndData(state, _ref) {
var layerData = _ref.layerData,
layer = _ref.layer,
idx = _ref.idx;
return (0, _extends14.default)({}, state, {
layers: state.layers.map(function (lyr, i) {
return i === idx ? layer : lyr;
}),
layerData: layerData ? state.layerData.map(function (d, i) {
return i === idx ? layerData : d;
}) : state.layerData
});
}
/**
* Called to update layer base config: dataId, label, column, isVisible
*
*/
function layerConfigChangeUpdater(state, action) {
var oldLayer = action.oldLayer;
var idx = state.layers.findIndex(function (l) {
return l.id === oldLayer.id;
});
var props = Object.keys(action.newConfig);
var newLayer = oldLayer.updateLayerConfig(action.newConfig);
if (newLayer.shouldCalculateLayerData(props)) {
var oldLayerData = state.layerData[idx];
var _calculateLayerData = (0, _layerUtils.calculateLayerData)(newLayer, state, oldLayerData, { sameData: true }),
layerData = _calculateLayerData.layerData,
layer = _calculateLayerData.layer;
return updateStateWithLayerAndData(state, { layerData: layerData, layer: layer, idx: idx });
}
var newState = (0, _extends14.default)({}, state, {
splitMaps: 'isVisible' in action.newConfig ? toggleLayerFromSplitMaps(state, newLayer) : state.splitMaps
});
return updateStateWithLayerAndData(newState, { layer: newLayer, idx: idx });
}
function layerTypeChangeUpdater(state, action) {
var oldLayer = action.oldLayer,
newType = action.newType;
var oldId = oldLayer.id;
var idx = state.layers.findIndex(function (l) {
return l.id === oldId;
});
if (!state.layerClasses[newType]) {
_window.console.error(newType + ' is not a valid layer type');
return state;
}
// get a mint layer, with new id and type
// because deck.gl uses id to match between new and old layer.
// If type has changed but id is the same, it will break
var newLayer = new state.layerClasses[newType]();
newLayer.assignConfigToLayer(oldLayer.config, oldLayer.visConfigSettings);
if (newLayer.config.dataId) {
var dataset = state.datasets[newLayer.config.dataId];
newLayer.updateLayerDomain(dataset);
}
var _calculateLayerData2 = (0, _layerUtils.calculateLayerData)(newLayer, state),
layerData = _calculateLayerData2.layerData,
layer = _calculateLayerData2.layer;
var newState = state;
// update splitMap layer id
if (state.splitMaps) {
newState = (0, _extends14.default)({}, state, {
splitMaps: state.splitMaps.map(function (settings) {
var _settings$layers = settings.layers,
oldLayerMap = _settings$layers[oldId],
otherLayers = (0, _objectWithoutProperties3.default)(_settings$layers, [oldId]);
return (0, _extends14.default)({}, settings, {
layers: (0, _extends14.default)({}, otherLayers, (0, _defineProperty3.default)({}, layer.id, oldLayerMap))
});
})
});
}
return updateStateWithLayerAndData(newState, { layerData: layerData, layer: layer, idx: idx });
}
function layerVisualChannelChangeUpdater(state, action) {
var oldLayer = action.oldLayer,
newConfig = action.newConfig,
channel = action.channel;
var dataset = state.datasets[oldLayer.config.dataId];
var idx = state.layers.findIndex(function (l) {
return l.id === oldLayer.id;
});
var newLayer = oldLayer.updateLayerConfig(newConfig);
newLayer.updateLayerVisualChannel(dataset, channel);
var oldLayerData = state.layerData[idx];
var _calculateLayerData3 = (0, _layerUtils.calculateLayerData)(newLayer, state, oldLayerData, {
sameData: true
}),
layerData = _calculateLayerData3.layerData,
layer = _calculateLayerData3.layer;
return updateStateWithLayerAndData(state, { layerData: layerData, layer: layer, idx: idx });
}
function layerVisConfigChangeUpdater(state, action) {
var oldLayer = action.oldLayer;
var idx = state.layers.findIndex(function (l) {
return l.id === oldLayer.id;
});
var props = Object.keys(action.newVisConfig);
var newVisConfig = (0, _extends14.default)({}, oldLayer.config.visConfig, action.newVisConfig);
var newLayer = oldLayer.updateLayerConfig({ visConfig: newVisConfig });
if (newLayer.shouldCalculateLayerData(props)) {
var oldLayerData = state.layerData[idx];
var _calculateLayerData4 = (0, _layerUtils.calculateLayerData)(newLayer, state, oldLayerData, { sameData: true }),
layerData = _calculateLayerData4.layerData,
layer = _calculateLayerData4.layer;
return updateStateWithLayerAndData(state, { layerData: layerData, layer: layer, idx: idx });
}
return updateStateWithLayerAndData(state, { layer: newLayer, idx: idx });
}
/* eslint-enable max-statements */
function interactionConfigChangeUpdater(state, action) {
var config = action.config;
var interactionConfig = (0, _extends14.default)({}, state.interactionConfig, (0, _defineProperty3.default)({}, config.id, config));
if (config.enabled && !state.interactionConfig[config.id].enabled) {
// only enable one interaction at a time
Object.keys(interactionConfig).forEach(function (k) {
if (k !== config.id) {
interactionConfig[k] = (0, _extends14.default)({}, interactionConfig[k], { enabled: false });
}
});
}
return (0, _extends14.default)({}, state, {
interactionConfig: interactionConfig
});
}
function setFilterUpdater(state, action) {
var idx = action.idx,
prop = action.prop,
value = action.value;
var newState = state;
var newFilter = (0, _extends14.default)({}, state.filters[idx], (0, _defineProperty3.default)({}, prop, value));
var _newFilter = newFilter,
dataId = _newFilter.dataId;
if (!dataId) {
return state;
}
var _state$datasets$dataI = state.datasets[dataId],
fields = _state$datasets$dataI.fields,
allData = _state$datasets$dataI.allData;
switch (prop) {
case 'dataId':
// if trying to update filter dataId. create an empty new filter
newFilter = (0, _filterUtils.getDefaultFilter)(dataId);
break;
case 'name':
// find the field
var fieldIdx = fields.findIndex(function (f) {
return f.name === value;
});
var field = fields[fieldIdx];
if (!field.filterProp) {
// get filter domain from field
// save filterProps: {domain, steps, value} to field, avoid recalculate
field = (0, _extends14.default)({}, field, {
filterProp: (0, _filterUtils.getFilterProps)(allData, field)
});
}
newFilter = (0, _extends14.default)({}, newFilter, field.filterProp, {
name: field.name,
// can't edit dataId once name is selected
freeze: true,
fieldIdx: fieldIdx
});
var enlargedFilterIdx = state.filters.findIndex(function (f) {
return f.enlarged;
});
if (enlargedFilterIdx > -1 && enlargedFilterIdx !== idx) {
// there should be only one enlarged filter
newFilter.enlarged = false;
}
newState = (0, _extends14.default)({}, state, {
datasets: (0, _extends14.default)({}, state.datasets, (0, _defineProperty3.default)({}, dataId, (0, _extends14.default)({}, state.datasets[dataId], {
fields: fields.map(function (d, i) {
return i === fieldIdx ? field : d;
})
})))
});
break;
case 'value':
default:
break;
}
// save new filters to newState
newState = (0, _extends14.default)({}, newState, {
filters: state.filters.map(function (f, i) {
return i === idx ? newFilter : f;
})
});
// filter data
newState = (0, _extends14.default)({}, newState, {
datasets: (0, _extends14.default)({}, newState.datasets, (0, _defineProperty3.default)({}, dataId, (0, _extends14.default)({}, newState.datasets[dataId], (0, _filterUtils.filterData)(allData, dataId, newState.filters))))
});
newState = updateAllLayerDomainData(newState, dataId, newFilter);
return newState;
}
var setFilterPlotUpdater = exports.setFilterPlotUpdater = function setFilterPlotUpdater(state, _ref2) {
var idx = _ref2.idx,
newProp = _ref2.newProp;
var newFilter = (0, _extends14.default)({}, state.filters[idx], newProp);
var prop = Object.keys(newProp)[0];
if (prop === 'yAxis') {
var plotType = (0, _filterUtils.getDefaultFilterPlotType)(newFilter);
if (plotType) {
newFilter = (0, _extends14.default)({}, newFilter, (0, _filterUtils.getFilterPlot)((0, _extends14.default)({}, newFilter, { plotType: plotType }), state.datasets[newFilter.dataId].allData), {
plotType: plotType
});
}
}
return (0, _extends14.default)({}, state, {
filters: state.filters.map(function (f, i) {
return i === idx ? newFilter : f;
})
});
};
var addFilterUpdater = exports.addFilterUpdater = function addFilterUpdater(state, action) {
return !action.dataId ? state : (0, _extends14.default)({}, state, {
filters: [].concat((0, _toConsumableArray3.default)(state.filters), [(0, _filterUtils.getDefaultFilter)(action.dataId)])
});
};
var toggleFilterAnimationUpdater = exports.toggleFilterAnimationUpdater = function toggleFilterAnimationUpdater(state, action) {
return (0, _extends14.default)({}, state, {
filters: state.filters.map(function (f, i) {
return i === action.idx ? (0, _extends14.default)({}, f, { isAnimating: !f.isAnimating }) : f;
})
});
};
var updateAnimationSpeedUpdater = exports.updateAnimationSpeedUpdater = function updateAnimationSpeedUpdater(state, action) {
return (0, _extends14.default)({}, state, {
filters: state.filters.map(function (f, i) {
return i === action.idx ? (0, _extends14.default)({}, f, { speed: action.speed }) : f;
})
});
};
var enlargeFilterUpdater = exports.enlargeFilterUpdater = function enlargeFilterUpdater(state, action) {
var isEnlarged = state.filters[action.idx].enlarged;
return (0, _extends14.default)({}, state, {
filters: state.filters.map(function (f, i) {
f.enlarged = !isEnlarged && i === action.idx;
return f;
})
});
};
var removeFilterUpdater = exports.removeFilterUpdater = function removeFilterUpdater(state, action) {
var idx = action.idx;
var dataId = state.filters[idx].dataId;
var newFilters = [].concat((0, _toConsumableArray3.default)(state.filters.slice(0, idx)), (0, _toConsumableArray3.default)(state.filters.slice(idx + 1, state.filters.length)));
var newState = (0, _extends14.default)({}, state, {
datasets: (0, _extends14.default)({}, state.datasets, (0, _defineProperty3.default)({}, dataId, (0, _extends14.default)({}, state.datasets[dataId], (0, _filterUtils.filterData)(state.datasets[dataId].allData, dataId, newFilters)))),
filters: newFilters
});
return updateAllLayerDomainData(newState, dataId);
};
var addLayerUpdater = exports.addLayerUpdater = function addLayerUpdater(state, action) {
var defaultDataset = Object.keys(state.datasets)[0];
var newLayer = new _layers.Layer((0, _extends14.default)({
isVisible: true,
isConfigActive: true,
dataId: defaultDataset
}, action.props));
return (0, _extends14.default)({}, state, {
layers: [].concat((0, _toConsumableArray3.default)(state.layers), [newLayer]),
layerData: [].concat((0, _toConsumableArray3.default)(state.layerData), [{}]),
layerOrder: [].concat((0, _toConsumableArray3.default)(state.layerOrder), [state.layerOrder.length]),
splitMaps: addNewLayersToSplitMap(state.splitMaps, newLayer)
});
};
var removeLayerUpdater = exports.removeLayerUpdater = function removeLayerUpdater(state, _ref3) {
var idx = _ref3.idx;
var layers = state.layers,
layerData = state.layerData,
clicked = state.clicked,
hoverInfo = state.hoverInfo;
var layerToRemove = state.layers[idx];
var newMaps = removeLayerFromSplitMaps(state, layerToRemove);
return (0, _extends14.default)({}, state, {
layers: [].concat((0, _toConsumableArray3.default)(layers.slice(0, idx)), (0, _toConsumableArray3.default)(layers.slice(idx + 1, layers.length))),
layerData: [].concat((0, _toConsumableArray3.default)(layerData.slice(0, idx)), (0, _toConsumableArray3.default)(layerData.slice(idx + 1, layerData.length))),
layerOrder: state.layerOrder.filter(function (i) {
return i !== idx;
}).map(function (pid) {
return pid > idx ? pid - 1 : pid;
}),
clicked: layerToRemove.isLayerHovered(clicked) ? undefined : clicked,
hoverInfo: layerToRemove.isLayerHovered(hoverInfo) ? undefined : hoverInfo,
splitMaps: newMaps
});
};
var reorderLayerUpdater = exports.reorderLayerUpdater = function reorderLayerUpdater(state, _ref4) {
var order = _ref4.order;
return (0, _extends14.default)({}, state, {
layerOrder: order
});
};
var removeDatasetUpdater = function removeDatasetUpdater(state, action) {
// extract dataset key
var datasetKey = action.key;
var datasets = state.datasets;
// check if dataset is present
if (!datasets[datasetKey]) {
return state;
}
/* eslint-disable no-unused-vars */
var layers = state.layers,
_state$datasets = state.datasets,
dataset = _state$datasets[datasetKey],
newDatasets = (0, _objectWithoutProperties3.default)(_state$datasets, [datasetKey]);
/* eslint-enable no-unused-vars */
var indexes = layers.reduce(function (listOfIndexes, layer, index) {
if (layer.config.dataId === datasetKey) {
listOfIndexes.push(index);
}
return listOfIndexes;
}, []);
// remove layers and datasets
var _indexes$reduce = indexes.reduce(function (_ref5, idx) {
var currentState = _ref5.newState,
indexCounter = _ref5.indexCounter;
var currentIndex = idx - indexCounter;
currentState = removeLayerUpdater(currentState, { idx: currentIndex });
indexCounter++;
return { newState: currentState, indexCounter: indexCounter };
}, { newState: (0, _extends14.default)({}, state, { datasets: newDatasets }), indexCounter: 0 }),
newState = _indexes$reduce.newState;
// remove filters
var filters = state.filters.filter(function (filter) {
return filter.dataId !== datasetKey;
});
// update interactionConfig
var interactionConfig = state.interactionConfig;
var _interactionConfig = interactionConfig,
tooltip = _interactionConfig.tooltip;
if (tooltip) {
var config = tooltip.config;
/* eslint-disable no-unused-vars */
var _config$fieldsToShow = config.fieldsToShow,
fields = _config$fieldsToShow[datasetKey],
fieldsToShow = (0, _objectWithoutProperties3.default)(_config$fieldsToShow, [datasetKey]);
/* eslint-enable no-unused-vars */
interactionConfig = (0, _extends14.default)({}, interactionConfig, {
tooltip: (0, _extends14.default)({}, tooltip, { config: (0, _extends14.default)({}, config, { fieldsToShow: fieldsToShow }) })
});
}
return (0, _extends14.default)({}, newState, { filters: filters, interactionConfig: interactionConfig });
};
exports.removeDatasetUpdater = removeDatasetUpdater;
var updateLayerBlendingUpdater = exports.updateLayerBlendingUpdater = function updateLayerBlendingUpdater(state, action) {
return (0, _extends14.default)({}, state, {
layerBlending: action.mode
});
};
var showDatasetTableUpdater = exports.showDatasetTableUpdater = function showDatasetTableUpdater(state, action) {
return (0, _extends14.default)({}, state, {
editingDataset: action.dataId
});
};
var resetMapConfigVisStateUpdater = exports.resetMapConfigVisStateUpdater = function resetMapConfigVisStateUpdater(state, action) {
return (0, _extends14.default)({}, INITIAL_VIS_STATE, state.initialState, {
initialState: state.initialState
});
};
/**
* Loads custom configuration into state
* @param state
* @param action
* @returns {*}
*/
var receiveMapConfigUpdater = exports.receiveMapConfigUpdater = function receiveMapConfigUpdater(state, action) {
if (!action.payload.visState) {
return state;
}
var _action$payload$visSt = action.payload.visState,
filters = _action$payload$visSt.filters,
layers = _action$payload$visSt.layers,
interactionConfig = _action$payload$visSt.interactionConfig,
layerBlending = _action$payload$visSt.layerBlending,
splitMaps = _action$payload$visSt.splitMaps;
// always reset config when receive a new config
var resetState = resetMapConfigVisStateUpdater(state);
var mergedState = (0, _extends14.default)({}, resetState, {
splitMaps: splitMaps || [] // maps doesn't require any logic
});
mergedState = (0, _visStateMerger.mergeFilters)(mergedState, filters);
mergedState = (0, _visStateMerger.mergeLayers)(mergedState, layers);
mergedState = (0, _visStateMerger.mergeInteractions)(mergedState, interactionConfig);
mergedState = (0, _visStateMerger.mergeLayerBlending)(mergedState, layerBlending);
return mergedState;
};
var layerHoverUpdater = exports.layerHoverUpdater = function layerHoverUpdater(state, action) {
return (0, _extends14.default)({}, state, {
hoverInfo: action.info
});
};
var layerClickUpdater = exports.layerClickUpdater = function layerClickUpdater(state, action) {
return (0, _extends14.default)({}, state, {
clicked: action.info && action.info.picked ? action.info : null
});
};
var mapClickUpdater = exports.mapClickUpdater = function mapClickUpdater(state, action) {
return (0, _extends14.default)({}, state, {
clicked: null
});
};
var toggleSplitMapUpdater = exports.toggleSplitMapUpdater = function toggleSplitMapUpdater(state, action) {
return state.splitMaps && state.splitMaps.length === 0 ? (0, _extends14.default)({}, state, {
// maybe we should use an array to store state for a single map as well
// if current maps length is equal to 0 it means that we are about to split the view
splitMaps: computeSplitMapLayers(state.layers)
}) : closeSpecificMapAtIndex(state, action);
};
/**
* This is triggered when view is split into multiple maps.
* It will only update layers that belong to the map layer dropdown
* the user is interacting wit
* @param state
* @param action
*/
var setVisibleLayersForMapUpdater = exports.setVisibleLayersForMapUpdater = function setVisibleLayersForMapUpdater(state, action) {
var mapIndex = action.mapIndex,
layerIds = action.layerIds;
if (!layerIds) {
return state;
}
var _state$splitMaps = state.splitMaps,
splitMaps = _state$splitMaps === undefined ? [] : _state$splitMaps;
if (splitMaps.length === 0) {
// we should never get into this state
// because this action should only be triggered
// when map view is split
// but something may have happened
return state;
}
// need to check if maps is populated otherwise will create
var _splitMaps$mapIndex = splitMaps[mapIndex],
map = _splitMaps$mapIndex === undefined ? {} : _splitMaps$mapIndex;
var layers = map.layers || [];
// we set visibility to true for all layers included in our input list
var newLayers = (Object.keys(layers) || []).reduce(function (currentLayers, idx) {
return (0, _extends14.default)({}, currentLayers, (0, _defineProperty3.default)({}, idx, (0, _extends14.default)({}, layers[idx], {
isVisible: layerIds.includes(idx)
})));
}, {});
var newMaps = [].concat((0, _toConsumableArray3.default)(splitMaps));
newMaps[mapIndex] = (0, _extends14.default)({}, splitMaps[mapIndex], {
layers: newLayers
});
return (0, _extends14.default)({}, state, {
splitMaps: newMaps
});
};
var toggleLayerForMapUpdater = exports.toggleLayerForMapUpdater = function toggleLayerForMapUpdater(state, action) {
if (!state.splitMaps[action.mapIndex]) {
return state;
}
var mapSettings = state.splitMaps[action.mapIndex];
var layers = mapSettings.layers;
if (!layers || !layers[action.layerId]) {
return state;
}
var layer = layers[action.layerId];
var newLayer = (0, _extends14.default)({}, layer, {
isVisible: !layer.isVisible
});
var newLayers = (0, _extends14.default)({}, layers, (0, _defineProperty3.default)({}, action.layerId, newLayer));
// const splitMaps = state.splitMaps;
var newSplitMaps = [].concat((0, _toConsumableArray3.default)(state.splitMaps));
newSplitMaps[action.mapIndex] = (0, _extends14.default)({}, mapSettings, {
layers: newLayers
});
return (0, _extends14.default)({}, state, {
splitMaps: newSplitMaps
});
};
/* eslint-disable max-statements */
var updateVisDataUpdater = exports.updateVisDataUpdater = function updateVisDataUpdater(state, action) {
// datasets can be a single data entries or an array of multiple data entries
var datasets = Array.isArray(action.datasets) ? action.datasets : [action.datasets];
if (action.config) {
// apply config if passed from action
state = receiveMapConfigUpdater(state, {
payload: { visState: action.config }
});
}
var newDateEntries = datasets.reduce(function (accu, _ref6) {
var _ref6$info = _ref6.info,
info = _ref6$info === undefined ? {} : _ref6$info,
data = _ref6.data;
return (0, _extends14.default)({}, accu, (0, _datasetUtils.createNewDataEntry)({ info: info, data: data }, state.datasets) || {});
}, {});
if (!Object.keys(newDateEntries).length) {
return state;
}
var stateWithNewData = (0, _extends14.default)({}, state, {
datasets: (0, _extends14.default)({}, state.datasets, newDateEntries)
});
// previously saved config before data loaded
var _stateWithNewData$fil = stateWithNewData.filterToBeMerged,
filterToBeMerged = _stateWithNewData$fil === undefined ? [] : _stateWithNewData$fil,
_stateWithNewData$lay = stateWithNewData.layerToBeMerged,
layerToBeMerged = _stateWithNewData$lay === undefined ? [] : _stateWithNewData$lay,
_stateWithNewData$int = stateWithNewData.interactionToBeMerged,
interactionToBeMerged = _stateWithNewData$int === undefined ? {} : _stateWithNewData$int;
// merge state with saved filters
var mergedState = (0, _visStateMerger.mergeFilters)(stateWithNewData, filterToBeMerged);
// merge state with saved layers
mergedState = (0, _visStateMerger.mergeLayers)(mergedState, layerToBeMerged);
if (mergedState.layers.length === state.layers.length) {
// no layer merged, find defaults
mergedState = addDefaultLayers(mergedState, newDateEntries);
}
if (mergedState.splitMaps.length) {
var newLayers = mergedState.layers.filter(function (l) {
return l.config.dataId in newDateEntries;
});
// if map is splited, add new layers to splitMaps
mergedState = (0, _extends14.default)({}, mergedState, {
splitMaps: addNewLayersToSplitMap(mergedState.splitMaps, newLayers)
});
}
// merge state with saved interactions
mergedState = (0, _visStateMerger.mergeInteractions)(mergedState, interactionToBeMerged);
// if no tooltips merged add default tooltips
Object.keys(newDateEntries).forEach(function (dataId) {
var tooltipFields = mergedState.interactionConfig.tooltip.config.fieldsToShow[dataId];
if (!Array.isArray(tooltipFields) || !tooltipFields.length) {
mergedState = addDefaultTooltips(mergedState, newDateEntries[dataId]);
}
});
return updateAllLayerDomainData(mergedState, Object.keys(newDateEntries));
};
/* eslint-enable max-statements */
function generateLayerMetaForSplitViews(layer) {
return {
isAvailable: layer.config.isVisible,
isVisible: layer.config.isVisible
};
}
/**
* This emthod will compute the default maps custom list
* based on the current layers status
* @param layers
* @returns {[*,*]}
*/
function computeSplitMapLayers(layers) {
var mapLayers = layers.reduce(function (newLayers, currentLayer) {
return (0, _extends14.default)({}, newLayers, (0, _defineProperty3.default)({}, currentLayer.id, generateLayerMetaForSplitViews(currentLayer)));
}, {});
return [{
layers: mapLayers
}, {
layers: mapLayers
}];
}
/**
* Remove an existing layers from custom map layer objects
* @param state
* @param layer
* @returns {[*,*]} Maps of custom layer objects
*/
function removeLayerFromSplitMaps(state, layer) {
return state.splitMaps.map(function (settings) {
var layers = settings.layers;
/* eslint-disable no-unused-vars */
var _ = layers[layer.id],
newLayers = (0, _objectWithoutProperties3.default)(layers, [layer.id]);
/* eslint-enable no-unused-vars */
return (0, _extends14.default)({}, settings, {
layers: newLayers
});
});
}
/**
* Add new layers to both existing maps
* @param splitMaps
* @param layers
* @returns {[*,*]} new splitMaps
*/
function addNewLayersToSplitMap(splitMaps, layers) {
var newLayers = Array.isArray(layers) ? layers : [layers];
if (!splitMaps || !splitMaps.length || !newLayers.length) {
return splitMaps;
}
// add new layer to both maps,
// don't override, if layer.id is already in splitMaps.settings.layers
return splitMaps.map(function (settings) {
return (0, _extends14.default)({}, settings, {
layers: (0, _extends14.default)({}, settings.layers, newLayers.reduce(function (accu, newLayer) {
return newLayer.config.isVisible ? (0, _extends14.default)({}, accu, (0, _defineProperty3.default)({}, newLayer.id, settings.layers[newLayer.id] ? settings.layers[newLayer.id] : generateLayerMetaForSplitViews(newLayer))) : accu;
}, {}))
});
});
}
/**
* Hide an existing layers from custom map layer objects
* @param state
* @param layer
* @returns {[*,*]} Maps of custom layer objects
*/
function toggleLayerFromSplitMaps(state, layer) {
return state.splitMaps.map(function (settings) {
var layers = settings.layers;
var newLayers = (0, _extends14.default)({}, layers, (0, _defineProperty3.default)({}, layer.id, generateLayerMetaForSplitViews(layer)));
return (0, _extends14.default)({}, settings, {
layers: newLayers
});
});
}
/**
* When a user clicks on the specific map closing icon
* the application will close the selected map
* and will merge the remaining one with the global state
* TODO: i think in the future this action should be called merge map layers with global settings
* @param state
* @param action
* @returns {*}
*/
function closeSpecificMapAtIndex(state, action) {
// retrieve layers meta data from the remaining map that we need to keep
var indexToRetrieve = 1 - action.payload;
var metaSettings = state.splitMaps[indexToRetrieve];
if (!metaSettings || !metaSettings.layers) {
// if we can't find the meta settings we simply clean up splitMaps and
// keep global state as it is
// but why does this ever happen?
return (0, _extends14.default)({}, state, {
splitMaps: []
});
}
var layers = state.layers;
// update layer visibility
var newLayers = layers.map(function (layer) {
return layer.updateLayerConfig({
isVisible: metaSettings.layers[layer.id] ? metaSettings.layers[layer.id].isVisible : layer.config.isVisible
});
});
// delete map
return (0, _extends14.default)({}, state, {
layers: newLayers,
splitMaps: []
});
}
// TODO: redo write handler to not use tasks
var loadFilesUpdater = exports.loadFilesUpdater = function loadFilesUpdater(state, action) {
var files = action.files;
var filesToLoad = files.map(function (fileBlob) {
return {
fileBlob: fileBlob,
info: {
id: (0, _utils.generateHashId)(4),
label: fileBlob.name,
size: fileBlob.size
},
handler: (0, _fileHandler.getFileHandler)(fileBlob)
};
});
// reader -> parser -> augment -> receiveVisData
var loadFileTasks = [_tasks2.default.all(filesToLoad.map(_tasks3.LOAD_FILE_TASK)).bimap(function (results) {
var data = results.reduce(function (f, c) {
return {
// using concat here because the current datasets could be an array or a single item
datasets: f.datasets.concat(c.datasets),
// we need to deep merge this thing unless we find a better solution
// this case will only happen if we allow to load multiple keplergl json files
config: (0, _extends14.default)({}, f.config, c.config || {})
};
}, { datasets: [], config: {}, options: { centerMap: true } });
return (0, _actions.addDataToMap)(data);
}, function (error) {
return (0, _visStateActions.loadFilesErr)(error);
})];
return (0, _tasks.withTask)((0, _extends14.default)({}, state, {
fileLoading: true
}), loadFileTasks);
};
var loadFilesErrUpdater = exports.loadFilesErrUpdater = function loadFilesErrUpdater(state, _ref7) {
var error = _ref7.error;
return (0, _extends14.default)({}, state, {
fileLoading: false,
fileLoadingErr: error
});
};
/**
* helper function to update All layer domain and layer data of state
*
* @param {object} state
* @param {string} datasets
* @returns {object} state
*/
function addDefaultLayers(state, datasets) {
var defaultLayers = Object.values(datasets).reduce(function (accu, dataset) {
return [].concat((0, _toConsumableArray3.default)(accu), (0, _toConsumableArray3.default)((0, _layerUtils.findDefaultLayer)(dataset, state.layerClasses) || []));
}, []);
return (0, _extends14.default)({}, state, {
layers: [].concat((0, _toConsumableArray3.default)(state.layers), (0, _toConsumableArray3.default)(defaultLayers)),
layerOrder: [].concat((0, _toConsumableArray3.default)(defaultLayers.map(function (_, i) {
return state.layers.length + i;
})), (0, _toConsumableArray3.default)(state.layerOrder))
});
}
/**
* helper function to find default tooltips
*
* @param {object} state
* @param {object} dataset
* @returns {object} state
*/
function addDefaultTooltips(state, dataset) {
var tooltipFields = (0, _interactionUtils.findFieldsToShow)(dataset);
return (0, _extends14.default)({}, state, {
interactionConfig: (0, _extends14.default)({}, state.interactionConfig, {
tooltip: (0, _extends14.default)({}, state.interactionConfig.tooltip, {
config: {
// find default fields to show in tooltip
fieldsToShow: (0, _extends14.default)({}, state.interactionConfig.tooltip.config.fieldsToShow, tooltipFields)
}
})
})
});
}
/**
* helper function to update layer domains for an array of datsets
*
* @param {object} state
* @param {array | string} dataId
* @param {object} newFilter - if is called by setFilter, the filter that has changed
* @returns {object} state
*/
function updateAllLayerDomainData(state, dataId, newFilter) {
var dataIds = typeof dataId === 'string' ? [dataId] : dataId;
var newLayers = [];
var newLayerDatas = [];
state.layers.forEach(function (oldLayer, i) {
if (oldLayer.config.dataId && dataIds.includes(oldLayer.config.dataId)) {
// No need to recalculate layer domain if filter has fixed domain
var newLayer = newFilter && newFilter.fixedDomain ? oldLayer : oldLayer.updateLayerDomain(state.datasets[oldLayer.config.dataId], newFilter);
var _calculateLayerData5 = (0, _layerUtils.calculateLayerData)(newLayer, state, state.layerData[i]),
layerData = _calculateLayerData5.layerData,
layer = _calculateLayerData5.layer;
newLayers.push(layer);
newLayerDatas.push(layerData);
} else {
newLayers.push(oldLayer);
newLayerDatas.push(state.layerData[i]);
}
});
return (0, _extends14.default)({}, state, {
layers: newLayers,
layerData: newLayerDatas
});
}
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9yZWR1Y2Vycy92aXMtc3RhdGUtdXBkYXRlcnMuanMiXSwibmFtZXMiOlsibGF5ZXJDb25maWdDaGFuZ2VVcGRhdGVyIiwibGF5ZXJUeXBlQ2hhbmdlVXBkYXRlciIsImxheWVyVmlzdWFsQ2hhbm5lbENoYW5nZVVwZGF0ZXIiLCJsYXllclZpc0NvbmZpZ0NoYW5nZVVwZGF0ZXIiLCJpbnRlcmFjdGlvbkNvbmZpZ0NoYW5nZVVwZGF0ZXIiLCJzZXRGaWx0ZXJVcGRhdGVyIiwiYWRkRGVmYXVsdExheWVycyIsImFkZERlZmF1bHRUb29sdGlwcyIsInVwZGF0ZUFsbExheWVyRG9tYWluRGF0YSIsIklOSVRJQUxfVklTX1NUQVRFIiwibGF5ZXJzIiwibGF5ZXJEYXRhIiwibGF5ZXJUb0JlTWVyZ2VkIiwibGF5ZXJPcmRlciIsImZpbHRlcnMiLCJmaWx0ZXJUb0JlTWVyZ2VkIiwiZGF0YXNldHMiLCJlZGl0aW5nRGF0YXNldCIsInVuZGVmaW5lZCIsImludGVyYWN0aW9uQ29uZmlnIiwiaW50ZXJhY3Rpb25Ub0JlTWVyZ2VkIiwibGF5ZXJCbGVuZGluZyIsImhvdmVySW5mbyIsImNsaWNrZWQiLCJmaWxlTG9hZGluZyIsImZpbGVMb2FkaW5nRXJyIiwic3BsaXRNYXBzIiwibGF5ZXJDbGFzc2VzIiwiTGF5ZXJDbGFzc2VzIiwidXBkYXRlU3RhdGVXaXRoTGF5ZXJBbmREYXRhIiwic3RhdGUiLCJsYXllciIsImlkeCIsIm1hcCIsImx5ciIsImkiLCJkIiwiYWN0aW9uIiwib2xkTGF5ZXIiLCJmaW5kSW5kZXgiLCJsIiwiaWQiLCJwcm9wcyIsIk9iamVjdCIsImtleXMiLCJuZXdDb25maWciLCJuZXdMYXllciIsInVwZGF0ZUxheWVyQ29uZmlnIiwic2hvdWxkQ2FsY3VsYXRlTGF5ZXJEYXRhIiwib2xkTGF5ZXJEYXRhIiwic2FtZURhdGEiLCJuZXdTdGF0ZSIsInRvZ2dsZUxheWVyRnJvbVNwbGl0TWFwcyIsIm5ld1R5cGUiLCJvbGRJZCIsIkNvbnNvbGUiLCJlcnJvciIsImFzc2lnbkNvbmZpZ1RvTGF5ZXIiLCJjb25maWciLCJ2aXNDb25maWdTZXR0aW5ncyIsImRhdGFJZCIsImRhdGFzZXQiLCJ1cGRhdGVMYXllckRvbWFpbiIsInNldHRpbmdzIiwib2xkTGF5ZXJNYXAiLCJvdGhlckxheWVycyIsImNoYW5uZWwiLCJ1cGRhdGVMYXllclZpc3VhbENoYW5uZWwiLCJuZXdWaXNDb25maWciLCJ2aXNDb25maWciLCJlbmFibGVkIiwiZm9yRWFjaCIsImsiLCJwcm9wIiwidmFsdWUiLCJuZXdGaWx0ZXIiLCJmaWVsZHMiLCJhbGxEYXRhIiwiZmllbGRJZHgiLCJmIiwibmFtZSIsImZpZWxkIiwiZmlsdGVyUHJvcCIsImZyZWV6ZSIsImVubGFyZ2VkRmlsdGVySWR4IiwiZW5sYXJnZWQiLCJzZXRGaWx0ZXJQbG90VXBkYXRlciIsIm5ld1Byb3AiLCJwbG90VHlwZSIsImFkZEZpbHRlclVwZGF0ZXIiLCJ0b2dnbGVGaWx0ZXJBbmltYXRpb25VcGRhdGVyIiwiaXNBbmltYXRpbmciLCJ1cGRhdGVBbmltYXRpb25TcGVlZFVwZGF0ZXIiLCJzcGVlZCIsImVubGFyZ2VGaWx0ZXJVcGRhdGVyIiwiaXNFbmxhcmdlZCIsInJlbW92ZUZpbHRlclVwZGF0ZXIiLCJuZXdGaWx0ZXJzIiwic2xpY2UiLCJsZW5ndGgiLCJhZGRMYXllclVwZGF0ZXIiLCJkZWZhdWx0RGF0YXNldCIsIkxheWVyIiwiaXNWaXNpYmxlIiwiaXNDb25maWdBY3RpdmUiLCJhZGROZXdMYXllcnNUb1NwbGl0TWFwIiwicmVtb3ZlTGF5ZXJVcGRhdGVyIiwibGF5ZXJUb1JlbW92ZSIsIm5ld01hcHMiLCJyZW1vdmVMYXllckZyb21TcGxpdE1hcHMiLCJmaWx0ZXIiLCJwaWQiLCJpc0xheWVySG92ZXJlZCIsInJlb3JkZXJMYXllclVwZGF0ZXIiLCJvcmRlciIsInJlbW92ZURhdGFzZXRVcGRhdGVyIiwiZGF0YXNldEtleSIsImtleSIsIm5ld0RhdGFzZXRzIiwiaW5kZXhlcyIsInJlZHVjZSIsImxpc3RPZkluZGV4ZXMiLCJpbmRleCIsInB1c2giLCJjdXJyZW50U3RhdGUiLCJpbmRleENvdW50ZXIiLCJjdXJyZW50SW5kZXgiLCJ0b29sdGlwIiwiZmllbGRzVG9TaG93IiwidXBkYXRlTGF5ZXJCbGVuZGluZ1VwZGF0ZXIiLCJtb2RlIiwic2hvd0RhdGFzZXRUYWJsZVVwZGF0ZXIiLCJyZXNldE1hcENvbmZpZ1Zpc1N0YXRlVXBkYXRlciIsImluaXRpYWxTdGF0ZSIsInJlY2VpdmVNYXBDb25maWdVcGRhdGVyIiwicGF5bG9hZCIsInZpc1N0YXRlIiwicmVzZXRTdGF0ZSIsIm1lcmdlZFN0YXRlIiwibGF5ZXJIb3ZlclVwZGF0ZXIiLCJpbmZvIiwibGF5ZXJDbGlja1VwZGF0ZXIiLCJwaWNrZWQiLCJtYXBDbGlja1VwZGF0ZXIiLCJ0b2dnbGVTcGxpdE1hcFVwZGF0ZXIiLCJjb21wdXRlU3BsaXRNYXBMYXllcnMiLCJjbG9zZVNwZWNpZmljTWFwQXRJbmRleCIsInNldFZpc2libGVMYXllcnNGb3JNYXBVcGRhdGVyIiwibWFwSW5kZXgiLCJsYXllcklkcyIsIm5ld0xheWVycyIsImN1cnJlbnRMYXllcnMiLCJpbmNsdWRlcyIsInRvZ2dsZUxheWVyRm9yTWFwVXBkYXRlciIsIm1hcFNldHRpbmdzIiwibGF5ZXJJZCIsIm5ld1NwbGl0TWFwcyIsInVwZGF0ZVZpc0RhdGFVcGRhdGVyIiwiQXJyYXkiLCJpc0FycmF5IiwibmV3RGF0ZUVudHJpZXMiLCJhY2N1IiwiZGF0YSIsInN0YXRlV2l0aE5ld0RhdGEiLCJ0b29sdGlwRmllbGRzIiwiZ2VuZXJhdGVMYXllck1ldGFGb3JTcGxpdFZpZXdzIiwiaXNBdmFpbGFibGUiLCJtYXBMYXllcnMiLCJjdXJyZW50TGF5ZXIiLCJfIiwiaW5kZXhUb1JldHJpZXZlIiwibWV0YVNldHRpbmdzIiwibG9hZEZpbGVzVXBkYXRlciIsImZpbGVzIiwiZmlsZXNUb0xvYWQiLCJmaWxlQmxvYiIsImxhYmVsIiwic2l6ZSIsImhhbmRsZXIiLCJsb2FkRmlsZVRhc2tzIiwiVGFzayIsImFsbCIsIkxPQURfRklMRV9UQVNLIiwiYmltYXAiLCJyZXN1bHRzIiwiYyIsImNvbmNhdCIsIm9wdGlvbnMiLCJjZW50ZXJNYXAiLCJsb2FkRmlsZXNFcnJVcGRhdGVyIiwiZGVmYXVsdExheWVycyIsInZhbHVlcyIsImRhdGFJZHMiLCJuZXdMYXllckRhdGFzIiwiZml4ZWREb21haW4iXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O1FBa0lnQkEsd0IsR0FBQUEsd0I7UUE0QkFDLHNCLEdBQUFBLHNCO1FBOENBQywrQixHQUFBQSwrQjtRQWlCQUMsMkIsR0FBQUEsMkI7UUE0QkFDLDhCLEdBQUFBLDhCO1FBdUJBQyxnQixHQUFBQSxnQjtRQTRzQkFDLGdCLEdBQUFBLGdCO1FBMEJBQyxrQixHQUFBQSxrQjtRQTZCQUMsd0IsR0FBQUEsd0I7O0FBLy9CaEI7O0FBQ0E7Ozs7QUFHQTs7QUFHQTs7QUFDQTs7QUFHQTs7QUFDQTs7QUFJQTs7QUFPQTs7QUFFQTs7QUFLQTs7QUFFQTs7QUFhQTs7OztBQUVBO0FBQ0E7OztBQXRDQTs7O0FBSkE7QUEyQ0E7O0FBVkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUF4Q0E7QUF2QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBcURPLElBQU1DLGdEQUFvQjtBQUMvQjtBQUNBQyxVQUFRLEVBRnVCO0FBRy9CQyxhQUFXLEVBSG9CO0FBSS9CQyxtQkFBaUIsRUFKYztBQUsvQkMsY0FBWSxFQUxtQjs7QUFPL0I7QUFDQUMsV0FBUyxFQVJzQjtBQVMvQkMsb0JBQWtCLEVBVGE7O0FBVy9CO0FBQ0FDLFlBQVUsRUFacUI7QUFhL0JDLGtCQUFnQkMsU0FiZTs7QUFlL0JDLHFCQUFtQiw4Q0FmWTtBQWdCL0JDLHlCQUF1QkYsU0FoQlE7O0FBa0IvQkcsaUJBQWUsUUFsQmdCO0FBbUIvQkMsYUFBV0osU0FuQm9C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