deck.gl IconLayer Example

Demo

Source

<html>
  <head>
    <title>deck.gl IconLayer Example</title>

    <script src="https://unpkg.com/deck.gl@^7.0.0/dist.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/rest.js/15.2.6/octokit-rest.min.js"></script>

    <style type="text/css">
      body {
        width: 100vw;
        height: 100vh;
        margin: 0;
        background: #f7f7f7;
        overflow: hidden;
      }
      #tooltip:empty {
        display: none;
      }
      #tooltip {
        font-family: Helvetica, Arial, sans-serif;
        position: absolute;
        padding: 4px;
        margin: 8px;
        background: rgba(0, 0, 0, 0.8);
        color: #fff;
        max-width: 300px;
        font-size: 10px;
        z-index: 9;
        pointer-events: none;
      }
    </style>
  </head>

  <body>
    <div id="tooltip"></div>
  </body>

  <script type="text/javascript">

    const {DeckGL, IconLayer, LineLayer, ScatterplotLayer, TextLayer, COORDINATE_SYSTEM} = deck;

    const deckgl =  new DeckGL({
      views: new OrthographicView(),
      viewState: { target: [0, 0, 0], zoom: 2 },
      controller: true
    });

    function updateTooltip({x, y, object}) {
      const tooltip = document.getElementById('tooltip');
      if (object) {
        tooltip.style.top = `${y}px`;
        tooltip.style.left = `${x}px`;
        tooltip.innerHTML = `
        <div><b>${object.login}</b></div>
        <div>Contributions: ${object.contributions}</div>`;
      } else {
        tooltip.innerHTML = '';
      }
    }

    function renderLayers(data) {
      const ORIGIN = [0, 0];

      const iconLayer = new IconLayer({
        id: 'users',
        coordinateSystem: COORDINATE_SYSTEM.IDENTITY,
        data,
        getIcon: d => ({
          url: d.avatar_url,
          width: 128,
          height: 128
        }),
        getSize : d => d.size,
        getPosition: d => d.position,
        sizeUnits: 'meters',
        pickable: true,
        onHover: updateTooltip
      });

      const lineLayer = new LineLayer({
        id: 'links',
        coordinateSystem: COORDINATE_SYSTEM.IDENTITY,
        data,
        pickable: true,
        getSourcePosition: d => ORIGIN,
        getTargetPosition: d => d.position,
        getColor: [228, 228, 228],
        getWidth: 3
      });

      const scatterPlotLayer = new ScatterplotLayer({
        id: 'deck.gl-circle',
        coordinateSystem: COORDINATE_SYSTEM.IDENTITY,
        data: [{position: [0, 0]}],
        getPosition: d => d.position,
        getFillColor: [23, 38, 42],
        getRadius: 12,
        radiusMaxPixels: 60,
        opacity: 1
      });

      const textLayer = new TextLayer({
        id: 'deck.gl-label',
        coordinateSystem: COORDINATE_SYSTEM.IDENTITY,
        data: [{position: [0, 0]}],
        getSize: 15,
        getPosition: d => d.position,
        getText: d => 'Deck.gl',
        getColor: [255, 255, 255]
      });

      deckgl.setProps({ layers: [lineLayer, iconLayer, scatterPlotLayer, textLayer] });
    }

    new Octokit().repos.getContributors({ owner: 'uber', repo: 'deck.gl' })
    .then(result => {
      let {data} = result;
      // process data
      const listOfContributions = data.map(contributor => contributor.contributions);
      const maxContributions = Math.max(...listOfContributions);

      // shuffle
      data.sort(() => 0.5 - Math.random());
      data = data.map((d, i) => {
        const angle = i / data.length * 2 * Math.PI;
        const distance = 30 * Math.sqrt(d.contributions / maxContributions) + 16;
        const x = Math.cos(angle) * distance;
        const y = Math.sin(angle) * distance;
        const size = Math.log2(d.contributions) + 1;
        return {
          login: d.login,
          avatar_url: d.avatar_url,
          contributions: d.contributions,
          position: [x, y],
          size
        };
      });

      renderLayers(data);
    })

  </script>
</html>