Public
Edited
Dec 20, 2023
Insert cell
Insert cell
Insert cell
Insert cell
limith = 1500
Insert cell
centerStrenghtScale = d3
.scaleLinear()
.domain(d3.extent(network.nodes, d => d.value))
.range(
centeringForceType === "Larger Nodes Outside"
? [0.5, 0.0001]
: centeringForceType === "Larger Nodes Inside"
? [0.0001, 0.5]
: [0.1, 0.1]
)
Insert cell
{
// Switch the option after 4.5s
await Promises.delay(4500);
viewof centeringForceType.value = "Larger Nodes Outside";
viewof centeringForceType.dispatchEvent(new CustomEvent("input"));
}
Insert cell
network = {
const dLinks = new Map();

for (let t of movies.slice(0,limith)) {
if (t.type == "Movie") {
const key = getKey(t.director, t.show_id);
if (key == "ignore") continue;
if (!dLinks.has(key)) dLinks.set(key, 0);

dLinks.set(key, dLinks.get(key) + 1);
}
}

const dNodes = new Map();
let links = [];
for (let [l, v] of dLinks) {
const [source, target] = l.split("~");

const s = findOrAdd(dNodes, source);
const t = findOrAdd(dNodes, target);

dNodes.set(source, ((s.value += 1), s));
dNodes.set(target, ((t.value += 1), t));
links.push({ source: s, target: t, value: v });
}

const network = { nodes: Array.from(dNodes.values()), links };
return network;
}
Insert cell
drag = simulation => {
function dragsubject(event) {
return simulation.find(event.x, event.y);
}

function dragstarted(event) {
if (!event.active) simulation.alphaTarget(0.3).restart();
event.subject.fx = event.subject.x;
event.subject.fy = event.subject.y;
}

function dragged(event) {
event.subject.fx = event.x;
event.subject.fy = event.y;
}

function dragended(event) {
if (!event.active) simulation.alphaTarget(0);
event.subject.fx = null;
event.subject.fy = null;
}

return d3
.drag()
.subject(dragsubject)
.on("start", dragstarted)
.on("drag", dragged)
.on("end", dragended);
}
Insert cell
color = d3.scaleOrdinal(d3.schemeCategory10)
Insert cell
opacity = d3
.scaleLinear()
.domain(d3.extent(network.links, d => d.value))
.range([0.1, 1])
Insert cell
size = d3
.scaleLinear()
.domain(d3.extent(network.nodes, d => d.value))
.range([1, 5])
Insert cell
height = 600
Insert cell
findOrAdd = (dNodes, n) => {
if (!dNodes.has(n)) dNodes.set(n, { id: n, value: 0 });
return dNodes.get(n);
}
Insert cell
getKey = (a, b) => { if (a == '' || b == '') return "ignore";
return `${a}~${b}`}
Insert cell
movies = FileAttachment("netflix_titles.csv").csv()
Insert cell
d3 = require("d3@6")
Insert cell
forceBoundary = require("d3-force-boundary")
Insert cell
import { Radio } from "@observablehq/inputs"
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