Search code examples
javascriptreactjsleafletreact-leaflet

Changing React Leaflet Circle color with Leaflet Timedimension Plugin


I'm building a React app that has a Leaflet map and integrates the Leaflet Timedimension Plugin.
The goal is to have a map that has some Circles, those changes radius and color whenever the Timedimension plugin loads a new time.

I've successfully created a map that has some Circles that changes based on the Timedimension plugin times (currentTimeIndex changes whenever a new time is loaded), but the colour wouldn't change.
The following code it's my approach to the problem:

      data.map((region) =>
        region.items.map((market) => (
          <Circle
            center={[market.lat, market.lon]}
            radius={values[currentTimeIndex]}
            pane='markets'
            key={market.id}
            color={colors[currentTimeIndex]}
          />
        )),
      )

Is possible to change the color of the Circle without having to remove and re-add them?

I'll leave here the codesandbox with the full code.


Solution

  • For weird reasons I cannot really explain, it seems like colors does not update, while pathOptions seems to work as intended.

    I've slightly updated your codesandbox which seems to produce the desired result, the following were changed:

    • I have moved colors out of the Leaflet component since it's actually a constant.
    • I have added a useMemo hook to get the current color according to the currentTimeIndex.
    • I have changed color with pathOptions, which is the real fix you need to do.

    Side note: I'm not sure how you want to style the circle itself. In case you want to use both fill and stroke, use fill and color in pathOptions, you can find documentation about that in the typings: https://definitelytyped.org/docs/leaflet--leaflet/interfaces/l.pathoptions.html

    Relevant code:

    const colors = ["red", "green", "blue", "black", "purple", "gray"];
    const Leaflet = () => {
      const map = useMap();
      const [currentTimeIndex, setCurrentTimeIndex] = useState(0);
      const values = [5, 15, 25, 5, 15, 25, 5];
    
      map.timeDimension.on("timeloading", (data) => {
        console.log(data.target._currentTimeIndex);
        setCurrentTimeIndex(data.target._currentTimeIndex);
      });
    
      const currentColor = useMemo(() => colors[currentTimeIndex], [
        currentTimeIndex
      ]);
    
      return (
        <>
          <Pane name="markets" />
          <TileLayer url={"https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"} />
          {SenegalData.map((region) =>
            region.items.map((market) => (
              <Circle
                center={[market.lat, market.lon]}
                radius={values[currentTimeIndex] * 1000}
                pane="markets"
                key={market.id}
                pathOptions={{
                  color: currentColor
                }}
              />
            ))
          )}
        </>
      );
    };
    

    Step 0 (color red): step 0

    Step 1 (color green): step 1

    Updated codesandbox: https://codesandbox.io/s/upbeat-dew-x11s1?file=/src/Leaflet.js