From 13b469d86afc4d51c6c07cad4b1d62565e7a4b8d Mon Sep 17 00:00:00 2001 From: Igor Dykhta Date: Wed, 20 Nov 2024 19:48:31 +0200 Subject: [PATCH 1/9] [chore] common-utils module (#2773) * [chore] common-utils module Signed-off-by: Ihor Dykhta --- package.json | 1 + src/common-utils/babel.config.js | 51 ++++ src/common-utils/package.json | 55 ++++ src/common-utils/src/data-type.ts | 255 +++++++++++++++++ src/common-utils/src/data.ts | 47 +++ src/common-utils/src/index.ts | 6 + src/common-utils/src/string.ts | 11 + src/common-utils/tsconfig.production.json | 28 ++ src/components/package.json | 1 + src/components/src/common/field-selector.tsx | 2 +- .../common/item-selector/dropdown-select.tsx | 2 +- .../common/item-selector/item-selector.tsx | 3 +- .../src/common/map-layer-selector.tsx | 2 +- src/components/src/container.tsx | 2 +- src/components/src/kepler-gl.tsx | 3 +- .../src/layer-animation-controller.tsx | 3 +- src/components/src/map/layer-hover-info.tsx | 2 +- src/components/src/map/map-popover.tsx | 3 +- .../layer-panel/layer-column-config.tsx | 2 +- src/effects/src/effect.ts | 3 +- src/layers/package.json | 1 + src/layers/src/base-layer.ts | 5 +- src/layers/src/editor-layer/editor-layer.ts | 2 +- src/layers/src/layer-text-label.ts | 3 +- src/layers/src/trip-layer/trip-utils.ts | 8 +- src/processors/package.json | 1 + src/processors/src/data-processor.ts | 11 +- src/processors/src/file-handler.ts | 3 +- src/reducers/package.json | 1 + src/reducers/src/interaction-utils.ts | 10 +- src/reducers/src/map-style-updaters.ts | 2 +- src/reducers/src/merger-handler.ts | 3 +- src/reducers/src/provider-state-updaters.ts | 3 +- src/reducers/src/vis-state-updaters.ts | 3 +- src/schemas/package.json | 1 + src/schemas/src/dataset-schema.ts | 2 +- src/schemas/src/vis-state-schema.ts | 3 +- src/table/package.json | 1 + src/table/src/gpu-filter-utils.ts | 3 +- src/table/src/kepler-table.ts | 3 +- src/utils/package.json | 1 + src/utils/src/data-scale-utils.ts | 3 +- src/utils/src/data-utils.ts | 12 +- src/utils/src/dataset-utils.ts | 270 +----------------- src/utils/src/export-utils.ts | 3 +- src/utils/src/filter-utils.ts | 5 +- src/utils/src/h3-utils.ts | 2 +- src/utils/src/index.ts | 5 - src/utils/src/notifications-utils.ts | 2 +- src/utils/src/plot.ts | 9 +- src/utils/src/time.ts | 2 +- src/utils/src/utils.ts | 29 -- test/helpers/comparison-utils.js | 2 +- test/node/utils/data-processor-test.js | 8 +- test/node/utils/util-test.js | 4 +- yarn.lock | 19 ++ 56 files changed, 551 insertions(+), 376 deletions(-) create mode 100644 src/common-utils/babel.config.js create mode 100644 src/common-utils/package.json create mode 100644 src/common-utils/src/data-type.ts create mode 100644 src/common-utils/src/data.ts create mode 100644 src/common-utils/src/index.ts create mode 100644 src/common-utils/src/string.ts create mode 100644 src/common-utils/tsconfig.production.json diff --git a/package.json b/package.json index 68cd97c61c..b876d640a9 100644 --- a/package.json +++ b/package.json @@ -18,6 +18,7 @@ "workspaces": [ "./src/types", "./src/constants", + "./src/common-utils", "./src/utils", "./src/styles", "./src/localization", diff --git a/src/common-utils/babel.config.js b/src/common-utils/babel.config.js new file mode 100644 index 0000000000..eb16706b69 --- /dev/null +++ b/src/common-utils/babel.config.js @@ -0,0 +1,51 @@ +// SPDX-License-Identifier: MIT +// Copyright contributors to the kepler.gl project + +const KeplerPackage = require('./package'); + +const PRESETS = ['@babel/preset-env', '@babel/preset-react', '@babel/preset-typescript']; +const PLUGINS = [ + ['@babel/plugin-transform-typescript', {isTSX: true, allowDeclareFields: true}], + '@babel/plugin-transform-modules-commonjs', + '@babel/plugin-transform-class-properties', + '@babel/plugin-transform-optional-chaining', + '@babel/plugin-transform-logical-assignment-operators', + '@babel/plugin-transform-nullish-coalescing-operator', + '@babel/plugin-transform-export-namespace-from', + [ + '@babel/transform-runtime', + { + regenerator: true + } + ], + [ + 'search-and-replace', + { + rules: [ + { + search: '__PACKAGE_VERSION__', + replace: KeplerPackage.version + } + ] + } + ] +]; +const ENV = { + test: { + plugins: ['istanbul'] + }, + debug: { + sourceMaps: 'inline', + retainLines: true + } +}; + +module.exports = function babel(api) { + api.cache(true); + + return { + presets: PRESETS, + plugins: PLUGINS, + env: ENV + }; +}; diff --git a/src/common-utils/package.json b/src/common-utils/package.json new file mode 100644 index 0000000000..4caa57a599 --- /dev/null +++ b/src/common-utils/package.json @@ -0,0 +1,55 @@ +{ + "name": "@kepler.gl/common-utils", + "author": "Shan He ", + "version": "3.0.0", + "description": "kepler.gl common utils", + "license": "MIT", + "main": "dist/index.js", + "types": "dist/index.d.ts", + "keywords": [ + "babel", + "es6", + "react", + "webgl", + "visualization", + "deck.gl" + ], + "repository": { + "type": "git", + "url": "https://github.com/keplergl/kepler.gl.git" + }, + "scripts": { + "build": "rm -fr dist && babel src --out-dir dist --source-maps inline --extensions '.ts,.tsx,.js,.jsx' --ignore '**/*.d.ts'", + "build:umd": "NODE_OPTIONS=--openssl-legacy-provider webpack --config ./webpack/umd.js --progress --env.prod", + "build:types": "tsc --project ./tsconfig.production.json", + "prepublish": "babel-node ../../scripts/license-header/bin --license ../../FILE-HEADER && yarn build && yarn build:types", + "stab": "mkdir -p dist && touch dist/index.js" + }, + "files": [ + "dist", + "umd" + ], + "dependencies": { + "@kepler.gl/constants": "3.0.0", + "@kepler.gl/types": "3.0.0", + "d3-array": "^2.8.0", + "global": "^4.3.0", + "type-analyzer": "0.4.0" + }, + "nyc": { + "sourceMap": false, + "instrument": false + }, + "maintainers": [ + "Shan He ", + "Igor Dykhta " + ], + "engines": { + "node": ">=18" + }, + "volta": { + "node": "18.18.2", + "yarn": "4.4.0" + }, + "packageManager": "yarn@4.4.0" +} diff --git a/src/common-utils/src/data-type.ts b/src/common-utils/src/data-type.ts new file mode 100644 index 0000000000..19740e6831 --- /dev/null +++ b/src/common-utils/src/data-type.ts @@ -0,0 +1,255 @@ +// SPDX-License-Identifier: MIT +// Copyright contributors to the kepler.gl project + +import {Analyzer, DATA_TYPES as AnalyzerDATA_TYPES} from 'type-analyzer'; +import {RowData, Field} from '@kepler.gl/types'; +import {ALL_FIELD_TYPES} from '@kepler.gl/constants'; +import {console as globalConsole} from 'global/window'; +import {range} from 'd3-array'; +import {isHexWkb, notNullorUndefined} from './data'; + +export const ACCEPTED_ANALYZER_TYPES = [ + AnalyzerDATA_TYPES.DATE, + AnalyzerDATA_TYPES.TIME, + AnalyzerDATA_TYPES.DATETIME, + AnalyzerDATA_TYPES.NUMBER, + AnalyzerDATA_TYPES.INT, + AnalyzerDATA_TYPES.FLOAT, + AnalyzerDATA_TYPES.BOOLEAN, + AnalyzerDATA_TYPES.STRING, + AnalyzerDATA_TYPES.GEOMETRY, + AnalyzerDATA_TYPES.GEOMETRY_FROM_STRING, + AnalyzerDATA_TYPES.PAIR_GEOMETRY_FROM_STRING, + AnalyzerDATA_TYPES.ZIPCODE, + AnalyzerDATA_TYPES.ARRAY, + AnalyzerDATA_TYPES.OBJECT +]; + +const IGNORE_DATA_TYPES = Object.keys(AnalyzerDATA_TYPES).filter( + type => !ACCEPTED_ANALYZER_TYPES.includes(type) +); + +/** + * Getting sample data for analyzing field type. + */ +export function getSampleForTypeAnalyze({ + fields, + rows, + sampleCount = 50 +}: { + fields: string[]; + rows: unknown[][] | RowData; + sampleCount?: number; +}): RowData { + const total = Math.min(sampleCount, rows.length); + // const fieldOrder = fields.map(f => f.name); + const sample = range(0, total, 1).map(() => ({})); + + if (rows.length < 1) { + return []; + } + const isRowObject = !Array.isArray(rows[0]); + + // collect sample data for each field + fields.forEach((field, fieldIdx) => { + // row counter + let i = 0; + // sample counter + let j = 0; + + while (j < total) { + if (i >= rows.length) { + // if depleted data pool + sample[j][field] = null; + j++; + } else if (notNullorUndefined(rows[i][isRowObject ? field : fieldIdx])) { + const value = rows[i][isRowObject ? field : fieldIdx]; + sample[j][field] = typeof value === 'string' ? value.trim() : value; + j++; + i++; + } else { + i++; + } + } + }); + + return sample; +} + +/** + * Convert type-analyzer output to kepler.gl field types + * + * @param aType + * @returns corresponding type in `ALL_FIELD_TYPES` + */ +/* eslint-disable complexity */ +export function analyzerTypeToFieldType(aType: string): string { + const { + DATE, + TIME, + DATETIME, + NUMBER, + INT, + FLOAT, + BOOLEAN, + STRING, + GEOMETRY, + GEOMETRY_FROM_STRING, + PAIR_GEOMETRY_FROM_STRING, + ZIPCODE, + ARRAY, + OBJECT + } = AnalyzerDATA_TYPES; + + // TODO: un recognized types + // CURRENCY PERCENT NONE + switch (aType) { + case DATE: + return ALL_FIELD_TYPES.date; + case TIME: + case DATETIME: + return ALL_FIELD_TYPES.timestamp; + case FLOAT: + return ALL_FIELD_TYPES.real; + case INT: + return ALL_FIELD_TYPES.integer; + case BOOLEAN: + return ALL_FIELD_TYPES.boolean; + case GEOMETRY: + case GEOMETRY_FROM_STRING: + case PAIR_GEOMETRY_FROM_STRING: + return ALL_FIELD_TYPES.geojson; + case ARRAY: + return ALL_FIELD_TYPES.array; + case OBJECT: + return ALL_FIELD_TYPES.object; + case NUMBER: + case STRING: + case ZIPCODE: + return ALL_FIELD_TYPES.string; + default: + globalConsole.warn(`Unsupported analyzer type: ${aType}`); + return ALL_FIELD_TYPES.string; + } +} + +/** + * Analyze field types from data in `string` format, e.g. uploaded csv. + * Assign `type`, `fieldIdx` and `format` (timestamp only) to each field + * + * @param data array of row object + * @param fieldOrder array of field names as string + * @returns formatted fields + * @public + * @example + * + * import {getFieldsFromData} from 'kepler.gl/common-utils'; + * const data = [{ + * time: '2016-09-17 00:09:55', + * value: '4', + * surge: '1.2', + * isTrip: 'true', + * zeroOnes: '0' + * }, { + * time: '2016-09-17 00:30:08', + * value: '3', + * surge: null, + * isTrip: 'false', + * zeroOnes: '1' + * }, { + * time: null, + * value: '2', + * surge: '1.3', + * isTrip: null, + * zeroOnes: '1' + * }]; + * + * const fieldOrder = ['time', 'value', 'surge', 'isTrip', 'zeroOnes']; + * const fields = getFieldsFromData(data, fieldOrder); + * // fields = [ + * // {name: 'time', format: 'YYYY-M-D H:m:s', fieldIdx: 1, type: 'timestamp'}, + * // {name: 'value', format: '', fieldIdx: 4, type: 'integer'}, + * // {name: 'surge', format: '', fieldIdx: 5, type: 'real'}, + * // {name: 'isTrip', format: '', fieldIdx: 6, type: 'boolean'}, + * // {name: 'zeroOnes', format: '', fieldIdx: 7, type: 'integer'}]; + * + */ +export function getFieldsFromData(data: RowData, fieldOrder: string[]): Field[] { + // add a check for epoch timestamp + const metadata = Analyzer.computeColMeta( + data, + [ + {regex: /.*geojson|all_points/g, dataType: 'GEOMETRY'}, + {regex: /.*census/g, dataType: 'STRING'} + ], + {ignoredDataTypes: IGNORE_DATA_TYPES} + ); + + const {fieldByIndex} = renameDuplicateFields(fieldOrder); + + const result = fieldOrder.map((field, index) => { + const name = fieldByIndex[index]; + + const fieldMeta = metadata.find(m => m.key === field); + + // fieldMeta could be undefined if the field has no data and Analyzer.computeColMeta + // will ignore the field. In this case, we will simply assign the field type to STRING + // since dropping the column in the RowData could be expensive + let type = fieldMeta?.type || 'STRING'; + const format = fieldMeta?.format || ''; + + // check if string is hex wkb + if (type === AnalyzerDATA_TYPES.STRING) { + type = data.some(d => isHexWkb(d[name])) ? AnalyzerDATA_TYPES.GEOMETRY : type; + } + + return { + name, + id: name, + displayName: name, + format, + fieldIdx: index, + type: analyzerTypeToFieldType(type), + analyzerType: type, + valueAccessor: dc => d => { + return dc.valueAt(d.index, index); + } + }; + }); + + return result; +} + +/** + * pass in an array of field names, rename duplicated one + * and return a map from old field index to new name + * + * @param fieldOrder + * @returns new field name by index + */ +export function renameDuplicateFields(fieldOrder: string[]): { + allNames: string[]; + fieldByIndex: string[]; +} { + return fieldOrder.reduce<{allNames: string[]; fieldByIndex: string[]}>( + (accu, field, i) => { + const {allNames} = accu; + let fieldName = field; + + // add a counter to duplicated names + if (allNames.includes(field)) { + let counter = 0; + while (allNames.includes(`${field}-${counter}`)) { + counter++; + } + fieldName = `${field}-${counter}`; + } + + accu.fieldByIndex[i] = fieldName; + accu.allNames.push(fieldName); + + return accu; + }, + {allNames: [], fieldByIndex: []} + ); +} diff --git a/src/common-utils/src/data.ts b/src/common-utils/src/data.ts new file mode 100644 index 0000000000..18bf7ba48a --- /dev/null +++ b/src/common-utils/src/data.ts @@ -0,0 +1,47 @@ +// SPDX-License-Identifier: MIT +// Copyright contributors to the kepler.gl project + +export function notNullorUndefined>(d: T | null | undefined): d is T { + return d !== undefined && d !== null; +} + +/** + * Check if string is a valid Well-known binary (WKB) in HEX format + * https://en.wikipedia.org/wiki/Well-known_text_representation_of_geometry + * + * @param str input string + * @returns true if string is a valid WKB in HEX format + */ +export function isHexWkb(str: string | null): boolean { + if (!str) return false; + // check if the length of the string is even and is at least 10 characters long + if (str.length < 10 || str.length % 2 !== 0) { + return false; + } + // check if first two characters are 00 or 01 + if (!str.startsWith('00') && !str.startsWith('01')) { + return false; + } + // check if the rest of the string is a valid hex + return /^[0-9a-fA-F]+$/.test(str.slice(2)); +} + +/** + * Converts non-arrays to arrays. Leaves arrays alone. Converts + * undefined values to empty arrays ([] instead of [undefined]). + * Otherwise, just returns [item] for non-array items. + * + * @param {*} item + * @returns {array} boom! much array. very indexed. so useful. + */ +export function toArray(item: T | T[]): T[] { + if (Array.isArray(item)) { + return item; + } + + if (typeof item === 'undefined' || item === null) { + return []; + } + + return [item]; +} diff --git a/src/common-utils/src/index.ts b/src/common-utils/src/index.ts new file mode 100644 index 0000000000..fd626ebbbd --- /dev/null +++ b/src/common-utils/src/index.ts @@ -0,0 +1,6 @@ +// SPDX-License-Identifier: MIT +// Copyright contributors to the kepler.gl project + +export * from './data'; +export * from './data-type'; +export * from './string'; diff --git a/src/common-utils/src/string.ts b/src/common-utils/src/string.ts new file mode 100644 index 0000000000..3b6fc93559 --- /dev/null +++ b/src/common-utils/src/string.ts @@ -0,0 +1,11 @@ +// SPDX-License-Identifier: MIT +// Copyright contributors to the kepler.gl project + +/** + * Generate a hash string based on number of character + * @param {number} count + * @returns {string} hash string + */ +export function generateHashId(count = 6): string { + return Math.random().toString(36).substr(count); +} diff --git a/src/common-utils/tsconfig.production.json b/src/common-utils/tsconfig.production.json new file mode 100644 index 0000000000..f8ee4aa488 --- /dev/null +++ b/src/common-utils/tsconfig.production.json @@ -0,0 +1,28 @@ +{ + "compilerOptions": { + "target": "es2020", + "allowJs": false, + "checkJs": false, + "jsx": "react", + "module": "esnext", + "moduleResolution": "node", + "declaration": true, + "emitDeclarationOnly": true, + "noImplicitAny": false, + "noImplicitReturns": true, + "noImplicitThis": true, + "noUnusedLocals": true, + "outDir": "dist", + "sourceMap": true, + "strictNullChecks": true, + "suppressImplicitAnyIndexErrors": false, + "esModuleInterop": true, + "allowSyntheticDefaultImports": true, + "skipLibCheck": true, + "strict": true, + "resolveJsonModule": true, + "isolatedModules": true, + "baseUrl": "./src" + }, + "include": ["src"] +} diff --git a/src/components/package.json b/src/components/package.json index d49b469b4c..e10d4387d4 100644 --- a/src/components/package.json +++ b/src/components/package.json @@ -39,6 +39,7 @@ "@floating-ui/react": "0.25.1", "@kepler.gl/actions": "3.0.0", "@kepler.gl/cloud-providers": "3.0.0", + "@kepler.gl/common-utils": "3.0.0", "@kepler.gl/constants": "3.0.0", "@kepler.gl/effects": "3.0.0", "@kepler.gl/layers": "3.0.0", diff --git a/src/components/src/common/field-selector.tsx b/src/components/src/common/field-selector.tsx index df058ca616..e317a51d73 100644 --- a/src/components/src/common/field-selector.tsx +++ b/src/components/src/common/field-selector.tsx @@ -7,7 +7,7 @@ import styled from 'styled-components'; import {createSelector} from 'reselect'; import {Field, TooltipField} from '@kepler.gl/types'; -import {notNullorUndefined, toArray} from '@kepler.gl/utils'; +import {notNullorUndefined, toArray} from '@kepler.gl/common-utils'; import ItemSelector from './item-selector/item-selector'; import {classList} from './item-selector/dropdown-list'; diff --git a/src/components/src/common/item-selector/dropdown-select.tsx b/src/components/src/common/item-selector/dropdown-select.tsx index 9b61abdb71..45eca3d13d 100644 --- a/src/components/src/common/item-selector/dropdown-select.tsx +++ b/src/components/src/common/item-selector/dropdown-select.tsx @@ -4,7 +4,7 @@ import React from 'react'; import styled from 'styled-components'; -import {notNullorUndefined} from '@kepler.gl/utils'; +import {notNullorUndefined} from '@kepler.gl/common-utils'; import {ComponentType} from 'react'; import {ArrowDown, Delete} from '../icons'; import {ListItem} from './dropdown-list'; diff --git a/src/components/src/common/item-selector/item-selector.tsx b/src/components/src/common/item-selector/item-selector.tsx index e95856be32..99cfe058b4 100644 --- a/src/components/src/common/item-selector/item-selector.tsx +++ b/src/components/src/common/item-selector/item-selector.tsx @@ -11,7 +11,8 @@ import ChickletedInput from './chickleted-input'; import Typeahead from './typeahead'; import DropdownList, {ListItem} from './dropdown-list'; import Portaled from '../../common/portaled'; -import {toArray, observeDimensions, unobserveDimensions} from '@kepler.gl/utils'; +import {observeDimensions, unobserveDimensions} from '@kepler.gl/utils'; +import {toArray} from '@kepler.gl/common-utils'; import {injectIntl, IntlShape} from 'react-intl'; import {ListItemProps} from './dropdown-select'; import DropdownSelect from './dropdown-select'; diff --git a/src/components/src/common/map-layer-selector.tsx b/src/components/src/common/map-layer-selector.tsx index e92a6d9b46..6473ff0b96 100644 --- a/src/components/src/common/map-layer-selector.tsx +++ b/src/components/src/common/map-layer-selector.tsx @@ -4,7 +4,7 @@ import React from 'react'; import styled from 'styled-components'; import Checkbox from './checkbox'; -import {generateHashId} from '@kepler.gl/utils'; +import {generateHashId} from '@kepler.gl/common-utils'; const MapLayerSelect = styled.div` padding: 12px; diff --git a/src/components/src/container.tsx b/src/components/src/container.tsx index b5bcba03c3..f7d7f88235 100644 --- a/src/components/src/container.tsx +++ b/src/components/src/container.tsx @@ -9,7 +9,7 @@ import {injector, provideRecipesToInjector, flattenDeps} from './injector'; import KeplerGlFactory from './kepler-gl'; import {registerEntry, deleteEntry, renameEntry, forwardTo} from '@kepler.gl/actions'; -import {notNullorUndefined} from '@kepler.gl/utils'; +import {notNullorUndefined} from '@kepler.gl/common-utils'; import {KeplerGlState} from '@kepler.gl/reducers'; export const ERROR_MSG = { diff --git a/src/components/src/kepler-gl.tsx b/src/components/src/kepler-gl.tsx index e4f97b5474..4e729f98f9 100644 --- a/src/components/src/kepler-gl.tsx +++ b/src/components/src/kepler-gl.tsx @@ -20,6 +20,8 @@ import { VisStateActions } from '@kepler.gl/actions'; +import {generateHashId} from '@kepler.gl/common-utils'; + type KeplerGlActions = { visStateActions: typeof VisStateActions; mapStateActions: typeof MapStateActions; @@ -52,7 +54,6 @@ import {CloudListProvider} from './hooks/use-cloud-list-provider'; import { filterObjectByPredicate, - generateHashId, validateToken, mergeMessages, observeDimensions, diff --git a/src/components/src/layer-animation-controller.tsx b/src/components/src/layer-animation-controller.tsx index 57c37def01..5a3ad5ddba 100644 --- a/src/components/src/layer-animation-controller.tsx +++ b/src/components/src/layer-animation-controller.tsx @@ -4,7 +4,8 @@ import React, {useCallback} from 'react'; import {ANIMATION_WINDOW} from '@kepler.gl/constants'; import {AnimationConfig, Timeline} from '@kepler.gl/types'; -import {snapToMarks, getTimelineFromAnimationConfig, toArray} from '@kepler.gl/utils'; +import {snapToMarks, getTimelineFromAnimationConfig} from '@kepler.gl/utils'; +import {toArray} from '@kepler.gl/common-utils'; import AnimationControllerFactory from './common/animation-control/animation-controller'; interface LayerAnimationControllerProps { diff --git a/src/components/src/map/layer-hover-info.tsx b/src/components/src/map/layer-hover-info.tsx index bedd23bc15..6b15a6a92f 100644 --- a/src/components/src/map/layer-hover-info.tsx +++ b/src/components/src/map/layer-hover-info.tsx @@ -7,7 +7,7 @@ import {TooltipField} from '@kepler.gl/types'; import {CenterFlexbox} from '../common/styled-components'; import {Layers} from '../common/icons'; import PropTypes from 'prop-types'; -import {notNullorUndefined} from '@kepler.gl/utils'; +import {notNullorUndefined} from '@kepler.gl/common-utils'; import {Layer} from '@kepler.gl/layers'; import { AggregationLayerHoverData, diff --git a/src/components/src/map/map-popover.tsx b/src/components/src/map/map-popover.tsx index a698a6872e..420b4f1458 100644 --- a/src/components/src/map/map-popover.tsx +++ b/src/components/src/map/map-popover.tsx @@ -9,7 +9,8 @@ import {injectIntl, IntlShape} from 'react-intl'; import {FormattedMessage} from '@kepler.gl/localization'; import {RootContext} from '../context'; import {parseGeoJsonRawFeature} from '@kepler.gl/layers'; -import {idToPolygonGeo, generateHashId} from '@kepler.gl/utils'; +import {idToPolygonGeo} from '@kepler.gl/utils'; +import {generateHashId} from '@kepler.gl/common-utils'; import {LAYER_TYPES} from '@kepler.gl/constants'; import {LayerHoverProp} from '@kepler.gl/reducers'; import {Feature, FeatureSelectionContext} from '@kepler.gl/types'; diff --git a/src/components/src/side-panel/layer-panel/layer-column-config.tsx b/src/components/src/side-panel/layer-panel/layer-column-config.tsx index 156097ce53..c992f53641 100644 --- a/src/components/src/side-panel/layer-panel/layer-column-config.tsx +++ b/src/components/src/side-panel/layer-panel/layer-column-config.tsx @@ -11,7 +11,7 @@ import { ColumnLabels, EnhancedFieldPair } from '@kepler.gl/types'; -import {toArray} from '@kepler.gl/utils'; +import {toArray} from '@kepler.gl/common-utils'; import ColumnSelectorFactory from './column-selector'; import {MinimalField} from '../../common/field-selector'; diff --git a/src/effects/src/effect.ts b/src/effects/src/effect.ts index dc35a57b2f..3958b92e17 100644 --- a/src/effects/src/effect.ts +++ b/src/effects/src/effect.ts @@ -1,7 +1,8 @@ // SPDX-License-Identifier: MIT // Copyright contributors to the kepler.gl project -import {generateHashId, validateEffectParameters} from '@kepler.gl/utils'; +import {validateEffectParameters} from '@kepler.gl/utils'; +import {generateHashId} from '@kepler.gl/common-utils'; import { Effect as EffectInterface, EffectProps, diff --git a/src/layers/package.json b/src/layers/package.json index 9d521b99d3..c825aaced5 100644 --- a/src/layers/package.json +++ b/src/layers/package.json @@ -36,6 +36,7 @@ "@deck.gl/geo-layers": "^8.9.27", "@deck.gl/layers": "^8.9.27", "@deck.gl/mesh-layers": "^8.9.27", + "@kepler.gl/common-utils": "3.0.0", "@kepler.gl/constants": "3.0.0", "@kepler.gl/deckgl-arrow-layers": "3.0.0", "@kepler.gl/deckgl-layers": "3.0.0", diff --git a/src/layers/src/base-layer.ts b/src/layers/src/base-layer.ts index 35bd3fdf7c..91439d4e24 100644 --- a/src/layers/src/base-layer.ts +++ b/src/layers/src/base-layer.ts @@ -37,18 +37,15 @@ import { import { DataContainerInterface, - generateHashId, getColorGroupByName, getLatLngBounds, getSampleContainerData, hasColorMap, hexToRgb, isPlainObject, - toArray, - notNullorUndefined, reverseColorRange } from '@kepler.gl/utils'; - +import {generateHashId, toArray, notNullorUndefined} from '@kepler.gl/common-utils'; import {Datasets, GpuFilter, KeplerTable} from '@kepler.gl/table'; import { ColorUI, diff --git a/src/layers/src/editor-layer/editor-layer.ts b/src/layers/src/editor-layer/editor-layer.ts index d9279c3ee9..bd8c109f58 100644 --- a/src/layers/src/editor-layer/editor-layer.ts +++ b/src/layers/src/editor-layer/editor-layer.ts @@ -13,7 +13,7 @@ import {PathStyleExtension} from '@deck.gl/extensions'; import {EDITOR_LAYER_ID, EDITOR_MODES, EDITOR_LAYER_PICKING_RADIUS} from '@kepler.gl/constants'; import {Viewport, Editor, Feature, FeatureSelectionContext} from '@kepler.gl/types'; -import {generateHashId} from '@kepler.gl/utils'; +import {generateHashId} from '@kepler.gl/common-utils'; import {EDIT_TYPES} from './constants'; import {LINE_STYLE, FEATURE_STYLE, EDIT_HANDLE_STYLE} from './feature-styles'; diff --git a/src/layers/src/layer-text-label.ts b/src/layers/src/layer-text-label.ts index 35760e88ea..d90607734a 100644 --- a/src/layers/src/layer-text-label.ts +++ b/src/layers/src/layer-text-label.ts @@ -3,7 +3,8 @@ import * as arrow from 'apache-arrow'; import {getDistanceScales} from 'viewport-mercator-project'; -import {notNullorUndefined, DataContainerInterface, ArrowDataContainer} from '@kepler.gl/utils'; +import {DataContainerInterface, ArrowDataContainer} from '@kepler.gl/utils'; +import {notNullorUndefined} from '@kepler.gl/common-utils'; import uniq from 'lodash.uniq'; export const defaultPadding = 20; diff --git a/src/layers/src/trip-layer/trip-utils.ts b/src/layers/src/trip-layer/trip-utils.ts index 201eaedbce..d76432baa4 100644 --- a/src/layers/src/trip-layer/trip-utils.ts +++ b/src/layers/src/trip-layer/trip-utils.ts @@ -6,12 +6,8 @@ import {Analyzer, DATA_TYPES} from 'type-analyzer'; import {Field} from '@kepler.gl/types'; import {parseGeoJsonRawFeature, getGeojsonFeatureTypes} from '../geojson-layer/geojson-utils'; -import { - DataContainerInterface, - getSampleContainerData, - notNullorUndefined, - timeToUnixMilli -} from '@kepler.gl/utils'; +import {DataContainerInterface, getSampleContainerData, timeToUnixMilli} from '@kepler.gl/utils'; +import {notNullorUndefined} from '@kepler.gl/common-utils'; import {Feature} from '@turf/helpers'; import {GeoJsonProperties, Geometry} from 'geojson'; diff --git a/src/processors/package.json b/src/processors/package.json index 742e3d4f0e..fbc77b2b5e 100644 --- a/src/processors/package.json +++ b/src/processors/package.json @@ -31,6 +31,7 @@ ], "dependencies": { "@danmarshall/deckgl-typings": "4.9.22", + "@kepler.gl/common-utils": "3.0.0", "@kepler.gl/constants": "3.0.0", "@kepler.gl/schemas": "3.0.0", "@kepler.gl/types": "3.0.0", diff --git a/src/processors/src/data-processor.ts b/src/processors/src/data-processor.ts index 80e5fbee8f..f6f0345281 100644 --- a/src/processors/src/data-processor.ts +++ b/src/processors/src/data-processor.ts @@ -11,14 +11,15 @@ import {ProcessorResult, Field} from '@kepler.gl/types'; import { arrowDataTypeToAnalyzerDataType, arrowDataTypeToFieldType, - notNullorUndefined, hasOwnProperty, - isPlainObject, - analyzerTypeToFieldType, + isPlainObject +} from '@kepler.gl/utils'; +import {notNullorUndefined, toArray} from '@kepler.gl/common-utils'; +import { getSampleForTypeAnalyze, getFieldsFromData, - toArray -} from '@kepler.gl/utils'; + analyzerTypeToFieldType +} from '@kepler.gl/common-utils'; import {KeplerGlSchema, ParsedDataset, SavedMap, LoadedMap} from '@kepler.gl/schemas'; import {Feature} from '@nebula.gl/edit-modes'; diff --git a/src/processors/src/file-handler.ts b/src/processors/src/file-handler.ts index ac3a75cf8a..087d2793e2 100644 --- a/src/processors/src/file-handler.ts +++ b/src/processors/src/file-handler.ts @@ -8,7 +8,8 @@ import {CSVLoader} from '@loaders.gl/csv'; import {GeoArrowLoader} from '@loaders.gl/arrow'; import {ParquetWasmLoader} from '@loaders.gl/parquet'; import {Loader} from '@loaders.gl/loader-utils'; -import {generateHashId, isPlainObject, generateHashIdFromString} from '@kepler.gl/utils'; +import {isPlainObject, generateHashIdFromString} from '@kepler.gl/utils'; +import {generateHashId} from '@kepler.gl/common-utils'; import {DATASET_FORMATS} from '@kepler.gl/constants'; import {LoadedMap, ProcessorResult} from '@kepler.gl/types'; import {Feature, AddDataToMapPayload} from '@kepler.gl/types'; diff --git a/src/reducers/package.json b/src/reducers/package.json index 4bdc4c66af..80a6fc12c8 100644 --- a/src/reducers/package.json +++ b/src/reducers/package.json @@ -32,6 +32,7 @@ "dependencies": { "@kepler.gl/actions": "3.0.0", "@kepler.gl/cloud-providers": "3.0.0", + "@kepler.gl/common-utils": "3.0.0", "@kepler.gl/constants": "3.0.0", "@kepler.gl/deckgl-arrow-layers": "3.0.0", "@kepler.gl/deckgl-layers": "3.0.0", diff --git a/src/reducers/src/interaction-utils.ts b/src/reducers/src/interaction-utils.ts index d390842998..4c304bd2ad 100644 --- a/src/reducers/src/interaction-utils.ts +++ b/src/reducers/src/interaction-utils.ts @@ -11,14 +11,8 @@ import { } from '@kepler.gl/constants'; import {Field, TooltipField, CompareType} from '@kepler.gl/types'; -import { - DataRow, - parseFieldValue, - getFormatter, - isNumber, - defaultFormatter, - notNullorUndefined -} from '@kepler.gl/utils'; +import {DataRow, parseFieldValue, getFormatter, isNumber, defaultFormatter} from '@kepler.gl/utils'; +import {notNullorUndefined} from '@kepler.gl/common-utils'; /** * Minus sign used in tooltip formatting. diff --git a/src/reducers/src/map-style-updaters.ts b/src/reducers/src/map-style-updaters.ts index 3850e3e097..0f488a3a9e 100644 --- a/src/reducers/src/map-style-updaters.ts +++ b/src/reducers/src/map-style-updaters.ts @@ -13,11 +13,11 @@ import { editTopMapStyle, editBottomMapStyle, getStyleImageIcon, - generateHashId, isPlainObject, hexToRgb, colorMaybeToRGB } from '@kepler.gl/utils'; +import {generateHashId} from '@kepler.gl/common-utils'; import { DEFAULT_MAP_STYLES, DEFAULT_LAYER_GROUPS, diff --git a/src/reducers/src/merger-handler.ts b/src/reducers/src/merger-handler.ts index 848242518c..db9bf092ef 100644 --- a/src/reducers/src/merger-handler.ts +++ b/src/reducers/src/merger-handler.ts @@ -2,7 +2,8 @@ // Copyright contributors to the kepler.gl project import {getGlobalTaskQueue} from 'react-palm/tasks'; -import {isObject, toArray} from '@kepler.gl/utils'; +import {isObject} from '@kepler.gl/utils'; +import {toArray} from '@kepler.gl/common-utils'; import {ValueOf} from '@kepler.gl/types'; import {VisState, Merger, PostMergerPayload} from '@kepler.gl/schemas'; diff --git a/src/reducers/src/provider-state-updaters.ts b/src/reducers/src/provider-state-updaters.ts index a48e5257a7..19a3c6a667 100644 --- a/src/reducers/src/provider-state-updaters.ts +++ b/src/reducers/src/provider-state-updaters.ts @@ -3,7 +3,8 @@ import {withTask} from 'react-palm/tasks'; import Console from 'global/console'; -import {generateHashId, getError, isPlainObject, toArray} from '@kepler.gl/utils'; +import {getError, isPlainObject} from '@kepler.gl/utils'; +import {generateHashId, toArray} from '@kepler.gl/common-utils'; import { EXPORT_FILE_TO_CLOUD_TASK, ACTION_TASK, diff --git a/src/reducers/src/vis-state-updaters.ts b/src/reducers/src/vis-state-updaters.ts index 9793f66f31..eda5f74cd1 100644 --- a/src/reducers/src/vis-state-updaters.ts +++ b/src/reducers/src/vis-state-updaters.ts @@ -45,7 +45,6 @@ import { adjustValueToFilterDomain, featureToFilterValue, filterDatasetCPU, - generateHashId, generatePolygonFilter, getDefaultFilter, getFilterIdInFeature, @@ -57,12 +56,12 @@ import { parseFieldValue, removeLayerFromSplitMaps, set, - toArray, mergeFilterDomainStep, updateFilterPlot, removeFilterPlot, isLayerAnimatable } from '@kepler.gl/utils'; +import {generateHashId, toArray} from '@kepler.gl/common-utils'; // Mergers import { diff --git a/src/schemas/package.json b/src/schemas/package.json index fa091f17da..832756a274 100644 --- a/src/schemas/package.json +++ b/src/schemas/package.json @@ -31,6 +31,7 @@ ], "dependencies": { "@kepler.gl/ai-assistant": "3.0.0", + "@kepler.gl/common-utils": "3.0.0", "@kepler.gl/constants": "3.0.0", "@kepler.gl/layers": "3.0.0", "@kepler.gl/table": "3.0.0", diff --git a/src/schemas/src/dataset-schema.ts b/src/schemas/src/dataset-schema.ts index b1725b5e82..ecd0446e60 100644 --- a/src/schemas/src/dataset-schema.ts +++ b/src/schemas/src/dataset-schema.ts @@ -8,7 +8,7 @@ import {ProtoDataset, RGBColor} from '@kepler.gl/types'; import {KeplerTable} from '@kepler.gl/table'; import {VERSIONS} from './versions'; import Schema from './schema'; -import {getFieldsFromData, getSampleForTypeAnalyze} from '@kepler.gl/utils'; +import {getFieldsFromData, getSampleForTypeAnalyze} from '@kepler.gl/common-utils'; export type SavedField = { name: string; diff --git a/src/schemas/src/vis-state-schema.ts b/src/schemas/src/vis-state-schema.ts index 302459a396..e2e36c4c08 100644 --- a/src/schemas/src/vis-state-schema.ts +++ b/src/schemas/src/vis-state-schema.ts @@ -4,7 +4,8 @@ import pick from 'lodash.pick'; import {VERSIONS} from './versions'; import {LAYER_VIS_CONFIGS, FILTER_VIEW_TYPES} from '@kepler.gl/constants'; -import {isFilterValidToSave, notNullorUndefined, findById} from '@kepler.gl/utils'; +import {isFilterValidToSave, findById} from '@kepler.gl/utils'; +import {notNullorUndefined} from '@kepler.gl/common-utils'; import Schema from './schema'; import cloneDeep from 'lodash.clonedeep'; import { diff --git a/src/table/package.json b/src/table/package.json index 2885c09c2f..960b4e7889 100644 --- a/src/table/package.json +++ b/src/table/package.json @@ -30,6 +30,7 @@ "umd" ], "dependencies": { + "@kepler.gl/common-utils": "3.0.0", "@kepler.gl/constants": "3.0.0", "@kepler.gl/layers": "3.0.0", "@kepler.gl/types": "3.0.0", diff --git a/src/table/src/gpu-filter-utils.ts b/src/table/src/gpu-filter-utils.ts index 8e4c0e2b0b..15d58bec55 100644 --- a/src/table/src/gpu-filter-utils.ts +++ b/src/table/src/gpu-filter-utils.ts @@ -4,8 +4,9 @@ import moment from 'moment'; import {MAX_GPU_FILTERS, FILTER_TYPES} from '@kepler.gl/constants'; import {Field, Filter} from '@kepler.gl/types'; +import {set, DataContainerInterface} from '@kepler.gl/utils'; +import {toArray, notNullorUndefined} from '@kepler.gl/common-utils'; -import {set, toArray, notNullorUndefined, DataContainerInterface} from '@kepler.gl/utils'; import {GpuFilter} from './kepler-table'; /** diff --git a/src/table/src/kepler-table.ts b/src/table/src/kepler-table.ts index 2cc19fea21..d479dcf308 100644 --- a/src/table/src/kepler-table.ts +++ b/src/table/src/kepler-table.ts @@ -30,7 +30,6 @@ import {getGpuFilterProps, getDatasetFieldIndexForFilter} from './gpu-filter-uti import {Layer} from '@kepler.gl/layers'; import { - generateHashId, getSortingFunction, timeToUnixMilli, createDataContainer, @@ -48,9 +47,9 @@ import { getOrdinalDomain, getQuantileDomain, DataContainerInterface, - notNullorUndefined, FilterChanged } from '@kepler.gl/utils'; +import {generateHashId, notNullorUndefined} from '@kepler.gl/common-utils'; export type GpuFilter = { filterRange: number[][]; diff --git a/src/utils/package.json b/src/utils/package.json index 50259d0462..79fb22cda3 100644 --- a/src/utils/package.json +++ b/src/utils/package.json @@ -30,6 +30,7 @@ "umd" ], "dependencies": { + "@kepler.gl/common-utils": "3.0.0", "@kepler.gl/constants": "3.0.0", "@kepler.gl/types": "3.0.0", "@luma.gl/constants": "^8.5.20", diff --git a/src/utils/src/data-scale-utils.ts b/src/utils/src/data-scale-utils.ts index eb4ef80ad7..78dfb0a668 100644 --- a/src/utils/src/data-scale-utils.ts +++ b/src/utils/src/data-scale-utils.ts @@ -1,6 +1,7 @@ // SPDX-License-Identifier: MIT // Copyright contributors to the kepler.gl project +import {notNullorUndefined} from '@kepler.gl/common-utils'; import {ALL_FIELD_TYPES, ColorMap, ColorRange, SCALE_FUNC, SCALE_TYPES} from '@kepler.gl/constants'; import {Layer, VisualChannel, VisualChannelDomain} from '@kepler.gl/layers'; import {HexColor, MapState} from '@kepler.gl/types'; @@ -8,7 +9,7 @@ import {bisectLeft, quantileSorted as d3Quantile, extent} from 'd3-array'; import moment from 'moment'; import {isRgbColor, rgbToHex} from './color-utils'; import {DataContainerInterface} from './data-container-interface'; -import {formatNumber, notNullorUndefined, reverseFormatNumber, unique} from './data-utils'; +import {formatNumber, reverseFormatNumber, unique} from './data-utils'; import {getTimeWidgetHintFormatter} from './filter-utils'; import {isPlainObject} from './utils'; diff --git a/src/utils/src/data-utils.ts b/src/utils/src/data-utils.ts index c5fb67e4f5..f34364233f 100644 --- a/src/utils/src/data-utils.ts +++ b/src/utils/src/data-utils.ts @@ -12,6 +12,7 @@ import { TOOLTIP_KEY, TooltipFormat } from '@kepler.gl/constants'; +import {notNullorUndefined} from '@kepler.gl/common-utils'; import {Field, Millisecond} from '@kepler.gl/types'; import {snapToMarks} from './plot'; @@ -86,13 +87,6 @@ export function timeToUnixMilli(value: string | number | Date, format: string): return null; } -/** - * whether null or undefined - */ -export function notNullorUndefined>(d: T | null | undefined): d is T { - return d !== undefined && d !== null; -} - /** * Whether d is a number, this filtered out NaN as well */ @@ -452,7 +446,3 @@ export function datetimeFormatter( : // return empty string instead of 'Invalid date' if ts is undefined/null format => ts => ts ? moment.utc(ts).format(format) : ''; } - -export function notNullOrUndefined(d: any): boolean { - return d !== undefined && d !== null; -} diff --git a/src/utils/src/dataset-utils.ts b/src/utils/src/dataset-utils.ts index 620e284548..5e56b412f2 100644 --- a/src/utils/src/dataset-utils.ts +++ b/src/utils/src/dataset-utils.ts @@ -1,20 +1,19 @@ // SPDX-License-Identifier: MIT // Copyright contributors to the kepler.gl project -import {console as globalConsole} from 'global/window'; import { ALL_FIELD_TYPES, FIELD_OPTS, TOOLTIP_FORMATS, TOOLTIP_FORMAT_TYPES } from '@kepler.gl/constants'; -import {Analyzer, DATA_TYPES as AnalyzerDATA_TYPES} from 'type-analyzer'; +import {getSampleForTypeAnalyze, getFieldsFromData} from '@kepler.gl/common-utils'; +import {Analyzer} from 'type-analyzer'; import assert from 'assert'; import { ProcessorResult, RGBColor, - RowData, Field, FieldPair, TimeLabelFormat, @@ -22,11 +21,11 @@ import { ProtoDataset } from '@kepler.gl/types'; import {TooltipFormat} from '@kepler.gl/constants'; +import {notNullorUndefined} from '@kepler.gl/common-utils'; import {isPlainObject} from './utils'; -import {notNullorUndefined, getFormatter} from './data-utils'; +import {getFormatter} from './data-utils'; import {getFormatValue} from './format'; -import {range} from 'd3-array'; import {hexToRgb} from './color-utils'; // apply a color for each dataset @@ -226,27 +225,6 @@ export function findDefaultColorField({ return null; } -export const ACCEPTED_ANALYZER_TYPES = [ - AnalyzerDATA_TYPES.DATE, - AnalyzerDATA_TYPES.TIME, - AnalyzerDATA_TYPES.DATETIME, - AnalyzerDATA_TYPES.NUMBER, - AnalyzerDATA_TYPES.INT, - AnalyzerDATA_TYPES.FLOAT, - AnalyzerDATA_TYPES.BOOLEAN, - AnalyzerDATA_TYPES.STRING, - AnalyzerDATA_TYPES.GEOMETRY, - AnalyzerDATA_TYPES.GEOMETRY_FROM_STRING, - AnalyzerDATA_TYPES.PAIR_GEOMETRY_FROM_STRING, - AnalyzerDATA_TYPES.ZIPCODE, - AnalyzerDATA_TYPES.ARRAY, - AnalyzerDATA_TYPES.OBJECT -]; - -const IGNORE_DATA_TYPES = Object.keys(AnalyzerDATA_TYPES).filter( - type => !ACCEPTED_ANALYZER_TYPES.includes(type) -); - /** * Validate input data, adding missing field types, rename duplicate columns */ @@ -330,246 +308,6 @@ function findNonEmptyRowsAtField(rows: unknown[][], fieldIdx: number, total: num } return sample; } -/** - * Getting sample data for analyzing field type. - */ -export function getSampleForTypeAnalyze({ - fields, - rows, - sampleCount = 50 -}: { - fields: string[]; - rows: unknown[][]; - sampleCount?: number; -}): RowData { - const total = Math.min(sampleCount, rows.length); - // const fieldOrder = fields.map(f => f.name); - const sample = range(0, total, 1).map(() => ({})); - - // collect sample data for each field - fields.forEach((field, fieldIdx) => { - // data counter - let i = 0; - // sample counter - let j = 0; - - while (j < total) { - if (i >= rows.length) { - // if depleted data pool - sample[j][field] = null; - j++; - } else if (notNullorUndefined(rows[i][fieldIdx])) { - const value = rows[i][fieldIdx]; - sample[j][field] = typeof value === 'string' ? value.trim() : value; - j++; - i++; - } else { - i++; - } - } - }); - - return sample; -} - -/** - * Check if string is a valid Well-known binary (WKB) in HEX format - * https://en.wikipedia.org/wiki/Well-known_text_representation_of_geometry - * - * @param str input string - * @returns true if string is a valid WKB in HEX format - */ -export function isHexWkb(str: string | null): boolean { - if (!str) return false; - // check if the length of the string is even and is at least 10 characters long - if (str.length < 10 || str.length % 2 !== 0) { - return false; - } - // check if first two characters are 00 or 01 - if (!str.startsWith('00') && !str.startsWith('01')) { - return false; - } - // check if the rest of the string is a valid hex - return /^[0-9a-fA-F]+$/.test(str.slice(2)); -} - -/** - * Analyze field types from data in `string` format, e.g. uploaded csv. - * Assign `type`, `fieldIdx` and `format` (timestamp only) to each field - * - * @param data array of row object - * @param fieldOrder array of field names as string - * @returns formatted fields - * @public - * @example - * - * import {getFieldsFromData} from 'kepler.gl/processors'; - * const data = [{ - * time: '2016-09-17 00:09:55', - * value: '4', - * surge: '1.2', - * isTrip: 'true', - * zeroOnes: '0' - * }, { - * time: '2016-09-17 00:30:08', - * value: '3', - * surge: null, - * isTrip: 'false', - * zeroOnes: '1' - * }, { - * time: null, - * value: '2', - * surge: '1.3', - * isTrip: null, - * zeroOnes: '1' - * }]; - * - * const fieldOrder = ['time', 'value', 'surge', 'isTrip', 'zeroOnes']; - * const fields = getFieldsFromData(data, fieldOrder); - * // fields = [ - * // {name: 'time', format: 'YYYY-M-D H:m:s', fieldIdx: 1, type: 'timestamp'}, - * // {name: 'value', format: '', fieldIdx: 4, type: 'integer'}, - * // {name: 'surge', format: '', fieldIdx: 5, type: 'real'}, - * // {name: 'isTrip', format: '', fieldIdx: 6, type: 'boolean'}, - * // {name: 'zeroOnes', format: '', fieldIdx: 7, type: 'integer'}]; - * - */ -export function getFieldsFromData(data: RowData, fieldOrder: string[]): Field[] { - // add a check for epoch timestamp - const metadata = Analyzer.computeColMeta( - data, - [ - {regex: /.*geojson|all_points/g, dataType: 'GEOMETRY'}, - {regex: /.*census/g, dataType: 'STRING'} - ], - {ignoredDataTypes: IGNORE_DATA_TYPES} - ); - - const {fieldByIndex} = renameDuplicateFields(fieldOrder); - - const result = fieldOrder.map((field, index) => { - const name = fieldByIndex[index]; - - const fieldMeta = metadata.find(m => m.key === field); - - // fieldMeta could be undefined if the field has no data and Analyzer.computeColMeta - // will ignore the field. In this case, we will simply assign the field type to STRING - // since dropping the column in the RowData could be expensive - let type = fieldMeta?.type || 'STRING'; - const format = fieldMeta?.format || ''; - - // check if string is hex wkb - if (type === AnalyzerDATA_TYPES.STRING) { - type = data.some(d => isHexWkb(d[name])) ? AnalyzerDATA_TYPES.GEOMETRY : type; - } - - return { - name, - id: name, - displayName: name, - format, - fieldIdx: index, - type: analyzerTypeToFieldType(type), - analyzerType: type, - valueAccessor: dc => d => { - return dc.valueAt(d.index, index); - } - }; - }); - - return result; -} - -/** - * pass in an array of field names, rename duplicated one - * and return a map from old field index to new name - * - * @param fieldOrder - * @returns new field name by index - */ -export function renameDuplicateFields(fieldOrder: string[]): { - allNames: string[]; - fieldByIndex: string[]; -} { - return fieldOrder.reduce<{allNames: string[]; fieldByIndex: string[]}>( - (accu, field, i) => { - const {allNames} = accu; - let fieldName = field; - - // add a counter to duplicated names - if (allNames.includes(field)) { - let counter = 0; - while (allNames.includes(`${field}-${counter}`)) { - counter++; - } - fieldName = `${field}-${counter}`; - } - - accu.fieldByIndex[i] = fieldName; - accu.allNames.push(fieldName); - - return accu; - }, - {allNames: [], fieldByIndex: []} - ); -} - -/** - * Convert type-analyzer output to kepler.gl field types - * - * @param aType - * @returns corresponding type in `ALL_FIELD_TYPES` - */ -/* eslint-disable complexity */ -export function analyzerTypeToFieldType(aType: string): string { - const { - DATE, - TIME, - DATETIME, - NUMBER, - INT, - FLOAT, - BOOLEAN, - STRING, - GEOMETRY, - GEOMETRY_FROM_STRING, - PAIR_GEOMETRY_FROM_STRING, - ZIPCODE, - ARRAY, - OBJECT - } = AnalyzerDATA_TYPES; - - // TODO: un recognized types - // CURRENCY PERCENT NONE - switch (aType) { - case DATE: - return ALL_FIELD_TYPES.date; - case TIME: - case DATETIME: - return ALL_FIELD_TYPES.timestamp; - case FLOAT: - return ALL_FIELD_TYPES.real; - case INT: - return ALL_FIELD_TYPES.integer; - case BOOLEAN: - return ALL_FIELD_TYPES.boolean; - case GEOMETRY: - case GEOMETRY_FROM_STRING: - case PAIR_GEOMETRY_FROM_STRING: - return ALL_FIELD_TYPES.geojson; - case ARRAY: - return ALL_FIELD_TYPES.array; - case OBJECT: - return ALL_FIELD_TYPES.object; - case NUMBER: - case STRING: - case ZIPCODE: - return ALL_FIELD_TYPES.string; - default: - globalConsole.warn(`Unsupported analyzer type: ${aType}`); - return ALL_FIELD_TYPES.string; - } -} const TIME_DISPLAY = '2020-05-11 14:00'; diff --git a/src/utils/src/export-utils.ts b/src/utils/src/export-utils.ts index cc0acd86ce..453c5cd114 100644 --- a/src/utils/src/export-utils.ts +++ b/src/utils/src/export-utils.ts @@ -13,8 +13,9 @@ import { OneXResolutionOption, ExportImage } from '@kepler.gl/constants'; +import {generateHashId} from '@kepler.gl/common-utils'; import domtoimage from './dom-to-image'; -import {generateHashId, set} from './utils'; +import {set} from './utils'; import {exportMapToHTML} from './export-map-html'; import {getApplicationConfig} from './application-config'; diff --git a/src/utils/src/filter-utils.ts b/src/utils/src/filter-utils.ts index 6690bb8b36..d33a648b95 100644 --- a/src/utils/src/filter-utils.ts +++ b/src/utils/src/filter-utils.ts @@ -41,9 +41,10 @@ import { AnimationConfig } from '@kepler.gl/types'; +import {generateHashId, toArray, notNullorUndefined} from '@kepler.gl/common-utils'; import {DataContainerInterface} from './data-container-interface'; -import {generateHashId, set, toArray} from './utils'; -import {notNullorUndefined, timeToUnixMilli, unique} from './data-utils'; +import {set} from './utils'; +import {timeToUnixMilli, unique} from './data-utils'; import {getCentroid} from './h3-utils'; import {updateTimeFilterPlotType, updateRangeFilterPlotType} from './plot'; import {KeplerTableModel} from './types'; diff --git a/src/utils/src/h3-utils.ts b/src/utils/src/h3-utils.ts index 64f00647a2..7346f365dd 100644 --- a/src/utils/src/h3-utils.ts +++ b/src/utils/src/h3-utils.ts @@ -3,7 +3,7 @@ import {h3GetResolution, H3Index, h3IsValid, h3ToGeo, h3ToGeoBoundary} from 'h3-js'; import {ALL_FIELD_TYPES} from '@kepler.gl/constants'; -import {notNullorUndefined} from './data-utils'; +import {notNullorUndefined} from '@kepler.gl/common-utils'; export {h3GetResolution, h3IsValid}; diff --git a/src/utils/src/index.ts b/src/utils/src/index.ts index d01fef6507..83a5afccf4 100644 --- a/src/utils/src/index.ts +++ b/src/utils/src/index.ts @@ -50,15 +50,10 @@ export { } from './time'; export { - ACCEPTED_ANALYZER_TYPES, - analyzerTypeToFieldType, datasetColorMaker, findDefaultColorField, getFieldFormatLabels, - getFieldsFromData, getFormatLabels, - getSampleForTypeAnalyze, - renameDuplicateFields, validateInputData } from './dataset-utils'; export {exportMapToHTML} from './export-map-html'; diff --git a/src/utils/src/notifications-utils.ts b/src/utils/src/notifications-utils.ts index 3d0343eb28..319d232238 100644 --- a/src/utils/src/notifications-utils.ts +++ b/src/utils/src/notifications-utils.ts @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT // Copyright contributors to the kepler.gl project -import {generateHashId} from './utils'; +import {generateHashId} from '@kepler.gl/common-utils'; import { DEFAULT_NOTIFICATION_MESSAGE, diff --git a/src/utils/src/plot.ts b/src/utils/src/plot.ts index d60b2618db..c962335a55 100644 --- a/src/utils/src/plot.ts +++ b/src/utils/src/plot.ts @@ -17,6 +17,7 @@ import { ValueOf, LineDatum } from '@kepler.gl/types'; +import {notNullorUndefined} from '@kepler.gl/common-utils'; import { ANIMATION_WINDOW, BINS, @@ -28,7 +29,7 @@ import { } from '@kepler.gl/constants'; import {VisState} from '@kepler.gl/schemas'; -import {notNullOrUndefined, roundValToStep} from './data-utils'; +import {roundValToStep} from './data-utils'; import {aggregate, AGGREGATION_NAME} from './aggregation'; import {capitalizeFirstLetter} from './strings'; import {getDefaultTimeFormat} from './format'; @@ -413,11 +414,11 @@ export function splitSeries(series) { let temp: any[] = []; for (let i = 0; i < series.length; i++) { const d = series[i]; - if (!notNullOrUndefined(d.y) && temp.length) { + if (!notNullorUndefined(d.y) && temp.length) { // ends temp lines.push(temp); temp = []; - } else if (notNullOrUndefined(d.y)) { + } else if (notNullorUndefined(d.y)) { temp.push(d); } @@ -426,7 +427,7 @@ export function splitSeries(series) { } } - const markers = lines.length > 1 ? series.filter(d => notNullOrUndefined(d.y)) : []; + const markers = lines.length > 1 ? series.filter(d => notNullorUndefined(d.y)) : []; return {lines, markers}; } diff --git a/src/utils/src/time.ts b/src/utils/src/time.ts index 4bbbde87be..5543861212 100644 --- a/src/utils/src/time.ts +++ b/src/utils/src/time.ts @@ -13,9 +13,9 @@ import { INTERVAL, TickInterval } from '@kepler.gl/constants'; +import {toArray} from '@kepler.gl/common-utils'; import {AnimationConfig, Timeline, TimeRangeFilter} from '@kepler.gl/types'; -import {toArray} from './utils'; import {getFrequency} from './aggregation'; export const TileTimeInterval = { diff --git a/src/utils/src/utils.ts b/src/utils/src/utils.ts index fdc1d90bb1..174ce34b0e 100644 --- a/src/utils/src/utils.ts +++ b/src/utils/src/utils.ts @@ -4,15 +4,6 @@ import window from 'global/window'; import {capitalizeFirstLetter} from './strings'; -/** - * Generate a hash string based on number of character - * @param {number} count - * @returns {string} hash string - */ -export function generateHashId(count = 6): string { - return Math.random().toString(36).substr(count); -} - /** * Generate a hash string based on string * @param str @@ -68,26 +59,6 @@ export const camelize = (str: string): string => { }); }; -/** - * Converts non-arrays to arrays. Leaves arrays alone. Converts - * undefined values to empty arrays ([] instead of [undefined]). - * Otherwise, just returns [item] for non-array items. - * - * @param {*} item - * @returns {array} boom! much array. very indexed. so useful. - */ -export function toArray(item: T | T[]): T[] { - if (Array.isArray(item)) { - return item; - } - - if (typeof item === 'undefined' || item === null) { - return []; - } - - return [item]; -} - /** * immutably insert value to an Array or Object * @param {Array|Object} obj diff --git a/test/helpers/comparison-utils.js b/test/helpers/comparison-utils.js index c66d8b0969..8ab7e18c54 100644 --- a/test/helpers/comparison-utils.js +++ b/test/helpers/comparison-utils.js @@ -2,7 +2,7 @@ // Copyright contributors to the kepler.gl project import {FILTER_TYPES} from '@kepler.gl/constants'; -import {toArray} from '@kepler.gl/utils'; +import {toArray} from '@kepler.gl/common-utils'; import {KeplerTable} from '@kepler.gl/table'; export function cmpObjectKeys(t, expectedObj, actualObj, name) { diff --git a/test/node/utils/data-processor-test.js b/test/node/utils/data-processor-test.js index e59cb368be..2715851e89 100644 --- a/test/node/utils/data-processor-test.js +++ b/test/node/utils/data-processor-test.js @@ -32,14 +32,14 @@ import { processRowObject } from '@kepler.gl/processors'; +import {validateInputData, createDataContainer} from '@kepler.gl/utils'; + import { ACCEPTED_ANALYZER_TYPES, analyzerTypeToFieldType, - getSampleForTypeAnalyze, - validateInputData, getFieldsFromData, - createDataContainer -} from '@kepler.gl/utils'; + getSampleForTypeAnalyze +} from '@kepler.gl/common-utils'; import {formatCsv} from '@kepler.gl/reducers'; diff --git a/test/node/utils/util-test.js b/test/node/utils/util-test.js index a90bb00af8..0bc7d450f8 100644 --- a/test/node/utils/util-test.js +++ b/test/node/utils/util-test.js @@ -8,9 +8,9 @@ import { camelize, capitalizeFirstLetter, getError, - set, - toArray + set } from '@kepler.gl/utils'; +import {toArray} from '@kepler.gl/common-utils'; import test from 'tape'; test('Utils -> set', t => { diff --git a/yarn.lock b/yarn.lock index 7940c7ba16..93309124bf 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3036,6 +3036,18 @@ __metadata: languageName: unknown linkType: soft +"@kepler.gl/common-utils@npm:3.0.0, @kepler.gl/common-utils@workspace:src/common-utils": + version: 0.0.0-use.local + resolution: "@kepler.gl/common-utils@workspace:src/common-utils" + dependencies: + "@kepler.gl/constants": "npm:3.0.0" + "@kepler.gl/types": "npm:3.0.0" + d3-array: "npm:^2.8.0" + global: "npm:^4.3.0" + type-analyzer: "npm:0.4.0" + languageName: unknown + linkType: soft + "@kepler.gl/components@npm:3.0.0, @kepler.gl/components@workspace:src/components": version: 0.0.0-use.local resolution: "@kepler.gl/components@workspace:src/components" @@ -3049,6 +3061,7 @@ __metadata: "@floating-ui/react": "npm:0.25.1" "@kepler.gl/actions": "npm:3.0.0" "@kepler.gl/cloud-providers": "npm:3.0.0" + "@kepler.gl/common-utils": "npm:3.0.0" "@kepler.gl/constants": "npm:3.0.0" "@kepler.gl/effects": "npm:3.0.0" "@kepler.gl/layers": "npm:3.0.0" @@ -3222,6 +3235,7 @@ __metadata: "@deck.gl/geo-layers": "npm:^8.9.27" "@deck.gl/layers": "npm:^8.9.27" "@deck.gl/mesh-layers": "npm:^8.9.27" + "@kepler.gl/common-utils": "npm:3.0.0" "@kepler.gl/constants": "npm:3.0.0" "@kepler.gl/deckgl-arrow-layers": "npm:3.0.0" "@kepler.gl/deckgl-layers": "npm:3.0.0" @@ -3280,6 +3294,7 @@ __metadata: resolution: "@kepler.gl/processors@workspace:src/processors" dependencies: "@danmarshall/deckgl-typings": "npm:4.9.22" + "@kepler.gl/common-utils": "npm:3.0.0" "@kepler.gl/constants": "npm:3.0.0" "@kepler.gl/schemas": "npm:3.0.0" "@kepler.gl/types": "npm:3.0.0" @@ -3304,6 +3319,7 @@ __metadata: dependencies: "@kepler.gl/actions": "npm:3.0.0" "@kepler.gl/cloud-providers": "npm:3.0.0" + "@kepler.gl/common-utils": "npm:3.0.0" "@kepler.gl/constants": "npm:3.0.0" "@kepler.gl/deckgl-arrow-layers": "npm:3.0.0" "@kepler.gl/deckgl-layers": "npm:3.0.0" @@ -3348,6 +3364,7 @@ __metadata: resolution: "@kepler.gl/schemas@workspace:src/schemas" dependencies: "@kepler.gl/ai-assistant": "npm:3.0.0" + "@kepler.gl/common-utils": "npm:3.0.0" "@kepler.gl/constants": "npm:3.0.0" "@kepler.gl/layers": "npm:3.0.0" "@kepler.gl/table": "npm:3.0.0" @@ -3378,6 +3395,7 @@ __metadata: version: 0.0.0-use.local resolution: "@kepler.gl/table@workspace:src/table" dependencies: + "@kepler.gl/common-utils": "npm:3.0.0" "@kepler.gl/constants": "npm:3.0.0" "@kepler.gl/layers": "npm:3.0.0" "@kepler.gl/types": "npm:3.0.0" @@ -3410,6 +3428,7 @@ __metadata: version: 0.0.0-use.local resolution: "@kepler.gl/utils@workspace:src/utils" dependencies: + "@kepler.gl/common-utils": "npm:3.0.0" "@kepler.gl/constants": "npm:3.0.0" "@kepler.gl/types": "npm:3.0.0" "@luma.gl/constants": "npm:^8.5.20" From ac469c13d95c6f36e7785d2adc32050c55021787 Mon Sep 17 00:00:00 2001 From: Indranil Halder <73965619+indranildeveloper@users.noreply.github.com> Date: Wed, 20 Nov 2024 23:36:33 +0530 Subject: [PATCH 2/9] [chore] Updated imports for Kepler GL Reducers in docs (#2774) Signed-off-by: Indranil Halder --- .../advanced-usages/reducer-plugin.md | 2 +- .../advanced-usages/replace-ui-component.md | 6 +- .../advanced-usages/using-updaters.md | 2 +- docs/api-reference/localization/README.md | 12 +- docs/api-reference/reducers/README.md | 8 +- docs/api-reference/reducers/combine.md | 8 +- docs/api-reference/reducers/map-state.md | 35 +++--- docs/api-reference/reducers/map-style.md | 61 +++++----- docs/api-reference/reducers/reducers.md | 28 ++--- docs/api-reference/reducers/ui-state.md | 101 ++++++++-------- docs/api-reference/reducers/vis-state.md | 113 +++++++++--------- 11 files changed, 192 insertions(+), 184 deletions(-) diff --git a/docs/api-reference/advanced-usages/reducer-plugin.md b/docs/api-reference/advanced-usages/reducer-plugin.md index 12c3b0ae69..4c15abb40e 100644 --- a/docs/api-reference/advanced-usages/reducer-plugin.md +++ b/docs/api-reference/advanced-usages/reducer-plugin.md @@ -6,7 +6,7 @@ For advanced users, who want to add additional action handler to kepler.gl reduc ```js import {combineReducers} from 'redux'; -import keplerGlReducer from 'kepler.gl/reducers'; +import keplerGlReducer from '@kepler.gl/reducers'; const customizedKeplerGlReducer = keplerGlReducer .plugin({ diff --git a/docs/api-reference/advanced-usages/replace-ui-component.md b/docs/api-reference/advanced-usages/replace-ui-component.md index 9f67f12ca3..ed7084244d 100644 --- a/docs/api-reference/advanced-usages/replace-ui-component.md +++ b/docs/api-reference/advanced-usages/replace-ui-component.md @@ -39,7 +39,7 @@ In kepler.gl, we create the app injector by calling provide with an array of def Here is an example of how to use `injectComponents` to replace default `PanelHeader`. ```js -import {injectComponents, PanelHeaderFactory} from 'kepler.gl/components'; +import {injectComponents, PanelHeaderFactory} from '@kepler.gl/components'; // define custom header const CustomHeader = () => (
My kepler.gl app
); @@ -68,8 +68,8 @@ const MapContainer = () => ; Here is an example of using `withState` helper to add reducer state and actions to customized component as additional props. ```js -import {withState, injectComponents, PanelHeaderFactory} from 'kepler.gl/components'; -import {visStateLens} from 'kepler.gl/reducers'; +import {withState, injectComponents, PanelHeaderFactory} from '@kepler.gl/components'; +import {visStateLens} from '@kepler.gl/reducers'; // custom action wrap to mounted instance const addTodo = (text) => ({ diff --git a/docs/api-reference/advanced-usages/using-updaters.md b/docs/api-reference/advanced-usages/using-updaters.md index 649d49787b..4cc5b6309c 100644 --- a/docs/api-reference/advanced-usages/using-updaters.md +++ b/docs/api-reference/advanced-usages/using-updaters.md @@ -21,7 +21,7 @@ const MapContainer = ({dispatch}) => ( or import the corresponding updater `mapStateUpdaters.togglePerspectiveUpdater` and call it inside the root reducer. The example below demos how to add a button outside kepler.gl component, and update the map perspective when click it. ```js -import keplerGlReducer, {mapStateUpdaters} from 'kepler.gl/reducers'; +import keplerGlReducer, {mapStateUpdaters} from '@kepler.gl/reducers'; // Root Reducer const reducers = combineReducers({ diff --git a/docs/api-reference/localization/README.md b/docs/api-reference/localization/README.md index 217381eae4..c6cce02547 100644 --- a/docs/api-reference/localization/README.md +++ b/docs/api-reference/localization/README.md @@ -1,7 +1,7 @@ # Localization Kepler.gl supports localization through [react-intl]. Locale is determined by `uiState.locale` value. -Current supported languages are: +Current supported languages are: | locale code | Language | Default? | |-------------|------------|----------| @@ -20,8 +20,8 @@ By default the first language is English `en`. The default language can be chang ```js import {combineReducers} from 'redux'; -import keplerGlReducer from 'kepler.gl/reducers'; -import {LOCALE_CODES} from 'kepler.gl/localization'; +import keplerGlReducer from '@kepler.gl/reducers'; +import {LOCALE_CODES} from '@kepler.gl/localization'; const customizedKeplerGlReducer = keplerGlReducer.initialState({ uiState: { @@ -55,7 +55,7 @@ Let's say we want to add the Swedish language to kepler.gl. Easiest way to add t ``` ## Modify default translation or add new translation -the `localeMessages` prop of `KeplerGl` takes additional translations and merge with default translation. +the `localeMessages` prop of `KeplerGl` takes additional translations and merge with default translation. #### Example 1. Update default translation To update the english translation of `layerManager.addData`, pass `localeMessages` like this. @@ -68,7 +68,7 @@ const localeMessages = { }; const App = () => ( - ( - (
@@ -73,7 +73,7 @@ User can import a specific action handler in their root reducer and use it to di Here is an example how you can listen to an app action `QUERY_SUCCESS` and call `updateVisDataUpdater` to load data into kepler.gl. ```js -import keplerGlReducer, {visStateUpdaters} from 'kepler.gl/reducers'; +import keplerGlReducer, {visStateUpdaters} from '@kepler.gl/reducers'; // Root Reducer const reducers = combineReducers({ diff --git a/docs/api-reference/reducers/combine.md b/docs/api-reference/reducers/combine.md index 48dd1889d7..46c8537f4f 100644 --- a/docs/api-reference/reducers/combine.md +++ b/docs/api-reference/reducers/combine.md @@ -2,8 +2,8 @@ ### Table of Contents -- [combinedUpdaters][1] - - [addDataToMapUpdater][3] +- [combinedUpdaters](#combinedupdaters) + - [addDataToMapUpdater](#adddatatomapupdater) ## combinedUpdaters @@ -14,7 +14,7 @@ as the first argument. Read more about [Using updaters][5] **Examples** ```javascript -import keplerGlReducer, {combinedUpdaters} from 'kepler.gl/reducers'; +import keplerGlReducer, {combinedUpdaters} from '@kepler.gl/reducers'; // Root Reducer const reducers = combineReducers({ keplerGl: keplerGlReducer, @@ -58,7 +58,7 @@ Combine data and full configuration update in a single action **Parameters** - `state` **[Object][7]** kepler.gl instance state, containing all subreducer state -- `action` **[Object][7]** +- `action` **[Object][7]** - `action.payload` **[Object][7]** `{datasets, options, config}` - `action.payload.datasets` **([Array][8]<[Object][7]> | [Object][7])** **\*required** datasets can be a dataset or an array of datasets Each dataset object needs to have `info` and `data` property. diff --git a/docs/api-reference/reducers/map-state.md b/docs/api-reference/reducers/map-state.md index 2ce9ccf1c0..53b601ce8f 100644 --- a/docs/api-reference/reducers/map-state.md +++ b/docs/api-reference/reducers/map-state.md @@ -2,14 +2,15 @@ ### Table of Contents -- [mapStateUpdaters][1] - - [fitBoundsUpdater][3] - - [INITIAL_MAP_STATE][5] - - [receiveMapConfigUpdater][7] - - [resetMapConfigUpdater][9] - - [togglePerspectiveUpdater][11] - - [toggleSplitMapUpdater][13] - - [updateMapUpdater][15] +- [mapStateUpdaters](#mapstateupdaters) + - [fitBoundsUpdater](#fitboundsupdater) + - [INITIAL\_MAP\_STATE](#initial_map_state) + - [Properties](#properties) + - [receiveMapConfigUpdater](#receivemapconfigupdater) + - [resetMapConfigUpdater](#resetmapconfigupdater) + - [togglePerspectiveUpdater](#toggleperspectiveupdater) + - [toggleSplitMapUpdater](#togglesplitmapupdater) + - [updateMapUpdater](#updatemapupdater) ## mapStateUpdaters @@ -19,7 +20,7 @@ Read more about [Using updaters][17] **Examples** ```javascript -import keplerGlReducer, {mapStateUpdaters} from 'kepler.gl/reducers'; +import keplerGlReducer, {mapStateUpdaters} from '@kepler.gl/reducers'; // Root Reducer const reducers = combineReducers({ keplerGl: keplerGlReducer, @@ -57,8 +58,8 @@ Fit map viewport to bounds **Parameters** -- `state` **[Object][19]** -- `action` **[Object][19]** +- `state` **[Object][19]** +- `action` **[Object][19]** - `action.payload` **[Array][20]<[number][21]>** bounds as `[lngMin, latMin, lngMax, latMax]` Returns **[Object][19]** nextState @@ -87,8 +88,8 @@ Update `mapState` to propagate a new config **Parameters** -- `state` **[Object][19]** -- `action` **[Object][19]** +- `state` **[Object][19]** +- `action` **[Object][19]** - `action.payload` **[Object][19]** saved map config - `action.payload.config` (optional, default `{}`) - `action.payload.options` (optional, default `{}`) @@ -116,7 +117,7 @@ Toggle between 3d and 2d map. **Parameters** -- `state` **[Object][19]** +- `state` **[Object][19]** Returns **[Object][19]** nextState @@ -128,7 +129,7 @@ Toggle between one or split maps **Parameters** -- `state` **[Object][19]** +- `state` **[Object][19]** Returns **[Object][19]** nextState @@ -140,8 +141,8 @@ Update map viewport **Parameters** -- `state` **[Object][19]** -- `action` **[Object][19]** +- `state` **[Object][19]** +- `action` **[Object][19]** - `action.payload` **[Object][19]** viewport Returns **[Object][19]** nextState diff --git a/docs/api-reference/reducers/map-style.md b/docs/api-reference/reducers/map-style.md index 1c5db37494..5e71853898 100644 --- a/docs/api-reference/reducers/map-style.md +++ b/docs/api-reference/reducers/map-style.md @@ -2,16 +2,17 @@ ### Table of Contents -- [mapStyleUpdaters][1] - - [INITIAL_MAP_STYLE][3] - - [initMapStyleUpdater][5] - - [inputMapStyleUpdater][7] - - [loadCustomMapStyleUpdater][9] - - [loadMapStyleErrUpdater][11] - - [loadMapStylesUpdater][13] - - [mapConfigChangeUpdater][15] - - [mapStyleChangeUpdater][17] - - [resetMapConfigMapStyleUpdater][19] +- [mapStyleUpdaters](#mapstyleupdaters) + - [INITIAL\_MAP\_STYLE](#initial_map_style) + - [Properties](#properties) + - [initMapStyleUpdater](#initmapstyleupdater) + - [inputMapStyleUpdater](#inputmapstyleupdater) + - [loadCustomMapStyleUpdater](#loadcustommapstyleupdater) + - [loadMapStyleErrUpdater](#loadmapstyleerrupdater) + - [loadMapStylesUpdater](#loadmapstylesupdater) + - [mapConfigChangeUpdater](#mapconfigchangeupdater) + - [mapStyleChangeUpdater](#mapstylechangeupdater) + - [resetMapConfigMapStyleUpdater](#resetmapconfigmapstyleupdater) ## mapStyleUpdaters @@ -21,7 +22,7 @@ Read more about [Using updaters][21] **Examples** ```javascript -import keplerGlReducer, {mapStyleUpdaters} from 'kepler.gl/reducers'; +import keplerGlReducer, {mapStyleUpdaters} from '@kepler.gl/reducers'; // Root Reducer const reducers = combineReducers({ keplerGl: keplerGlReducer, @@ -76,10 +77,10 @@ populate mapStyles. **Parameters** -- `state` **[Object][23]** -- `action` **[Object][23]** - - `action.payload` **[Object][23]** - - `action.payload.mapboxApiAccessToken` **[string][22]** +- `state` **[Object][23]** +- `action` **[Object][23]** + - `action.payload` **[Object][23]** + - `action.payload.mapboxApiAccessToken` **[string][22]** Returns **[Object][23]** nextState @@ -100,8 +101,8 @@ Input a custom map style object - `action.payload.name` **[string][22]** style name - `action.payload.layerGroups` **[Object][23]** layer groups that can be used to set map layer visibility - `action.payload.icon` **[Object][23]** icon image data url - - `action.payload.inputStyle` - - `action.payload.mapState` + - `action.payload.inputStyle` + - `action.payload.mapState` Returns **[Object][23]** nextState @@ -114,14 +115,14 @@ Callback when a custom map style object is received **Parameters** - `state` **[Object][23]** `mapStyle` -- `action` **[Object][23]** - - `action.payload` **[Object][23]** - - `action.payload.icon` **[string][22]** - - `action.payload.style` **[Object][23]** - - `action.payload.error` **any** - - `action.payload.icon` - - `action.payload.style` - - `action.payload.error` +- `action` **[Object][23]** + - `action.payload` **[Object][23]** + - `action.payload.icon` **[string][22]** + - `action.payload.style` **[Object][23]** + - `action.payload.error` **any** + - `action.payload.icon` + - `action.payload.style` + - `action.payload.error` Returns **[Object][23]** nextState @@ -134,7 +135,7 @@ Callback when load map style error **Parameters** - `state` **[Object][23]** `mapStyle` -- `action` **[Object][23]** +- `action` **[Object][23]** - `action.payload` **any** error Returns **[Object][23]** nextState @@ -148,7 +149,7 @@ Callback when load map style success **Parameters** - `state` **[Object][23]** `mapStyle` -- `action` **[Object][23]** +- `action` **[Object][23]** - `action.payload` **[Object][23]** a `{[id]: style}` mapping Returns **[Object][23]** nextState @@ -162,7 +163,7 @@ Update `visibleLayerGroups`to change layer group visibility **Parameters** - `state` **[Object][23]** `mapStyle` -- `action` **[Object][23]** +- `action` **[Object][23]** - `action.payload` **[Object][23]** new config `{visibleLayerGroups: {label: false, road: true, background: true}}` Returns **[Object][23]** nextState @@ -176,8 +177,8 @@ Change to another map style. The selected style should already been loaded into **Parameters** - `state` **[Object][23]** `mapStyle` -- `action` **[Object][23]** - - `action.payload` **[string][22]** +- `action` **[Object][23]** + - `action.payload` **[string][22]** Returns **[Object][23]** nextState diff --git a/docs/api-reference/reducers/reducers.md b/docs/api-reference/reducers/reducers.md index 54055fdcce..46eb2d2d36 100644 --- a/docs/api-reference/reducers/reducers.md +++ b/docs/api-reference/reducers/reducers.md @@ -2,14 +2,14 @@ ### Table of Contents -- [keplerGlReducer][1] - - [keplerGlReducer.initialState][3] - - [keplerGlReducer.plugin][6] -- [mapStateLens][9] -- [mapStyleLens][11] -- [providerStateLens][13] -- [uiStateLens][15] -- [visStateLens][17] +- [keplerGlReducer](#keplerglreducer) + - [keplerGlReducer.initialState](#keplerglreducerinitialstate) + - [keplerGlReducer.plugin](#keplerglreducerplugin) +- [mapStateLens](#mapstatelens) +- [mapStyleLens](#mapstylelens) +- [providerStateLens](#providerstatelens) +- [uiStateLens](#uistatelens) +- [visStateLens](#visstatelens) ## keplerGlReducer @@ -19,7 +19,7 @@ to mount it at another address e.g. `foo` you will need to specify it when you m **Examples** ```javascript -import keplerGlReducer from 'kepler.gl/reducers'; +import keplerGlReducer from '@kepler.gl/reducers'; import {createStore, combineReducers, applyMiddleware, compose} from 'redux'; import {taskMiddleware} from 'react-palm/tasks'; @@ -109,7 +109,7 @@ Connect subreducer `mapState`, used with `injectComponents`. Learn more at **Parameters** -- `reduxState` **any** +- `reduxState` **any** ## mapStyleLens @@ -118,7 +118,7 @@ Connect subreducer `mapStyle`, used with `injectComponents`. Learn more at **Parameters** -- `reduxState` **any** +- `reduxState` **any** ## providerStateLens @@ -127,7 +127,7 @@ Connect subreducer `providerState`, used with `injectComponents`. Learn more at **Parameters** -- `reduxState` **any** +- `reduxState` **any** ## uiStateLens @@ -136,7 +136,7 @@ Connect subreducer `uiState`, used with `injectComponents`. Learn more at **Parameters** -- `reduxState` **any** +- `reduxState` **any** ## visStateLens @@ -145,7 +145,7 @@ Connect subreducer `visState`, used with `injectComponents`. Learn more at **Parameters** -- `reduxState` **any** +- `reduxState` **any** [1]: #keplerglreducer diff --git a/docs/api-reference/reducers/ui-state.md b/docs/api-reference/reducers/ui-state.md index adb525131e..ba90d510aa 100644 --- a/docs/api-reference/reducers/ui-state.md +++ b/docs/api-reference/reducers/ui-state.md @@ -2,32 +2,37 @@ ### Table of Contents -- [uiStateUpdaters][1] - - [addNotificationUpdater][3] - - [cleanupExportImage][5] - - [DEFAULT_EXPORT_DATA][7] - - [DEFAULT_EXPORT_IMAGE][9] - - [DEFAULT_MAP_CONTROLS_FEATURES][11] - - [hideExportDropdownUpdater][13] - - [INITIAL_UI_STATE][15] - - [loadFilesErrUpdater][17] - - [loadFilesUpdater][19] - - [openDeleteModalUpdater][21] - - [removeNotificationUpdater][23] - - [setExportDataTypeUpdater][25] - - [setExportDataUpdater][27] - - [setExportFilteredUpdater][29] - - [setExportImageDataUri][31] - - [setExportImageSetting][33] - - [setExportSelectedDatasetUpdater][35] - - [showExportDropdownUpdater][37] - - [startExportingImage][39] - - [toggleMapControlUpdater][41] - - [toggleModalUpdater][43] - - [toggleSidePanelUpdater][45] - - [toggleSplitMapUpdater][47] -- [DEFAULT_EXPORT_HTML][49] -- [setUserMapboxAccessTokenUpdater][51] +- [uiStateUpdaters](#uistateupdaters) + - [addNotificationUpdater](#addnotificationupdater) + - [cleanupExportImage](#cleanupexportimage) + - [DEFAULT\_EXPORT\_DATA](#default_export_data) + - [Properties](#properties) + - [DEFAULT\_EXPORT\_IMAGE](#default_export_image) + - [Properties](#properties-1) + - [DEFAULT\_MAP\_CONTROLS\_FEATURES](#default_map_controls_features) + - [Properties](#properties-2) + - [hideExportDropdownUpdater](#hideexportdropdownupdater) + - [INITIAL\_UI\_STATE](#initial_ui_state) + - [Properties](#properties-3) + - [loadFilesErrUpdater](#loadfileserrupdater) + - [loadFilesUpdater](#loadfilesupdater) + - [openDeleteModalUpdater](#opendeletemodalupdater) + - [removeNotificationUpdater](#removenotificationupdater) + - [setExportDataTypeUpdater](#setexportdatatypeupdater) + - [setExportDataUpdater](#setexportdataupdater) + - [setExportFilteredUpdater](#setexportfilteredupdater) + - [setExportImageDataUri](#setexportimagedatauri) + - [setExportImageSetting](#setexportimagesetting) + - [setExportSelectedDatasetUpdater](#setexportselecteddatasetupdater) + - [showExportDropdownUpdater](#showexportdropdownupdater) + - [startExportingImage](#startexportingimage) + - [toggleMapControlUpdater](#togglemapcontrolupdater) + - [toggleModalUpdater](#togglemodalupdater) + - [toggleSidePanelUpdater](#togglesidepanelupdater) + - [toggleSplitMapUpdater](#togglesplitmapupdater) +- [DEFAULT\_EXPORT\_HTML](#default_export_html) + - [Properties](#properties-4) +- [setUserMapboxAccessTokenUpdater](#setusermapboxaccesstokenupdater) ## uiStateUpdaters @@ -37,7 +42,7 @@ Read more about [Using updaters][53] **Examples** ```javascript -import keplerGlReducer, {uiStateUpdaters} from 'kepler.gl/reducers'; +import keplerGlReducer, {uiStateUpdaters} from '@kepler.gl/reducers'; // Root Reducer const reducers = combineReducers({ keplerGl: keplerGlReducer, @@ -77,8 +82,8 @@ Existing notification is going to be updated in case of matching ids. **Parameters** - `state` **[Object][55]** `uiState` -- `action` **[Object][55]** - - `action.payload` **[Object][55]** +- `action` **[Object][55]** + - `action.payload` **[Object][55]** Returns **[Object][55]** nextState @@ -174,9 +179,9 @@ Handles load file error and set fileLoading property to false **Parameters** -- `state` -- `error` **[Object][55]** - - `error.error` +- `state` +- `error` **[Object][55]** + - `error.error` Returns **[Object][55]** nextState @@ -201,7 +206,7 @@ Toggle active map control panel **Parameters** - `state` **[Object][55]** `uiState` -- `action` **[Object][55]** +- `action` **[Object][55]** - `action.payload` **[string][57]** dataset id Returns **[Object][55]** nextState @@ -215,7 +220,7 @@ Remove a notification **Parameters** - `state` **[Object][55]** `uiState` -- `action` **[Object][55]** +- `action` **[Object][55]** - `action.payload` **[String][57]** id of the notification to be removed Returns **[Object][55]** nextState @@ -229,7 +234,7 @@ Set data format for exporting data **Parameters** - `state` **[Object][55]** `uiState` -- `action` **[Object][55]** +- `action` **[Object][55]** - `action.payload` **[string][57]** one of `'text/csv'` Returns **[Object][55]** nextState @@ -255,8 +260,8 @@ Whether to export filtered data, `true` or `false` **Parameters** - `state` **[Object][55]** `uiState` -- `action` **[Object][55]** - - `action.payload` **[boolean][58]** +- `action` **[Object][55]** + - `action.payload` **[boolean][58]** Returns **[Object][55]** nextState @@ -269,7 +274,7 @@ Set `exportImage.setExportImageDataUri` to a image dataUri **Parameters** - `state` **[Object][55]** `uiState` -- `action` **[Object][55]** +- `action` **[Object][55]** - `action.payload` **[string][57]** export image data uri Returns **[Object][55]** nextState @@ -283,8 +288,8 @@ Set `exportImage.legend` to `true` or `false` **Parameters** - `state` **[Object][55]** `uiState` -- `$1` **[Object][55]** - - `$1.payload` +- `$1` **[Object][55]** + - `$1.payload` Returns **[Object][55]** nextState @@ -297,7 +302,7 @@ Set selected dataset for export **Parameters** - `state` **[Object][55]** `uiState` -- `action` **[Object][55]** +- `action` **[Object][55]** - `action.payload` **[string][57]** dataset id Returns **[Object][55]** nextState @@ -311,7 +316,7 @@ Hide and show side panel header dropdown, activated by clicking the share link o **Parameters** - `state` **[Object][55]** `uiState` -- `action` **[Object][55]** +- `action` **[Object][55]** - `action.payload` **[string][57]** id of the dropdown Returns **[Object][55]** nextState @@ -339,7 +344,7 @@ Toggle active map control panel - `state` **[Object][55]** `uiState` - `action` **[Object][55]** action - `action.payload` **[string][57]** map control panel id, one of the keys of: [`DEFAULT_MAP_CONTROLS`][60] - - `action.payload.panelId` + - `action.payload.panelId` - `action.payload.index` (optional, default `0`) Returns **[Object][55]** nextState @@ -353,7 +358,7 @@ Show and hide modal dialog **Parameters** - `state` **[Object][55]** `uiState` -- `action` **[Object][55]** +- `action` **[Object][55]** - `action.payload` **([string][57] | null)** id of modal to be shown, null to hide modals. One of:- [`DATA_TABLE_ID`][76] - [`DELETE_DATA_ID`][77] - [`ADD_DATA_ID`][78] @@ -372,7 +377,7 @@ Toggle active side panel **Parameters** - `state` **[Object][55]** `uiState` -- `action` **[Object][55]** +- `action` **[Object][55]** - `action.payload` **([string][57] | null)** id of side panel to be shown, one of `layer`, `filter`, `interaction`, `map`. close side panel if `null` Returns **[Object][55]** nextState @@ -385,7 +390,7 @@ Handles toggle map split and reset all map control index to 0 **Parameters** -- `state` +- `state` Returns **[Object][55]** nextState @@ -407,8 +412,8 @@ whether to export a mapbox access to HTML single page **Parameters** - `state` **[Object][55]** `uiState` -- `action` **[Object][55]** - - `action.payload` **[string][57]** +- `action` **[Object][55]** + - `action.payload` **[string][57]** Returns **[Object][55]** nextState diff --git a/docs/api-reference/reducers/vis-state.md b/docs/api-reference/reducers/vis-state.md index d51bb329e2..10ca6e4c16 100644 --- a/docs/api-reference/reducers/vis-state.md +++ b/docs/api-reference/reducers/vis-state.md @@ -2,39 +2,40 @@ ### Table of Contents -- [visStateUpdaters][1] - - [addFilterUpdater][3] - - [addLayerUpdater][5] - - [applyCPUFilterUpdater][7] - - [enlargeFilterUpdater][9] - - [INITIAL_VIS_STATE][11] - - [interactionConfigChangeUpdater][13] - - [layerClickUpdater][15] - - [layerHoverUpdater][17] - - [layerTypeChangeUpdater][19] - - [layerVisConfigChangeUpdater][21] - - [layerVisualChannelChangeUpdater][23] - - [loadFilesErrUpdater][25] - - [loadFilesUpdater][27] - - [mapClickUpdater][29] - - [receiveMapConfigUpdater][31] - - [removeDatasetUpdater][33] - - [removeFilterUpdater][35] - - [removeLayerUpdater][37] - - [reorderLayerUpdater][39] - - [resetMapConfigUpdater][41] - - [setFilterPlotUpdater][43] - - [setFilterUpdater][45] - - [setMapInfoUpdater][47] - - [showDatasetTableUpdater][49] - - [toggleFilterAnimationUpdater][51] - - [toggleLayerForMapUpdater][53] - - [toggleSplitMapUpdater][55] - - [updateAnimationTimeUpdater][57] - - [updateFilterAnimationSpeedUpdater][59] - - [updateLayerAnimationSpeedUpdater][61] - - [updateLayerBlendingUpdater][63] - - [updateVisDataUpdater][65] +- [visStateUpdaters](#visstateupdaters) + - [addFilterUpdater](#addfilterupdater) + - [addLayerUpdater](#addlayerupdater) + - [applyCPUFilterUpdater](#applycpufilterupdater) + - [enlargeFilterUpdater](#enlargefilterupdater) + - [INITIAL\_VIS\_STATE](#initial_vis_state) + - [Properties](#properties) + - [interactionConfigChangeUpdater](#interactionconfigchangeupdater) + - [layerClickUpdater](#layerclickupdater) + - [layerHoverUpdater](#layerhoverupdater) + - [layerTypeChangeUpdater](#layertypechangeupdater) + - [layerVisConfigChangeUpdater](#layervisconfigchangeupdater) + - [layerVisualChannelChangeUpdater](#layervisualchannelchangeupdater) + - [loadFilesErrUpdater](#loadfileserrupdater) + - [loadFilesUpdater](#loadfilesupdater) + - [mapClickUpdater](#mapclickupdater) + - [receiveMapConfigUpdater](#receivemapconfigupdater) + - [removeDatasetUpdater](#removedatasetupdater) + - [removeFilterUpdater](#removefilterupdater) + - [removeLayerUpdater](#removelayerupdater) + - [reorderLayerUpdater](#reorderlayerupdater) + - [resetMapConfigUpdater](#resetmapconfigupdater) + - [setFilterPlotUpdater](#setfilterplotupdater) + - [setFilterUpdater](#setfilterupdater) + - [setMapInfoUpdater](#setmapinfoupdater) + - [showDatasetTableUpdater](#showdatasettableupdater) + - [toggleFilterAnimationUpdater](#togglefilteranimationupdater) + - [toggleLayerForMapUpdater](#togglelayerformapupdater) + - [toggleSplitMapUpdater](#togglesplitmapupdater) + - [updateAnimationTimeUpdater](#updateanimationtimeupdater) + - [updateFilterAnimationSpeedUpdater](#updatefilteranimationspeedupdater) + - [updateLayerAnimationSpeedUpdater](#updatelayeranimationspeedupdater) + - [updateLayerBlendingUpdater](#updatelayerblendingupdater) + - [updateVisDataUpdater](#updatevisdataupdater) ## visStateUpdaters @@ -44,7 +45,7 @@ Read more about [Using updaters][67] **Examples** ```javascript -import keplerGlReducer, {visStateUpdaters} from 'kepler.gl/reducers'; +import keplerGlReducer, {visStateUpdaters} from '@kepler.gl/reducers'; // Root Reducer const reducers = combineReducers({ keplerGl: keplerGlReducer, @@ -111,7 +112,7 @@ When select dataset for export, apply cpu filter to selected dataset **Parameters** - `state` **[Object][69]** `visState` -- `action` **[Object][69]** +- `action` **[Object][69]** - `action.dataId` **[string][70]** dataset id Returns **[Object][69]** nextState @@ -138,24 +139,24 @@ Type: [Object][69] #### Properties -- `layers` **[Array][75]** -- `layerData` **[Array][75]** -- `layerToBeMerged` **[Array][75]** -- `layerOrder` **[Array][75]** -- `filters` **[Array][75]** -- `filterToBeMerged` **[Array][75]** -- `datasets` **[Array][75]** -- `editingDataset` **[string][70]** -- `interactionConfig` **[Object][69]** -- `interactionToBeMerged` **[Object][69]** -- `layerBlending` **[string][70]** -- `hoverInfo` **[Object][69]** -- `clicked` **[Object][69]** -- `mousePos` **[Object][69]** +- `layers` **[Array][75]** +- `layerData` **[Array][75]** +- `layerToBeMerged` **[Array][75]** +- `layerOrder` **[Array][75]** +- `filters` **[Array][75]** +- `filterToBeMerged` **[Array][75]** +- `datasets` **[Array][75]** +- `editingDataset` **[string][70]** +- `interactionConfig` **[Object][69]** +- `interactionToBeMerged` **[Object][69]** +- `layerBlending` **[string][70]** +- `hoverInfo` **[Object][69]** +- `clicked` **[Object][69]** +- `mousePos` **[Object][69]** - `splitMaps` **[Array][75]** a list of objects of layer availabilities and visibilities for each map -- `layerClasses` **[Object][69]** -- `animationConfig` **[Object][69]** -- `editor` **[Object][69]** +- `layerClasses` **[Object][69]** +- `animationConfig` **[Object][69]** +- `editor` **[Object][69]** ### interactionConfigChangeUpdater @@ -255,7 +256,7 @@ Trigger loading file error - `state` **[Object][69]** `visState` - `action` **[Object][69]** action - - `action.error` **any** + - `action.error` **any** Returns **[Object][69]** nextState @@ -381,7 +382,7 @@ Set the property of a filter plot - `state` **[Object][69]** `visState` - `action` **[Object][69]** action - - `action.idx` **[Number][74]** + - `action.idx` **[Number][74]** - `action.newProp` **[Object][69]** key value mapping of new prop `{yAxis: 'histogram'}` Returns **[Object][69]** nextState @@ -453,8 +454,8 @@ Toggle visibility of a layer in a split map **Parameters** -- `state` **[Object][69]** -- `action` **[Object][69]** +- `state` **[Object][69]** +- `action` **[Object][69]** - `action.mapIndex` **[Number][74]** index of the split map - `action.layerId` **[string][70]** id of the layer From 931e2c6bb2b1bc7143b3a082f0f7ff0163dafa88 Mon Sep 17 00:00:00 2001 From: Indranil Halder <73965619+indranildeveloper@users.noreply.github.com> Date: Thu, 21 Nov 2024 00:01:08 +0530 Subject: [PATCH 3/9] [fix] Update the path to relative path in utils (#2775) Signed-off-by: Indranil Halder --- src/utils/src/index.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/utils/src/index.ts b/src/utils/src/index.ts index 83a5afccf4..6bc80717a8 100644 --- a/src/utils/src/index.ts +++ b/src/utils/src/index.ts @@ -142,5 +142,5 @@ export {getCentroid, getHexFields, h3IsValid, idToPolygonGeo} from './h3-utils'; export type {Centroid} from './h3-utils'; // Application config -export {getApplicationConfig, initApplicationConfig} from '../../utils/src/application-config'; -export type {KeplerApplicationConfig, MapLibInstance} from '../../utils/src/application-config'; +export {getApplicationConfig, initApplicationConfig} from './application-config'; +export type {KeplerApplicationConfig, MapLibInstance} from './application-config'; From a253cae1f53e9db623d8a296e53f6bf39d86e8b2 Mon Sep 17 00:00:00 2001 From: Indranil Halder <73965619+indranildeveloper@users.noreply.github.com> Date: Thu, 21 Nov 2024 00:03:05 +0530 Subject: [PATCH 4/9] Update the keplergl processors update (#2776) Signed-off-by: Indranil Halder --- docs/api-reference/processors/processors.md | 32 ++++++++++----------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/docs/api-reference/processors/processors.md b/docs/api-reference/processors/processors.md index 10ac22b1b4..b978d62dba 100644 --- a/docs/api-reference/processors/processors.md +++ b/docs/api-reference/processors/processors.md @@ -2,11 +2,11 @@ ### Table of Contents -- [getFieldsFromData][1] -- [processCsvData][4] -- [processGeojson][7] -- [processKeplerglJSON][10] -- [processRowObject][13] +- [getFieldsFromData](#getfieldsfromdata) +- [processCsvData](#processcsvdata) +- [processGeojson](#processgeojson) +- [processKeplerglJSON](#processkeplergljson) +- [processRowObject](#processrowobject) ## getFieldsFromData @@ -21,7 +21,7 @@ Assign `type`, `tableFieldIndex` and `format` (timestamp only) to each field **Examples** ```javascript -import {getFieldsFromData} from 'kepler.gl/processors'; +import {getFieldsFromData} from '@kepler.gl/processors'; const data = [{ time: '2016-09-17 00:09:55', value: '4', @@ -66,7 +66,7 @@ The data object can be wrapped in a `dataset` and pass to [`addDataToMap`][18] **Examples** ```javascript -import {processCsvData} from 'kepler.gl/processors'; +import {processCsvData} from '@kepler.gl/processors'; const testData = `gps_data.utc_timestamp,gps_data.lat,gps_data.lng,gps_data.types,epoch,has_result,id,time,begintrip_ts_utc,begintrip_ts_local,date 2016-09-17 00:09:55,29.9900937,31.2590542,driver_analytics,1472688000000,False,1,2016-09-23T00:00:00.000Z,2016-10-01 09:41:39+00:00,2016-10-01 09:41:39+00:00,2016-09-23 @@ -100,8 +100,8 @@ The data object can be wrapped in a `dataset` and pass to [`addDataToMap`][18] **Examples** ```javascript -import {addDataToMap} from 'kepler.gl/actions'; -import {processGeojson} from 'kepler.gl/processors'; +import {addDataToMap} from '@kepler.gl/actions'; +import {processGeojson} from '@kepler.gl/processors'; const geojson = { "type" : "FeatureCollection", @@ -138,15 +138,15 @@ The json object should contain `datasets` and `config`. **Parameters** -- `rawData` **[Object][17]** - - `rawData.datasets` **[Array][16]** - - `rawData.config` **[Object][17]** +- `rawData` **[Object][17]** + - `rawData.datasets` **[Array][16]** + - `rawData.config` **[Object][17]** **Examples** ```javascript -import {addDataToMap} from 'kepler.gl/actions'; -import {processKeplerglJSON} from 'kepler.gl/processors'; +import {addDataToMap} from '@kepler.gl/actions'; +import {processKeplerglJSON} from '@kepler.gl/processors'; dispatch(addDataToMap(processKeplerglJSON(keplerGlJson))); ``` @@ -164,8 +164,8 @@ Process data where each row is an object, output can be passed to [`addDataToMap **Examples** ```javascript -import {addDataToMap} from 'kepler.gl/actions'; -import {processRowObject} from 'kepler.gl/processors'; +import {addDataToMap} from '@kepler.gl/actions'; +import {processRowObject} from '@kepler.gl/processors'; const data = [ {lat: 31.27, lng: 127.56, value: 3}, From 5b4f65376c4e2cd1b1df8fdbc893609b100c6d04 Mon Sep 17 00:00:00 2001 From: Igor Dykhta Date: Tue, 26 Nov 2024 14:57:35 +0200 Subject: [PATCH 5/9] [feat] create new dataset action (#2778) * [feat] create new dataset action - createNewDataEntry now returns a react-palm task to create or update a dataset asynchronously. - updateVisDataUpdater now returns tasks to create or update a dataset asynchronously, and once done triggers createNewDatasetSuccess action. - refactoring of demo-app App and Container to functional components Signed-off-by: Ihor Dykhta Co-authored-by: Shan He --- examples/demo-app/package.json | 1 + examples/demo-app/src/{app.js => app.tsx} | 348 ++++++++---------- examples/demo-app/src/store.js | 13 +- examples/demo-app/yarn.lock | 17 + src/actions/src/action-types.ts | 4 +- src/actions/src/vis-state-actions.ts | 18 + src/components/src/common/field-token.tsx | 33 +- .../common/item-selector/dropdown-select.tsx | 7 +- src/components/src/container.tsx | 136 +++---- src/components/src/index.ts | 5 +- src/components/src/map-container.tsx | 4 +- src/layers/src/geojson-layer/geojson-layer.ts | 7 +- src/layers/src/layer-utils.ts | 10 +- src/processors/package.json | 1 + src/processors/src/data-processor.ts | 43 +-- src/processors/src/file-handler.ts | 77 ++-- src/reducers/src/combined-updaters.ts | 4 +- src/reducers/src/merger-handler.ts | 2 +- src/reducers/src/vis-state-updaters.ts | 85 +++-- src/reducers/src/vis-state.ts | 4 +- src/table/package.json | 3 +- src/table/src/dataset-utils.ts | 38 +- src/table/src/kepler-table.ts | 98 ++--- src/types/actions.d.ts | 18 +- src/types/layers.d.ts | 8 +- src/utils/src/application-config.ts | 10 +- src/utils/src/arrow-data-container.ts | 8 +- src/utils/src/data-container-interface.ts | 4 +- src/utils/src/data-container-utils.ts | 4 +- src/utils/src/dataset-utils.ts | 2 +- src/utils/src/row-data-container.ts | 4 +- test/browser/components/container-test.js | 32 +- test/browser/components/injector-test.js | 2 +- .../channel-by-value-selctor-test.js | 2 +- .../components/side-panel/layer-list.spec.js | 10 +- .../layer-tests/geojson-layer-specs.js | 7 +- test/browser/layer-tests/point-layer-specs.js | 15 +- .../fixtures/synced-filter-with-trip-layer.js | 10 +- test/helpers/layer-utils.js | 33 +- test/helpers/mock-state.js | 95 +++-- test/helpers/table-utils.js | 26 ++ test/node/reducers/composer-state-test.js | 77 +++- test/node/reducers/root-test.js | 24 +- test/node/reducers/vis-state-merger-test.js | 138 ++++--- test/node/reducers/vis-state-test.js | 240 ++++++++---- test/node/utils/index.js | 1 + test/node/utils/kepler-table-test.js | 31 +- test/node/utils/kepler-table-utils-test.js | 31 ++ test/node/utils/layer-utils-test.js | 19 +- yarn.lock | 2 + 50 files changed, 1132 insertions(+), 679 deletions(-) rename examples/demo-app/src/{app.js => app.tsx} (62%) create mode 100644 test/helpers/table-utils.js create mode 100644 test/node/utils/kepler-table-utils-test.js diff --git a/examples/demo-app/package.json b/examples/demo-app/package.json index d2bf40df5a..602f7b6a98 100644 --- a/examples/demo-app/package.json +++ b/examples/demo-app/package.json @@ -44,6 +44,7 @@ "react-virtualized": "^9.21.0", "redux": "^4.2.1", "redux-actions": "^2.2.1", + "redux-logger": "^3.0.6", "redux-thunk": "^1.0.0", "styled-components": "^4.1.3" }, diff --git a/examples/demo-app/src/app.js b/examples/demo-app/src/app.tsx similarity index 62% rename from examples/demo-app/src/app.js rename to examples/demo-app/src/app.tsx index 8be0057a41..500c076993 100644 --- a/examples/demo-app/src/app.js +++ b/examples/demo-app/src/app.tsx @@ -1,11 +1,11 @@ // SPDX-License-Identifier: MIT // Copyright contributors to the kepler.gl project -import React, {Component} from 'react'; +import React, {useCallback, useEffect, useMemo, useState} from 'react'; import AutoSizer from 'react-virtualized/dist/commonjs/AutoSizer'; import styled, {ThemeProvider} from 'styled-components'; import window from 'global/window'; -import {connect} from 'react-redux'; +import {connect, useDispatch} from 'react-redux'; import cloneDeep from 'lodash.clonedeep'; import {ScreenshotWrapper} from 'react-ai-assist'; @@ -30,7 +30,7 @@ import { onLoadCloudMapSuccess } from './actions'; -import {loadCloudMap, addDataToMap, addNotification, replaceDataInMap} from '@kepler.gl/actions'; +import {loadCloudMap, addDataToMap, replaceDataInMap} from '@kepler.gl/actions'; import {CLOUD_PROVIDERS} from './cloud-providers'; const KeplerGl = require('@kepler.gl/components').injectComponents([ @@ -48,7 +48,7 @@ import sampleGeojsonConfig from './data/sample-geojson-config'; import sampleH3Data, {config as h3MapConfig} from './data/sample-hex-id-csv'; import sampleS2Data, {config as s2MapConfig, dataId as s2DataId} from './data/sample-s2-data'; import sampleAnimateTrip, {animateTripDataId} from './data/sample-animate-trip-data'; -import sampleIconCsv, {config as savedMapConfig} from './data/sample-icon-csv'; +import sampleIconCsv from './data/sample-icon-csv'; import sampleGpsData from './data/sample-gps-data'; import sampleRowData, {config as rowDataConfig} from './data/sample-row-data'; import {processCsvData, processGeojson, processRowObject} from '@kepler.gl/processors'; @@ -93,24 +93,23 @@ const CONTAINER_STYLE = { width: '100%', height: '100%', left: 0, - top: 0 + top: 0, + display: 'flex', + flexDirection: 'row' }; -class App extends Component { - state = { - showBanner: false, - width: window.innerWidth, - height: window.innerHeight - }; +const App = props => { + const [showBanner, toggleShowBanner] = useState(false); + const {params: {id, provider} = {}, location: {query = {}} = {}} = props; + const dispatch = useDispatch(); - componentDidMount() { + useEffect(() => { // if we pass an id as part of the url // we ry to fetch along map configurations - const {params: {id, provider} = {}, location: {query = {}} = {}} = this.props; const cloudProvider = CLOUD_PROVIDERS.find(c => c.name === provider); if (cloudProvider) { - this.props.dispatch( + dispatch( loadCloudMap({ loadParams: query, provider: cloudProvider, @@ -122,83 +121,56 @@ class App extends Component { // Load sample using its id if (id) { - this.props.dispatch(loadSampleConfigurations(id)); + dispatch(loadSampleConfigurations(id)); } // Load map using a custom if (query.mapUrl) { // TODO?: validate map url - this.props.dispatch(loadRemoteMap({dataUrl: query.mapUrl})); + dispatch(loadRemoteMap({dataUrl: query.mapUrl})); } // delay zs to show the banner // if (!window.localStorage.getItem(BannerKey)) { - // window.setTimeout(this._showBanner, 3000); + // window.setTimeout(_showBanner, 3000); // } // load sample data - // this._loadSampleData(); + // _loadSampleData(); // Notifications - // this._loadMockNotifications(); - } - - _setStartScreenCapture = flag => { - this.props.dispatch(setStartScreenCapture(flag)); - }; + // _loadMockNotifications(); + }, [dispatch, id, provider, query]); + + const _setStartScreenCapture = useCallback( + flag => { + dispatch(setStartScreenCapture(flag)); + }, + [dispatch] + ); - _setScreenCaptured = screenshot => { - this.props.dispatch(setScreenCaptured(screenshot)); - }; + const _setScreenCaptured = useCallback( + screenshot => { + dispatch(setScreenCaptured(screenshot)); + }, + [dispatch] + ); - _showBanner = () => { - this.setState({showBanner: true}); - }; + // eslint-disable-next-line no-unused-vars + const _showBanner = useCallback(() => { + toggleShowBanner(true); + }, [toggleShowBanner]); - _hideBanner = () => { - this.setState({showBanner: false}); - }; + const hideBanner = useCallback(() => { + toggleShowBanner(false); + }, [toggleShowBanner]); - _disableBanner = () => { - this._hideBanner(); + const _disableBanner = useCallback(() => { + hideBanner(); window.localStorage.setItem(BannerKey, 'true'); - }; - - _loadMockNotifications = () => { - const notifications = [ - [{message: 'Welcome to Kepler.gl'}, 3000], - [{message: 'Something is wrong', type: 'error'}, 1000], - [{message: 'I am getting better', type: 'warning'}, 1000], - [{message: 'Everything is fine', type: 'success'}, 1000] - ]; - - this._addNotifications(notifications); - }; - - _addNotifications(notifications) { - if (notifications && notifications.length) { - const [notification, timeout] = notifications[0]; - - window.setTimeout(() => { - this.props.dispatch(addNotification(notification)); - this._addNotifications(notifications.slice(1)); - }, timeout); - } - } + }, [hideBanner]); - _loadSampleData() { - // this._loadPointData(); - // this._loadGeojsonData(); - // this._loadTripGeoJson(); - // this._loadIconData(); - // this._loadH3HexagonData(); - // this._loadS2Data(); - // this._loadScenegraphLayer(); - // this._loadGpsData(); - // this._loadRowData(); - } - - _loadRowData() { - this.props.dispatch( + const _loadRowData = useCallback(() => { + dispatch( addDataToMap({ datasets: [ { @@ -212,10 +184,10 @@ class App extends Component { config: rowDataConfig }) ); - } + }, [dispatch]); - _loadPointData() { - this.props.dispatch( + const _loadPointData = useCallback(() => { + dispatch( addDataToMap({ datasets: [ { @@ -248,10 +220,10 @@ class App extends Component { config: sampleTripDataConfig }) ); - } + }, [dispatch]); - _loadScenegraphLayer() { - this.props.dispatch( + const _loadScenegraphLayer = useCallback(() => { + dispatch( addDataToMap({ datasets: { info: { @@ -282,11 +254,11 @@ class App extends Component { } }) ); - } + }, [dispatch]); - _loadIconData() { + const _loadIconData = useCallback(() => { // load icon data and config and process csv file - this.props.dispatch( + dispatch( addDataToMap({ datasets: [ { @@ -299,10 +271,10 @@ class App extends Component { ] }) ); - } + }, [dispatch]); - _loadTripGeoJson() { - this.props.dispatch( + const _loadTripGeoJson = useCallback(() => { + dispatch( addDataToMap({ datasets: [ { @@ -312,17 +284,45 @@ class App extends Component { ] }) ); - } + }, [dispatch]); - _replaceData = () => { + const _loadGeojsonData = useCallback(() => { + // load geojson + const geojsonPoints = processGeojson(sampleGeojsonPoints); + const geojsonZip = processGeojson(sampleGeojson); + dispatch( + addDataToMap({ + datasets: [ + geojsonPoints + ? { + info: {label: 'Bart Stops Geo', id: 'bart-stops-geo'}, + data: geojsonPoints + } + : null, + geojsonZip + ? { + info: {label: 'SF Zip Geo', id: 'sf-zip-geo'}, + data: geojsonZip + } + : null + ].filter(d => d !== null), + options: { + keepExistingConfig: true + }, + config: sampleGeojsonConfig + }) + ); + }, [dispatch]); + + const _replaceData = useCallback(() => { // add geojson data const sliceData = processGeojson({ type: 'FeatureCollection', features: sampleGeojsonPoints.features.slice(0, 5) }); - this._loadGeojsonData(); + _loadGeojsonData(); window.setTimeout(() => { - this.props.dispatch( + dispatch( replaceDataInMap({ datasetToReplaceId: 'bart-stops-geo', datasetToUse: { @@ -332,33 +332,11 @@ class App extends Component { }) ); }, 1000); - }; - - _loadGeojsonData() { - // load geojson - this.props.dispatch( - addDataToMap({ - datasets: [ - { - info: {label: 'Bart Stops Geo', id: 'bart-stops-geo'}, - data: processGeojson(sampleGeojsonPoints) - } - // { - // info: {label: 'SF Zip Geo', id: 'sf-zip-geo'}, - // data: processGeojson(sampleGeojson) - // } - ], - options: { - keepExistingConfig: true - }, - config: sampleGeojsonConfig - }) - ); - } + }, [dispatch, _loadGeojsonData]); - _loadH3HexagonData() { + const _loadH3HexagonData = useCallback(() => { // load h3 hexagon - this.props.dispatch( + dispatch( addDataToMap({ datasets: [ { @@ -375,11 +353,11 @@ class App extends Component { } }) ); - } + }, [dispatch]); - _loadS2Data() { + const _loadS2Data = useCallback(() => { // load s2 - this.props.dispatch( + dispatch( addDataToMap({ datasets: [ { @@ -396,10 +374,10 @@ class App extends Component { } }) ); - } + }, [dispatch]); - _loadGpsData() { - this.props.dispatch( + const _loadGpsData = useCallback(() => { + dispatch( addDataToMap({ datasets: [ { @@ -415,66 +393,66 @@ class App extends Component { } }) ); - } - _toggleCloudModal = () => { - // TODO: this lives only in the demo hence we use the state for now - // REFCOTOR using redux - this.setState({ - cloudModalOpen: !this.state.cloudModalOpen - }); - }; - - _getMapboxRef = mapbox => { - if (!mapbox) { - // The ref has been unset. - // https://reactjs.org/docs/refs-and-the-dom.html#callback-refs - // console.log(`Map ${index} has closed`); - } else { - // We expect an Map created by KeplerGl's MapContainer. - // https://visgl.github.io/react-map-gl/docs/api-reference/map - const map = mapbox.getMap(); - map.on('zoomend', () => { - // console.log(`Map ${index} zoom level: ${e.target.style.z}`); - }); - } - }; - - combinedMessages = Object.keys(messages).reduce( - (acc, language) => ({ - ...acc, - [language]: { - ...(messages[language] || {}), - ...(aiAssistantMessages[language] || {}) - } - }), - {} - ); - - render() { - return ( - - { - node ? (this.root = node) : null; - }} + }, [dispatch]); + + const combinedMessages = useMemo(() => { + return Object.keys(messages).reduce( + (acc, language) => ({ + ...acc, + [language]: { + ...(messages[language] || {}), + ...(aiAssistantMessages[language] || {}) + } + }), + {} + ); + }, []); + + // eslint-disable-next-line no-unused-vars + const _loadSampleData = useCallback(() => { + // _loadPointData(); + // _loadGeojsonData(); + // _loadTripGeoJson(); + // _loadIconData(); + // _loadH3HexagonData(); + // _loadS2Data(); + // _loadScenegraphLayer(); + // _loadGpsData(); + // _loadRowData(); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [ + _loadPointData, + _loadGeojsonData, + _loadTripGeoJson, + _loadIconData, + _loadH3HexagonData, + _loadS2Data, + _loadScenegraphLayer, + _loadGpsData, + _loadRowData, + _replaceData + ]); + + return ( + + { + // node ? (this.root = node) : null; + // }} + > + - - - - -
+ + + +
+
{({height, width}) => (
- - - - ); - } -} +
+ + + + ); +}; const mapStateToProps = state => state; const dispatchToProps = dispatch => ({dispatch}); diff --git a/examples/demo-app/src/store.js b/examples/demo-app/src/store.js index 0bff99757f..30d07f29fe 100644 --- a/examples/demo-app/src/store.js +++ b/examples/demo-app/src/store.js @@ -5,7 +5,7 @@ import {combineReducers, createStore, applyMiddleware, compose} from 'redux'; import {routerReducer, routerMiddleware} from 'react-router-redux'; import {browserHistory} from 'react-router'; import {enhanceReduxMiddleware} from '@kepler.gl/reducers'; -import thunk from 'redux-thunk'; +import {createLogger} from 'redux-logger'; // eslint-disable-next-line no-unused-vars import window from 'global/window'; @@ -16,7 +16,16 @@ const reducers = combineReducers({ routing: routerReducer }); -export const middlewares = enhanceReduxMiddleware([thunk, routerMiddleware(browserHistory)]); +export const middlewares = enhanceReduxMiddleware([routerMiddleware(browserHistory)]); + +// eslint-disable-next-line no-process-env +if (NODE_ENV === 'local') { + // Redux logger + const logger = createLogger({ + collapsed: () => true // Collapse all actions for more compact log + }); + middlewares.push(logger); +} export const enhancers = [applyMiddleware(...middlewares)]; diff --git a/examples/demo-app/yarn.lock b/examples/demo-app/yarn.lock index da6bbad798..a0a520c279 100644 --- a/examples/demo-app/yarn.lock +++ b/examples/demo-app/yarn.lock @@ -4625,6 +4625,13 @@ __metadata: languageName: node linkType: hard +"deep-diff@npm:^0.3.5": + version: 0.3.8 + resolution: "deep-diff@npm:0.3.8" + checksum: 10c0/dbb10937ccff21b1ad1ee5e64ad926643a7000cb9837bc2165bacfddf569788c78b8bfd74401c32121af3fb1cb1092b7447319d9f01900676473a1b840c08ade + languageName: node + linkType: hard + "deep-equal@npm:^1.0.1": version: 1.1.2 resolution: "deep-equal@npm:1.1.2" @@ -7588,6 +7595,15 @@ __metadata: languageName: node linkType: hard +"redux-logger@npm:^3.0.6": + version: 3.0.6 + resolution: "redux-logger@npm:3.0.6" + dependencies: + deep-diff: "npm:^0.3.5" + checksum: 10c0/65eb71a1c72d9636368672a684bde62c746e64c19c8b92e3f00bdf5cf240ea1695eccb95a0fa3d5044f6a86cbf11fd35dc5150fd3351fa53c72721c336e9098f + languageName: node + linkType: hard + "redux-thunk@npm:^1.0.0": version: 1.0.3 resolution: "redux-thunk@npm:1.0.3" @@ -7769,6 +7785,7 @@ __metadata: react-virtualized: "npm:^9.21.0" redux: "npm:^4.2.1" redux-actions: "npm:^2.2.1" + redux-logger: "npm:^3.0.6" redux-thunk: "npm:^1.0.0" styled-components: "npm:^4.1.3" languageName: unknown diff --git a/src/actions/src/action-types.ts b/src/actions/src/action-types.ts index dfa8f59651..f9e0cf0dc8 100644 --- a/src/actions/src/action-types.ts +++ b/src/actions/src/action-types.ts @@ -43,6 +43,7 @@ export const ActionTypes = { ADD_DATA: `${ACTION_PREFIX}ADD_DATA`, ADD_FILTER: `${ACTION_PREFIX}ADD_FILTER`, CREATE_OR_UPDATE_FILTER: `${ACTION_PREFIX}CREATE_OR_UPDATE_FILTER`, + CREATE_NEW_DATASET_SUCCESS: `${ACTION_PREFIX}CREATE_NEW_DATASET_SUCCESS`, ADD_LAYER: `${ACTION_PREFIX}ADD_LAYER`, APPLY_LAYER_CONFIG: `${ACTION_PREFIX}APPLY_LAYER_CONFIG`, DUPLICATE_LAYER: `${ACTION_PREFIX}DUPLICATE_LAYER`, @@ -190,6 +191,7 @@ export const ActionTypes = { }; // eslint-disable-next-line prettier/prettier -const assignType = (obj: T): { [K in keyof T]: `${typeof ACTION_PREFIX}${string & K}`; } => obj as any +const assignType = (obj: T): {[K in keyof T]: `${typeof ACTION_PREFIX}${string & K}`} => + obj as any; export default assignType(ActionTypes); diff --git a/src/actions/src/vis-state-actions.ts b/src/actions/src/vis-state-actions.ts index 2775d91ec4..73c2b77740 100644 --- a/src/actions/src/vis-state-actions.ts +++ b/src/actions/src/vis-state-actions.ts @@ -23,6 +23,9 @@ import { EffectPropsPartial, SyncTimelineMode } from '@kepler.gl/types'; +import {createAction} from '@reduxjs/toolkit'; + +import {KeplerTable} from '@kepler.gl/table'; // TODO - import LoaderObject type from @loaders.gl/core when supported // TODO - import LoadOptions type from @loaders.gl/core when supported @@ -1596,6 +1599,21 @@ export function setTimeFilterSyncTimelineMode({ }; } +export type CreateNewDatasetSuccessPayload = { + results: (PromiseFulfilledResult> | PromiseRejectedResult)[]; + addToMapOptions: AddDataToMapPayload['options']; +}; + +/** + * Called when a new dataset is created successfully via async table methods + * @param payload + * @param payload.results - results of promises.allSettlted + * @returns + */ +export const createNewDatasetSuccess = createAction( + ActionTypes.CREATE_NEW_DATASET_SUCCESS +); + /** * This declaration is needed to group actions in docs */ diff --git a/src/components/src/common/field-token.tsx b/src/components/src/common/field-token.tsx index 49567f05e4..e66657eaf6 100644 --- a/src/components/src/common/field-token.tsx +++ b/src/components/src/common/field-token.tsx @@ -8,30 +8,27 @@ import {FIELD_TYPE_DISPLAY, FIELD_COLORS} from '@kepler.gl/constants'; export type FieldTokenProps = { type: string; }; +const FieldTag = styled.div` + background-color: rgba(${props => props.color}, 0.2); + border-radius: 2px; + border: 1px solid rgb(${props => props.color}); + color: rgb(${props => props.color}); + display: inline-block; + font-size: 10px; + font-weight: 400; + padding: 0 5px; + text-align: center; + width: ${props => props.theme.fieldTokenWidth}px; + line-height: ${props => props.theme.fieldTokenHeight}px; +`; function FieldTokenFactory( fieldTypeDisplay: ReturnType, fieldColors: ReturnType ): React.FC { - const FieldTag = styled.div` - background-color: rgba(${props => props.color}, 0.2); - border-radius: 2px; - border: 1px solid rgb(${props => props.color}); - color: rgb(${props => props.color}); - display: inline-block; - font-size: 10px; - font-weight: 400; - padding: 0 5px; - text-align: center; - width: ${props => props.theme.fieldTokenWidth}px; - line-height: ${props => props.theme.fieldTokenHeight}px; - `; - const FieldToken = ({type}: FieldTokenProps) => ( - - {fieldTypeDisplay[type].label} + + {fieldTypeDisplay[type]?.label} ); return FieldToken; diff --git a/src/components/src/common/item-selector/dropdown-select.tsx b/src/components/src/common/item-selector/dropdown-select.tsx index 45eca3d13d..c537830a70 100644 --- a/src/components/src/common/item-selector/dropdown-select.tsx +++ b/src/components/src/common/item-selector/dropdown-select.tsx @@ -1,14 +1,14 @@ // SPDX-License-Identifier: MIT // Copyright contributors to the kepler.gl project -import React from 'react'; +import React, {ComponentType} from 'react'; import styled from 'styled-components'; import {notNullorUndefined} from '@kepler.gl/common-utils'; -import {ComponentType} from 'react'; +import {FormattedMessage} from '@kepler.gl/localization'; + import {ArrowDown, Delete} from '../icons'; import {ListItem} from './dropdown-list'; -import {FormattedMessage} from '@kepler.gl/localization'; export type ListItemProps