diff --git a/superset-frontend/temporary_superset_ui/superset-ui-plugins-deckgl/package.json b/superset-frontend/temporary_superset_ui/superset-ui-plugins-deckgl/package.json index 03b4bba1dc3fe..53c027ed9c5f1 100644 --- a/superset-frontend/temporary_superset_ui/superset-ui-plugins-deckgl/package.json +++ b/superset-frontend/temporary_superset_ui/superset-ui-plugins-deckgl/package.json @@ -40,10 +40,10 @@ "license": "Apache-2.0", "devDependencies": { "@superset-ui/build-config": "^0.1.0", - "@superset-ui/commit-config": "^0.0.9", "@superset-ui/chart": "^0.12.1", "@superset-ui/chart-composition": "^0.12.1", "@superset-ui/color": "^0.12.1", + "@superset-ui/commit-config": "^0.0.9", "@superset-ui/connection": "^0.12.0", "@superset-ui/core": "^0.12.0", "@superset-ui/dimension": "^0.12.0", @@ -59,6 +59,7 @@ "husky": "^3.0.3", "lerna": "^3.2.1", "lint-staged": "^9.2.1", + "luma.gl": "^7.3.0", "react": "^16.6.0", "react-dom": "^16.6.0", "yarn": "^1.9.4" diff --git a/superset-frontend/temporary_superset_ui/superset-ui-plugins-deckgl/packages/superset-ui-legacy-preset-chart-kepler/README.md b/superset-frontend/temporary_superset_ui/superset-ui-plugins-deckgl/packages/superset-ui-legacy-preset-chart-kepler/README.md new file mode 100644 index 0000000000000..189a81fc9021f --- /dev/null +++ b/superset-frontend/temporary_superset_ui/superset-ui-plugins-deckgl/packages/superset-ui-legacy-preset-chart-kepler/README.md @@ -0,0 +1,40 @@ +## @superset-ui/legacy-preset-chart-deckgl + +[![Version](https://img.shields.io/npm/v/@superset-ui/legacy-preset-chart-deckgl.svg?style=flat-square)](https://img.shields.io/npm/v/@superset-ui/legacy-preset-chart-deckgl.svg?style=flat-square) +[![David (path)](https://img.shields.io/david/apache-superset/superset-ui-plugins.svg?path=packages%2Fsuperset-ui-legacy-preset-chart-deckgl&style=flat-square)](https://david-dm.org/apache-superset/superset-ui-plugins?path=packages/superset-ui-legacy-preset-chart-deckgl) + +This plugin provides `deck.gl` for Superset. + +### Usage + +Import the preset and register. This will register all the chart plugins under `deck.gl`. + +```js +import { DeckGLChartPreset } from '@superset-ui/legacy-preset-chart-deckgl'; + +new DeckGLChartPreset().register(); +``` + +or register charts one by one. Configure `key`, which can be any `string`, and register the plugin. This `key` will be used to lookup this chart throughout the app. + +```js +import { ArcChartPlugin } from '@superset-ui/legacy-preset-chart-deckgl'; + +new ArcChartPlugin() + .configure({ key: 'deck_arc' }) + .register(); +``` + +Then use it via `SuperChart`. See [storybook](https://apache-superset.github.io/superset-ui-plugins-deckgl) for more details. + +```js + +``` diff --git a/superset-frontend/temporary_superset_ui/superset-ui-plugins-deckgl/packages/superset-ui-legacy-preset-chart-kepler/package.json b/superset-frontend/temporary_superset_ui/superset-ui-plugins-deckgl/packages/superset-ui-legacy-preset-chart-kepler/package.json new file mode 100644 index 0000000000000..3ca94f6830000 --- /dev/null +++ b/superset-frontend/temporary_superset_ui/superset-ui-plugins-deckgl/packages/superset-ui-legacy-preset-chart-kepler/package.json @@ -0,0 +1,49 @@ +{ + "name": "@superset-ui/legacy-preset-chart-kepler", + "version": "0.1.0", + "description": "Superset Chart - kerpler.gl", + "sideEffects": true, + "main": "lib/index.js", + "module": "esm/index.js", + "files": [ + "esm", + "lib" + ], + "repository": { + "type": "git", + "url": "git+https://github.com/apache-superset/superset-ui-plugins-deckgl.git" + }, + "keywords": [ + "superset" + ], + "author": "Superset", + "license": "Apache-2.0", + "bugs": { + "url": "https://github.com/apache-superset/superset-ui-plugins-deckgl/issues" + }, + "homepage": "https://github.com/apache-superset/superset-ui-plugins-deckgl#readme", + "publishConfig": { + "access": "public" + }, + "dependencies": { + "kepler.gl": "1.1.8", + "lodash": "^4.17.15", + "mapbox-gl": "^0.53.0", + "prop-types": "^15.6.0", + "react-palm": "^3.1.2", + "shortid": "^2.2.15", + "styled-components": "^4.4.0", + "viewport-mercator-project": "^6.1.1" + }, + "peerDependencies": { + "@superset-ui/chart": "^0.12.0", + "@superset-ui/color": "^0.12.0", + "@superset-ui/connection": "^0.12.0", + "@superset-ui/core": "^0.12.0", + "@superset-ui/dimension": "^0.12.0", + "@superset-ui/number-format": "^0.12.0", + "@superset-ui/time-format": "^0.12.0", + "@superset-ui/translation": "^0.12.0", + "react": "^15 || ^16" + } +} diff --git a/superset-frontend/temporary_superset_ui/superset-ui-plugins-deckgl/packages/superset-ui-legacy-preset-chart-kepler/src/Kepler.css b/superset-frontend/temporary_superset_ui/superset-ui-plugins-deckgl/packages/superset-ui-legacy-preset-chart-kepler/src/Kepler.css new file mode 100644 index 0000000000000..0eb74534ae52d --- /dev/null +++ b/superset-frontend/temporary_superset_ui/superset-ui-plugins-deckgl/packages/superset-ui-legacy-preset-chart-kepler/src/Kepler.css @@ -0,0 +1,20 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +.kepler { +} diff --git a/superset-frontend/temporary_superset_ui/superset-ui-plugins-deckgl/packages/superset-ui-legacy-preset-chart-kepler/src/Kepler.jsx b/superset-frontend/temporary_superset_ui/superset-ui-plugins-deckgl/packages/superset-ui-legacy-preset-chart-kepler/src/Kepler.jsx new file mode 100644 index 0000000000000..a2aa492b6433d --- /dev/null +++ b/superset-frontend/temporary_superset_ui/superset-ui-plugins-deckgl/packages/superset-ui-legacy-preset-chart-kepler/src/Kepler.jsx @@ -0,0 +1,150 @@ +/* eslint-disable import/no-extraneous-dependencies */ +/* eslint-disable prefer-destructuring */ +/* eslint-disable react/destructuring-assignment */ +/* eslint-disable react/jsx-handler-names */ +/* eslint-disable react/no-deprecated */ +/* eslint-disable no-negated-condition */ +/* eslint-disable react/prop-types */ +/* eslint-disable react/require-default-props */ +/* eslint-disable sort-keys */ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +import React from 'react'; +import { connect, Provider } from 'react-redux'; +import PropTypes from 'prop-types'; +import KeplerGl from 'kepler.gl'; +import KeplerGlSchema from 'kepler.gl/schemas'; +import { addDataToMap } from 'kepler.gl/actions'; +import Processors from 'kepler.gl/processors'; +import shortid from 'shortid'; + +import getKeplerStore from './store'; +import './Kepler.css'; + +const propTypes = { + height: PropTypes.number, + setControlValue: PropTypes.func, + readonly: PropTypes.boolean, +}; + +class Kepler extends React.PureComponent { + constructor(props) { + super(props); + this.setMapConfig = this.setMapConfig.bind(this); + this.state = { + keplerId: shortid.generate(), + }; + } + + componentDidMount() { + this.addDataToMap(this.props); + this.setMapConfig(); + } + + componentWillReceiveProps(nextProps) { + if (nextProps.features !== this.props.features) { + this.addDataToMap(nextProps, false); + this.setMapConfig(); + } + } + + getCurrentConfig() { + try { + const { keplerGl } = this.props; + + return KeplerGlSchema.getConfigToSave(keplerGl[this.state.keplerId]); + } catch (e) { + return null; + } + } + + setMapConfig() { + const { setControlValue } = this.props; + const config = this.getCurrentConfig(); + if (config) { + setControlValue('config', JSON.stringify(this.getCurrentConfig(), null, 2)); + } + } + + addDataToMap(props, useControlConfig = true) { + let config = props.config; + if (!config) { + config = {}; + } else { + config = useControlConfig ? JSON.parse(config) : this.getCurrentConfig(); + } + const data = Processors.processRowObject(props.features); + const datasets = [ + { + data, + info: { + id: 'main', + label: 'Superset Data', + }, + }, + ]; + const options = { readOnly: this.props.readonly }; + if (this.props.autozoom) { + options.centerMap = true; + if (config && config.config) { + config.config.mapState = {}; + } + } + props.dispatch(addDataToMap({ datasets, config, options })); + } + + render() { + return ( +
+ +
+ ); + } +} + +Kepler.displayName = 'Kepler'; +Kepler.propTypes = propTypes; + +const mapStateToProps = state => ({ keplerGl: state.keplerGl }); +const dispatchToProps = dispatch => ({ dispatch }); +const KeplerConnected = connect( + mapStateToProps, + dispatchToProps, +)(Kepler); + +// eslint-disable-next-line react/no-multi-comp +export default class SubApp extends React.Component { + constructor(props) { + super(props); + this.store = getKeplerStore(props.setControlValue); + } + + render() { + return ( + + + + ); + } +} diff --git a/superset-frontend/temporary_superset_ui/superset-ui-plugins-deckgl/packages/superset-ui-legacy-preset-chart-kepler/src/KeplerChartPlugin.js b/superset-frontend/temporary_superset_ui/superset-ui-plugins-deckgl/packages/superset-ui-legacy-preset-chart-kepler/src/KeplerChartPlugin.js new file mode 100644 index 0000000000000..a33e97404bef1 --- /dev/null +++ b/superset-frontend/temporary_superset_ui/superset-ui-plugins-deckgl/packages/superset-ui-legacy-preset-chart-kepler/src/KeplerChartPlugin.js @@ -0,0 +1,40 @@ +/* eslint-disable sort-keys */ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +import { t } from '@superset-ui/translation'; +import { ChartMetadata, ChartPlugin } from '@superset-ui/chart'; +import transformProps from './transformProps'; +import thumbnail from './images/thumbnail.png'; + +const metadata = new ChartMetadata({ + name: t('Kepler.gl'), + description: '', + credits: ['https://github.com/uber/kepler.gl'], + thumbnail, +}); + +export default class KeplerChartPlugin extends ChartPlugin { + constructor() { + super({ + metadata, + transformProps, + loadChart: () => import('./Kepler'), + }); + } +} diff --git a/superset-frontend/temporary_superset_ui/superset-ui-plugins-deckgl/packages/superset-ui-legacy-preset-chart-kepler/src/images/thumbnail.png b/superset-frontend/temporary_superset_ui/superset-ui-plugins-deckgl/packages/superset-ui-legacy-preset-chart-kepler/src/images/thumbnail.png new file mode 100644 index 0000000000000..1be1622647513 Binary files /dev/null and b/superset-frontend/temporary_superset_ui/superset-ui-plugins-deckgl/packages/superset-ui-legacy-preset-chart-kepler/src/images/thumbnail.png differ diff --git a/superset-frontend/temporary_superset_ui/superset-ui-plugins-deckgl/packages/superset-ui-legacy-preset-chart-kepler/src/images/thumbnailLarge.png b/superset-frontend/temporary_superset_ui/superset-ui-plugins-deckgl/packages/superset-ui-legacy-preset-chart-kepler/src/images/thumbnailLarge.png new file mode 100644 index 0000000000000..b5ca42daff03b Binary files /dev/null and b/superset-frontend/temporary_superset_ui/superset-ui-plugins-deckgl/packages/superset-ui-legacy-preset-chart-kepler/src/images/thumbnailLarge.png differ diff --git a/superset-frontend/temporary_superset_ui/superset-ui-plugins-deckgl/packages/superset-ui-legacy-preset-chart-kepler/src/index.js b/superset-frontend/temporary_superset_ui/superset-ui-plugins-deckgl/packages/superset-ui-legacy-preset-chart-kepler/src/index.js new file mode 100644 index 0000000000000..072a7e0087421 --- /dev/null +++ b/superset-frontend/temporary_superset_ui/superset-ui-plugins-deckgl/packages/superset-ui-legacy-preset-chart-kepler/src/index.js @@ -0,0 +1,2 @@ +export { default as KeplerChartPreset } from './preset'; +export { default as KeplerChartPlugin } from './KeplerChartPlugin'; diff --git a/superset-frontend/temporary_superset_ui/superset-ui-plugins-deckgl/packages/superset-ui-legacy-preset-chart-kepler/src/preset.js b/superset-frontend/temporary_superset_ui/superset-ui-plugins-deckgl/packages/superset-ui-legacy-preset-chart-kepler/src/preset.js new file mode 100644 index 0000000000000..9d9be9e024827 --- /dev/null +++ b/superset-frontend/temporary_superset_ui/superset-ui-plugins-deckgl/packages/superset-ui-legacy-preset-chart-kepler/src/preset.js @@ -0,0 +1,29 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +import { Preset } from '@superset-ui/core'; +import KeplerChartPlugin from './KeplerChartPlugin'; + +export default class KeplerChartPreset extends Preset { + constructor() { + super({ + name: 'Kepler charts', + plugins: [new KeplerChartPlugin().configure({ key: 'kepler' })], + }); + } +} diff --git a/superset-frontend/temporary_superset_ui/superset-ui-plugins-deckgl/packages/superset-ui-legacy-preset-chart-kepler/src/store.js b/superset-frontend/temporary_superset_ui/superset-ui-plugins-deckgl/packages/superset-ui-legacy-preset-chart-kepler/src/store.js new file mode 100644 index 0000000000000..acbf4d017c20c --- /dev/null +++ b/superset-frontend/temporary_superset_ui/superset-ui-plugins-deckgl/packages/superset-ui-legacy-preset-chart-kepler/src/store.js @@ -0,0 +1,86 @@ +/* eslint-disable babel/new-cap */ +/* eslint-disable babel/no-invalid-this */ +/* eslint-disable compat/compat */ +/* eslint-disable import/no-extraneous-dependencies */ +/* eslint-disable no-magic-numbers */ +/* eslint-disable sort-keys */ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +import { createStore, combineReducers, applyMiddleware, compose } from 'redux'; +import keplerGlReducer from 'kepler.gl/reducers'; +import KeplerGlSchema from 'kepler.gl/schemas'; +import { taskMiddleware } from 'react-palm/tasks'; + +let previousValue = null; + +// Rates limit and only runs the latest call +function RateLimit(fn, delay, context) { + let latestCall = null; + let timer = null; + + function processLatestCall() { + if (latestCall) { + fn.apply(latestCall.context, latestCall.arguments); + clearInterval(timer); + timer = null; + } + } + + return function limited(...args) { + latestCall = { + context: context || this, + arguments: [].slice.call(args), + }; + if (timer) { + clearInterval(timer); + } + timer = setInterval(processLatestCall, delay); + }; +} + +function updateConfigControl(store, setControlValue) { + const keplerState = Object.values(store.getState().keplerGl)[0]; + const stateToSave = KeplerGlSchema.getConfigToSave(keplerState); + const config = JSON.stringify(stateToSave, null, 2); + if (previousValue !== config) { + setControlValue('config', config); + previousValue = config; + } +} +const rateLimitedUpdateConfigControl = RateLimit(updateConfigControl, 1000); + +export default function getKeplerStore(setControlValue) { + // Using react-palm middleware to intercept changes and + // save the state into the config control as text + const stateChangeMiddleware = store => next => action => { + const returnValue = next(action); + rateLimitedUpdateConfigControl(store, setControlValue); + + return returnValue; + }; + const reducers = combineReducers({ + keplerGl: keplerGlReducer, + readonly: false, + }); + const middlewares = [taskMiddleware, stateChangeMiddleware]; + const enhancers = [applyMiddleware(...middlewares)]; + const store = createStore(reducers, {}, compose(...enhancers)); + + return store; +} diff --git a/superset-frontend/temporary_superset_ui/superset-ui-plugins-deckgl/packages/superset-ui-legacy-preset-chart-kepler/src/transformProps.js b/superset-frontend/temporary_superset_ui/superset-ui-plugins-deckgl/packages/superset-ui-legacy-preset-chart-kepler/src/transformProps.js new file mode 100644 index 0000000000000..1375072c777c0 --- /dev/null +++ b/superset-frontend/temporary_superset_ui/superset-ui-plugins-deckgl/packages/superset-ui-legacy-preset-chart-kepler/src/transformProps.js @@ -0,0 +1,35 @@ +/* eslint-disable sort-keys */ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +export default function transformProps(chartProps) { + const { formData, height, width, queryData, hooks } = chartProps; + const { mapboxApiAccessToken, features } = queryData.data; + const { config, autozoom, readonly } = formData; + + return { + height, + width, + config, + autozoom, + readonly, + features, + setControlValue: hooks.setControlValue, + mapboxApiAccessToken, + }; +}