Kepler.gl is a data-agnostic, high-performance web-based application for visual exploration of large-scale geolocation data sets. Built on top of MapLibre GL and deck.gl, kepler.gl can render millions of points representing thousands of trips and perform spatial aggregations on the fly.
Kepler.gl is also a React component that uses Redux to manage its state and data flow. It can be embedded into other React-Redux applications and is highly customizable. For information on how to embed kepler.gl in your app take a look at this step-by-step tutorial on vis.academy.
- Website
- Demo
- Examples
- Get Started
- App User Guide
- Jupyter Widget User Guide
- Tutorial
- Stack Overflow
- Contribution Guidelines
- Api Reference
- Roadmap
Use Node 18.18.2 or above, older node versions have not been supported/ tested.
For best results, use nvm nvm install
.
Kepler.gl consists of different modules. Each module can be added to the project like this:
npm install --save @kepler.gl/components
// or
yarn add @kepler.gl/components
kepler.gl is built upon mapbox. You will need a Mapbox Access Token to use it.
If you don't use a module bundler, it's also fine. Kepler.gl npm package includes precompiled production UMD builds in the umd folder. You can add the script tag to your html file as it follows (latest version of Kepler.gl):
<script src="https://unpkg.com/kepler.gl/umd/keplergl.min.js" />
or if you would like, you can load a specific version:
<script src="https://unpkg.com/[email protected]/umd/keplergl.min.js" />
Take a look at the development guide to develop kepler.gl locally.
Here are the basic steps to import kepler.gl into your app. You also take a look at the examples folder. Each example in the folder can be installed and run locally.
Kepler.gl uses Redux to manage its internal state, along with react-palm middleware to handle side effects.
You need to add taskMiddleware
of react-palm
to your store too. We are actively working on a solution where
react-palm
will not be required, however it is still a very lightweight side effects management tool that is easier to test than react-thunk.
import {createStore, combineReducers, applyMiddleware, compose} from 'redux';
import keplerGlReducer from '@kepler.gl/reducers';
import {enhanceReduxMiddleware} from '@kepler.gl/middleware';
const initialState = {};
const reducers = combineReducers({
// <-- mount kepler.gl reducer in your app
keplerGl: keplerGlReducer,
// Your other reducers here
app: appReducer
});
// using createStore
export default createStore(
reducer,
initialState,
applyMiddleware(
enhanceReduxMiddleware([
/* Add other middlewares here */
])
)
);
Or if use enhancer:
// using enhancers
const initialState = {};
const middlewares = enhanceReduxMiddleware([
// Add other middlewares here
]);
const enhancers = [applyMiddleware(...middlewares)];
export default createStore(reducer, initialState, compose(...enhancers));
If you mount kepler.gl reducer in another address instead of keplerGl
, or the kepler.gl reducer is not
mounted at root of your state, you will need to specify the path to it when you mount the component
with the getState
prop.
Read more about Reducers.
import KeplerGl from '@kepler.gl/components';
const Map = props => (
<KeplerGl id="foo" width={width} mapboxApiAccessToken={token} height={height} />
);
- Default:
map
The id of this KeplerGl instance. id
is required if you have multiple
KeplerGl instances in your app. It defines the prop name of the KeplerGl state that is
stored in the KeplerGl reducer. For example, the state of the KeplerGl component with id foo
is
stored in state.keplerGl.foo
.
In case you create multiple kepler.gl instances using the same id, the kepler.gl state defined by the entry will be overridden by the latest instance and reset to a blank state.
- Default:
undefined
By default, kepler.gl uses mapbox-gl.js to render its base maps. You can create a free account at mapbox and create a token at www.mapbox.com/account/access-tokens.
If you replaced kepler.gl default map styles with your own, and they are not Mapbox styles. mapboxApiAccessToken
will not be required.
Read more about Custom Map Styles.
- Default:
state => state.keplerGl
The path to the root keplerGl state in your reducer.
- Default:
800
Width of the KeplerGl UI.
- Default:
800
- Default:
Kepler.Gl
App name displayed in side panel header
- Default:
v1.0
version displayed in side panel header
- Default:
undefined
Action called when click Save Map Url in side panel header.
- Default:
undefined
- Parameter:
viewState
- An updated view state object containing parameters such as longitude, latitude, zoom etc
Action triggered when map viewport is updated.
- Default:
undefined
Function called when KeplerGL
adds or removes a MapContainer
component having an inner Mapbox map.
The mapbox
argument is an MapRef
when added or null
when removed.
The index
argument is 0 for a single map or 1 for an additional map (since KeplerGL
supports an optional split map view).
- Default:
{}
Actions creators to replace default kepler.gl action creator. Only use custom action when you want to modify action payload.
- Default:
true
Whether to load a fresh empty state when component is mounted. when parse mint: true
kepler.gl component will always load a fresh state when re-mount the same component, state inside this component will be destroyed once its unmounted.
By Parsing mint: false
kepler.gl will keep the component state in the store even when it is unmounted, and use it as initial state when re-mounted again. This is useful when mounting kepler.gl in a modal, and keep the same map when re-open.
Read more about Components.
- default:
null
One of "dark"
, "light"
or "base"
You can pass theme name or object used to customize Kepler.gl style. Kepler.gl provide an 'light'
theme besides the default 'dark' theme. When pass in a theme object Kepler.gl will use the value passed as input to override values from theme.
Read more about Custom Theme
- Default:
https://api.mapbox.com
If you are using your own mapbox tile server, you can pass in your own tile server api url.
- Default:
false
kepler.gl provide 4 map styles to choose from. Pass true
if you want to supply your own mapStyles
. See Below.
- Default:
[]
You can supply additional map styles to be displayed in map style selection panel. By default, additional map styles will be added to default map styles. If pass mapStylesReplaceDefault: true
, they will replace the default ones. kepler.gl will attempt to group layers of your style based on its id
naming convention and use it to allow toggle visibility of base map layers. Supply your own layerGroups
to override default for more accurate layer grouping.
Each mapStyles
should has the following properties:
id
(String, required) unique string that should not be one of these reserveddark
light
muted
.muted_night
label
(String, required) name to be displayed in map style selection panelurl
(String, required) mapbox style url or a url pointing to the map style json object written in Mapbox GL Style Spec.icon
(String, optional) image icon of the style, it can be a url, or an image data urllayerGroups
(Array, optional)
const mapStyles = [
{
id: 'my_dark_map',
label: 'Dark Streets 9',
url: 'mapbox://styles/mapbox/dark-v9',
icon: `${apiHost}/styles/v1/mapbox/dark-v9/static/-122.3391,37.7922,9.19,0,0/400x300?access_token=${accessToken}&logo=false&attribution=false`,
layerGroups: [
{
slug: 'label',
filter: ({id}) => id.match(/(?=(label|place-|poi-))/),
defaultVisibility: true
},
{
// adding this will keep the 3d building option
slug: '3d building',
filter: () => false,
defaultVisibility: false
}
]
}
];
Read more about Custom Map Styles.
- Default:
undefined
Intial UI State applied to uiState reducer, value will be shallow merged with default INITIAL_UI_STATE
- Default:
undefined
Modify default translation or add new translation
Read more about Localization.
One advantage of using the reducer over React component state to handle keplerGl state is the flexibility
to customize its behavior. If you only have one KeplerGl
instance in your app or never intend to dispatch actions to KeplerGl from outside the component itself,
you don’t need to worry about forwarding dispatch and can move on to the next section. But life is full of customizations, and we want to make yours as enjoyable as possible.
There are multiple ways to dispatch actions to a specific KeplerGl
instance.
- In the root reducer, with reducer updaters.
Each action is mapped to a reducer updater in kepler.gl. You can import the reducer updater corresponding to a specific action, and call it with the previous state and action payload to get the updated state.
e.g. updateVisDataUpdater
is the updater for ActionTypes.UPDATE_VIS_DATA
(take a look at each reducer reducers/vis-state.js
for action to updater mapping).
Here is an example how you can listen to an app action QUERY_SUCCESS
and call updateVisDataUpdater
to load data into Kepler.Gl.
import {keplerGlReducer, visStateUpdaters} from '@kepler.gl/reducers';
// Root Reducer
const reducers = combineReducers({
keplerGl: keplerGlReducer,
app: appReducer
});
const composedReducer = (state, action) => {
switch (action.type) {
case 'QUERY_SUCCESS':
return {
...state,
keplerGl: {
...state.keplerGl,
// 'map' is the id of the keplerGl instance
map: {
...state.keplerGl.map,
visState: visStateUpdaters.updateVisDataUpdater(state.keplerGl.map.visState, {
datasets: action.payload
})
}
}
};
}
return reducers(state, action);
};
export default composedReducer;
Read more about using updaters to modify kepler.gl state
- Using redux
connect
You can add a dispatch function to your component that dispatches actions to a specific keplerGl
component,
using connect.
// component
import KeplerGl from '@kepler.gl/components';
// action and forward dispatcher
import {toggleFullScreen, forwardTo} from '@kepler.gl/actions';
import {connect} from 'react-redux';
const MapContainer = props => (
<div>
<button onClick={() => props.keplerGlDispatch(toggleFullScreen())}/>
<KeplerGl
id="foo"
/>
</div>
)
const mapStateToProps = state => state
const mapDispatchToProps = (dispatch, props) => ({
dispatch,
keplerGlDispatch: forwardTo(‘foo’, dispatch)
});
export default connect(
mapStateToProps,
mapDispatchToProps
)(MapContainer);
- Wrap action payload
You can also simply wrap an action into a forward action with the wrapTo
helper
// component
import KeplerGl from '@kepler.gl/components';
// action and forward dispatcher
import {toggleFullScreen, wrapTo} from '@kepler.gl/actions';
// create a function to wrapper action payload to 'foo'
const wrapToMap = wrapTo('foo');
const MapContainer = ({dispatch}) => (
<div>
<button onClick={() => dispatch(wrapToMap(toggleFullScreen())} />
<KeplerGl
id="foo"
/>
</div>
);
Read more about forward dispatching actions
Kepler.gl implements css styling using Styled-Components. By using said framework Kepler.gl offers the ability to customize its style/theme using the following approaches:
- Passing a Theme prop
- Styled-Components ThemeProvider
The available properties to customize are listed here theme.
You can customize Kepler.gl theme by passing a theme props to Kepler.gl react component as it follows:
const white = '#ffffff';
const customTheme = {
sidePanelBg: white,
titleTextColor: '#000000',
sidePanelHeaderBg: '#f7f7F7',
subtextColorActive: '#2473bd'
};
return (
<KeplerGl
mapboxApiAccessToken={MAPBOX_TOKEN}
id="map"
width={800}
height={800}
theme={customTheme}
/>
);
As you can see the customTheme object defines certain properties which will override Kepler.gl default style rules.
In order to customize Kepler.gl theme using ThemeProvider you can simply wrap Kepler.gl using ThemeProvider as it follows:
import {ThemeProvider} from 'styled-components';
const white = '#ffffff';
const customTheme = {
sidePanelBg: white,
titleTextColor: '#000000',
sidePanelHeaderBg: '#f7f7F7',
subtextColorActive: '#2473bd'
};
return (
<ThemeProvider theme={customTheme}>
<KeplerGl mapboxApiAccessToken={MAPBOX_TOKEN} id="map" width={800} height={800} />
</ThemeProvider>
);
Everyone wants the flexibility to render custom kepler.gl components. Kepler.gl has a dependency injection system that allow you to inject
components to KeplerGl replacing existing ones. All you need to do is to create a component factory for the one you want to replace, import the original component factory
and call injectComponents
at the root component of your app where KeplerGl
is mounted.
Take a look at examples/demo-app/src/app.js
and see how it renders a custom side panel header in kepler.gl
import {injectComponents, PanelHeaderFactory} from '@kepler.gl/components';
// define custom header
const CustomHeader = () => <div>My kepler.gl app</div>;
const myCustomHeaderFactory = () => CustomHeader;
// Inject custom header into Kepler.gl, replacing default
const KeplerGl = injectComponents([[PanelHeaderFactory, myCustomHeaderFactory]]);
// render KeplerGl, it will render your custom header instead of the default
const MapContainer = () => (
<div>
<KeplerGl id="foo" />
</div>
);
Using withState
helper to add reducer state and actions to customized component as additional props.
import {withState, injectComponents, PanelHeaderFactory} from '@kepler.gl/components';
import {visStateLens} from '@kepler.gl/reducers';
// custom action wrap to mounted instance
const addTodo = text =>
wrapTo('map', {
type: 'ADD_TODO',
text
});
// define custom header
const CustomHeader = ({visState, addTodo}) => (
<div onClick={() => addTodo('hello')}>{`${
Object.keys(visState.datasets).length
} dataset loaded`}</div>
);
// now CustomHeader will receive `visState` and `addTodo` as additional props.
const myCustomHeaderFactory = () =>
withState(
// keplerGl state lenses
[visStateLens],
// customMapStateToProps
headerStateToProps,
// actions
{addTodo}
)(CustomHeader);
Read more about replacing UI component
To interact with a kepler.gl instance and add new data to it, you can dispatch the addDataToMap
action from anywhere inside your app. It adds a dataset or multiple datasets to a kepler.gl instance and updates the full configuration (mapState, mapStyle, visState).
-
data
Object *required-
datasets
(Array<Object> | Object) *required datasets can be a dataset or an array of datasets Each dataset object needs to haveinfo
anddata
property. -
options
Objectoptions.centerMap
booleandefault: true
ifcenterMap
is set totrue
kepler.gl will place the map view within the data points boundariesoptions.readOnly
booleandefault: false
ifreadOnly
is set totrue
the left setting panel will be hiddenoptions.keepExistingConfig
booleandefault: false
whether to keep exiting map config, including layers, filters and splitMaps.
-
-
config
Object this object will contain the full kepler.gl instance configuration {mapState, mapStyle, visState}
Kepler.gl provides an easy API KeplerGlSchema.getConfigToSave
to generate a json blob of the current kepler instance configuration.
// app.js
import {addDataToMap} from '@kepler.gl/actions';
const sampleTripData = {
fields: [
{name: 'tpep_pickup_datetime', format: 'YYYY-M-D H:m:s', type: 'timestamp'},
{name: 'pickup_longitude', format: '', type: 'real'},
{name: 'pickup_latitude', format: '', type: 'real'}
],
rows: [
['2015-01-15 19:05:39 +00:00', -73.99389648, 40.75011063],
['2015-01-15 19:05:39 +00:00', -73.97642517, 40.73981094],
['2015-01-15 19:05:40 +00:00', -73.96870422, 40.75424576]
]
};
const sampleConfig = {
visState: {
filters: [
{
id: 'me',
dataId: 'test_trip_data',
name: 'tpep_pickup_datetime',
type: 'timeRange',
view: 'enlarged'
}
]
}
};
this.props.dispatch(
addDataToMap({
datasets: {
info: {
label: 'Sample Taxi Trips in New York City',
id: 'test_trip_data'
},
data: sampleTripData
},
option: {
centerMap: true,
readOnly: false
},
config: sampleConfig
})
);
Read more about addDataToMap and Saving and loading maps with schema manager.
kepler.gl's People
Forkers
cxz federicosan tchen0123 ndjido symbol-research cuulee yifangma reactual malekcellier lp249839965 soedr ivanrigovsky talentedandrew edbea tapasag sharadgupta27 nimeshvaghasiya tonyle9 troyyip derickson haj viksin672 tophap mbrukman jakedsouza zhengyange ezhangle pnishanth firatkocabay donrv wendyanthony jianlirong soundofdarkness zhaohuining123 buyuhuang hhy5277 richfry shaunstanislauslau stratigraph eric-seekas jdc08161063 donglongwen-daren beikehanbao23 gzzgz pessimo justingosses wl-tsui wsf1990 tomzhang stevenlol mathronica496 hcxiong dzxwind hexiaoting wallaceliu judaa11 linecode tngamemo abhijitmehta x8 r0ms vittorino noahkim11 kimlab fulquan rezavfx qioixiy httpmad ianshan0915 duthedd dorothyzhangxt yanghaha11514 markneville i-spark maniacs-oss weiplanet locussam sunguo mhamine shellsec micseb yanlincodex bopeng48 karthik-cbe chrushr lesliesie wonderino bobbleoxs cybernetics wenhengqiu ctrimm feixiegis getiaotiao auctionomics madhukar02 tokopedia anilsener pauloaug 1alvho why333kepler.gl's Issues
GeoJSON LineStrings supported?
Hello,
I'm trying to visualize GeoJSON LineStrings of aircraft flight paths and nothing happens. I'm prompted to pick Lat0/Lng0 and Lat1/Lng0, but that makes it seem like it only supports "lines" with a start/finish location rather than multi-vertex linestrings. Is that correct? Are traditional line strings not supported at this time?
Geoserver integration
are there plans to support geoserver out of the box as a data source?
P0: Export image with Legend
TimeSlider precision
I would like to thanks the team first for this awesome projet :)
I have one week of data to display, and the frequency of data is per second.
I wanted to implement a TimeSlider widget to reduce the number of my data on screen, but it seems I can't reduce the slider's interval less than 24h...
Is there any hack to reduce the quantity of time in the time slider please (console hack, something like that...)?
Thanks!
Custom Mapbox API token input
403 Forbidden Error: Not able to render base map styles 'Light' or 'Muted Light' when Label Map Layer is selected
When running a local deployment of kepler.gl (also problem happened when doing a Vis Academy embed kepler.gl tutorial), the original Dark Base Map Style loads perfectly fine with my mapbox token, but when I try to switch the Base Map Style to 'Light' or 'Muted Light' the map doesn't render and I get loads of error.
The error doesn't appear when I try to load 'Muted Dark'.
Here is a screenshot of the map that loads when you select Light or Muted Light, it is not the correct basemap and if you zoom in much further even the simple country outline disappears and no labels or borders appear. I have also attached a screenshot of the console errors. I am able to load data no problem and am able to load custom styles no problem.
Increase upload limit
I am trying to upload 540 MB of data. Chrome won't support but it throws no error. Safari crashes and reloads the web page. Firefox too won't load the data.
P1: Can't remove a dataset if the name is too long
Possible Bug: Integer column appears as boolean
I've loaded some centroids that have valid coordinates in both geojson and csv (just to see if there was a difference). Map renders, but if I want to classify the data based upon an integer column Kepler recognizes the data, but incorrectly casts the data as a Boolean. Anyone else having the same issue?
P2: Provide data util functions
Provide data util functions, such as transform points into geojson, etc.
DateTime fields read as strings
Kepler.gl looks super cool and I'm excited to be able to use it. After adding my data, my fields only show up as integers and strings, even my DateTime field. I've tried going back into LibreCalc to set the format to date, time, and custom YYYY/MM/DD HH:MM:SS format, but it still just comes through as a string after upload the UTF-8 CSV file.
SyracuseSiteData_Qonly_UTF-8.zip
P1: Allow to add filters for each panel in split view
It would be a game changer for exploratory analysis. Currently need to materialize filtered data in two separate layers to have a split-screen visualization.
react-onclickoutside throws npm error
Seems kepler points directly too "react-onclickoutside": "https://registry.npmjs.org/react-onclickoutside/-/react-onclickoutside-6.7.1.tgz"
& this package is not found in npm registry currently. Throwing build errors due to this package saying {"error":"Not found"}
when visiting the tarball link
P2: Allow to duplicate layers
This would make it easier to create a similar layer and only adjusting some minor styling things.
Update the website with the new tokens
Add contribution guidelines
CSV loading, but not displaying
Sorry for not having a more descriptive title, or a more specific description of the problem. I'll try to describe what I'm seeing as detailed as possible; and I'm attaching the test data below.
I have a CSV that is just not displaying on the map. It's a three-column file (title, WKT geometry, an "ItemType" string field). Some observations:
- Upload seems to go fine. Colum types are properly recognized (string, geo, string), and everything looks ok in the grid view
- After loading, the map stays empty
- If I add a filter to show just rows of ItemType PLACE, the map renders as it should
- If I add a filter to show just rows of ItemType OBJECT, the map goes back to blank
- If I clip the CSV to just the first 500 rows (all of which are OBJECTs), and upload to a fresh map, everything works as it should.
Since the clipped dataset works, I'm guessing there might be something in the data that kepler.gl doesn't like. But I can't figure out what it is. Below, I'm attaching:
- The full dataset all.csv.zip (that's causing the issues)
- Only the first 500 rows partial_500.csv.zip (which look ok on the map)
Geojson files can't be uploaded
Hello, I want to see the upload file data structure, so according to the method provided by https://medium.com/vis-gl/visualizing-u-s-county-unemployment-with-kepler-gl-c5f2ed31c71 I generated a counties-unemployment.geojson file, the file is only about 1800K, but can not be uploaded to the kepler.gl, I do not know what to do Is it? If you need the file I generated, I can send it to you. Thank you.
P2: Enable data aggregation or transformation
Problem:
Currently, kepler.gl doesn’t do much with data aggregation or transformation. User has to massage the data in certain way that fits the layer paradigm. For example, I have to deserialize the points of each trip into a set of points with trip id to plot them by point layer.
Suggestions:
- Enable to do nearest neighbor joins to create line or arc layers from two csv files of points. https://github.com/mourner/geokdbush can be helpful.
- Join sequence of points (by timestamp/sequence id) into line
Yarn engines should use a valid engine
Kepler causes sites to need to run with --ignore-engines we should have it specify a valid engine
P1: Lines are wildly sticking out and will not scale up or down by zooming
Custom basemap background color
One of the custom mapbox styles questions we got was to be able to set a custom background color when using a basemap.
We'll need a mapbox style url to reproduce this issue.
P0: Polygon stroke once turned off would disappear and there is no way to get it back unless redo the mapping from the start
P0: Solve the problem of kepler.gl relying on the react lifecycle (componentWillMount) to register a new entry in the reducer
Currently, user has to wait for the component to be mounted first and then pass the data in componentDidMount
adding second timestamp filter break the enlarged state
step to reproduce:
- load any dataset with 2 timestamp column
- add a filter on one time
- add a filter on the other time
now 2 filters both mark themselves as enlarged internally. but only the first filter is used in the large panel.
if you click to show the second filter, it will hide the enlarged filter instead of switching to the second.
Allowing float argument for "Elevation scale"
First of all, thanks for this amazing work!
When enabling height, the elevation scale
parameter is forced to be an integer apparently. But when visualizing small objects (like small individual houses, couple of meters wide), even the smallest value of 1 can be too high.
Can we allow floating point number here, pretty please?
P2: Enable data aggregation or transformation
End up I need to massage the data in certain way that fits the layer paradigm. For example, I have to deserialize the points of each trip into a set of points with trip id to plot them by point layer.
Example: Join sequence of points (by timestamp/sequence id) into line
Demo App Fails Webpack Build
I'm currently unable to build the demo-app project in the /examples directory. Following the included readme, I ran npm install
followed by npm start
, but I'm receiving the following output. Any ideas? I'm not particularly well-versed in React, so am I missing something obvious?
> @ start /Users/username/Projects/demos/kepler-demo/node_modules/kepler.gl/examples/demo-app
> webpack-dev-server --progress --hot --open
10% building modules 1/1 modules 0 active
Project is running at http://localhost:8080/
webpack output is served from /
10% building modules 3/3 modules 0 activewebpack: wait until bundle finished: /
Hash: bfbb95190c60eccaeb52
Version: webpack 2.7.0
Time: 588ms
Asset Size Chunks Chunk Names
bundle.js 351 kB 0 [emitted] [big] app
bundle.js.map 413 kB 0 [emitted] app
chunk {0} bundle.js, bundle.js.map (app) 321 kB [entry] [rendered]
[2] (webpack)/hot/emitter.js 77 bytes {0} [built]
[3] (webpack)-dev-server/client?http://localhost:8080 7.93 kB {0} [built]
[4] (webpack)/hot/dev-server.js 1.57 kB {0} [built]
[5] ./src/main.js 369 bytes {0} [built] [failed] [1 error]
[7] ./~/ansi-regex/index.js 135 bytes {0} [built]
[8] ./~/events/events.js 8.33 kB {0} [built]
[9] ./~/html-entities/index.js 231 bytes {0} [built]
[12] ./~/loglevel/lib/loglevel.js 7.86 kB {0} [built]
[18] ./~/strip-ansi/index.js 161 bytes {0} [built]
[19] ./~/url/url.js 23.3 kB {0} [built]
[21] (webpack)-dev-server/client/overlay.js 3.67 kB {0} [built]
[22] (webpack)-dev-server/client/socket.js 1.08 kB {0} [built]
[24] (webpack)/hot nonrecursive ^\.\/log$ 160 bytes {0} [built]
[25] (webpack)/hot/log-apply-result.js 1.02 kB {0} [built]
[26] multi (webpack)-dev-server/client?http://localhost:8080 webpack/hot/dev-server ./src/main.js 52 bytes {0} [built]
+ 12 hidden modules
ERROR in ./src/main.js
Module parse failed: /Users/username/Projects/demos/kepler-demo/node_modules/kepler.gl/examples/demo-app/src/main.js Unexpected token (36:2)
You may need an appropriate loader to handle this file type.
|
| const Root = () => (
| <Provider store={store}>
| <Router history={history}>
| <Route path="/(:id)" component={App} />
@ multi (webpack)-dev-server/client?http://localhost:8080 webpack/hot/dev-server ./src/main.js
webpack: Failed to compile.
P1: Allow to edit individual colors
Request:
I would love the ability to edit the individual colors or have a custom color array type for use in “color based on”.
Reasoning:
Frequently the colors on a map represent an actual data value as opposed to just needing to visually differentiate between the values. For an overly simple example if an analysis is supposed to show locations that are being green lighted for another process, I should have the ability to set a specific green color for those points. And likewise set red, orange, yellow for points depending on their data value.
Support custom color hexcode for points on map
Ability to provide a specific hexcode for custom colors on map.
How do I generate & export (as a video?) visualization like `A Day's Worth of Trips in London` given a csv file with data?
P2: Enable defining pickup and dropoff geofences and see the distribution of trips
I define a pickup geofence, and several dropoff geofences.
And I can see the distribution of trips from this geofence into those dropoff geofences.
Vice versa - define a dropoff geofence and list of pickup geofences.
processRowObject runs typeAnalyzer on all data not a sample
https://github.com/uber/kepler.gl/blob/master/src/processors/data-processor.js#L271
This function should probably call getSampleForTypeAnalyze
before passing to getFieldsFromData
GeometryCollection GeoJSON not supported
Adding a GeometryCollection GeoJson layer throw this error:
deck.gl deck.gl error during initialization of <GeoJsonLayer:'vyik0jh'> Error: GeoJsonLayer: GeometryCollection not supported.
Error: GeoJsonLayer: GeometryCollection not supported.
You can reproduce it with testCase.csv.zip
Yarn install fails - `react-onclickoutside-6.7.1` 404's from NPM
Problem
When running yarn install
as of ~4PM PST on 5/25/18, the package for https://registry.npmjs.org/Pomax/-/react-onclickoutside-6.7.1.tgz
fails to download from NPM with a 404 error. I've replicated this on a local machine and in Travis tests, and it looks to be specific to the NPM URL route.
Impact
- Developers cannot install a local copy of kepler.gl
- All tests for new PRs fail (#56)
cc/ @heshan0131
P0: Map/visualization export for developers
Requires:
- Saving Custom Map Styles
- Requires react lifecycle API features
Add "Share" wording on Save/Export button
P1: Add an annotation layer
Even if we could pin multiple tooltips at a time to draw attention to specific objects it would make a massive difference.
Annotation layer as a GIS jargon for labelling options where you stick/pin a name, or other string/Int value of table data to got a proper and easy identification. Different of legend and tooltip popup it define clearly (depend of the case) what the data represents. Just something that takes lat, Lon, Text, offset type values. Like geom_text in ggplot2
Shan:
My thinking is this can be an additional option for each layer as a ‘Add label’ toggle. point, line, arc and polygon should offer this option
Add analytics tracking for usage kepler.gl
Consider adding a middleware for the redux store and push events from actions.
Events we're interested are tracked in this spreadsheet.
Travis CI is intermittently failing
Logged travis-ci/travis-ci#9679 (comment)
Started seeing apt-get failures on Travis CI since about 10 hours ago. (E.g. #71)
P0: Oddly drawn polygons
There are at least three oddly drawn polygons (US counties) in the image below: one in Alaska and two in the contiguous 48 states. This was produced with the kepler.gl website.
The was geojson file was originally an sf object stored in a .RData file (R language) - subsequently converted to geojson.
I attempted to replicate this problem with the geojson file in D3 v4 (seen here), but it did not produce the same oddly drawn polygons.
I have the geojson file, kepler config file, and D3 attempt contained within this gist.
Unable to center the map when loading the new data
CSV Not Working
I'm trying to upload a very small CSV (2MB), and I followed the guidelines by having columns named x_lat, x_lng, and some others, but when I click to load the file, the interface has a spinning wheel indefinitely and never goes to the mapping screen. By the way, the project looks very interesting.
what is the best way to go about making a sharable version of the map?
I've really enjoyed working with data in keplergl and have recommended it to others. One feedback question I've gotten back, and I've had difficulty with as well, is :
what is the best way to go about making a sharable version of the map?
It is very easy and intuitive to make things from client-side GUI, but they go away when you close the browser. There is export functionality, but not a lot of documentation on how to go about building a map with that exported data and configuration that you could share via github pages. There have been some great Medium posts on how users can load their own data into the application, perhaps something similar would be helpful if not here within a separate readme?
If someone wants to take this on, feel free to tag me for feedback / edits.
Image Layer Possibility
I would like to project satellite images as a layer under geojson map data. Does anyone have any ideas or suggestions on how I could do this?
I have json files with GPS bounding boxes and associated satellite imagery (low quality jpg's and high quality tif's) that cover the spaces that I want to view.
My initial idea was to extend the GridLayer class, but so far I've had little luck. Any suggestsions would be highly appreciated
props is cached in TimeRangeSlider.constructor
https://github.com/uber/kepler.gl/blob/master/src/components/common/time-range-slider.js#L68
onChange is cached in constructor and nothing handle the change of the onChange handler
this make this component not reusable and might cause issue since react reuse component whenever possible
that lines in constructor() should be moved to render()
P0: Allow to import the exported map config
That would also open up the ability to reuse styles across projects or even on multiple datasets in the same project. You could possibly even allow for multiple datasets to be in a single layer with a single style (assuming their data structure is consistent)
-
Save map config via save map choose config only, and downlaod the config json, and store somewhere that can be accessed via url
-
Load kepler.gl/#/demo?mapConfig=http://xxxxx.xxxx.json. Load kepler.gl with a preset config (layers, filters, mapStyles etc).
3.1 The config might contain 1 dataset, in which case kepler.gl try to map layer, filter to it
3.2 The config contain 2 dataset...........
Rules to match config to data: dataset must contain field that layer column and layer color / size by are depends on. must contain fields that filters are depends on....
Currently
if you call receiveMapconfig
without data preloaded, kepler will try to match layers / filters based on dataId
, it is not finding those fieds, then it will saved the layer/filter to layersToBeMerged
filtersToBeMerged
. When you then call addDataToMap
without config. kepler will use the to be merged the ones.
For Example:
- If someone saved layer 1 -> dataset a; layer 2 -> dataset b
- upload dataset a -> kepler create layer 1. layer 2 will not be match, it will be stored as
layersToBeMerged
in visState reducer
[P0 Bug] How to draw Icon layer didn't have react
ability to add imagery tilelayers that aren't Mapbox
mapbox is great but it would be hugely beneficial if users had the option to load in WMS/WMTS imagery tilelayers as basemaps that are hosted/sold by other companies
or if you can't allow entire tilelayers to be added, consider adding single raster images, especially when users want to use kepler in disconnected environments where they woudn't have access to mapbox baselayers they could load a single raster image that is stored locally instead and still get the same effect
Exporting Config does not include all MapStyles
Exporting the configuration only includes the currently selected map style and not all other map styles that have been added to the configuration. The expectation would be for the map styles to include all configured styles, and for the mapStyle to indicate which of the styles has been selected.
To reproduce the issue, open a default kepler.gl app. It should have the standard map styles added "Dark, Light, Muted Night, Muted Light". By default the Dark style is selected. Click on the "Save / Export" button and select "Export Config". Note that the map styles are empty in the config JSON.
"mapStyle": {
"styleType": "dark",
"topLayerGroups": {},
"visibleLayerGroups": {
"label": true,
"road": true,
"border": false,
"building": true,
"water": true,
"land": true
},
"mapStyles": {}
}
The expectation would be that all the map styles are in the config:
"mapStyle": {
"styleType": "dark",
"topLayerGroups": {},
"visibleLayerGroups": {
"label": true,
"road": true,
"border": false,
"building": true,
"water": true,
"land": true
},
"mapStyles": {
"dark": {
"id": "dark",
"label": "Dark",
"icon": "...",
"url": "..."
"layerGroups": [],
},
"light": { ... },
"mutednight": { ... },
"mutedlight": { ... },
}
}
Thus using this.getMapConfig() to preserve the map configuration when loading new data means having to regenerate the mapStyles. i.e.
// Created to show how to replace dataset with new data and keeping the same configuration
replaceData = () => {
// Use processCsvData helper to convert csv file into kepler.gl structure {fields, rows}
const data = Processors.processCsvData(nycTripsSubset);
// Create dataset structure
const dataset = {
data,
info: {
id: 'my_data'
// this is used to match the dataId defined in nyc-config.json. For more details see API documentation.
// It is paramount that this id mathces your configuration otherwise the configuration file will be ignored.
}
};
// read the current configuration
const config = this.getMapConfig();
// addDataToMap action to inject dataset into kepler.gl instance
this.props.dispatch(addDataToMap({datasets: dataset, config}));
means that the config won't have the complete set of mapstyles.
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.