Настраивать:
Приложение Basic React с использованием react-map-gl для отображения карты с Deck.gl ScatterplotLayer поверх для визуализации данных
Цель:
1) Отображение точек на карте в виде кругов заданного радиуса и цвета.
2) Когда пользователь нажимает на круг, всплывающая подсказка / всплывающее окно должны отображаться с дополнительными данными о нем (включенными в предоставленные данные) до тех пор, пока пользователь не щелкнет (по сути, так же, как этот график, но для щелчка вместо наведения, http://uber.github.io/deck.gl/#/documentation/layer-catalog/scatterplot-layer. К вашему сведению, я посмотрел на код для этого, и логика наведения была удалена, я полагаю, для простоты).
Проблема:
Я выполнил пункт 1, но не могу заставить работать пункт 2. Самое большое, что я смог доказать, это данные для входа в консоль.
Отметить:
Я не замужем за реакцией-всплывающей подсказкой - я не возражаю полностью удалить ее, если есть лучший способ сделать это. Мне нужно оставить только mapbox и deck.gl.
Данные: https://gist.github.com/NikkiChristofi/bf79ca37028b293b50cfbf79ca37028b293b50cd
deckgl-overlay.js
import React, {Component} from 'react';
import ReactTooltip from 'react-tooltip';
import DeckGL, {ScatterplotLayer} from 'deck.gl';
export default class DeckGLOverlay extends Component {
static get defaultViewport() {
return {
longitude: 0,
latitude: 0,
zoom: 2,
maxZoom: 16,
pitch: 0,
bearing: 0
};
}
# in this method I want to update the variable tooltipText with
# whatever object data has been clicked.
# The console log successfully logs the right data (i.e. the third
# element in the array), but the tooltip doesn't even show
onClickHandler = (info) => {
let dataToShow = info ? info.object[2] : "not found";
this.tooltipText = dataToShow;
console.log(dataToShow);
}
render() {
const {viewport, lowPerformerColor, highPerformerColor, data, radius, smallRadius, largeRadius} = this.props;
if (!data) {
return null;
}
const layer = new ScatterplotLayer({
id: 'scatter-plot',
data,
radiusScale: radius,
radiusMinPixels: 0.25,
getPosition: d => [d[1], d[0], 0],
getColor: d => d[2] > 50 ? lowPerformerColor : highPerformerColor,
getRadius: d => d[2] < 25 || d[2] > 75 ? smallRadius : largeRadius,
updateTriggers: {
getColor: [lowPerformerColor, highPerformerColor]
},
pickable: true,
onClick: info => this.onClickHandler(info),
opacity: 0.3
});
return (
<DeckGL {...viewport} layers={ [layer] } data-tip={this.tooltipText}>
<ReactTooltip />
</DeckGL>
);
}
}
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 {json as requestJson} from 'd3-request';
const MAPBOX_TOKEN = process.env.MAPBOX_TOKEN; // eslint-disable-line
const lowPerformerColor = [204, 0, 0];
const highPerformerColor = [0, 255, 0];
const smallRadius = 500;
const largeRadius = 1000;
const DATA_URL = 'https://gist.github.com/NikkiChristofi/bf79ca37028b29b50cffb215360db999';
export default class App extends Component {
constructor(props) {
super(props);
this.state = {
viewport: {
...DeckGLOverlay.defaultViewport,
width: 500,
height: 500
},
data: null
};
requestJson(DATA_URL, (error, response) => {
if (!error) {
console.log(response);
this.setState({data: response});
}
else{
console.log(error);
}
});
}
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}
});
}
render() {
const {viewport, data} = this.state;
return (
<MapGL
{...viewport}
onViewportChange={this._onViewportChange.bind(this)}
mapboxApiAccessToken={MAPBOX_TOKEN}
mapStyle='mapbox://styles/mapbox/dark-v9'>
<DeckGLOverlay viewport={viewport}
data={data}
lowPerformerColor={lowPerformerColor}
highPerformerColor={highPerformerColor}
smallRadius={smallRadius}
largeRadius={largeRadius}
radius={300}
/>
</MapGL>
);
}
}