Published
Edited
Aug 27, 2019
4 stars
Insert cell
Insert cell
Insert cell
{
const height = 425
const width = 425
const svg = d3.select(DOM.svg(width, height))
.attr("transform-origin", "200px 245px")
.attr("transform", "rotate(45)")

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

let config = {'dx': 30, 'dy': 30, "rows": 10, "cols": 10, 'margin': 50, 'padding': 0 }
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 boxes = []
for(let a = 0; a <= 90; a+=angle) {
d.boxes.push({parent: d, a: a, i: x+y, translate: `${-d.path[0].x},${-d.path[0].y}`})
}
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})`)
let subnodes = g.selectAll("path.subnodes")
.data(d => d.boxes)
.enter().append("path")
.attr("class", "subnodes")
.attr("transform-origin", d => `${(d.parent.x-d.parent.x1)+1}px ${(d.parent.y-d.parent.y1)+1}px`)
.attr("transform", d => `scale(0) rotate(0) translate(${d.translate})`)
.attr("style", (d, i) => `fill:none; stroke: ${d3.schemeCategory10[i%10]}`)
.attr("d", d => "M" + d.parent.path.map((d,i) => `${d.x},${d.y}`).join("L"))
// only show the transition/demo on the first page load
if(mutable transition) {
subnodes.transition()
.duration(1000)
.delay(d => d.i*100)
.attrTween("transform", d => d3.interpolateString(`scale(0) rotate(0) translate(${d.translate})`,
`scale(${1*(d.a/90)}) rotate(${d.a}) translate(${d.translate})`))
mutable transition = false
} else {
subnodes.attr("transform", d=> `scale(${1*(d.a/90)}) rotate(${d.a}) translate(${d.translate})`)
}
return svg.node()
}
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