-
Notifications
You must be signed in to change notification settings - Fork 2.1k
/
deckgl-overlay.js
129 lines (108 loc) · 2.77 KB
/
deckgl-overlay.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
/* global window */
import React, {Component} from 'react';
import DeckGL, {HexagonLayer} from 'deck.gl';
const LIGHT_SETTINGS = {
lightsPosition: [-0.144528, 49.739968, 8000, -3.807751, 54.104682, 8000],
ambientRatio: 0.4,
diffuseRatio: 0.6,
specularRatio: 0.2,
lightsStrength: [0.8, 0.0, 0.8, 0.0],
numberOfLights: 2
};
const colorRange = [
[1, 152, 189],
[73, 227, 206],
[216, 254, 181],
[254, 237, 177],
[254, 173, 84],
[209, 55, 78]
];
const elevationScale = {min: 1, max: 50};
const defaultProps = {
radius: 1000,
upperPercentile: 100,
coverage: 1
};
export default class DeckGLOverlay extends Component {
static get defaultColorRange() {
return colorRange;
}
static get defaultViewport() {
return {
longitude: -1.4157267858730052,
latitude: 52.232395363869415,
zoom: 6.6,
minZoom: 5,
maxZoom: 15,
pitch: 40.5,
bearing: -27.396674584323023
};
}
constructor(props) {
super(props);
this.startAnimationTimer = null;
this.intervalTimer = null;
this.state = {
elevationScale: elevationScale.min
};
this._startAnimate = this._startAnimate.bind(this);
this._animateHeight = this._animateHeight.bind(this);
}
componentDidMount() {
this._animate();
}
componentWillReceiveProps(nextProps) {
if (nextProps.data.length !== this.props.data.length) {
this._animate();
}
}
componentWillUnmount() {
this._stopAnimate();
}
_animate() {
this._stopAnimate();
// wait 1.5 secs to start animation so that all data are loaded
this.startAnimationTimer = window.setTimeout(this._startAnimate, 1500);
}
_startAnimate() {
this.intervalTimer = window.setInterval(this._animateHeight, 20);
}
_stopAnimate() {
window.clearTimeout(this.startAnimationTimer);
window.clearTimeout(this.intervalTimer);
}
_animateHeight() {
if (this.state.elevationScale === elevationScale.max) {
this._stopAnimate();
} else {
this.setState({elevationScale: this.state.elevationScale + 1});
}
}
render() {
const {viewport, data, radius, coverage, upperPercentile} = this.props;
if (!data) {
return null;
}
const layers = [
new HexagonLayer({
id: 'heatmap',
colorRange,
coverage,
data,
elevationRange: [0, 3000],
elevationScale: this.state.elevationScale,
extruded: true,
getPosition: d => d,
lightSettings: LIGHT_SETTINGS,
onHover: this.props.onHover,
opacity: 1,
pickable: Boolean(this.props.onHover),
radius,
upperPercentile
})
];
return <DeckGL {...viewport} layers={layers} />;
}
}
DeckGLOverlay.displayName = 'DeckGLOverlay';
DeckGLOverlay.defaultProps = defaultProps;