Published
Edited
Sep 5, 2021
2 forks
72 stars
Insert cell
Insert cell
Insert cell
html`<svg width=440 height=440 style="fill:none; stroke:black; stroke-width:1; stroke-opacity:0.5">
<rect x="40" y="40" width="160" height="160" />
<rect x="240" y="40" width="160" height="160" />
<rect x="40" y="240" width="160" height="160" />
<rect x="240" y="240" width="160" height="160" />
</svg>`
Insert cell
Insert cell
// Width of the SVG
two_svgWidth = 440
Insert cell
// Height of the SVG
two_svgHeight = 440
Insert cell
// Margin size between the squares
two_margin = 40
Insert cell
// Size of square we want
two_squareSize = (two_svgWidth - (3*two_margin))/2
Insert cell
html`<svg width=${two_svgWidth} height=${two_svgHeight} style="fill:none; stroke:black; stroke-width:1; stroke-opacity:0.5">
<rect x="${two_margin}" y="${two_margin}" width="${two_squareSize}" height="${two_squareSize}" />
<rect x="${2 * two_margin + two_squareSize}" y="${two_margin}" width="${two_squareSize}" height="${two_squareSize}" />
<rect x="${two_margin}" y="${2* two_margin + two_squareSize}" width="${two_squareSize}" height="${two_squareSize}" />
<rect x="${2* two_margin + two_squareSize}" y="${2* two_margin + two_squareSize}" width="${two_squareSize}" height="${two_squareSize}"/>
</svg>`
Insert cell
Insert cell
// How many squares we want to plot
three_squares = 5
Insert cell
// How big the squares should be
three_squareSize = 160
Insert cell
// Margin size
three_margin = 40
Insert cell
Insert cell
// Width of the SVG
three_svgWidth = (2 * three_squareSize) + (3 * three_margin)
Insert cell
// Height of the SVG. We use Math.ceil() here so we don't get remainders
three_svgHeight = ((Math.ceil(three_squares / 2)) * three_squareSize) + ((Math.ceil(three_squares / 2) + 1) * three_margin)
Insert cell
Insert cell
three_squarePositions = {
let squarePositions = []
for (let i = 0; i < three_squares; i++) {
if (i % 2 == 0) {
let x = three_margin;
let y = ((Math.floor(i/2) + 1) *three_margin) + ((Math.floor(i/2) * three_squareSize));
squarePositions.push([x, y]);
} else {
let x = (three_margin*2) + three_squareSize;
let y = ((Math.floor(i/2) + 1) * three_margin) + ((Math.floor(i/2) * three_squareSize));
squarePositions.push([x, y]);
}
}
return squarePositions;
}
Insert cell
Insert cell
d3 = require("d3@5")
Insert cell
three_svg = {
const svg = DOM.svg(three_svgWidth, three_svgHeight);
d3.select(svg)
.selectAll("rect")
.data(three_squarePositions)
.enter().append("rect")
.attr("x", coords => coords[0])
.attr("y", coords => coords[1])
.attr("width", three_squareSize)
.attr("height", three_squareSize)
.attr("stroke", "black")
.attr("fill", "none");
return svg;
}
Insert cell
Insert cell
// Here's the page width
width
Insert cell
// Number of rows
four_rows = 5
Insert cell
// Number of columns
four_columns = 15
Insert cell
// Size of the margin
four_margin = 10
Insert cell
Insert cell
// Calculate the size of each square based on the width, margin and number of columns
four_squareSize = (width - ((four_columns + 1) * four_margin)) / four_columns
Insert cell
// Calculate the height of the SVG based on the square size and number of rows we want
four_svgHeight = (four_squareSize * four_rows) + (four_margin * (four_rows + 1))
Insert cell
Insert cell
four_squarePositions = {
let squarePositions = [] ;
for (let i = 0; i < four_columns; i++) {
for (let j = 0; j < four_rows; j++) {
// At this point in the code i represents the column number and j is the row number
let square = {column: i, row: j,
x: (four_margin * (i + 1) + four_squareSize * i),
y: (four_margin * (j + 1) + four_squareSize * j)
};
squarePositions.push(square);
}
}
return squarePositions;
}
Insert cell
Insert cell
four_svg = {
const svg = DOM.svg(width, four_svgHeight);
d3.select(svg)
.selectAll("rect")
.data(four_squarePositions)
.enter().append("rect")
.attr("x", square => square.x)
.attr("y", square => square.y)
.attr("width", four_squareSize)
.attr("height", four_squareSize)
.attr("stroke", "black")
.attr("fill", "none");
return svg;
}
Insert cell
Insert cell
html`
<svg width=440 height=440 style="fill:none;stroke:black;stroke-width:1;stroke-opacity:0.5">
<path d="M40 40 L200 40 L200 200 L40 200 Z" />
<path d="M240 40 L400 40 L400 200 L240 200 Z" />
<path d="M40 240 L200 240 L200 400 L40 400 Z" />
<path d="M240 240 L400 240 L400 400 L240 400 Z" />
</svg>`
Insert cell
Insert cell
five_squarePositions = {
let squarePositions = [];
for (let i = 0; i < four_columns; i++) {
for (let j = 0; j < four_rows; j++) {
// At this point in the code i represents the column number and j is the row number
let square = {column: i, row: j,
x1: (four_margin * (i + 1) + four_squareSize * i),
y1: (four_margin * (j + 1) + four_squareSize * j),
x2: (four_margin * (i + 1) + four_squareSize * (i + 1)),
y2: (four_margin * (j + 1) + four_squareSize * j),
x3: (four_margin * (i + 1) + four_squareSize * (i + 1)),
y3: (four_margin * (j + 1) + four_squareSize * (j + 1)),
x4: (four_margin * (i + 1) + four_squareSize * i),
y4: (four_margin * (j + 1) + four_squareSize * (j + 1))
};
squarePositions.push(square);
}
}
return squarePositions;
}
Insert cell
Insert cell
five_svg = {
const svg = DOM.svg(width, four_svgHeight);
d3.select(svg)
.selectAll("path")
.data(five_squarePositions)
.enter().append("path")
.attr("d", square => `M${square.x1} ${square.y1} L${square.x2} ${square.y2} L${square.x3} ${square.y3} L${square.x4} ${square.y4} Z`)
.attr("stroke", "black")
.attr("fill", "none");
return svg;
}
Insert cell
Insert cell
perturber = (square) => {
let magnitude = square.column * 2 // This line defines how the randomness spreads across the image
let perturb = () => ((Math.random() - 0.5) * (magnitude * 3)); // The line defines the size of the randomness
let wonkySquare = {column: square.column, row: square.row,
x1: square.x1 + perturb(),
x2: square.x2 + perturb(),
x3: square.x3 + perturb(),
x4: square.x4 + perturb(),
y1: square.y1 + perturb(),
y2: square.y2 + perturb(),
y3: square.y3 + perturb(),
y4: square.y4 + perturb()
};
return wonkySquare;
}
Insert cell
Insert cell
six_squarePositions = {
let squarePositions = [];
for (let i = 0; i < five_squarePositions.length; i++) {
squarePositions.push(perturber(five_squarePositions[i]));
};
return squarePositions;
}
Insert cell
Insert cell
six_svg = {
const svg = DOM.svg(width, four_svgHeight);
d3.select(svg)
.selectAll("path")
.data(six_squarePositions)
.enter()
.append("path")
.attr("d", square => `M${square.x1} ${square.y1} L${square.x2} ${square.y2} L${square.x3} ${square.y3} L${square.x4} ${square.y4} Z`)
.attr("stroke", "black")
.attr("fill", "none");
return svg;
}
Insert cell
Insert cell
seven_squarePositions = {
let squarePositions = [];
for (let i = 0; i < five_squarePositions.length; i++) {
squarePositions.push(perturber(five_squarePositions[i]))
// This is the new bit - a for loop that runs a number of times equal to the column number minus one.
for (let j = 0; j < five_squarePositions[i].column; j++) {
squarePositions.push(perturber(five_squarePositions[i]));
}
};
return squarePositions;
}
Insert cell
Insert cell
seven_svg = {
const svg = DOM.svg(width, four_svgHeight);
d3.select(svg)
.selectAll("path")
.data(seven_squarePositions)
.enter()
.append("path")
.attr("d", square => `M${square.x1} ${square.y1} L${square.x2} ${square.y2} L${square.x3} ${square.y3} L${square.x4} ${square.y4} Z`)
.attr("stroke", "black")
.attr("fill", "none");
return svg;
}
Insert cell
Insert cell
import {slider} from "@jashkenas/inputs"
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
changing = {
while (true) {
yield Promises.delay(100, Math.random());
}
}
Insert cell
Insert cell
nine_perturber = (square) => {
let magnitude = square.column * 2 // This line defines how the randomness spreads across the image
let perturb = () => ((changing + Math.random() - 1) * (magnitude * 2)); // The line defines the size of the randomness
let wonkySquare = {column: square.column, row: square.row,
x1: square.x1 + perturb(),
x2: square.x2 + perturb(),
x3: square.x3 + perturb(),
x4: square.x4 + perturb(),
y1: square.y1 + perturb(),
y2: square.y2 + perturb(),
y3: square.y3 + perturb(),
y4: square.y4 + perturb()
};
return wonkySquare;
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
ten_changing = {
while (true) {
yield Promises.delay(100, 0);
}
}
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