Skip to content

earthrise-media/justice-map

Repository files navigation

Justice40

Justice40 EJScreen prototype application.

  • This is a Next.js, styled with Tailwind, using Mapbox GL for most of the magic.
  • It's currently deployed to GitHub Pages, so none of the Next.js fancy stuff is usable.

Getting Started

First, run the development server:

npm run dev
# or
yarn dev

Open http://localhost:3000 with your browser to see the result.


Notes for Huncwot

This is a Next.js website, so it's a layer on top of React. This writeup assume that you're familiar with React.

image

There are three components working here:

  1. pages/index.tsx: the page skeleton
  2. components/map.tsx: the map
  3. components/chart.tsx: the chart, which reflects values on the map and can be used to filter the map

The only vital part of the code other than that is lib/pmap.ts, which has the logic for how the map is set up and changed.

Here's how a few different things work:

Changing indicators

For example, toggling between PM2.5 and Respiratory Hazard, right now.

This is done with React state in the pages/index.tsx component, here:

The chosen indicator is sent to the Map component here:

And the Map component receives those values and uses a useEffect call to modify the displayed layer:

  • useEffect(() => {
    try {
    for (let l of fillLayers) {
    mapRef.current.map.setLayoutProperty(
    l.id,
    "visibility",
    l.id.startsWith(layer) ? "visible" : "none"
    );
    }
    for (let l of highlightLayers) {
    mapRef.current.map.setLayoutProperty(
    l.id,
    "visibility",
    l.id.startsWith(layer) ? "visible" : "none"
    );
    }
    } catch (e) {
    // Doing this sort of update with GL JS is pretty
    // awful, just ignore the error here.
    }
    }, [mapRef, layer]);

Showing the data from the map in a chart on the left side

The data for that chart is called viewportData. When the user moves the map, we wait until the map has loaded all of the necessary data, then run countMapFeatures, which uses Mapbox GL JS's queryRenderedFeatures to find the features currently visible. These features are added together and then send back to the pages/index.tsx component with the setViewPortData method in the Map component, and then sent down to the Chart component.

How the chart works and how it controls the map

The chart uses d3 using the approach of using React to render the DOM, and d3 to do math. The slider on the chart is powered by react-aria.

When the slider moves, the Chart component calls setFilter, which then is applied to the Map in another useEffect call in the Map component.