0

Currently trying to use this tooltip: http://cbracco.me/a-simple-css-tooltip/

I'm creating an SVG map with dynamically-created SVG circles depicting universities in different counties. The problem is, I can't get my tooltip to show up. Here's some of my code:

/**
 * Tooltip Styles
 */

/* Add this attribute to the element that needs a tooltip */
[data-tooltip] {
  position: relative;
  z-index: 2;
  cursor: pointer;
}

/* Hide the tooltip content by default */
[data-tooltip]:before,
[data-tooltip]:after {
  visibility: hidden;
  -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";
  filter: progid: DXImageTransform.Microsoft.Alpha(Opacity=0);
  opacity: 0;
  pointer-events: none;
}

/* Position tooltip above the element */
[data-tooltip]:before {
  position: absolute;
  bottom: 150%;
  left: 50%;
  margin-bottom: 5px;
  margin-left: -80px;
  padding: 7px;
  width: 160px;
  -webkit-border-radius: 3px;
  -moz-border-radius: 3px;
  border-radius: 3px;
  background-color: #000;
  background-color: hsla(0, 0%, 20%, 0.9);
  color: #fff;
  content: attr(data-tooltip);
  text-align: center;
  font-size: 14px;
  line-height: 1.2;
}

/* Triangle hack to make tooltip look like a speech bubble */
[data-tooltip]:after {
  position: absolute;
  bottom: 150%;
  left: 50%;
  margin-left: -5px;
  width: 0;
  border-top: 5px solid #000;
  border-top: 5px solid hsla(0, 0%, 20%, 0.9);
  border-right: 5px solid transparent;
  border-left: 5px solid transparent;
  content: " ";
  font-size: 0;
  line-height: 0;
}

/* Show tooltip content on hover */
[data-tooltip]:hover:before,
[data-tooltip]:hover:after {
  visibility: visible;
-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=100)";
  filter: progid: DXImageTransform.Microsoft.Alpha(Opacity=100);
  opacity: 1;
}
</style>

//json
var data = {"counties":[{"id":"Tippecanoe", "title":"Purdue University", "r":"5"} ]};

<svg>
    <g id="counties">    
        <path id="Tippecanoe" d="M146.7,210.6 L171.4,211.3 L190.2,211.4 L200.5,211.5 L200.3,234.4 L200.3,234.4 L200.3,234.4 L200.3,234.4 L200.0,251.9 L199.7,272.8 L169.1,272.3 L146.1,272.0 L146.4,251.5 L146.6,245.2 L146.8,226.0 L146.7,226.0 L146.7,213.2 Z"></path>
    </g>
</svg>

//for each id, match up the json to the svg
function getTitleById (id){
  for(var i = 0; i < data.counties.length; i++){
    if (data.counties[i].id == id){
      return data.counties[i].title;
    }
  }
};

//same as above, but grab the radius
function getRById (id){
  for(var i = 0; i < data.counties.length; i++){
    if (data.counties[i].id == id){
      return data.counties[i].r;
    }
  }
};

//find center of each svg
var mainSVG = document.getElementById("counties");
$(document).ready(function() {
  $(".school").each(function() {
        var bbox = this.getBBox();
        var currentId = $(this).attr('id');
    var xc = Math.floor(bbox.x + bbox.width/2.0);
    var yc = Math.floor(bbox.y + bbox.height/2.0);    

//create circle
var circleNode = document.createElementNS("http://www.w3.org/2000/svg", "circle");
    circleNode.setAttribute("cx", xc);
    circleNode.setAttribute("cy", yc);
    circleNode.setAttribute("class", "circle");
    circleNode.setAttribute("stroke-width", "4");
    circleNode.setAttribute("stroke", "black");
    circleNode.setAttribute("fill", "black");
    circleNode.setAttribute("title", getTitleById(currentId));
    circleNode.setAttribute("r", getRById(currentId));
    circleNode.setAttribute("data-tooltip", getTitleById(currentId));  //suspicious line
    mainSVG.appendChild(circleNode);
});

});

The circles are showing up correctly, just not the tooltip. I think it may have to do with how I'm referencing circleNode.setAttribute("data-tooltip", getTitleById(currentId));, but when I inspect the wepbage itself, it shows up correctly as data-tooltip="Purdue University". And yet no tooltip.

altocumulus
  • 21,179
  • 13
  • 61
  • 84

1 Answers1

0

I don't think you can use the data-* attribute on SVG elements.

Check out this StackOverflow question and answer:

Do SVG docs support custom data- attributes?

Community
  • 1
  • 1
Jonathan Marzullo
  • 6,879
  • 2
  • 40
  • 46
  • Hi Jonathan, This causes my circles to be created in the code, but not on the page. For example: `` But the pointer on the webpage says "circle 0px x 0px". – angel1199410 Dec 01 '15 at 20:09
  • I am sorry i updated my answer. I made it so the namespace is `null`. So it should work now. Here check this following example which uses the same type of code. I basically am creating and appending SVG `circle` elements to the page and then animating them .. http://codepen.io/jonathan/pen/EVgYbB – Jonathan Marzullo Dec 01 '15 at 20:26
  • Hi Jonathan, The circles are back but still no tooltip. But thank you for helping me with the namespace attribute! **The more you know** – angel1199410 Dec 01 '15 at 20:35
  • Are you binding your javascript event for the tooltip after all circles have been appended? Meaning the event handler for the tooltip is not binding to the `circle` elements. I think that is why it is not firing the tooltip on hover, So you need to call the tooltip code after your `circle` elements are added to the DOM, and after the DOM is ready and after the window is loaded. Then the tooltip will fire – Jonathan Marzullo Dec 01 '15 at 20:40
  • There isn't an event, it's all CSS. When I hover over the circle, the pointer is changing (as it should from the css) but the tooltip isn't appearing. – angel1199410 Dec 01 '15 at 20:46
  • Also an example would be helpful to see your code in context? Especially the CSS you are using, since your triggering with CSS :) – Jonathan Marzullo Dec 01 '15 at 20:47
  • Also i believe you can not use the `data-*` attribute on SVG elements.. see this stackoverflow answer http://stackoverflow.com/questions/15532371/do-svg-docs-support-custom-data-attributes – Jonathan Marzullo Dec 01 '15 at 20:57
  • 1
    @JonathanMarzullo setAttributeNS(null, ...) is exactly the same as setAttribute(...) you only need setAttributeNS for xlink attributes. – Robert Longson Dec 01 '15 at 21:18
  • @RobertLongson you can actually use both.. and not just for xlink attributes according to the spec, since they both return the attribute according to the spec once SVG is used inside the DOM. So giving me a downvote for my answer when both technically can be used according to the DOM 2 spec is just plain wrong good sir .. http://www.w3.org/TR/DOM-Level-2-Core/core.html#ID-ElSetAttrNS .. http://www.w3.org/TR/DOM-Level-2-Core/core.html – Jonathan Marzullo Dec 01 '15 at 21:54
  • Jonathan, you were totally right about the data- attribute! Thanks for that! – angel1199410 Dec 01 '15 at 21:58
  • 1
    @JonathanMarzullo Advising the OP to change all his code to no benefit is a waste of time. It also incorrectly says the SVG namespace is null. It isn't, the null namespace is null and most SVG attributes are in the null namespace whereas its elements are in the SVG namespace. The first two paragraphs are right and I'd like to encourage you to delete all the nonsense after that. If you did I would upvote it. – Robert Longson Dec 02 '15 at 06:47
  • @RobertLongson I have removed the unrelated part of my answer. i appreciate your advice . Have a nice day! – Jonathan Marzullo Dec 02 '15 at 13:12
  • @angel1199410 This answer still misses the main point. The `data-*` attributes aren't the cause for the trouble with this approach. A rule like `[data-tooltip]{fill:red;}` will work perfectly fine. I am still not convinced, the spec disallows `data-*` attributes, but even if you don't like them, you could just add a custom namespace to them to circumvent any problems associated with this. The real problem is that the solution the OP wanted to use, heavily relies on `:before` and `:after` pseudo-elements as well as the `content` property which the SVG spec clearly rules out. @RobertLongson – altocumulus Dec 02 '15 at 17:45
  • i agree @RobertLongson .. looks like SVG does not like that generated `content` along with `::before` and `::after`. Here is an example .. http://codepen.io/jonathan/pen/vLBMwG/?editors=110 .. with both the anchor tag tooltip using `data-tooltip` and an SVG `circle` element, `[data-tooltip]{fill:red;}` works, but no `pseudo-element` `content` tooltip working on SVG – Jonathan Marzullo Dec 03 '15 at 14:57
  • @altocumulus You can use data-* attributes if you want, you just can't use a dataset to access them as dataset is HTML only. – Robert Longson Dec 03 '15 at 22:13