Public
Edited
Oct 20, 2022
Insert cell
# Intro to Event Handlers
Insert cell
{
const width = 600;
const height = 600;

const svg = d3.create("svg").attr("width", width).attr("height", height);

// Filter a bit the data -> more than 1 million inhabitants
const data = populations.filter((d) => d.value > 10000000);

// Color palette for continents.
const color = d3
.scaleOrdinal()
.domain(["Asia", "Europe", "Africa", "Oceania", "Americas"])
.range(d3.schemeSet1);

// Size scale for countries
const size = d3.scaleLinear().domain([0, 1400000000]).range([7, 100]); // circle will be between 7 and 100 px wide

const nodes = svg
.append("g")
.selectAll("circle")
.data(data)
.join("circle")
.attr("r", (d) => size(d.value))
.attr("cx", width / 2)
.attr("cy", height / 2)
.attr("stroke", "black")
.style("stroke-width", 1)
.style("fill", (d) => color(d.region))
.style("fill-opacity", 0.8);

// Part 0: Observe what happens when you click on a circle.
nodes.on("click", (event, d) => {
console.log("You clicked on", d);
});

// Part 1: Add a thicker border to nodes as the mouse is on top of them.
// You'll need to modify the "mouseover" and "mouseout" callback functions.
nodes
.on("mouseover", (event) => {
d3.select(event.target).style("stroke-width", 5);
})
.on("mouseout", (event) => {
d3.select(event.target).style("stroke-width", 1);
});

// Part 2: Add a tooltip to the circles.
// To start this part of the exercise, uncomment the code block below.
// You should see a tooltip on your circles that says "I'm a circle"
//
// Note: calling nodes.on("mouseover", ...) overwrites your function above.
// If you want to keep the hovering behavior, you'll have to put it inside the functions below.
//
// Make the tooltip say the name of the country that the mouse is on top of.
// You can add other details, like the region, subregion or population.

const tooltip = d3
.select("body")
.append("div")
.style("position", "absolute")
.style("visibility", "hidden")
// .text("I'm a circle!");

nodes
.on("mouseover", (event, d) => {
// When the mouse enters a circle, draw the tooltip.
tooltip.style("visibility", "visible");
d3.select(event.target).style("stroke-width", 5);
tooltip.html(`<p> ${d.key}, ${d.subregion}, ${d.region} </p>`)
})
.on("mousemove", (event, d) => {
// Keep the tooltip aligned with the mouse as we move it.
tooltip
.style("top", event.clientY - 10 + "px")
.style("left", event.clientX + 10 + "px");
})
.on("mouseout", (event, d) => {
// As the mouse leaves, we want to remove the tooltip
tooltip.style("visibility", "hidden");
d3.select(event.target).style("stroke-width", 1);
});

const simulation = d3
.forceSimulation()
.force(
"center",
d3
.forceCenter()
.x(width / 2)
.y(height / 2)
) // Attraction to the center of the svg area
.force("charge", d3.forceManyBody().strength(0.1)) // Nodes are attracted one each other of value is > 0
.force(
"collide",
d3
.forceCollide()
.strength(0.2)
.radius(function (d) {
return size(d.value) + 3;
})
.iterations(1) // Force that avoids circle overlapping
)
.nodes(data)
.on("tick", () => {
nodes.attr("cx", (d) => d.x).attr("cy", (d) => d.y);
});

return svg.node();
}
Insert cell
populations = FileAttachment("population.csv").csv()
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