Public
Edited
May 22
Insert cell
Insert cell
legend = Swatches(chart.scales.color)
Insert cell
chart = {
// Specify the dimensions of the chart.
const width = 928;
const height = 680;

// Specify the color scale.
const color = d3.scaleOrdinal(d3.schemeCategory10);

// The force simulation mutates links and nodes, so create a copy
// so that re-evaluating this cell produces the same result.
const links = data.links.map(d => ({...d}));
const nodes = data.nodes.map(d => ({...d}));

// Create a simulation with several forces.
const simulation = d3.forceSimulation(nodes)
.force("link", d3.forceLink(links).id(d => d.id))
.force("charge", d3.forceManyBody())
.force("x", d3.forceX())
.force("y", d3.forceY());

// Create the SVG container.
const svg = d3.create("svg")
.attr("width", width)
.attr("height", height)
.attr("viewBox", [-width / 2, -height / 2, width, height])
.attr("style", "max-width: 100%; height: auto;");

// Add a line for each link, and a circle for each node.
const link = svg.append("g")
.attr("stroke", "#999")
.attr("stroke-opacity", 0.6)
.selectAll("line")
.data(links)
.join("line")
.attr("stroke-width", d => Math.sqrt(d.value));

const node = svg.append("g")
.attr("stroke", "#fff")
.attr("stroke-width", 1.5)
.selectAll("circle")
.data(nodes)
.join("circle")
.attr("r", d => degreeScale(degreeMap.get(d.id)))
.attr("fill", d => color(d.group));

node.append("title")
.text(d => d.id);

// Add a drag behavior.
node.call(d3.drag()
.on("start", dragstarted)
.on("drag", dragged)
.on("end", dragended));
// Set the position attributes of links and nodes each time the simulation ticks.
simulation.on("tick", () => {
link
.attr("x1", d => d.source.x)
.attr("y1", d => d.source.y)
.attr("x2", d => d.target.x)
.attr("y2", d => d.target.y);

node
.attr("cx", d => d.x)
.attr("cy", d => d.y);
});

// Reheat the simulation when drag starts, and fix the subject position.
function dragstarted(event) {
if (!event.active) simulation.alphaTarget(0.3).restart();
event.subject.fx = event.subject.x;
event.subject.fy = event.subject.y;
}

// Update the subject (dragged node) position during drag.
function dragged(event) {
event.subject.fx = event.x;
event.subject.fy = event.y;
}

// Restore the target alpha so the simulation cools after dragging ends.
// Unfix the subject position now that it’s no longer being dragged.
function dragended(event) {
if (!event.active) simulation.alphaTarget(0);
event.subject.fx = null;
event.subject.fy = null;
}

// When this cell is re-run, stop the previous simulation. (This doesn’t
// really matter since the target alpha is zero and the simulation will
// stop naturally, but it’s a good practice.)
invalidation.then(() => simulation.stop());

return Object.assign(svg.node(), {scales: {color}});
}
Insert cell
degreeScale = d3.scalePow()
.range([5,30])
.domain(d3.extent(degreeMap.values(),))
Insert cell
degreeMap = {
const degree = new Map();
data.nodes.forEach(d => {
degree.set(d.id,0);
})
data.links.forEach(d => {
degree.set(d.target, degree.get(d.target)+1);
})

return degree
}
Insert cell
//Sort the map with actors and directors
Sorted ={ const mapSort = new Map([...degreeMap.entries()].sort((a, b) => b[1] - a[1]))
return mapSort
};
Insert cell
//Get the fisrt actor and director and its values
function GetActorAndDirector(mapSort, data) {
const mapArray = Array.from(mapSort); // Convert Map to Array

let actor = null;
let director = null;
let numFilmsActor = 0;
let numFilmsDirector = 0;
let i = 0;

while ((actor === null || director === null) && i < mapArray.length) {
const [key, value] = mapArray[i];

const isActor = data.nodes.some(
(node) => node.actor1 === key || node.actor2 === key
);
const isDirector = data.nodes.some(
(node) => node.director === key
);

if (isActor && actor === null) {
actor = key;
numFilmsActor = value;
} else if (isDirector && director === null) {
director = key;
numFilmsDirector = value;
}

i++;
}

return [actor, numFilmsActor, director, numFilmsDirector];
}

Insert cell
Result = {
const result = GetActorAndDirector(Sorted, data)
return (`The actor with most participations is ${result[0]}, with ${result[1]} films, and the director with most participations is ${result[2]}, with ${result[3]} films`)
}
Insert cell
import {Swatches} from "@d3/color-legend"
Insert cell
data = FileAttachment("imdb_data_100_2025.json").json()
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