Skip to content

Commit 37114f8

Browse files
committed
extra lesson
1 parent e21003c commit 37114f8

File tree

2 files changed

+114
-2
lines changed

2 files changed

+114
-2
lines changed

observablehq.config.js

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ export default {
4343
},
4444
{
4545
name: "Lab 3: Mayoral Mystery",
46-
open: true,
46+
open: false,
4747
pages: [
4848
{ name: "Instructions", path: "/lab_3/readme" },
4949
{ name: "Dashboard", path: "/lab_3/index" },
@@ -54,13 +54,20 @@ export default {
5454
},
5555
{
5656
name: "Lab 4: Clearwater Crisis",
57-
open: true,
57+
open: false,
5858
pages: [
5959
{ name: "Instructions", path: "/lab_4/readme" },
6060
{ name: "Dashboard", path: "/lab_4/index" },
6161
{ name: "Week 13 Notes", path: "/lab_4/week_13_notes" },
6262
{ name: "Week 13 Class", path: "/lab_4/week_13_class" },
6363
],
64+
},
65+
{
66+
name: "Extra Lessons",
67+
open: true,
68+
pages: [
69+
{ name: "Data Art", path: "/extra_lessons/data_art" },
70+
],
6471
}
6572

6673
],

src/extra_lessons/data_art.md

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
---
2+
title: "Week 14: Extras"
3+
toc: true
4+
---
5+
6+
# Data Art
7+
8+
### Delaunay
9+
10+
Create a small array of 100 data points that are randomly spread across the svg:
11+
```js echo
12+
const height = 300
13+
const points = Array.from({ length: 100 }, (_) => [
14+
Math.random() * width,
15+
Math.random() * height
16+
])
17+
display(points)
18+
```
19+
20+
These points are static, and randomly spread out:
21+
```js
22+
Plot.plot({
23+
width,
24+
height,
25+
marks: [
26+
Plot.dot(points)
27+
]
28+
})
29+
```
30+
31+
Given set of points in x and y, the Delaunay marks compute the [Delaunay triangulation](https://en.wikipedia.org/wiki/Delaunay_triangulation), its dual the [Voronoi tessellation](https://en.wikipedia.org/wiki/Voronoi_diagram), and the [convex hull](https://en.wikipedia.org/wiki/Convex_hull). The [voronoi mark](https://observablehq.com/plot/marks/delaunay#voronoi) computes the region closest to each point (its Voronoi cell). The cell can be empty if another point shares the exact same coordinates. Together, the cells cover the entire plot.
32+
33+
The voronoi can be considered the space that "belongs" to each point. The lines that make up the voronoi mesh divide these spaces between points.
34+
35+
```js
36+
Plot.plot({
37+
width,
38+
height,
39+
marks: [
40+
Plot.dot(points),
41+
Plot.voronoiMesh(points)
42+
]
43+
})
44+
```
45+
46+
This is incredibly helpful with something like tooltips. If you set the tooltip on the voronoi mesh, the user will always see some data, rather than having to carefully position their cursor over a small dot to trigger the tootlip.
47+
48+
```js
49+
Plot.plot({
50+
width,
51+
height,
52+
marks: [
53+
Plot.dot(points),
54+
Plot.voronoiMesh(points, { tip: true, opacity: 0.2 })
55+
]
56+
})
57+
```
58+
59+
We can take this further and make it more "artsy", like a wobly stained glass window effect, by coloring and manipulating the mesh itself with sinusoidal motion:
60+
61+
```js
62+
// simulate ticking of an animation
63+
const t = (async function* () {
64+
for (let j = 0; true; ++j) {
65+
yield j;
66+
await new Promise((resolve) => setTimeout(resolve, 50));
67+
}
68+
})();
69+
```
70+
71+
```js echo
72+
const voronoi = d3.Delaunay.from(
73+
// move the points in an elliptical pattern
74+
points.map(([x, y], i) => [
75+
x + 1.5 * Math.sin(t + i * i), // horizontal
76+
y + 2.0 * Math.cos(t + i * i) // vertical
77+
])
78+
).voronoi([0, 0, width, height])
79+
// this part does what `Plot.voronoiMesh` does inherently
80+
const data = [...voronoi.cellPolygons()].flatMap((cell) =>
81+
cell.map(([x, y]) => ({ x, y, i: cell.index }))
82+
)
83+
display(data)
84+
```
85+
86+
```js
87+
Plot.plot({
88+
width,
89+
height,
90+
x: { axis: null },
91+
y: { axis: null },
92+
marks: [
93+
Plot.dot(points),
94+
Plot.line(data, {
95+
x: "x",
96+
y: "y",
97+
fill: "i",
98+
stroke: "white",
99+
strokeWidth: 5,
100+
})
101+
]
102+
})
103+
```
104+
source: [Plot example](https://observablehq.com/@lsh/plot-voronoi)
105+

0 commit comments

Comments
 (0)