deck.gl
react-map-glを使った
データ可視化
2023/4/6 MIERUNE meetup mini #6
目次
deck.gl
react-map-gl とは
deck.glとは
deck.glとは
react-map-glとは
レイヤ表示
レイヤ表示
レイヤ表示
import DeckGL from '@deck.gl/react';
import { HeatmapLayer } from '@deck.gl/aggregation-layers';
�function App({ data, viewState }) {
const layer = new HeatmapLayer({
id: 'heatmapLayer',
data,
getPosition: (d) => {
return [d.longitude, d.latitude];
},
aggregation: 'SUM',
});
� return <DeckGL viewState={viewState} layers={[layer]} />;
}
レイヤ表示
import DeckGL from '@deck.gl/react';
import { HexagonLayer } from '@deck.gl/aggregation-layers';
�function App({ data, viewState }) {
const layer = new HexagonLayer({
id: 'hexagon-layer',
data,
pickable: false,
extruded: true,
radius: 15000,
elevationScale: 500,
getPosition: (d) => {
return [d.longitude, d.latitude];
},
});
� return <DeckGL viewState={viewState} layers={[layer]} />;
}
レイヤ表示
import DeckGL from '@deck.gl/react';
import { ScatterplotLayer } from '@deck.gl/layers';
�function App({ data, viewState }) {
const layer = new ScatterplotLayer({
id: 'scatterplot-layer',
data,
pickable: true,
opacity: 0.8,
stroked: true,
filled: true,
radiusScale: 30,
radiusMinPixels: 1,
radiusMaxPixels: 100,
lineWidthMinPixels: 1,
getPosition: (d) => {
return [d.longitude, d.latitude];
},
getRadius: 10,
getFillColor: (d) => [255, 140, 0],
getLineColor: (d) => [0, 0, 0],
});
� return <DeckGL viewState={viewState} layers={[layer]} />;
}
地図表示
地図表示
const App = () => {
const DeckGLOverlay = (props) => {
const overlay = useControl(() => new MapboxOverlay(props));
overlay.setProps(props);
return null;
};
// Mapboxアクセストークン
const MAPBOX_ACCESS_TOKEN = ‘your_access_token';
// 初期ビューポートの設定
const INITIAL_VIEW_STATE = {
latitude: 38.875584,
longitude: 139.7454316,
bearing: 0,
pitch: 0,
zoom: 5,
};
// LineLayerで使うデータ
const data = [{ sourcePosition: [139.7454316, 38.875584], targetPosition: [145.7454316, 40.875584] }];
// LineLayer
const layers = [new LineLayer({ id: 'line-layer', data })];
return (
<div className="App">
<Map
initialViewState={INITIAL_VIEW_STATE}
mapStyle="mapbox://styles/mapbox/light-v9"
style={{ width: '100vw', height: '100vh' }}
mapboxAccessToken={MAPBOX_ACCESS_TOKEN}
>
<DeckGLOverlay layers={layers} />
</Map>
</div>
);
};
�export default App;
地図表示
(略)
<div className="App">
<Map
initialViewState={INITIAL_VIEW_STATE}
mapStyle="mapbox://styles/mapbox/light-v9"
style={{ width: '100vw', height: '100vh' }}
mapboxAccessToken={MAPBOX_ACCESS_TOKEN}
attributionControl={false}
>
<DeckGLOverlay layers={layers} />
{/* ユーザーの位置を特定するためのボタン */}
<GeolocateControl />
{/* フルスクリーンモードのマップをトグルするためのボタン */}
<FullscreenControl />
{/* ズームボタンとコンパス */}
<NavigationControl />
{/* 地図上の距離と地上の対応する距離の比率を表示 */}
<ScaleControl />
{/* 帰属を表示 */}
<AttributionControl customAttribution="hogehoge"/>
</Map>
</div>
(略)
地図表示
地図コントロール用のボタンが押せなかった
ハマりポイント😢
<div className="App">
<DeckGL
initialViewState={INITIAL_VIEW_STATE}
controller={true}
layers={layers}
>
<Map
mapboxAccessToken={MAPBOX_ACCESS_TOKEN}
mapStyle="mapbox://styles/mapbox/light-v9"
>
<GeolocateControl />
<FullscreenControl />
<NavigationControl />
<ScaleControl />
</Map>
</DeckGL>
</div>
地図表示
ハマりポイント😢
react-map-gl
z-index: -1
deck.gl
z-index: 0
地図表示
ハマりポイント😢
ChatGPT に聞いても解決しなかった
「公式ドキュメントを読め高校校歌」
ズーム機能
export default function App() {
const mapRef = useRef
const onSelectCity = useCallback(({longitude, latitude}) => {
mapRef.current?.flyTo({center: [longitude, latitude], duration: 2000});
}, []);
return (
<>
<Map
ref={mapRef}
initialViewState={initialViewState}
mapStyle="mapbox://styles/mapbox/dark-v9"
mapboxAccessToken={MAPBOX_TOKEN}
/>
<ControlPanel onSelectCity={onSelectCity} />
</>
);
}
ズーム機能
ハマりポイント😢
ズーム機能
ズーム機能
ハマりポイント😢
「公式ドキュメントを読め高校校歌」
まとめ
データ可視化フレームワーク
レイヤの種類が豊富
Mapbox GL JS のReact ラッパー
地図表示、地図コントロールができる
まとめ
組み合わせると
便利!
得た知見をアウトプットして、情報量を増やしていく!
まとめ
つらみポイント
ご清聴
ありがとうございました!