How to create an SVG “tooltip”-like box?

2019-01-17 10:26发布

问题:

Given an existing valid SVG document, what's the best way to create "informational popups", so that when you hover or click on certain elements (let's say ) you popup a box with an arbitrary amount (i.e. not just a single line tooltip) of extra information?

This should display correctly at least in Firefox and be invisible if the image was rasterized to a bitmap format.

回答1:

<svg>
  <text id="thingyouhoverover" x="50" y="35" font-size="14">Mouse over me!</text>
  <text id="thepopup" x="250" y="100" font-size="30" fill="black" visibility="hidden">Change me
    <set attributeName="visibility" from="hidden" to="visible" begin="thingyouhoverover.mouseover" end="thingyouhoverover.mouseout"/>
  </text>
</svg>

Further explanation can be found here.



回答2:

This question was asked in 2008. SVG has improved rapidly in the intervening four years. Now tooltips are fully supported in all platforms I'm aware of. Use a <title> tag (not an attribute) and you will get a native tooltip.

Here are the docs: https://developer.mozilla.org/en-US/docs/SVG/Element/title



回答3:

Since the <set> element doesn't work with Firefox 3, I think you have to use ECMAScript.

If you add the following script element into your SVG:

  <script type="text/ecmascript"> <![CDATA[

    function init(evt) {
        if ( window.svgDocument == null ) {
        // Define SGV
        svgDocument = evt.target.ownerDocument;
        }
        tooltip = svgDocument.getElementById('tooltip');
    }

    function ShowTooltip(evt) {
        // Put tooltip in the right position, change the text and make it visible
        tooltip.setAttributeNS(null,"x",evt.clientX+10);
        tooltip.setAttributeNS(null,"y",evt.clientY+30);
        tooltip.firstChild.data = evt.target.getAttributeNS(null,"mouseovertext");
        tooltip.setAttributeNS(null,"visibility","visible");
    }

    function HideTooltip(evt) {
        tooltip.setAttributeNS(null,"visibility","hidden");
    }
    ]]></script>

You need to add onload="init(evt)" into the SVG element to call the init() function.

Then, to the end of the SVG, add the tooltip text:

<text id="tooltip" x="0" y="0" visibility="hidden">Tooltip</text>

Finally, to each of the element that you want to have the mouseover function add:

onmousemove="ShowTooltip(evt)"
onmouseout="HideTooltip(evt)"
mouseovertext="Whatever text you want to show"

I've written a more detailed explanation with improved functionality at http://www.petercollingridge.co.uk/interactive-svg-components/tooltip

I haven't yet included multi-line tooltips, which would require multiple <tspan> elements and manual word wrapping.



回答4:

This should work:

nodeEnter.append("svg:element")
   .style("fill", function(d) { return d._children ? "lightsteelblue" : "#fff"; })
   .append("svg:title")
   .text(function(d) {return d.Name+"\n"+d.Age+"\n"+d.Dept;}); // It shows the tool tip box with item [Name,Age,Dept] and upend to the svg dynamicaly