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.08k stars 424 forks source link

How to put text in the map? #84

Open mgorabbani opened 6 years ago

zimrick commented 6 years ago

Hi @mgorabbani,

With text it depends a little bit what you are trying to do, but generally, you can add text directly into the map, as if you were working with raw SVG. Note I am using the basic SVG <text /> element, not anything specific to react-simple-maps.

import { ComposableMap, ZoomableGrou, Geographies, Markers } from "react-simple-maps"

const Map = () =>
  <ComposableMap>
    <ZoomableGroup>
      <Geographies>...</Geographies>
      <Markers>...</Markers>
      <text x={0} y={100}>
        { "Just add text anywhere" }
      </text>
    </ZoomableGroup>
  </ComposableMap>

If you are trying to place text geographically, you can use either a <Marker /> or an <Annotation /> component. Check out the docs for markers or annotations.

Let me know if this answers your question.

pjisha commented 6 years ago

@zimrick Is there a way you can show something more than a text, a div for example, by which you can display more data/details geographically ?

zimrick commented 6 years ago

If you want to add some kind of static overlay box and text in it at a specific geographic location you can do that without divs. You can't really work with divs in SVG (unless you use something like foreignObject), but you have rect, text, and tspan, which you can use to create something that looks like a div with text in it.

The only problem is text wrapping, which is not supported by default in SVG. In order to add a text box at a geographic location, you can use Marker, since it doesn't make any assumptions about what you want to render at a specific geographic location. You can pass in any valid SVG.

...
<ComposableMap>
  <ZoomableGroup>
    <Markers>
      <Marker marker={{ coordinates: [0,0] }}>
        <rect x={0} y={0} width={200} height={100} fill="#EEE" />
        <text x={8} y={8}>{ "Text content" }</text>
      </Marker>
    </Markers>
  </ZoomableGroup>
</ComposableMap>
...

You can also check out this example by Mike Bostock on d3-blocks, which has a nifty little js function to help with wrapping: https://bl.ocks.org/mbostock/7555321

There is also Victory, which has a VictoryLabel component. I think it supports new line characters and wraps the text for you.

Let me know if that works out.