Have a stand alone SVG to which I want to add a tooltip (stand alone meaning: it's not in an HTML document and not controlled by styles external to the SVG).
The SVG will be injected into HTML, together with other SVGs of a similar type (based on a database query). For example, an SVG will be displayed "center,center" in an table cell. The table, for example, will have 5 columns and 4 rows (20 SVGs total)
Here's what I have so far:
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 300 200"
id="tooltip-svg-1"
>
<style>
#tooltip {dominant-baseline: hanging;}
</style>
<rect x="-20" y="10" width="80" height="80" fill="#007bbf" class="tooltip-trigger" data-tooltip-text="Short-text"/>
<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-1');
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>
</svg>
Now would like to include a PNG in the center of an SVG
Have added xmlns:xlink="http://www.w3.org/1999/xlink"
to the SVG header.
Then inject a child-SVG as follows:
<svg viewBox="0 0 760 760" x="-34" y="15">
<image xlink:href="http://lorempixel.com/output/city-q-c-256-256-5.jpg" width="256px" height="256px"/>
</svg>
Here is that implementation:
<svg
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
viewBox="0 0 300 200"
id="tooltip-svg-2"
>
<style>
#tooltip {dominant-baseline: hanging;}
</style>
<defs>
<radialGradient id="RadialGradient-1" cx="0.5" cy="0.5" r="2">
<stop offset="0.00" style="stop-color:#ffffff; stop-opacity:1;" />
<stop offset="1.00" style="stop-color:#696969; stop-opacity:1;" />
</radialGradient>
</defs>
<rect
style="fill:url(#RadialGradient-1)"
rx="10"
ry="10"
x="10"
y="10"
width="80"
height="80"
class="tooltip-trigger"
data-tooltip-text="label with several words"
/>
<svg viewBox="0 0 760 760" x="-34" y="15">
<image xlink:href="http://lorempixel.com/output/city-q-c-256-256-5.jpg" width="256px" height="256px"/>
</svg>
<g id="tooltip" visibility="hidden" >
<rect x="2" y="2" width="200" height="24" fill="black" opacity="0.4" rx="2" ry="2"/>
<rect width="200" 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-2');
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>
</svg>
All PNGs have the same dimensions: width="256px" height="256"px
All SVG <rect>
have the same dimensions: width="80" height="80"
But there are two issues:
1 as you can see, i've munged the child-SVG viewBox
and x,y coordinates
to position PNG in the parent-SVG.
2 the tooltip does not hover over the PNG addition (the child-SVG); it displays only on the border of the parent-SVG.
Have two questions:
1 How to properly configure/relate the child-SVG (containing the PNG) to the parent-SVG (the rectangle)? In other words, how to combine the two systematically (where the position of the child-SVG is relative to the parent-SVG), as opposed to the hack that manually adjusts the child relative to the parent?
2 How to modify the <g id="tooltip">
defining the tooltip so that text is visible when hovering over the child-SVG (with the PNG), as well as the parent-SVG?