zcreativelabs / react-simple-maps

Beautiful React SVG maps with d3-geo and topojson using a declarative api.
https://www.react-simple-maps.io/
MIT License
3.06k stars 424 forks source link

Grouping Paths by Region #147

Open capstonednc opened 5 years ago

capstonednc commented 5 years ago

I'm trying to zoom into a region on click and show users that regions with small countries can click on the regions to zoom. I'd need to get the bounding box of the group of SVGs, but the only SVG group ( element) is the main Zoomable Group. Is there a way to create multiple Zoomable groups in a ComposableMap or multiple Geographies in a Zoomable Group?

zimrick commented 5 years ago

Hi @capstonednc, Yes, multiple geography groups are possible. There are two ways you could try this:

  1. Create multiple Geographies each with a subset of Geography components.
<ZoomableGroup>
  <Graticule />
  <Geographies geography={geoPaths}>
    {(geos, proj) =>
      geos.map((geo, i) => (
        <Geography fill="#EEE" key={geo.id + i} geography={geo} projection={proj} />
      )
    )}
  </Geographies>
  <Geographies geography={geoPaths}>
    {(geos, proj) => geos.slice(0, 4).map((geo, i) => (
      <Geography key={properties.iso3} geography={geo} projection={proj} />
    ))}
  </Geographies>
</ZoomableGroup>
  1. Create one Geographies component with multiple <g> groups each with a subset of the geographies returned by the Geographies component (geos).
<Geographies geography={geoPaths}>
  {(geos, proj) => (
    <g>
      <g>
        {geos.slice(0, 4).map((geo, i) => (
          <Geography key={geo.properties.iso3} geography={geo} projection={proj} />
        ))}
      </g>
      <g>
        {geos.slice(4).map((geo, i) => (
          <Geography key={geo.properties.iso3} geography={geo} projection={proj} />
        ))}
      </g>
    </g>
  )}
</Geographies>

You could also work with a custom projection like here: https://codesandbox.io/s/o4yzwxy19y

That way you could create your own geoPath based on that projection, which should give you a way of processing the geos array in a click event and to get a centroid coordinate + bbox of a set of paths...

This might also be useful: https://github.com/zcreativelabs/react-simple-maps/issues/60

capstonednc commented 5 years ago

So I can create multiple JSONs by region and pass them each into the geography prop of a Geographies component?

On further tinkering, I was able to select all of a region's paths onHover/Click. Can I dynamically create additional groups from those selections?