Public
Edited
Dec 18
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
graph = {
const _graph = datasets[selectedDataset];

// Compute degrees
var degrees = {}
_graph.edges.forEach((e) => {
const { source, target } = e;
degrees[source] = (degrees[source] || 0) + 1
degrees[target] = (degrees[target] || 0) + 1
})
_graph.nodes.forEach((n) => {
const attributes = n.attributes;
const t = new Set();
const classes = [];
let classes_sorted = JSON.parse(JSON.stringify(classes));
classes_sorted = classes_sorted.sort();
attributes.classes_sorted = classes_sorted;
const modeValue = d3.mode(classes);
const modeValueIntensity =
classes.filter((c) => c === modeValue).length / classes.length;
attributes.modeValue = modeValue;
attributes.modeValueIntensity = modeValueIntensity;
});
_graph.edges.forEach((e) => {
const { source, target } = e;

const sourceNode = _graph.nodes.find((n) => n.id === source);
e.x1 = sourceNode.x;
e.y1 = sourceNode.y;

const targetNode = _graph.nodes.find((n) => n.id === target);
e.x2 = targetNode.x;
e.y2 = targetNode.y;

var continuity = 0
for (let i = 0; i < 10; i++) {
const sourceAttributes = sourceNode.attributes;
const targetAttributes = targetNode.attributes;
const key = "Modularity Class_" + i;
const same = sourceAttributes[key] == targetAttributes[key]
if (same) { continuity += 0.1 }
}

e.continuity = continuity

// Bias
/*const degree1 = 10+(degrees[source])
const degree2 = 10+(degrees[target])
e.bias = degree1/(degree1+degree2)*/
e.bias = 0.5
e.angle = Math.atan2(e.y2-e.y1,e.x2-e.x1) + Math.PI/2
});
return _graph;
}
Insert cell
Insert cell
// Compute Voronoï and related data
v = {
// Adjust coordinates to account for the translation
const delaunay = d3.Delaunay.from(
graph.nodes,
d => x(d.x),
d => y(d.y)
);
const voronoi = delaunay.voronoi([
-width / 2, // left
-height / 2, // top
width / 2, // right
height / 2 // bottom
]);
return {
delaunay,
voronoi
}
}
Insert cell
rendering2 = {
// scales
const scales = {
nodes: d3
.scaleSequential()
.range(["#000000", "#FF0000"])
.domain(d3.extent(graph.nodes, (d) => d.attributes.hesitancy)),
continuedEdges: d3
.scaleSequential()
.range(["#FF0000", "#000000"])
.domain(d3.extent(graph.edges, (d) => d.continuity)),
breakingEdges: d3
.scaleSequential()
.range(["#FFFFFF", "#FF0000"])
.domain(d3.extent(graph.edges, (d) => d.continuity)),
};
const breakSize = 25
const svg = d3.create("svg").attr("viewBox", `0 0 ${width} ${height}`);
const defs = svg.append("defs");
const g = svg
.append("g")
.attr("transform", `translate(${width / 2},${height / 2})`);
/*
// Add Voronoi cell paths
const voronoiPaths = g
.selectAll("path.voronoi")
.data(graph.nodes)
.join("path")
.attr("class", "voronoi")
.attr("d", (d, i) => v.voronoi.renderCell(i))
.attr("fill", "rgba(0,0,255,0.1)") // Light blue with transparency
.attr("stroke", "rgba(0,0,255,0.3)") // Slightly darker border
.attr("stroke-width", 1)
.attr("pointer-events", "none"); // Ensure it doesn't interfere with other interactions
*/
// Tinkering
var segments = []
v.delaunay.halfedges.forEach((j, i) => {
console.log(i,j)
let x1 =
segments.push({x1, y1, x2, y2})
})
/*const edgeBlack = g
.selectAll("line.black")
.data(graph.edges, (d) => d.id)
.join("line")
.attr("class", "black")
.attr("fill", "none")
.attr("stroke", (d) => scales.continuedEdges(d.continuity))
.attr("stroke-width", (d) => 3)
.attr("x1", (d) => x(d.x1))
.attr("y1", (d) => y(d.y1))
.attr("x2", (d) => x(d.x2))
.attr("y2", (d) => y(d.y2))
;*/
const node = g
.selectAll("circle.top")
.data(graph.nodes, (d) => d.id)
.join("circle")
.attr("class", "bg")
.attr("r", (d) => s(d.size))
.attr("cx", (d) => x(d.x))
.attr("cy", (d) => y(d.y))
.attr("fill", (d) => scales.nodes(d.attributes.hesitancy))
;
return svg.node();
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
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