Public
Edited
Feb 21, 2023
1 fork
12 stars
Also listed in…
Observable Tricks
Insert cell
Insert cell
Insert cell
{
const svg = d3.create("svg").attr("width", width).attr("height", height);

const g = svg
.append("g")
.attr("transform", `translate(${margin.top}, ${margin.right})`);

g.append("g")
.call(d3.axisBottom(x))
.attr("transform", `translate(0, ${iheight})`);
g.append("g").call(d3.axisLeft(y));

g.selectAll("circle")
.data(data)
.join("circle")
.attr("cx", (d) => x(d[xAttr]))
.attr("cy", (d) => y(d[yAttr]))
.attr("fill", "steelblue")
.attr("r", 3)
// TOOLTIP
.call((circles) =>
circles
.append("title")
.text((d) => `${xAttr}: ${d[xAttr]}; ${yAttr}: ${d[yAttr]}`)
);

return svg.node();
}
Insert cell
Insert cell
{
const svg = d3.create("svg").attr("width", width).attr("height", height).style("overflow", "visible");

const g = svg
.append("g")
.attr("transform", `translate(${margin.top}, ${margin.right})`);

g.append("g")
.call(d3.axisBottom(x))
.attr("transform", `translate(0, ${iheight})`);
g.append("g").call(d3.axisLeft(y));
const gPoints = g.append("g").attr("class", "gPoints");

// Let's create a tooltip SVG text element
const tooltip = g
.append("text")
.attr("class", "tooltip")
.attr("fill", "black")
.style("pointer-events", "none");

gPoints
.selectAll("circle")
.data(data)
.join("circle")
.attr("cx", (d) => x(d[xAttr]))
.attr("cy", (d) => y(d[yAttr]))
.attr("fill", "steelblue")
.attr("r", 3)
// Change the contents and position of the tooltip
.on("mouseover", (evt, d) => {
const [mx, my] = d3.pointer(evt);
tooltip
.attr("x", mx)
.attr("y", my)
.text(`a ${xAttr}: ${d[xAttr]}; ${yAttr}: ${d[yAttr]}`);
})
.on("mouseout", () => {
// clear the tooltip
tooltip.text("");
});

return svg.node();
}
Insert cell
Insert cell
{
const svg = d3
.create("svg")
.attr("width", width)
.attr("height", height)
.style("overflow", "visible");

const g = svg
.append("g")
.attr("transform", `translate(${margin.top}, ${margin.right})`);

g.append("g")
.call(d3.axisBottom(x))
.attr("transform", `translate(0, ${iheight})`);
g.append("g").call(d3.axisLeft(y));
const gPoints = g.append("g").attr("class", "gPoints");

// Let's create a tooltip SVG text element
const tooltip = g
.append("text")
.attr("class", "tooltip")
.attr("fill", "black");

gPoints
.selectAll("circle")
.data(data)
.join("circle")
.attr("cx", (d) => x(d[xAttr]))
.attr("cy", (d) => y(d[yAttr]))
.attr("fill", "steelblue")
.attr("r", 3)
// Change the contents and position of the tooltip
.on("mouseenter", (evt, d) => {
const [mx, my] = d3.pointer(evt);
const tooltipText = `${xAttr}: ${d[xAttr]}\n ${yAttr}: ${d[yAttr]}`;
tooltip
.attr("transform", `translate(${mx}, ${my})`)
.selectAll("tspan")
.data(tooltipText.split("\n"))
.join("tspan")
.attr("dy", "1em")
.attr("x", "0px")
.text((text) => text );
})
.on("mouseout", () => tooltip.selectAll("tspan").remove());

return svg.node();
}
Insert cell
Insert cell
{
const svg = d3
.create("svg")
.attr("width", width)
.attr("height", height)
.style("overflow", "visible");

// We wrap the SVG with a container that has the html element above it
const container = html`<div>
<style>.tooltip {
font: sans-serif 12pt;
background: #eeeeeeee;
pointer-events: none;
border-radius: 2px;
padding: 5px;
position: absolute;
top: 0px;
left: 0px;
z-index: 1;

}</style>

<div class="tooltip"></div>
${svg.node()}

</div>`

const g = svg
.append("g")
.attr("transform", `translate(${margin.top}, ${margin.right})`);

g.append("g")
.call(d3.axisBottom(x))
.attr("transform", `translate(0, ${iheight})`);
g.append("g").call(d3.axisLeft(y));
const gPoints = g.append("g").attr("class", "gPoints");

// A selection for the tooltip
const tooltip = d3.select(container).select(".tooltip");

gPoints
.selectAll("circle")
.data(data)
.join("circle")
.attr("cx", (d) => x(d[xAttr]))
.attr("cy", (d) => y(d[yAttr]))
.attr("fill", "steelblue")
.attr("r", 3)
// Change the contents and position of the tooltip
.on("mouseenter", (evt, d) => {
const [mx, my] = d3.pointer(evt);
const tooltipText = `
<strong>${xAttr}</strong>: ${d[xAttr]}
<br>
<strong>${yAttr}</strong>: ${d[yAttr]}`;
tooltip
.style("top", `${my}px`)
.style("left", `${mx}px`)
.html(tooltipText);
})
.on("mouseout", () => tooltip.text());

return container;
}
Insert cell
Insert cell
{
const svg = d3
.create("svg")
.attr("width", width)
.attr("height", height)
.style("overflow", "visible");

const g = svg
.append("g")
.attr("transform", `translate(${margin.top}, ${margin.right})`);

g.append("g")
.call(d3.axisBottom(x))
.attr("transform", `translate(0, ${iheight})`);
g.append("g").call(d3.axisLeft(y));
const gPoints = g.append("g").attr("class", "gPoints");

const points = gPoints
.selectAll("circle")
.data(data)
.join("circle")
.attr("cx", (d) => x(d[xAttr]))
.attr("cy", (d) => y(d[yAttr]))
.attr("fill", "steelblue")
.attr("r", 3)

hover(points, invalidation);

return svg.node();
}
Insert cell
import {hover} with {tipcontent} from "@fil/hello-tippy"
Insert cell
function tipcontent(d) {
return `<strong>${xAttr}</strong>: ${d[xAttr]}
<br>
<strong>${yAttr}</strong>: ${d[yAttr]}`;
}
Insert cell
x = d3.scaleLinear()
.domain(d3.extent(data, d => d[xAttr]))
.range([0, iwidth])
Insert cell
y = d3.scaleLinear()
.domain(d3.extent(data, d => d[yAttr]))
.range([iheight, 0])
Insert cell
xAttr = "culmen_length_mm"
Insert cell
yAttr = "culmen_depth_mm"
Insert cell
iwidth = width - margin.left - margin.right
Insert cell
iheight = height - margin.top - margin.bottom
Insert cell
height = 300
Insert cell
width = 400
Insert cell
data = penguins
Insert cell
margin = ({left: 20, top: 20, right: 20, bottom: 20})
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