UNPKG

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
'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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