Public
Edited
Feb 2, 2024
Insert cell
Insert cell
chart = {
const width = 960;
const height = 600;

const tooltipWidth = 500;
const tooltipHeight = 200;

const projection = d3
.geoAlbersUsa()
.translate([width / 2, height / 2])
.scale([1200]);

const path = d3.geoPath().projection(projection);

const svg = d3.select(DOM.svg(width, height));

svg
.append("path")
.datum(topojson.merge(us, us.objects.lower48.geometries))
.attr("fill", "#f3e9dc")
.attr("stroke", "#c08552")
.attr("d", d3.geoPath());

svg
.append("path")
.datum(topojson.mesh(us, us.objects.lower48, (a, b) => a !== b))
.attr("fill", "none")
.attr("stroke", "#c08552")
.attr("stroke-linejoin", "round")
.attr("d", d3.geoPath());

const g = svg.append("g").attr("fill", "none").attr("stroke", "black");

const tooltip = d3
.select("body")
.append("div")
.attr("class", "tooltip")
.style("opacity", 0.9)
.style("position", "absolute")
.style("width", tooltipWidth + "px") // Set the width of the tooltip
.style("height", tooltipHeight + "px") // Set the height of the tooltip
.style("display", "flex") // Use flexbox for layout
.style("align-items", "center") // Center items vertically
.style("background", "white")
.style("padding", "10px")
.style("border", "1px solid #ccc")
.style("border-radius", "5px")
.style("pointer-events", "none")
.style("font-size", "0.55em")
.style("color", "black")
.style("box-shadow", "2px 2px 10px rgba(0,0,0,0.5)");

svg
.selectAll("circle")
.data(df)
.enter()
.append("circle")
.attr("cx", (d) => projection([d.longitude, d.latitude])[0])
.attr("cy", (d) => projection([d.longitude, d.latitude])[1])
.attr("r", 8)
.attr("opacity", 0.5)
.attr("fill", "#8B4513")
.attr("stroke", "black")
.on("mouseover", (event, d) => {
const xOffset =
event.pageX + tooltipWidth + 20 > window.innerWidth
? -tooltipWidth - 20
: 10;
tooltip.transition().duration(200).style("opacity", 0.9);
tooltip
.html(
`<div style="height: 100%; display: flex; justify-content: start;">
<img src="${d.image}" alt="${d.name}" style="max-width: 50%; max-height: 100%; margin-right: 10px;">
<div>
<strong>${d.name}</strong><br/>
${d.description}
</div>
</div>`
)
.style("left", event.pageX + xOffset + "px")
.style("top", event.pageY - tooltipHeight / 2 + "px"); // Center the tooltip vertically
})
.on("mouseout", () => {
tooltip.transition().duration(500).style("opacity", 0);
});
return svg.node();
}
Insert cell
groundhogs.csv
Type Table, then Shift-Enter. Ctrl-space for more options.

Insert cell
groundhogs.csv
SELECT * FROM groundhogs
where country = 'USA'
Insert cell
us = {
const us = await d3.json("https://cdn.jsdelivr.net/npm/us-atlas@1/us/10m.json");
us.objects.lower48 = {
type: "GeometryCollection",
geometries: us.objects.states.geometries.filter(d => d.id !== "02" && d.id !== "15")
};
return us;
}
Insert cell
projection = d3.geoAlbersUsa().scale(1280).translate([480, 300])
Insert cell
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