network = () => {
const svg = d3.select(DOM.svg(width, height)).style("background", "#ececec");
const g = svg.append("g").attr("transform", "translate(100,50)");
const diagram = delaunay.voronoi([0, 0, width, width / 1.6]);
const links = [];
const { halfedges, triangles, hull } = delaunay;
for (let i = 0, n = halfedges.length; i < n; ++i) {
const j = halfedges[i];
if (j < i) continue;
const ti = triangles[i] * 2;
const tj = triangles[j] * 2;
links.push({ source: nodes[ti / 2], target: nodes[tj / 2] });
}
let hullIndex = -1;
links.push({
source: nodes[hull[++hullIndex]],
target: nodes[hull[++hullIndex]]
});
while (hullIndex + 2 <= hull.length)
links.push({
source: nodes[hull[++hullIndex]],
target: nodes[hull[++hullIndex]]
});
links.forEach((link, index) => {
link.defaultColor = "#333";
if (link == null || link.source == null || link.target == null)
link.target = link.source;
const dx = link.source[0] - link.target[0];
const dy = link.source[1] - link.target[1];
link.distance = Math.sqrt(dx * dx + dy * dy);
});
nodes.forEach((pt) => {
pt.edges = links.filter((link) => pt === link.source || pt === link.target);
});
g.attr("stroke-width", 1);
const edges = g
.selectAll("path.link")
.data(links)
.enter()
.append("path")
.attr("stroke-opacity", (d) => {
return (
1 -
Math.sqrt(
Math.pow(d.source[0] - d.target[0], 2) +
Math.pow(d.source[1] - d.target[1], 2)
) /
70
);
})
.attr("stroke", (d) => {
if (isNaN(d.source[0])) {
d.source[0] = d.target[0];
d.source[1] = d.target[1];
}
if (isNaN(d.target[0])) {
d.target[0] = d.source[0];
d.target[1] = d.source[1];
}
var mid = (d.source[1] + d.target[1]) / 2;
return color(heightScale(mid));
})
.attr("d", (d) => `M${d.source} L${d.target}`);
const circles = g
.selectAll("circle")
.data(nodes)
.enter()
.append("circle")
.attr("r", (d) => 0.5 + Math.random() * 1.5)
.attr("opacity", (d) => opacityRand())
.attr("fill", (d, i) => {
return color(d[1] ? heightScale(d[1]) : 0.5);
})
.attr("cx", (d) => (d[0] ? d[0] : 0))
.attr("cy", (d) => (d[1] ? d[1] : -1000));
g.selectAll("circle")
.transition()
.delay((d) => Math.random() * 1000)
.duration(2500)
.on("start", function repeat() {
d3.active(this)
.attr("r", (d) => Math.random() * 7)
.transition()
.on("start", repeat);
});
return svg.node();
}