forked from visgl/deck.gl
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add contour layer example in website folder
- Loading branch information
Showing
8 changed files
with
373 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
This is a minimal standalone version of the ContourLayer example | ||
on [deck.gl](http://deck.gl) website. | ||
|
||
### Usage | ||
|
||
Copy the content of this folder to your project. | ||
|
||
To see the base map, you need a [Mapbox access token](https://docs.mapbox.com/help/how-mapbox-works/access-tokens/). You can either set an environment variable: | ||
|
||
```bash | ||
export MapboxAccessToken=<mapbox_access_token> | ||
``` | ||
|
||
Or set `MAPBOX_TOKEN` directly in `app.js`. | ||
|
||
Other options can be found at [using with Mapbox GL](../../../docs/get-started/using-with-map.md). | ||
|
||
```bash | ||
# install dependencies | ||
npm install | ||
# or | ||
yarn | ||
# bundle and serve the app with webpack | ||
npm start | ||
``` | ||
|
||
### Data format | ||
|
||
Sample data is stored in [deck.gl Example Data](https://github.com/uber-common/deck.gl-data/tree/master/examples/3d-heatmap). To use your own data, checkout | ||
the [documentation of ContourLayer](../../../docs/layers/contour-layer.md). |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
body { | ||
margin: 0; | ||
font-family: sans-serif; | ||
width: 100vw; | ||
height: 100vh; | ||
overflow: hidden; | ||
} | ||
#control-panel { | ||
position: fixed; | ||
z-index: 9; | ||
top: 25px; | ||
right: 25px; | ||
overflow-x: hidden; | ||
overflow-y: auto; | ||
width: 280px; | ||
background: white; | ||
padding: 20px; | ||
} | ||
.input-label { | ||
padding-right: 25px; | ||
} | ||
.input-group { | ||
line-height: 40px; | ||
} | ||
.radio { | ||
height: 20px; | ||
width: 20px; | ||
text-align: center; | ||
} | ||
.radio-label { | ||
top: -5px; | ||
position: relative; | ||
padding-right: 25px; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,128 @@ | ||
import React, {PureComponent, Fragment} from 'react'; | ||
import {render} from 'react-dom'; | ||
import {StaticMap} from 'react-map-gl'; | ||
import {ContourLayer} from '@deck.gl/aggregation-layers'; | ||
import DeckGL from '@deck.gl/react'; | ||
import RangeSlider from './rangeSlider'; | ||
|
||
// Set your mapbox token here | ||
const MAPBOX_TOKEN = process.env.MapboxAccessToken; // eslint-disable-line | ||
|
||
// Source data CSV | ||
const DATA_URL = | ||
'https://raw.githubusercontent.com/uber-common/deck.gl-data/master/examples/3d-heatmap/heatmap-data.csv'; // eslint-disable-line | ||
|
||
const INITIAL_VIEW_STATE = { | ||
longitude: -1.4157267858730052, | ||
latitude: 52.232395363869415, | ||
zoom: 6.6, | ||
minZoom: 5, | ||
maxZoom: 15, | ||
pitch: 40.5, | ||
bearing: -27.396674584323023 | ||
}; | ||
|
||
const THRESHOLD = { | ||
MIN: 1, | ||
MAX: 500 | ||
}; | ||
|
||
export class App extends PureComponent { | ||
constructor(props) { | ||
super(props); | ||
this.state = { | ||
thresholdValue1: 100, | ||
thresholdValue2: 300, | ||
cellSize: 1000 | ||
}; | ||
this.onCellSizeChange = this.onCellSizeChange.bind(this); | ||
this.onThresholdChange = this.onThresholdChange.bind(this); | ||
} | ||
|
||
onThresholdChange(thresholdValue1, thresholdValue2) { | ||
this.setState({ | ||
thresholdValue1, | ||
thresholdValue2 | ||
}); | ||
} | ||
|
||
onCellSizeChange(event) { | ||
const cellSize = event.target.value; | ||
this.setState({cellSize}); | ||
} | ||
|
||
_renderLayers() { | ||
const {data} = this.props; | ||
const {thresholdValue1, thresholdValue2, cellSize} = this.state; | ||
return [ | ||
new ContourLayer({ | ||
id: 'contourlayer', | ||
data, | ||
getPosition: d => d, | ||
contours: [ | ||
{threshold: [THRESHOLD.MIN, thresholdValue1], color: [255, 255, 178]}, | ||
{threshold: [thresholdValue1, thresholdValue2], color: [253, 141, 60]}, | ||
{threshold: [thresholdValue2, THRESHOLD.MAX], color: [189, 0, 38]} | ||
], | ||
cellSize | ||
}) | ||
]; | ||
} | ||
|
||
render() { | ||
const {mapStyle = 'mapbox://styles/mapbox/dark-v9'} = this.props; | ||
return ( | ||
<Fragment> | ||
<DeckGL | ||
layers={this._renderLayers()} | ||
initialViewState={INITIAL_VIEW_STATE} | ||
controller={true} | ||
> | ||
<StaticMap | ||
reuseMaps | ||
mapStyle={mapStyle} | ||
preventStyleDiffing={true} | ||
mapboxApiAccessToken={MAPBOX_TOKEN} | ||
/> | ||
</DeckGL> | ||
<div id="control-panel"> | ||
<div className="input-group"> | ||
<label className="input-label">Threshold</label> | ||
<RangeSlider | ||
handleChange={this.onThresholdChange} | ||
range={[THRESHOLD.MIN, THRESHOLD.MAX]} | ||
defaultMin={this.state.thresholdValue1} | ||
defaultMax={this.state.thresholdValue2} | ||
/> | ||
</div> | ||
<div className="input-group"> | ||
<label className="input-label" style={{marginRight: '15px'}}> | ||
cellSize | ||
</label> | ||
<input | ||
style={{width: '180px'}} | ||
id="cellSize" | ||
type="range" | ||
min="100" | ||
max="2000" | ||
step="100" | ||
value={this.state.cellSize} | ||
onChange={this.onCellSizeChange} | ||
/> | ||
</div> | ||
</div> | ||
</Fragment> | ||
); | ||
} | ||
} | ||
|
||
export function renderToDOM(container) { | ||
render(<App />, container); | ||
|
||
require('d3-request').csv(DATA_URL, (error, response) => { | ||
if (!error) { | ||
const data = response.map(d => [Number(d.lng), Number(d.lat)]); | ||
render(<App data={data} />, container); | ||
} | ||
}); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
<!DOCTYPE html> | ||
<html lang="en"> | ||
<head> | ||
<meta charset="utf-8" /> | ||
<title>deck.gl Example</title> | ||
<meta name="viewport" content="width=device-width, initial-scale=1" /> | ||
<link href="app.css" rel="stylesheet" /> | ||
<link href="rangeSlider.css" rel="stylesheet" /> | ||
</head> | ||
<body> | ||
<div id="app"></div> | ||
</body> | ||
<script type="text/javascript" src="app.js"></script> | ||
<script type="text/javascript"> | ||
App.renderToDOM(document.getElementById('app')); | ||
</script> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
{ | ||
"name": "contour", | ||
"version": "0.0.0", | ||
"license": "MIT", | ||
"scripts": { | ||
"start-local": "webpack-dev-server --env.local --progress --hot --open", | ||
"start": "webpack-dev-server --progress --hot --open" | ||
}, | ||
"dependencies": { | ||
"d3-request": "^1.0.5", | ||
"deck.gl": "^7.1.0", | ||
"react": "^16.3.0", | ||
"react-dom": "^16.3.0", | ||
"react-map-gl": "^5.0.0" | ||
}, | ||
"devDependencies": { | ||
"@babel/core": "^7.4.0", | ||
"@babel/preset-react": "^7.0.0", | ||
"babel-loader": "^8.0.5", | ||
"webpack": "^4.20.2", | ||
"webpack-cli": "^3.1.2", | ||
"webpack-dev-server": "^3.7.2" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
.rangeslider input[type='range'] { | ||
width: 180px; | ||
height: 30px; | ||
overflow: hidden; | ||
cursor: pointer; | ||
outline: none; | ||
} | ||
.rangeslider input[type='range'], | ||
.rangeslider input[type='range']::-webkit-slider-runnable-track, | ||
.rangeslider input[type='range']::-webkit-slider-thumb { | ||
background: none; | ||
} | ||
|
||
.rangeslider input[type='range']::-webkit-slider-thumb { | ||
position: relative; | ||
z-index: 1; | ||
} | ||
|
||
.rangeslider input[type='range']:nth-child(1)::-webkit-slider-thumb { | ||
z-index: 2; | ||
} | ||
|
||
.rangeslider { | ||
position: relative; | ||
height: 30px; | ||
width: 180px; | ||
display: inline-block; | ||
} | ||
.rangeslider input { | ||
position: absolute; | ||
} | ||
|
||
.rangeslider span { | ||
position: absolute; | ||
margin-top: 30px; | ||
left: 0; | ||
} | ||
|
||
.rangeslider .right { | ||
position: relative; | ||
float: right; | ||
margin-right: -5px; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
import React, {Fragment, Component} from 'react'; | ||
|
||
class RangeSlider extends Component { | ||
constructor(props) { | ||
super(props); | ||
this.state = { | ||
minValue: this.props.defaultMin || this.props.range[0], | ||
maxValue: this.props.defaultMax || this.props.range[1] | ||
}; | ||
this.handleRangeChange = this.handleRangeChange.bind(this); | ||
} | ||
|
||
handleRangeChange(event) { | ||
const rangeInputId = event.target.id; | ||
const value = parseInt(event.target.value, 10); | ||
if (rangeInputId === 'min' && value < this.state.maxValue) { | ||
this.setState({minValue: value}, () => { | ||
this.props.handleChange(this.state.minValue, this.state.maxValue); | ||
}); | ||
} else if (rangeInputId === 'max' && value > this.state.minValue) { | ||
this.setState({maxValue: value}, () => { | ||
this.props.handleChange(this.state.minValue, this.state.maxValue); | ||
}); | ||
} | ||
} | ||
|
||
render() { | ||
const {range, step} = this.props; | ||
return ( | ||
<Fragment> | ||
<div className="rangeslider"> | ||
<input | ||
id="min" | ||
className="min" | ||
name="range_1" | ||
type="range" | ||
min={range[0]} | ||
max={range[1]} | ||
step={step} | ||
value={this.state.minValue} | ||
onChange={this.handleRangeChange} | ||
/> | ||
<input | ||
id="max" | ||
className="max" | ||
name="range_2" | ||
type="range" | ||
min={range[0]} | ||
max={range[1]} | ||
step={step} | ||
value={this.state.maxValue} | ||
onChange={this.handleRangeChange} | ||
/> | ||
</div> | ||
</Fragment> | ||
); | ||
} | ||
} | ||
|
||
export default RangeSlider; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
// NOTE: To use this example standalone (e.g. outside of deck.gl repo) | ||
// delete the local development overrides at the bottom of this file | ||
|
||
const webpack = require('webpack'); | ||
|
||
const CONFIG = { | ||
mode: 'development', | ||
|
||
entry: { | ||
app: './app.js' | ||
}, | ||
|
||
output: { | ||
library: 'App' | ||
}, | ||
|
||
module: { | ||
rules: [ | ||
{ | ||
// Transpile ES6 to ES5 with babel | ||
// Remove if your app does not use JSX or you don't need to support old browsers | ||
test: /\.js$/, | ||
loader: 'babel-loader', | ||
exclude: [/node_modules/], | ||
options: { | ||
presets: ['@babel/preset-react'] | ||
} | ||
} | ||
] | ||
}, | ||
|
||
// Optional: Enables reading mapbox token from environment variable | ||
plugins: [new webpack.EnvironmentPlugin(['MapboxAccessToken'])] | ||
}; | ||
|
||
// This line enables bundling against src in this repo rather than installed module | ||
module.exports = env => (env ? require('../webpack.config.local')(CONFIG)(env) : CONFIG); |