I am using React-Simple-Maps to manipulate and render an SVG of a map (a chloropeth map). I am using React-Tooltip to display a tooltip over each constituency on the map, displaying their full names and an option for "more detail." So far, I haven't been able to render even the names, let alone a fully stylized div with the aforementioned details.
Using the documentation available on the sites of both respective libraries, I've ended up doing something like this (with no success). Here is the codesandbox link, which I followed: https://codesandbox.io/s/map-chart-with-tooltip-forked-42sldc?file=/src/index.js
The Map component code (note that on mouseEnter, I was able to log the names onto the console, but I don't know why it's not setting up for the content of the tooltip, or if anything else is an issue). Ignore the marker (you may comment it out if you wish to run or test the code).
const MapChart = ({
setTooltipContent,
}: {
setTooltipContent: (content: string) => void;
}) => {
return (
<div id='map' className=''>
<ComposableMap className='stroke-black'>
<Geographies
geography={SgMap}
fill='#D6D6DA'
stroke='#FFFFFF'
className=''
>
{({ geographies }) =>
geographies.map((geo) => (
<Geography
key={geo.rsmKey}
geography={geo}
onMouseEnter={() => {
setTooltipContent(geo.properties.name);
}}
onMouseLeave={() => {
setTooltipContent('');
}}
data-tip
data-for='map'
style={{
default: {
fill: '#D6D6DA',
outline: 'none',
},
hover: {
fill: '#F53',
outline: 'none',
},
pressed: {
fill: '#E42',
outline: 'none',
},
}}
/>
))
}
</Geographies>
{ConstituenciesNamesandCoordinates.map(({ name, coordinates }, i) => (
<Marker key={i} coordinates={coordinates}>
<text
textAnchor='middle'
y={-10}
className='font-times text-[0.5rem] text-black'
style={{
userSelect: 'none',
pointerEvents: 'none',
fontWeight: 100,
}}
>
{name}
</text>
</Marker>
))}
</ComposableMap>
</div>
);
};
The code where i am trying to render the tooltip
import MapChart from "./MapComponent";
const MapSection=()=> {
const [content, setContent] = useState("");
return (
<div>
<MapChart setTooltipContent={setContent} />
<Tooltip data-tooltip-id="map" content={content} float />
</div>
);
}
export default MapSection;
Any help would be much appreciated. The Sandbox version works; btw, mine doesn't for some reason.
If using react-tooltip
v5.13.0 or newer, then the typical basic usage would be to add an id
attribute to the react-tooltip
component; <Tooltip />
(e.g. my-tooltip
), like so:
import { Tooltip } from 'react-tooltip'
// ...
<Tooltip id="my-tooltip" content={content} float />
And then, within each mapped <Geography>
component, you would set the data
attribute; data-tooltip-id="my-tooltip"
, whereby this is how the react-tooltip component would reference to each geography / constituent:
import { ComposableMap, Geographies, Geography } from "react-simple-maps";
// ...
<ComposableMap className='stroke-black'>
<Geographies
geography={SgMap}
fill='#D6D6DA'
stroke='#FFFFFF'
>
{({ geographies }) =>
geographies.map((geo) => (
<Geography
key={geo.rsmKey}
geography={geo}
data-tooltip-id="my-tooltip"
onMouseEnter={() => setTooltipContent(geo.properties.name)}
onMouseLeave={() => setTooltipContent("")}
/>
))
}
</Geographies>
</ComposableMap>
Also, as a bonus, if you're simply rendering plain simple content (e.g. constituent / geography country name) in the tooltip for each <Geography>
, then you may be able to get away with not needing to maintain a local component state at all, by omitting the need for content={content}
, and just set another data attribute; data-tooltip-content
on <Geography>
, like so:
import { ComposableMap, Geographies, Geography } from "react-simple-maps";
// ...
<ComposableMap className='stroke-black'>
<Geographies
geography={SgMap}
fill='#D6D6DA'
stroke='#FFFFFF'
>
{({ geographies }) =>
geographies.map((geo) => (
<Geography
key={geo.rsmKey}
geography={geo}
data-tooltip-id="my-tooltip"
data-tooltip-content={geo.properties.name}
/>
))
}
</Geographies>
</ComposableMap>
Source documentation: https://react-tooltip.com/docs/getting-started#using-anchor-data-attributes