4

I created an SVG map, however, I want to make it so that the there is a tooltip (that follows the mouse) when somebody hovers over it and is unique to each path. In addition to having a tooltip, I would like each SVG path to be clickable and lead to a link if possible.

I would like to style the tooltip with this CSS:

.map-tooltip {
  position: absolute;
  display: none;
  -webkit-border-radius: 3px;
  -moz-border-radius: 3px;
  border-radius: 3px;
  border:#d3d3d3 solid 1px;
  background: #fff;
  color: black;
  font-family: Comfortaa, Verdana;
  font-size: smaller;
  padding: 8px;
  pointer-events:none;
  box-shadow: 0 8px 17px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19); 
}

And here is my SVG: https://jsfiddle.net/3ojet4oL/

Thanks for helping!

spjy
  • 467
  • 8
  • 17

1 Answers1

6

You can do this with the following script (read the comments)

var tooltip = document.querySelector('.map-tooltip');

// iterate through all `path` tags
[].forEach.call(document.querySelectorAll('path.HI-map'), function(item) {
  // attach click event, you can read the URL from a attribute for example.
  item.addEventListener('click', function(){
    window.open('http://google.co.il')
  });

  // attach mouseenter event
  item.addEventListener('mouseenter', function() {
    var sel = this,
        // get the borders of the path - see this question: http://stackoverflow.com/q/10643426/863110
        pos = sel.getBoundingClientRect()

    tooltip.style.display = 'block';
    tooltip.style.top = pos.top + 'px';
    tooltip.style.left = pos.left + 'px';
  });

  // when mouse leave hide the tooltip
  item.addEventListener('mouseleave', function(){
    tooltip.style.display = 'none';
  });
});

See the updated jsfiddle: https://jsfiddle.net/3ojet4oL/3/

Update

  1. For dynamic tooltip text, there are some ways. One of them is to store the text on data-* attribute. In my example data-tooltip, then you can read it when you want to show the tooltip:

html

<path class="HI-map maui" data-tooltip="tooltip10"

javascript

 tooltip.innerText = item.getAttribute('data-tooltip');

Just now, I saw that you want to put an html in the tooltip. So I change a little bit the logic as you can see in the jsfiddle below. The logic is to store the tooltip content in object then, get it by the data-tooltip attribute.

  1. For tooltip will move with the cursor, you just need to use mousemove event:
item.addEventListener('mousemove', function(e) {
  tooltip.style.top = e.clientY + 'px';
  tooltip.style.left = e.clientX + 'px';
});

https://jsfiddle.net/3ojet4oL/7/

Update 2

For dynamic URL add attribute data-link the script will open this URL in new window.

https://jsfiddle.net/3ojet4oL/9/

Mosh Feu
  • 28,354
  • 16
  • 88
  • 135
  • Thanks, this is almost perfect! Is there any way you could make it so that the tooltip follows the mouse, similar to [this?](http://jsfiddle.net/HJf8q/2/) – spjy Jun 15 '16 at 18:31
  • Also, how would I make it so that I can create unique tooltips for each island? – spjy Jun 15 '16 at 19:20
  • 1
    Use the positioning information of a mousemove event, e.g. like this: https://jsfiddle.net/3ojet4oL/4/ . To create unique tooltips, you can e.g. store the tooltip text on the path elements (see the JSFiddle). You can also use standard tooltips that are created with `` elements inside the `<path>` elements (no JavaScript required for those).</path> – Thomas W Jun 15 '16 at 21:16
  • Sorry, do you mind showing me how to store the tooltip text? I don't get how to do that. In yours it seems to show the class text. Also, I would like to have HTML inside of the tooltip; I read somewhere that you can't have HTML in tags if I read correctly @ThomasW – spjy Jun 15 '16 at 23:58
  • @MoshFeu Hi! Unfortunately I'm not able to input HTML in there; it only inputs text. For example: https://jsfiddle.net/3ojet4oL/8/ Would you happen to be familiar with JQVMap? I would like something similar to that, feature: http://codepen.io/anon/pen/KMMXXJ (the `onLabelShow:` part and how you can enter HTML at the end). – spjy Jun 16 '16 at 05:21
  • @DarkTakua Did you see the part `I saw that you want to put an html` in my answer? I explain there how can you show html. In the second fiddle (https://jsfiddle.net/3ojet4oL/7/) you can see that my tooltip contains html. Let me know, if it's OK for you. – Mosh Feu Jun 16 '16 at 06:33
  • Ahh ok sorry, I didn't catch the second fiddle. Looks good, but now how would I incorporate the unique link system (so each island will lead to its page. I will be editing the color variables into its name)? Just a note, I will be having other code besides the island name in the `var colors` so if you may have to attach a name to each tooltip and link it or something like that. Sorry I'm asking for a lot! – spjy Jun 16 '16 at 08:38
  • @DarkTakua No problem. I'm happy to help. I was updated my answer. I didn't understand the last part of your comment.. Do you want advice or you did it already? – Mosh Feu Jun 16 '16 at 08:56
  • @MoshFeu Almost perfect! However, when I tried to rename all of the islands, for some reason it begins at Kauai, but in this case, the first island is supposed to Niihau and then everything gets thrown off. The last island, Hawaii, becomes `undefined` as demonstrated: https://jsfiddle.net/3ojet4oL/10/ While we're at it, is it possible to also position the tooltip on the top left part of the cursor (so the mouse doesn't overlap) instead of on the bottom right? – spjy Jun 17 '16 at 00:18
  • 1
    The problem was that the `for` loop start with `1` and `countries` array start at `0` so you need to get access to `countries[i - 1]` like in this fiddle: https://jsfiddle.net/3ojet4oL/11/ – Mosh Feu Jun 19 '16 at 10:45
  • @MoshFeu Yes, how about the mouse feature? I promise, last thing! :D – spjy Jun 24 '16 at 08:32
  • 1
    I think that what the code do. But you always add some pixels to the position. Something like: `tooltip.style.top = (e.clientY + 5) + 'px';` or something. – Mosh Feu Jun 24 '16 at 10:58