I am writing some JavaScript which is embedded in an SVG file. This code causes some multiline tooltips to appear when they mouse over a circle. The code is working fairly well at this point except for one thing. The text appears correctly when they first mouse over the circle, but the next time they mouseover, the same text gets appended to the first, so that the text appears twice. I have been trying to figure out how to clear this in my mouseoff function but I am stumped.
Update: I've added the SVG as well, so this is the full file.
<?xml version="1.0" encoding="utf-8"?>
<svg id="oidc" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 422 339.2" overflow="visible">
<style type="text/css">
.st13 {
fill:#d9489b
}
.st13:hover {
cursor:help;
fill:#E66E31;
}
#tooltip {
dominant-baseline: hanging;
font-size: 8px;
}
</style>
<g>
<g>
<circle class="st13" cx="47.8" cy="69.2" r="6" data-tooltip-text="I am some fairly long text." data-width="150" />
<circle class="st13" cx="321.2" cy="65.7" r="6" data-tooltip-text="I am some much much much much much much longer text, so long that I cannot discuss or itemize my exact length. It's looooong, very long. I can't say more." data-width="100" />
</g>
<g id="tooltip" visibility="hidden" transform="translate(87.9511512134412 127.90914747977598)">
<rect x="2" y="2" width="52.90066909790039" height="24" fill="black" opacity="0.4" rx="2" ry="2"></rect>
<rect width="52.90066909790039" height="24" fill="lightblue" rx="2" ry="2"></rect>
<text x="4" y="6">A box</text>
</g>
</g>
<script type="text/javascript"><![CDATA[
(function () {
var svg = document.getElementById("oidc");
var tooltip = svg.getElementById("tooltip");
var tooltipRects = tooltip.getElementsByTagName("rect");
var triggers = svg.getElementsByClassName("st13");
var tooltipText = tooltip.getElementsByTagName("text")[0];
// Add listeners
for (var i = 0; i < triggers.length; i++) {
triggers[i].addEventListener("mouseover", showTooltip);
triggers[i].addEventListener("mouseout", hideTooltip);
}
function showTooltip(evt) {
var CTM = svg.getScreenCTM();
var x = (evt.clientX - CTM.e + 6) / CTM.a;
var tspanX = tooltipText.getAttributeNS(null, 'x');
var y = (evt.clientY - CTM.f + 20) / CTM.d;
tooltip.setAttributeNS(null, "transform", "translate(" + x + " " + y + ")");
tooltip.setAttributeNS(null, "visibility", "visible");
// Sets variable containing data-width as float
var width = parseFloat(evt.target.getAttributeNS(null, "data-width"));
// Replaces text Element string with string from st13
tooltipText.firstChild.data = evt.target.getAttributeNS(null, "data-tooltip-text");
// Convert string to array of words
var words = tooltipText.firstChild.data.split(' ');
// Clear original text
tooltipText.firstChild.data = "";
// Create empty tspan element
var tspanElement = document.createElementNS("http://www.w3.org/2000/svg", "tspan");
// Create text node containing a word
var textNode = document.createTextNode(words[0]);
// Add tspan element to DOM
tspanElement.appendChild(textNode);
// Add text to tspan element
tooltipText.appendChild(tspanElement);
for (var i = 1; i < words.length; i++) {
var len = textNode.data.length;
// Add next word
tspanElement.firstChild.data += " " + words[i];
if (tspanElement.getComputedTextLength() > width) {
// Remove added word
tspanElement.firstChild.data = tspanElement.firstChild.data.slice(0, len);
// Create new tspan element
tspanElement = document.createElementNS("http://www.w3.org/2000/svg", "tspan");
tspanElement.setAttributeNS(null, "x", tspanX);
tspanElement.setAttributeNS(null, "dy", 10);
textNode = document.createTextNode(words[i]);
tspanElement.appendChild(textNode);
tooltipText.appendChild(tspanElement);
}
}
var bbox = tooltipText.getBBox();
var textWidth = bbox.width;
for (var i = 0; i < tooltipRects.length; i++) {
tooltipRects[i].setAttributeNS(null, "width", textWidth + 8);
}
var textHeight = bbox.height;
for (var i = 0; i < tooltipRects.length; i++) {
tooltipRects[i].setAttributeNS(null, "height", textHeight + 8);
}
}
function hideTooltip(evt) {
tooltip.setAttributeNS(null, "visibility", "hidden");
}
})()
]]>
</script>
</svg>