I am following an example provided on the deck.gl github repository that displays polygons from a geojson.
I've since changed the initial focus of the map and provided my own geojson to visualise, the data I've replaced the examples with has a temporal component that I'd like to visualise via the manipulation of a range input.
Example GeoJSON Structure
{
"type": "FeatureCollection",
"name": "RandomData",
"crs": { "type": "name", "properties": { "name": "urn:ogc:def:crs:OGC:1.3:CRS84" } },
"features": [
{ "type": "Feature",
"properties": { "id": 1,"hr00": 10000, "hr01": 12000, "hr02": 12000, "hr03": 30000, "hr04": 40000, "hr05": 10500, "hr06": 50000}, "geometry": { "type": "Polygon", "coordinates": [ [ [ 103.73992, 1.15903 ], [ 103.74048, 1.15935 ], [ 103.74104, 1.15903 ], [ 103.74104, 1.15837 ], [ 103.74048, 1.15805 ], [ 103.73992, 1.15837 ], [ 103.73992, 1.15903 ] ] ] } } ] }
Instead of repeating each geometry for every timepoint I've shifted the temporal aspect of the data to the properties. This makes the file size manageable on the complete dataset (~50mb versus ~500mb).
For visualising a single time point I know that I can provide the property to getElevation
and getFillColor
.
_renderLayers() {
const {data = DATA_URL} = this.props;
return [
new GeoJsonLayer({
id: 'geojson',
data,
opacity: 0.8,
stroked: false,
filled: true,
extruded: true,
wireframe: true,
fp64: true,
getElevation: f => f.properties.hr00,
getFillColor: f => COLOR_SCALE(f.properties.hr00),
getLineColor: [255, 255, 255],
lightSettings: LIGHT_SETTINGS,
pickable: true,
onHover: this._onHover,
transitions: {
duration: 300
}
})
];
}
So I went ahead and used range.slider, adding code to my app.js
, this following snippet was added. I believe I also may be placing this in the wrong location, should this exist in render()
?
import ionRangeSlider from 'ion-rangeslider';
// Code for slider input
$("#slider").ionRangeSlider({
min: 0,
max: 24,
from: 12,
step: 1,
grid: true,
grid_num: 1,
grid_snap: true
});
$(".js-range-slider").ionRangeSlider();
added to my index.html
<input type="text" id="slider" class="js-range-slider" name="my_range" value=""/>
So how can I have the slider change which property of my geojson is being supplied to getElevation
and getFillColor
?
My JavaScript/JQuery is lacking and I have been unable to find any clear examples of how to change the data property based on the input, any help is greatly appreciated.
Here is a codesandbox link - doesn't seem to like it there however.
Locally with npm install
and npm start
should have it behave as intended.
At first you'll need to tell your dependent accessors about the value that is going to be changed by the slider. This can be done by using updateTriggers
:
_renderLayers() {
const { data = DATA_URL } = this.props;
return [
new GeoJsonLayer({
// ...
getElevation: f => f.properties[this.state.geoJsonValue],
getFillColor: f => COLOR_SCALE(f.properties[this.state.geoJsonValue]),
updateTriggers: {
getElevation: [this.state.geoJsonValue],
getFillColor: [this.state.geoJsonValue]
}
// ...
})
];
}
And to actually change this value using range-slider you need to add onChange
callback during the initialization:
constructor(props) {
super(props);
this.state = { hoveredObject: null, geoJsonValue: "hr01" };
this.sliderRef = React.createRef();
this._handleChange = this._handleChange.bind(this);
// ...
}
componentDidMount() {
// Code for slider input
$(this.sliderRef.current).ionRangeSlider({
// ...
onChange: this._handleChange
});
}
_handleChange(data) {
this.setState({
geoJsonValue: `hr0${data.from}`
});
}
render() {
...
<DeckGL ...>
...
</DeckGL>
<div id="sliderstyle">
<input
ref={this.sliderRef}
id="slider"
className="js-range-slider"
name="my_range"
/>
</div>
...
}
And this is basically it. And here is the full code
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With