Public
Edited
Jun 14, 2023
Importers
3 stars
Insert cell
Insert cell
Insert cell
{
const scatter = Plot.plot({
marks: [
Plot.dot(cars, {x: "power (hp)", y: "economy (mpg)", fill: "slateblue", title: d => d.name})
]
})

const scatterSelect = d3.select(scatter)
const tooltip = addTooltip(scatterSelect, scatterSelect.selectAll("circle"))

return scatter
}
Insert cell
Insert cell
Insert cell
{
const svg = d3.select("#example-svg")
const circles = svg.selectAll("circle")
const tooltip = addTooltip(svg)

circles.on("mouseover", (e,d) => {
tooltip.show(""+d, d[0], d[1])
})

circles.on("mouseleave", (e,d) => {
tooltip.hide()
})
return tooltip
}
Insert cell
Insert cell
Insert cell
Insert cell
{
const plot = Plot.plot({
projection: "albers-usa",
marks: [
Plot.geo(counties, { stroke: "lightgrey", fill: "white" }),
Plot.geo(states, { stroke: "slategrey" })
]
})

const plotSelect = d3.select(plot)
const geoSelect = d3.select(plotSelect.selectAll("g[aria-label='geo'").nodes()[0])
.selectAll("path")
const tooltip = addTooltip(plotSelect)

geoSelect.on("mouseover", (e,d) => {
const bbox = e.target.getBBox()
const centroid = [bbox.x + bbox.width/2, bbox.y+bbox.height/2]
tooltip.show(counties.features[d].properties.name, centroid[0], centroid[1])
})
.on("mouseleave", () => tooltip.hide())

return plot
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
function addTooltip(svgSelect, elementSelect=null) {
const mouseOffset = [10,10]

const style = `
.svg-tooltip {
background-color: rgba(255, 255, 255, 0.7);
position: absolute;
transform: translate(178px, 410.19px);
border-style: solid;
border-color: black;
border-width: 1px;
border-radius: 2px;
font-family: sans-serif;
font-size: 12px;
padding: 8px;
visibility: hidden;
max-width: 150px;
}`

svgSelect.append("style").text(style)
const foreignObject = svgSelect.append("foreignObject")
.attr("width", "100%")
.attr("height", "100%")
.attr("pointer-events", "none")

const tooltip = foreignObject.append("xhtml:div")
.attr("class", "svg-tooltip")

function show(text, x, y) {
let posX = x + mouseOffset[0]
let posY = y + mouseOffset[1]
tooltip.html(text)
tooltip.style("visibility", "visible")
const svgBox = svgSelect.node().getBBox()
const tooltipBox = tooltip.node().getBoundingClientRect()

if (posX > svgBox.width - tooltipBox.width) {
posX = x - tooltipBox.width - mouseOffset[0]
}
if (posY > svgBox.height - tooltipBox.height) {
posY = y - tooltipBox.height - mouseOffset[1]
}
tooltip.style("transform", `translate(${posX}px,${posY}px)`)
}

function hide() {
tooltip.style("visibility", "hidden")
}

if (elementSelect != null) {
elementSelect.on("mouseover", e => {
const title = d3.select(e.target).select("title").text()
const bbox = e.target.getBBox()
const centroid = [bbox.x + bbox.width/2, bbox.y+bbox.height/2]
show(title, centroid[0], centroid[1])
})
.on("mouseleave", () => hide())
}
return {show, hide}
}
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more