react-simple-maps icon indicating copy to clipboard operation
react-simple-maps copied to clipboard

Markers Size is changing on zoom in and zoom out

Open prathyusha311 opened this issue 5 years ago • 8 comments

Hi Currently, On Zoom-in and Zoom-out, Marker size is changing accordingly. Is there a way to keep the marker size fixed, i.e it shouldn't change its size on zoom-in and zoom-out.

prathyusha311 avatar Apr 13 '20 08:04 prathyusha311

It's not well documented at the moment, but you can achieve this by using the useZoomPan hook. This is the same hook that react simple maps uses under the hood for the ZoomableGroup component. You can make a completely custom zoomable group and use the position object to resize markers based on zoom.

Here's an example of this: https://codesandbox.io/s/custom-zoomablegroup-iqtwj

zimrick avatar Apr 18 '20 15:04 zimrick

Would love to see this documented and <CustomZoomableGroup> added to this library -- I think this was previously easy to achieve with the <Markers> component, but the equivalent functionality simply doesn't exist anymore.

Also, MapContext isn't exposed to consumers of this package so anyone reimplementing a <CustomZoomableGroup> can't use it like it's used in <ZoomableGroup> itself:

https://github.com/zcreativelabs/react-simple-maps/blob/a0004e4ad0a15644c0ce466c8edf1d69279935ca/src/components/ZoomableGroup.js#L21

lostfictions avatar Jul 11 '20 23:07 lostfictions

Hi there. In version 2.3.0 onMove event is available https://github.com/zcreativelabs/react-simple-maps/blob/master/src/components/useZoomPan.js#L51 which exposes scale factor as property k. So it's now possible to implement this feature quite easily without need of CustomZoomableGroup in few lines of code:

const [scaleFactor, setScaleFactor] = useState(1);
//...
<ZoomableGroup onMove={({ k }) => setScaleFactor(k)}>
//...
<circle r={12 / scaleFactor} fill="#F53" />

See working example here

https://codesandbox.io/s/react-simple-maps-do-not-change-markers-size-on-zoom-cwstb?file=/package.json

See also docs here: https://www.react-simple-maps.io/docs/zoomable-group/

I believe the issue can be closed now

kopach avatar Jun 29 '21 16:06 kopach

Going forward, some hook like this one could be created and re-used across app

export function useStaticMapMarkerSize(
  markerRadius: number,
  initialMapScaleFactor: number = 1
): [number, (scaleFactor: number) => void] {
  const [scaleFactor, setScaleFactor] = useState<number>(initialMapScaleFactor)
  const scaledRadius = markerRadius / (scaleFactor - initialMapScaleFactor + 1)

  return [scaledRadius, setScaleFactor]
}

and later in code

  const initialScaleFactor = 1.4
  const [scaledMarkerRadius, setScaleFactor] = useStaticMapMarkerSize(markerRadius, initialScaleFactor)

  //..
  <ZoomableGroup
    zoom={initialScaleFactor}
    onMove={({ k }: { k: number }): void => setScaleFactor(k)}
  >
    // ..
    {markers.map(({ name, coordinates, status }) => (
      <Marker key={coordinates.toString()} coordinates={coordinates}>
        <circle r={scaledMarkerRadius} />
      </Marker>
    ))}
  </ZoomableGroup>

kopach avatar Jun 29 '21 19:06 kopach

I used demo custom marker here: https://www.react-simple-maps.io/examples/custom-markers/ And when I zoom in on the map chart then I see that the marker with custom is not able to scale. With marker is a <circle/> tag is easer to scale with property r as <circle r={12 / scaleFactor} fill="#F53" /> but when I used <path/> tag and how can I scale it to match with chart

AstaDK avatar Jan 02 '22 14:01 AstaDK

tom m

You can try scaling the corresponding attributes that modify the custom marker's position/size. On the element it would be something like: transform={translate(${-8 / scaleFactor}, ${-20 / scaleFactor}), scale(${.7 / scaleFactor})}

arquilca avatar Mar 21 '22 18:03 arquilca

On a similar note, how do we make the marker stay at the coordinate as you zoom in/pan?

drecloud avatar Mar 23 '22 13:03 drecloud

On a similar note, how do we make the marker stay at the coordinate as you zoom in/pan?

I think that's what the translate portion of the transform is for.

arquilca avatar Mar 23 '22 18:03 arquilca