Search code examples
htmlcssreactjsdeck.glreact-map-gl

How do I get deck.gl and react-map-gl to display correctly?


Here is a code sandbox example where I am trying to display a map inside of a specific component. But, I am not able to get the deck.gl and react-map-gl divs to live inside their parent. instead, they spill out to the extent of the document body.

The basic layout of the example is:

        <Box id='mapcontainer'>
            <DeckGL id="deck-gl">
                <MapView id="map"  >
                    <StaticMap/>
                </MapView>
            </DeckGL>
        </Box>

It appears that Deck.gl is creating a <div> and a <canvas> element between the <Box id='mapcontainer'> div and the <DeckGL id='deck-gl'> div, and I can not get the div and canvas to live inside of their parent Box.

The id of the <div> and the <canvas> appear to be created from the id passed into the DeckGL component, id="deck-gl-wrapper" and id="deck-gl" respectively. Where "deck-gl" is the id I passed into the <deckGL> component.

That may or may not be the actual problem, but using the elements inspector in devtools that is my best guess right now.

element structure screenshot from devtools

Can anyone help me figure out why deck.gl and react-map-gl components are not living within their parent bounds? Even when I set the parent and/or canvas props in the DeckGL component?

Documentation links:
react-map-gl
deck.gl

A functioning example is included in the codesandbox linked above. I have included many of the things I have tried as comments but no luck so far.

https://codesandbox.io/s/deck-gl-and-mui-react-e3t23?file=/src/App.js

Thank you...

For local quick reference, the app.js file looks something like this.

import Box from "@material-ui/core/Box";
import DeckGL from "@deck.gl/react";
import { MapView } from "@deck.gl/core";
import { LineLayer } from "@deck.gl/layers";
import { StaticMap } from "react-map-gl";

const MAPBOX_ACCESS_TOKEN = <tokenInCodeSandboxIfYouNeedIt>

const INITIAL_VIEW_STATE = {
    longitude: -122.41669,
    latitude: 37.7853,
    zoom: 13,
    pitch: 0,
    bearing: 0
};

const data = [
    {
        sourcePosition: [-122.41669, 37.7853],
        targetPosition: [-122.41669, 37.781]
    }
];

function App() {
    return (
        <Box
            id='mapcontainer'
            sx={{
                border: 1,
                height: 450,
                width: "auto",
                m: 5
            }}
        >
            <DeckGL
                initialViewState={INITIAL_VIEW_STATE}
                controller={true}
                id="deck-gl"
            >
                <LineLayer id="line-layer" data={data} />
                <MapView
                    id="map"
                    controller={false}
                >
                    <StaticMap
                        mapStyle="mapbox://styles/mapbox/dark-v9"
                        mapboxApiAccessToken={MAPBOX_ACCESS_TOKEN} 
                    />
                </MapView>
            </DeckGL>
        </Box>
    );
}

export default App;


Solution

  • In order to allow the deck.gl component to take up the available space of the parent component you can add position: 'relative' into the overrides for your Box with an id of mapcontainer.