Published
Edited
Sep 21, 2019
8 stars
Insert cell
Insert cell
Insert cell
Insert cell
{
const height = 425;
const svg = d3.select(DOM.svg(width, height));

let data = { nodes: [], links: [] };

let config = { dx: 30, dy: 30, rows: 16, cols: 16, margin: 10, padding: 0 };
let sx = config.dx - config.margin,
sy = config.dy - config.margin;

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"]
};
}
}

for (let x = 0; x <= config["cols"] - 1; x++) {
for (let y = 0; y <= config["rows"] - 1; y++) {
let line = [];
let tl = matrix[x][y];
line.push(tl);
line.push(matrix[x + 1][y]);
line.push(matrix[x + 1][y + 1]);
line.push(matrix[x][y + 1]);
line.push(matrix[x][y]);

let c = d3.polygonCentroid(line.map(d => [d.x, d.y]));
let d = {
id: data.nodes.length + 1,
path: line,
x1: tl.x,
y1: tl.y,
x: c[0],
y: c[1],
boxes: []
};

let startAngle = 0;
for (let a = startAngle; a < 360 + startAngle; a += angle) {
if (Math.random() > randomness) continue;

const [x, y] = polyPoint(4, Math.PI / 4, (a / Math.PI) * 180);
d.boxes.push({ parent: d, x: d.x + x * sx, y: d.y + y * sy });
}
data.nodes.push(d);
}
}

let g = svg
.selectAll("g.nodes")
.data(data.nodes)
.enter()
.append("g")
.attr("class", "nodes")
.attr("transform", d => `translate(${d.x1},${d.y1})`);

g.append("path")
.attr("class", "outlines")
.attr(
"style",
(d, i) => `fill:none; stroke: ${d3.schemeCategory10[i % 10]}`
)
.attr("d", d => "M" + d.path.map((d, i) => `${d.x},${d.y}`).join("L"));

g.selectAll("path.sublines")
.data(d => d.boxes)
.enter()
.append("path")
.attr("class", "sublines")
.attr(
"transform-origin",
d => `${d.parent.x - d.parent.x1 + 1}px ${d.parent.y - d.parent.y1 + 1}px`
)
.attr(
"style",
(d, i) => `fill:blue; stroke: ${d3.schemeCategory10[i % 10]}`
)
.attr("d", d => `M${d.x},${d.y}L${d.parent.x},${d.parent.y}`);

return svg.node();
}
Insert cell
d3 = require('d3@5')
Insert cell
import {slider} from "@jashkenas/inputs"
Insert cell
import {polyPoint} from '@mootari/polygon-sine-wave'
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