{
const height = 425;
const svg = d3.select(DOM.svg(width, height));
let container = svg
.append("g")
.attr("transform-origin", "350px 155px")
.attr("transform", "rotate(45)");
let elements = 54;
let size = 20;
let config = {
dx: size,
dy: size,
rows: elements / 2,
cols: elements / 2,
margin: 0,
padding: 2
};
let matrix = {};
for (let y = 0; y <= config["rows"]; y++) {
matrix[y] = {};
for (let x = 0; x <= config["cols"]; x++) {
matrix[y][x] = {
x: config["margin"] + x * config["dx"],
y: config["margin"] + y * config["dy"]
};
}
}
var data = { nodes: [], links: [] };
for (let x = 0; x <= config["cols"] - 1; x++) {
for (let y = 0; y <= config["rows"] - 1; y++) {
let line = [];
line.push(matrix[x][y]);
line.push(matrix[x + 1][y]);
line.push(matrix[x + 1][y + 1]);
line.push(matrix[x][y + 1]);
line.push(matrix[x][y]);
line = line.map(d => {
return {
x: d.x + config['padding'] * y,
y: d.y + config['padding'] * x
};
});
let tl = line[0];
let c = d3.polygonCentroid(line.map(d => [d.x, d.y]));
data.nodes.push({
id: data.nodes.length + 1,
path: line,
x1: tl.x,
y1: tl.y,
x: c[0],
y: c[1]
});
}
}
let voronoi = d3
.voronoi()
.x(d => d.x)
.y(d => d.y);
voronoi.links(data.nodes).forEach(l => {
var dx = l.source.x - l.target.x,
dy = l.source.y - l.target.y;
l.distance = Math.sqrt(dx * dx + dy * dy);
// only connect neighbors
if (l.distance <= config["dx"] + config["dy"]) {
data.links.push({
distance: Math.sqrt(dx * dx + dy * dy),
source: l.source,
target: l.target
});
}
});
var gLines = container
.append("g")
.attr("class", "lines")
.selectAll("g.lines");
var link = gLines
.data(data.links)
.enter()
.append("line")
.attr(
"style",
(_, i) => `stroke-width: 4px; stroke: ${d3.schemeCategory10[3]}`
);
var g = container
.selectAll("g.nodes")
.data(data.nodes)
.enter()
.append("g")
.attr("class", "nodes");
var node = g;
g.append("path")
.attr("class", "poly")
.attr("transform", d => `translate(${d.x},${d.y})`)
.attr("style", (_, i) => `fill: white; stroke: ${d3.schemeCategory10[3]}`)
.attr("d", d => "M" + d.path.map((d, i) => `${d.x},${d.y}`).join("L"));
var simulation = d3
.forceSimulation()
.force("link", d3.forceLink().id(d => d.id))
.force("charge", d3.forceManyBody());
simulation.nodes(data.nodes);
simulation.force("link").links(data.links);
function tick(e) {
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("transform", d => `translate(${d.x},${d.y})`);
}
simulation.on("tick", tick);
simulation.stop();
tick();
return svg.node();
}