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

One platform to build and deploy the best data apps

Experiment and prototype by building visualizations in live JavaScript notebooks. Collaborate with your team and decide which concepts to build out.
Use Observable Framework to build data apps locally. Use data loaders to build in any language or library, including Python, SQL, and R.
Seamlessly deploy to Observable. Test before you ship, use automatic deploy-on-commit, and ensure your projects are always up-to-date.
Learn more