JSFiddle - React, Tailwind, and code Playground
by IceCreamYou
HTML
<div id="svg"></div>
<div id="tooltip-position"></div>
CSS
svg {
border: 1px solid blue;
}
div.tooltip {
position: absolute;
text-align: center;
box-sizing: border-box;
padding: 2px;
font: 12px sans-serif;
background: lightsteelblue;
border: 0px;
border-radius: 8px;
pointer-events: none;
}
JavaScript
var spaceCircles = [30, 70, 110, 150, 190, 230, 270];
var colors = ["red", "orange", "yellow", "green", "blue", "purple", "gray"];
var svgWidth = 300;
var svgHeight = 300;
var svgContainer = d3.select("#svg").append("svg")
.attr("width", svgWidth).attr("height", svgHeight);
var circles = svgContainer.selectAll("circle")
.data(spaceCircles).enter().append("circle");
var tooltipWidth = 150;
var tooltipHeight = 64;
var tooltip = d3.select("body").append("div")
.attr("class", "tooltip")
.style("opacity", 0)
.style("width", tooltipWidth + "px")
.style("height", tooltipHeight + "px");
circles
.attr("cx", function (d) { return d; })
.attr("cy", function (d) { return d; })
.attr("r", 20 )
.style("fill", function(d) {
return colors[spaceCircles.indexOf(d)] || "black";
})
.style("stroke-width", "1px")
.style("stroke", "black")
.on("mouseover", function(d) {
tooltip.transition().duration(200).style("opacity", 0.9);
// Center of hovered point
var cx = parseInt(d3.select(this).attr("cx"), 10);
var cy = parseInt(d3.select(this).attr("cy"), 10);
// Start out centered + above
var endPosition = "above";
var x = cx - tooltipWidth / 2;
var y = cy - tooltipHeight;
// If the tooltip goes above the top of the SVG, move it below
if (y - tooltipHeight < 0) {
endPosition = "below";
y = cy;
}
// If the tooltip is now below the bottom of the SVG, center it vertically and move it to right
if (y + tooltipHeight > svgHeight) {
endPosition = "right";
y = cy - tooltipHeight / 2;
x = cx;
}
// If the tooltip is now outside of the SVG's right side, move it to the left
if (x + tooltipWidth > svgWidth) {
endPosition = "left";
x = cx - tooltipWidth;
}
// If the tooltip is now outside of the SVG's left side, move it centered over the hovered point
if (x < 0) {
endPosition = "center";
x = cx - tooltipWidth / 2;
...