Public
Edited
Mar 26
Insert cell
Insert cell
d3 = require("d3@6")
Insert cell
VegaLite = require("vega-embed@6")
Insert cell
lecture_exercise.csv
Type Table, then Shift-Enter. Ctrl-space for more options.

Insert cell
dataFile = FileAttachment("lecture_exercise.csv").csv({typed: true})
Insert cell
csvData = d3.csvParse(await FileAttachment("lecture_exercise.csv").text(), d3.autoType)
Insert cell
csvData[0]
Insert cell
data =
{
// Build an array of nodes from the CSV data:
const nodes = csvData.map(d => ({ id: d[""] }));
// Build an array of links:
const links = csvData.flatMap(d => {
const source = d[""]; // The node label from the first column.
return Object.entries(d)
.filter(([key, value]) => key !== "" && +value > 0) // ignore the empty key and zero weights (if you want to skip zero-value links)
.map(([target, value]) => ({ source, target, value: +value }));
});
// Return the object with nodes and links:
return { nodes, links };
}

Insert cell
chart = {
const base = vl.markRect({ tooltip: true }).encode(
vl.x().fieldO('source').sort(vl.field('source_group')).title(null).axis({ orient: 'top' }),
vl.y().fieldO('target').sort(vl.field('source_group')).title(null),
vl.color().fieldN('source_group').title('group')
);

const reverse = base.encode(
vl.x().fieldO('target').sort(vl.field('source_group')),
vl.y().fieldO('source').sort(vl.field('source_group'))
);

return vl
.layer(base, reverse)
.data(data.links)
.width(600)
.height(600)
.render();
}
Insert cell
import {ForceGraph} from "@d3/force-directed-graph-component"
Insert cell
svg marker path {
fill: currentColor;
}
Insert cell
{
const extent = d3.extent(data.links, l => l.value);
const minValue = extent[0];
const maxValue = extent[1];
const midValue = (minValue + maxValue) / 2;
const colorScale = d3.scaleLinear()
.domain([minValue, midValue, maxValue])
.range(["green", "yellow", "red"]);
//return { minValue, maxValue };
return ForceGraph(data, {
nodeId: d => d.id,
nodeGroup: d => d.group,
nodeTitle: d => `${d.id}\n${d.group}`,
nodeRadius: 10,
linkFill: l => colorScale(l.value), // sets link color based on its value
linkStroke: l => colorScale(l.value), // sets link color based on its value
linkStrokeWidth: l => Math.sqrt(l.value)*5,
nodeStrength: -100,
linkStrength: 0.001,
width,
height: 600,
invalidation
})
}
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