lgrimes12
lgrimes12

Reputation: 7

Create Tooltip for SVG <image> tag

I am attempting to create a tooltip that will appear when the user hover overs the icon, the tootltip will give information regarding the event. The tag is within an SVG image.

This is the code for the image:

<image  class="tooltip-trigger" data-tooltip-text="Battles" id="Battles" x="100" y="200" width="30" height="30" xlink:href="battle.png" />


<g id="tooltip" visibility="hidden" >
        <rect x="2" y="2" width="80" height="24" fill="black" opacity="0.4" rx="2" ry="2"/>
        <rect width="80" height="24" fill="white" rx="2" ry="2"/>
        <text x="3" y="6">Tooltip</text>
    </g>


<script type="text/ecmascript"><![CDATA[
    (function() {
        var svg = document.getElementById('tooltip-svg-5');
        var tooltip = svg.getElementById('tooltip');
        var tooltipText = tooltip.getElementsByTagName('text')[0].firstChild;
        var triggers = svg.getElementsByClassName('tooltip-trigger');
        for (var i = 0; i < triggers.length; i++) {
            triggers[i].addEventListener('mousemove', showTooltip);
            triggers[i].addEventListener('mouseout', hideTooltip);
        }
        function showTooltip(evt) {
            var CTM = svg.getScreenCTM();
            var x = (evt.clientX - CTM.e + 6) / CTM.a;
            var y = (evt.clientY - CTM.f + 20) / CTM.d;
            tooltip.setAttributeNS(null, "transform", "translate(" + x + " " + y + ")");
            tooltip.setAttributeNS(null, "visibility", "visible");
            tooltipText.data = evt.target.getAttributeNS(null, "data-tooltip-text");
        }
        function hideTooltip(evt) {
            tooltip.setAttributeNS(null, "visibility", "hidden");
        }
    })()
]]></script>

When loaded, the tooltip does not appear

Upvotes: 1

Views: 447

Answers (1)

enxaneta
enxaneta

Reputation: 33044

Your code is working. The problem you may have is that the tooltip appears mostly outside the svg element. I've added overflow:visible; to the svg element and now you can see the tooltip.

  (function() {
        var svg = document.getElementById('tooltip-svg-5');
        var tooltip = svg.getElementById('tooltip');
        var tooltipText = tooltip.getElementsByTagName('text')[0].firstChild;
        var triggers = svg.getElementsByClassName('tooltip-trigger');
        for (var i = 0; i < triggers.length; i++) {
            triggers[i].addEventListener('mousemove', showTooltip);
            triggers[i].addEventListener('mouseout', hideTooltip);
        }
        function showTooltip(evt) {
            var CTM = svg.getScreenCTM();
            var x = (evt.clientX - CTM.e + 6) / CTM.a;
            var y = (evt.clientY - CTM.f + 20) / CTM.d;
            tooltip.setAttributeNS(null, "transform", "translate(" + x + " " + y + ")");
            tooltip.setAttributeNS(null, "visibility", "visible");
            tooltipText.data = evt.target.getAttributeNS(null, "data-tooltip-text");
        }
        function hideTooltip(evt) {
            tooltip.setAttributeNS(null, "visibility", "hidden");
        }
    })()
svg{border:1px solid; overflow:visible;display:block;margin:auto}
<svg id="tooltip-svg-5" viewBox="0 -8 130 238" width="200">

  <image class="tooltip-trigger" data-tooltip-text="Battles" id="Battles" x="100" y="200" width="30" height="30" xlink:href="https://s3-us-west-2.amazonaws.com/s.cdpn.io/222579/pin.png" /> 
  <g id="tooltip" visibility="hidden"> 
    <rect x="2" y="2" width="80" height="24" fill="black" opacity="0.4" rx="2" ry="2"/> 
    <rect width="80" height="24" fill="white" rx="2" ry="2"/> 
    <text x="3" y="6">Tooltip</text> 
  </g> 
</svg>

Another option would have been adding text-anchor="end" to the text and rewriting the rects accordingly.

Yet another potion would have been using an HTML element for the tooltip.

Upvotes: 1

Related Questions