Reputation: 397
I've run into an impasse in deck.gl and would hope you can help me out guys. I haven´t been able to understand how you display the properties of the bars in the hexagonLayer example that is displayed in the deck.gl official webpage: https://uber.github.io/deck.gl/#/examples/core-layers/hexagon-layer. The example that is available in GitHub doesn't have this functionality and the browser layer is a too intricate to for me. I tried incorporating the layer-info component that is embedded in the layer-browser example, but I don´t understand what is (info), and I keep getting this error :
"Module parse failed: You may need an appropriate loader to handle this file type.
Thank you very much for your time! I'm a newbie in react! I'm sorry if it's trivial.
App.js
import React, {Component} from 'react';
import {render} from 'react-dom';
import MapGL from 'react-map-gl';
import DeckGLOverlay from './deckgl-overlay.js';
import Controls from './components/controls';
import {csv as requestCsv} from 'd3-request';
import LayerInfo from './components/layer-info';
// Set your mapbox token here
const MAPBOX_TOKEN =MBToken
// 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
class Root extends Component {
constructor(props) {
super(props);
this.state = {
datad: {
package: 'react-dat-gui',
radius: 1100,
isAwesome: true,
feelsLike: '#2FA1D6',
},
viewport: {
...DeckGLOverlay.defaultViewport,
width: 500,
height: 500
},
data: null,
hoveredItem: null,
clickedItem: null,
queriedItems: null
};
requestCsv(DATA_URL, (error, response) => {
if (!error) {
const data = response.map(d => [Number(d.lng), Number(d.lat)]);
this.setState({data});
}
});
}
componentDidMount() {
window.addEventListener('resize', this._resize.bind(this));
this._resize();
}
_resize() {
this._onViewportChange({
width: window.innerWidth,
height: window.innerHeight
});
}
_onViewportChange(viewport) {
this.setState({
viewport: {...this.state.viewport, ...viewport}
});
}
onParentUpdate(datad) {
this.setState({ datad });
}
onHover(info) {
this.setState({hoveredItem: info});
}
render() {
const {viewport, datad, data} = this.state;
return (
<div>
<MapGL
{...viewport}
mapStyle="mapbox://styles/mapbox/dark-v9"
onViewportChange={this._onViewportChange.bind(this)}
mapboxApiAccessToken={MAPBOX_TOKEN}
>
<DeckGLOverlay viewport={viewport}
data={data || [] }
datad = {this.state.datad }
onLayerHover= {this.onHover}
/>
</MapGL>
<Controls
onUpdate = {(datad) => this.onParentUpdate(datad)}
datad = {this.state.datad}
/>
<LayerInfo
hovered={hoveredItem}
/>
</div>
);
}
}
render(<Root />, document.body.appendChild(document.createElement('div')));
layer-info.js
import React, {PureComponent} from 'react';
export default class LayerInfo extends PureComponent {
_infoToString(info) {
const object = info.feature || info.object;
if (!object) {
return 'None';
}
const props = object.properties || object;
return JSON.stringify(props);
}
render() {
const {hovered, clicked, queried} = this.props;
return (
<div>
{hovered && (
<div>
<h4>Hover</h4>
<span>
Layer: {hovered.layer.id} Object: {this._infoToString(hovered)}
</span>
</div>
)}
</div>
);
}
}
deckgl-overlay.js
import React, {Component} from 'react';
import {render} from 'react-dom';
import MapGL from 'react-map-gl';
import DeckGLOverlay from './deckgl-overlay.js';
import Controls from './components/controls';
import {csv as requestCsv} from 'd3-request';
import LayerInfo from './components/layer-info';
// Set your mapbox token here
const MAPBOX_TOKEN = MBToken; // 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
class Root extends Component {
constructor(props) {
super(props);
this.state = {
datad: {
package: 'react-dat-gui',
radius: 1100,
isAwesome: true,
feelsLike: '#2FA1D6',
},
viewport: {
...DeckGLOverlay.defaultViewport,
width: 500,
height: 500
},
data: null,
hoveredItem: null,
clickedItem: null,
queriedItems: null
};
requestCsv(DATA_URL, (error, response) => {
if (!error) {
const data = response.map(d => [Number(d.lng), Number(d.lat)]);
this.setState({data});
}
});
}
componentDidMount() {
window.addEventListener('resize', this._resize.bind(this));
this._resize();
}
_resize() {
this._onViewportChange({
width: window.innerWidth,
height: window.innerHeight
});
}
_onViewportChange(viewport) {
this.setState({
viewport: {...this.state.viewport, ...viewport}
});
}
onParentUpdate(datad) {
this.setState({ datad });
}
onHover(info) {
this.setState({hoveredItem: info});
}
render() {
const {viewport, datad, data} = this.state;
return (
<div>
<MapGL
{...viewport}
mapStyle="mapbox://styles/mapbox/dark-v9"
onViewportChange={this._onViewportChange.bind(this)}
mapboxApiAccessToken={MAPBOX_TOKEN}
>
<DeckGLOverlay viewport={viewport}
data={data || [] }
datad = {this.state.datad }
onLayerHover= {this.onHover}
/>
</MapGL>
<Controls
onUpdate = {(datad) => this.onParentUpdate(datad)}
datad = {this.state.datad}
/>
<LayerInfo
hovered={hoveredItem}
/>
</div>
);
}
}
render(<Root />, document.body.appendChild(document.createElement('div')));
update: I now get another error "Uncaught ReferenceError: hoveredItem is not defined"
Upvotes: 0
Views: 4906
Reputation: 1542
In deckgl-overlay.js
in the render method, you pass hoveredItem
to the LayerInfo but there is no definition for it thus the Uncaught ReferenceError
.
As it seems to be stored in the component state, you should define it at the top of the render method like this:
const {viewport, datad, data, hoveredItem} = this.state;
Upvotes: 2