gpt4 book ai didi

reactjs - Deck.gl 如何在点击时显示弹出窗口

转载 作者:行者123 更新时间:2023-12-03 13:44:16 28 4
gpt4 key购买 nike

设置:

使用react-map-gl的基本react应用程序显示 map ,顶部带有deck.gl ScatterplotLayer以可视化数据

目标:

1) 将 map 上的点显示为给定半径和颜色的圆圈。
2) 当用户单击圆圈时,工具提示/弹出窗口应显示更多有关该圆圈的数据(包含在提供的数据中),直到用户单击为止(与此图基本相同,但单击而不是悬停,http://uber.github.io/deck.gl/#/documentation/layer-catalog/scatterplot-layer .仅供引用,我查看了此代码,并且悬停逻辑已被删除,我认为是为了简单起见)。

问题:

我已经完成了第 1 点,但无法让第 2 点起作用。我所能证明的最远的数据就是记录到控制台。

注意:

我并没有和react-tooltip结婚——如果有更好的方法的话,我不介意把它完全删除。我只需要保留mapbox和deck.gl。

数据:https://gist.github.com/NikkiChristofi/bf79ca37028b29b50cffb215360db999

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>
);
}
}

最佳答案

想出了一个办法。

解决方案

我将 onClick 事件冒泡到 MapGL 图层,并使用 Popup 元素来显示数据。

所以在 app.js 中:
1)从react-map-gl导入Popup元素

import MapGL, { Popup } from 'react-map-gl';

2)设置坐标状态和“信息”(在弹出窗口中显示)

constructor(props) {
super(props);
this.state = {
viewport: {
...DeckGLOverlay.defaultViewport,
width: 500,
height: 500
},
data: null,
coordinates: [-0.13235092163085938,51.518250335096376],
info: "Hello"
};

3)创建用新数据设置状态的回调方法(信息只是数据中的一个元素,可以是您想要在弹出窗口中显示的任何内容)

myCallback = (info) => {
console.log(info);
if(info){
this.setState({coordinates: info.lngLat, info: info.object[2]});
}
}

4)渲染弹窗并引用DeckGL层的回调方法

 return (
<MapGL
{...viewport}
{...this.props}
onViewportChange={this._onViewportChange.bind(this)}
mapboxApiAccessToken={MAPBOX_TOKEN}
mapStyle='mapbox://styles/mapbox/dark-v9'>
<Popup
longitude={this.state.coordinates[0]}
latitude={this.state.coordinates[1]}>
<div style={style}>
<p>{this.state.info}</p>
</div>
</Popup>
<DeckGLOverlay viewport={viewport}
data={data}
lowPerformerColor={lowPerformerColor}
highPerformerColor={highPerformerColor}
smallRadius={smallRadius}
largeRadius={largeRadius}
radius={300}
callbackFromParent={this.myCallback}
/>
</MapGL>
);

以及在dececkgl-overlay.js中:
1)将数据信息输入父级(app.js)方法

onClick: info => this.props.callbackFromParent(info),

(显然删除了deckoverlay.js中的React-tooltip元素和onClick事件处理程序来清理)

关于reactjs - Deck.gl 如何在点击时显示弹出窗口,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46310202/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com