Skip to content

Commit 14f8576

Browse files
authored
Merge pull request #26 from SuLab/lotz-ivd-viz
Add IVD atlas spec evolution visualizations
2 parents 1f3a3ce + 86b8729 commit 14f8576

9 files changed

Lines changed: 1114 additions & 0 deletions

File tree

_cite/.cache/cache.db

0 Bytes
Binary file not shown.

_data/citations.yaml

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -371,6 +371,25 @@
371371
buttons:
372372
- type: pdf
373373
link: pdf/Tsueng_2022b.pdf
374+
- id: doi:10.64898/2026.04.09.716978
375+
title: "Topography structures of arthropod communities revealed by leaf-derived\
376+
\ environmental DNA on O\u2019ahu, Hawai\u2019i"
377+
authors:
378+
- Sven Weber
379+
- Leke Hutchins
380+
- Pritam Banerjee
381+
- Willow Callaghan
382+
- Alex Augustus Farrow
383+
- Jeremy Andersen
384+
- Rosemary Gillespie
385+
- George Roderick
386+
publisher: openRxiv
387+
date: '2026-04-10'
388+
link: https://doi.org/hbwvk2
389+
orcid: 0000-0001-7627-2086
390+
willow-callaghan-list: true
391+
plugin: orcid.py
392+
file: orcid.yaml
374393
- id: doi:10.1111/mec.16873
375394
title: Ecological network structure in response to community assembly processes
376395
over evolutionary time

lotz-ivd/index.html

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8">
5+
<title>IVD Atlas — Spec Evolution</title>
6+
<style>
7+
body { background: #0f1923; color: #ccd6e0; font-family: 'Segoe UI', system-ui, sans-serif;
8+
display: flex; flex-direction: column; align-items: center; justify-content: center;
9+
min-height: 100vh; margin: 0; padding: 2rem; }
10+
.card { background: #162433; border-radius: 14px; padding: 2.5rem 3rem;
11+
border: 1px solid #1e3448; max-width: 640px; width: 100%; }
12+
h1 { color: white; font-size: 1.5rem; margin-bottom: 0.3rem; }
13+
.sub { color: #7a99b0; font-size: 0.9rem; margin-bottom: 2rem; }
14+
ul { list-style: none; padding: 0; display: flex; flex-direction: column; gap: 0.8rem; }
15+
li a { display: block; background: #1a2e40; border-radius: 8px; padding: 0.9rem 1.2rem;
16+
text-decoration: none; color: #ccd6e0; border: 1px solid #1e3448;
17+
transition: border-color 0.15s, background 0.15s; }
18+
li a:hover { background: #213447; border-color: #57c4ad; }
19+
li a .title { color: white; font-weight: 600; font-size: 0.95rem; }
20+
li a .desc { color: #7a99b0; font-size: 0.8rem; margin-top: 0.2rem; }
21+
</style>
22+
</head>
23+
<body>
24+
<div class="card">
25+
<h1>IVD Single-Cell Atlas</h1>
26+
<p class="sub">Human-in-the-loop spec evolution · 7 weeks · 7 commits · 13 modules</p>
27+
<ul>
28+
<li><a href="viz1_stacked_growth.html">
29+
<div class="title">1 · Spec corpus growth</div>
30+
<div class="desc">Stacked bar — total lines of human instruction per commit, colored by module</div>
31+
</a></li>
32+
<li><a href="viz2_heatmap.html">
33+
<div class="title">2 · Human attention heatmap</div>
34+
<div class="desc">Net lines changed per spec per commit — shows where the human's focus went</div>
35+
</a></li>
36+
<li><a href="viz3_timeline.html">
37+
<div class="title">3 · Commit timeline</div>
38+
<div class="desc">Bar height = magnitude of each human intervention, annotated with context</div>
39+
</a></li>
40+
<li><a href="viz4_snapshot.html">
41+
<div class="title">4 · Current spec sizes</div>
42+
<div class="desc">Today's blueprint: 2,155 lines, 17,078 words of human instruction</div>
43+
</a></li>
44+
<li><a href="viz5_integration.html">
45+
<div class="title">5 · Integration spec deep dive</div>
46+
<div class="desc">The one spec that tripled — batch correction strategy, iterated by human judgment</div>
47+
</a></li>
48+
</ul>
49+
</div>
50+
</body>
51+
</html>

lotz-ivd/viz1_stacked_growth.html

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8">
5+
<title>Viz 1 · Spec Corpus Growth</title>
6+
<script src="https://cdn.jsdelivr.net/npm/chart.js@4.4.0/dist/chart.umd.min.js"></script>
7+
<style>
8+
body { background: #0f1923; color: #ccd6e0; font-family: 'Segoe UI', system-ui, sans-serif;
9+
display: flex; flex-direction: column; align-items: center; justify-content: center;
10+
min-height: 100vh; margin: 0; padding: 2rem; }
11+
.card { background: #162433; border-radius: 14px; padding: 2rem 2.5rem;
12+
border: 1px solid #1e3448; width: 100%; max-width: 960px; }
13+
h2 { color: white; font-size: 1.4rem; margin-bottom: 0.3rem; }
14+
.desc { color: #7a99b0; font-size: 0.88rem; margin-bottom: 1.5rem; line-height: 1.5; max-width: 80ch; }
15+
.nav { margin-top: 1.5rem; font-size: 0.8rem; color: #445566; }
16+
.nav a { color: #57c4ad; text-decoration: none; margin: 0 0.5rem; }
17+
</style>
18+
</head>
19+
<body>
20+
<div class="card">
21+
<h2>Spec corpus growth — stacked by module</h2>
22+
<p class="desc">
23+
Each band is one spec module. The human's written instructions grew from <strong style="color:#e9c46a">1,377 → 2,155 lines</strong> over 7 weeks.
24+
The towering growth of <strong style="color:#e76f51">05 Integration</strong> reflects the hardest scientific decision — batch-correction strategy —
25+
being iterated most heavily. Stable modules (gray-blue bands) barely moved once written.
26+
</p>
27+
<canvas id="chart" height="60"></canvas>
28+
<div class="nav">
29+
<a href="viz2_heatmap.html">← Heatmap</a> ·
30+
<a href="viz3_timeline.html">Timeline →</a> ·
31+
<a href="viz4_snapshot.html">Snapshot →</a> ·
32+
<a href="viz5_integration.html">Integration →</a>
33+
</div>
34+
</div>
35+
36+
<script>
37+
Chart.defaults.color = '#7a99b0';
38+
Chart.defaults.borderColor = '#1e3448';
39+
40+
const DATES = ['Feb 26', 'Feb 27', 'Mar 9', 'Mar 10', 'Mar 20', 'Apr 9', 'Apr 13'];
41+
const SPECS = [
42+
'00 Project','01 Discovery','02 Metadata','03 Preprocessing','04 Annotation',
43+
'05 Integration','06 Clustering','07 Post-annot.','08 Differential',
44+
'09 Interpretation','10 Trajectory','11 Comm.','12 Reporting'
45+
];
46+
const DATA = {
47+
'00 Project': [131, 166, 166, 172, 172, 176, 176],
48+
'01 Discovery': [155, 165, 165, 165, 165, 165, 165],
49+
'02 Metadata': [109, 119, 119, 119, 119, 119, 119],
50+
'03 Preprocessing': [166, 177, 177, 177, 182, 182, 182],
51+
'04 Annotation': [135, 147, 107, 146, 146, 146, 146],
52+
'05 Integration': [158, 170, 355, 228, 228, 425, 488],
53+
'06 Clustering': [ 0, 0, 0, 85, 85, 87, 87],
54+
'07 Post-annot.': [ 0, 0, 0, 165, 169, 169, 169],
55+
'08 Differential': [132, 151, 0, 163, 168, 168, 168],
56+
'09 Interpretation': [ 0, 170, 170, 171, 171, 171, 171],
57+
'10 Trajectory': [ 0, 151, 153, 153, 153, 153, 153],
58+
'11 Comm.': [ 0, 0, 0, 83, 83, 83, 83],
59+
'12 Reporting': [ 48, 48, 48, 48, 48, 48, 48],
60+
};
61+
const COLORS = [
62+
'#1a6b96','#2a9d8f','#57c4ad','#a8dadc','#457b9d',
63+
'#e76f51','#f4a261','#e9c46a','#8ecae6','#264653',
64+
'#2a9d8f','#1a6b96','#a0c4ff'
65+
];
66+
67+
new Chart(document.getElementById('chart'), {
68+
type: 'bar',
69+
data: {
70+
labels: DATES,
71+
datasets: SPECS.map((sp, i) => ({
72+
label: sp,
73+
data: DATA[sp],
74+
backgroundColor: COLORS[i],
75+
borderColor: '#0f1923',
76+
borderWidth: 0.8,
77+
stack: 'stack',
78+
}))
79+
},
80+
options: {
81+
responsive: true,
82+
plugins: {
83+
legend: {
84+
position: 'right',
85+
labels: { boxWidth: 14, font: { size: 12 }, color: '#ccd6e0', padding: 10 }
86+
},
87+
tooltip: {
88+
callbacks: {
89+
footer: (items) => `Total: ${items.reduce((s,i)=>s+i.raw,0).toLocaleString()} lines`
90+
}
91+
}
92+
},
93+
scales: {
94+
x: {
95+
stacked: true,
96+
ticks: { color: '#ccd6e0', font: { size: 12 } },
97+
grid: { color: '#1e3448' }
98+
},
99+
y: {
100+
stacked: true,
101+
ticks: { color: '#ccd6e0' },
102+
grid: { color: '#1e3448' },
103+
title: { display: true, text: 'Total lines of spec', color: '#7a99b0', font: { size: 12 } }
104+
}
105+
}
106+
}
107+
});
108+
</script>
109+
</body>
110+
</html>

lotz-ivd/viz2_heatmap.html

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8">
5+
<title>Viz 2 · Human Attention Heatmap</title>
6+
<style>
7+
body { background: #0f1923; color: #ccd6e0; font-family: 'Segoe UI', system-ui, sans-serif;
8+
display: flex; flex-direction: column; align-items: center; justify-content: center;
9+
min-height: 100vh; margin: 0; padding: 2rem; }
10+
.card { background: #162433; border-radius: 14px; padding: 2rem 2.5rem;
11+
border: 1px solid #1e3448; width: 100%; max-width: 960px; }
12+
h2 { color: white; font-size: 1.4rem; margin-bottom: 0.3rem; }
13+
.desc { color: #7a99b0; font-size: 0.88rem; margin-bottom: 1.5rem; line-height: 1.5; max-width: 80ch; }
14+
table { border-collapse: collapse; width: 100%; }
15+
th { color: #7a99b0; font-weight: 600; font-size: 11px; padding: 6px 10px; text-align: center; white-space: nowrap; }
16+
th.spec-col { text-align: left; min-width: 130px; }
17+
td { padding: 5px 8px; font-size: 12px; text-align: center; border: 1px solid #0f1923; border-radius: 3px; font-weight: 600; }
18+
td.spec-label { text-align: left; color: #ccd6e0; font-weight: 400; white-space: nowrap; padding-right: 16px; }
19+
.legend { display: flex; gap: 16px; align-items: center; margin-top: 14px; font-size: 11px; color: #7a99b0; }
20+
.swatch { display: inline-block; width: 32px; height: 14px; border-radius: 3px; vertical-align: middle; margin-right: 4px; }
21+
.nav { margin-top: 1.5rem; font-size: 0.8rem; color: #445566; }
22+
.nav a { color: #57c4ad; text-decoration: none; margin: 0 0.5rem; }
23+
24+
/* Column header annotations */
25+
.col-note { font-size: 9px; color: #557799; font-weight: 400; display: block; }
26+
</style>
27+
</head>
28+
<body>
29+
<div class="card">
30+
<h2>Human attention map — net lines changed per spec per commit</h2>
31+
<p class="desc">
32+
Blue = lines added, red/orange = lines removed, dash = unchanged.
33+
The concentration of change in <strong style="color:#57c4ad">05 Integration</strong> stands out immediately.
34+
The Mar 10 structural column shows the human splitting module 05 into three new specs — a deliberate architectural decision.
35+
Most specs were written once and barely touched again.
36+
</p>
37+
38+
<table id="heatmap"></table>
39+
40+
<div class="legend">
41+
<span><span class="swatch" style="background:#1a6b96"></span>lines added</span>
42+
<span><span class="swatch" style="background:rgba(26,107,150,0.3)"></span>small addition</span>
43+
<span><span class="swatch" style="background:#e76f51"></span>lines removed</span>
44+
<span><span class="swatch" style="background:#0f1923;border:1px solid #334455"></span>unchanged</span>
45+
</div>
46+
47+
<div class="nav">
48+
<a href="viz1_stacked_growth.html">← Growth</a> ·
49+
<a href="viz3_timeline.html">Timeline →</a> ·
50+
<a href="viz4_snapshot.html">Snapshot →</a> ·
51+
<a href="viz5_integration.html">Integration →</a>
52+
</div>
53+
</div>
54+
55+
<script>
56+
const DATES = ['Feb 26', 'Feb 27', 'Mar 9', 'Mar 10', 'Mar 20', 'Apr 9', 'Apr 13'];
57+
const COL_NOTES = ['initial', 'reporting', 'restructure', 'split +3', 'workflows', 'CCA params', 'NP exp.'];
58+
const SPECS = [
59+
'00 Project','01 Discovery','02 Metadata','03 Preprocessing','04 Annotation',
60+
'05 Integration','06 Clustering','07 Post-annot.','08 Differential',
61+
'09 Interpretation','10 Trajectory','11 Comm.','12 Reporting'
62+
];
63+
const DATA = {
64+
'00 Project': [131, 166, 166, 172, 172, 176, 176],
65+
'01 Discovery': [155, 165, 165, 165, 165, 165, 165],
66+
'02 Metadata': [109, 119, 119, 119, 119, 119, 119],
67+
'03 Preprocessing': [166, 177, 177, 177, 182, 182, 182],
68+
'04 Annotation': [135, 147, 107, 146, 146, 146, 146],
69+
'05 Integration': [158, 170, 355, 228, 228, 425, 488],
70+
'06 Clustering': [ 0, 0, 0, 85, 85, 87, 87],
71+
'07 Post-annot.': [ 0, 0, 0, 165, 169, 169, 169],
72+
'08 Differential': [132, 151, 0, 163, 168, 168, 168],
73+
'09 Interpretation': [ 0, 170, 170, 171, 171, 171, 171],
74+
'10 Trajectory': [ 0, 151, 153, 153, 153, 153, 153],
75+
'11 Comm.': [ 0, 0, 0, 83, 83, 83, 83],
76+
'12 Reporting': [ 48, 48, 48, 48, 48, 48, 48],
77+
};
78+
79+
function cellColor(v) {
80+
if (v === 0) return '#0f1923';
81+
const max = 230;
82+
const t = Math.min(Math.abs(v) / max, 1);
83+
if (v > 0) {
84+
const r = Math.round(15 + t * (26 - 15));
85+
const g = Math.round(36 + t * (107 - 36));
86+
const b = Math.round(55 + t * (210 - 55));
87+
return `rgb(${r},${g},${b})`;
88+
} else {
89+
const r = Math.round(80 + t * (231 - 80));
90+
const g = Math.round(30 + t * (20));
91+
const b = Math.round(30 + t * (10));
92+
return `rgb(${r},${g},${b})`;
93+
}
94+
}
95+
96+
function textColor(v, bg) {
97+
if (v === 0) return '#334455';
98+
return Math.abs(v) > 50 ? 'white' : '#ccd6e0';
99+
}
100+
101+
const table = document.getElementById('heatmap');
102+
// Header
103+
let html = '<thead><tr><th class="spec-col">Spec</th>';
104+
DATES.forEach((d, i) => {
105+
html += `<th>${d}<span class="col-note">${COL_NOTES[i]}</span></th>`;
106+
});
107+
html += '</tr></thead><tbody>';
108+
109+
SPECS.forEach(sp => {
110+
const deltas = DATA[sp].map((v, i) => i === 0 ? v : v - DATA[sp][i-1]);
111+
html += `<tr><td class="spec-label">${sp}</td>`;
112+
deltas.forEach(v => {
113+
const bg = cellColor(v);
114+
const tc = textColor(v, bg);
115+
const label = v === 0 ? '—' : (v > 0 ? `+${v}` : `${v}`);
116+
html += `<td style="background:${bg};color:${tc}">${label}</td>`;
117+
});
118+
html += '</tr>';
119+
});
120+
121+
// Totals row
122+
html += '<tr style="border-top:2px solid #334455"><td class="spec-label" style="color:#7a99b0">Total lines</td>';
123+
DATES.forEach((_, ci) => {
124+
const total = SPECS.reduce((s, sp) => s + DATA[sp][ci], 0);
125+
html += `<td style="background:#1a2e40;color:#e9c46a;font-size:11px">${total.toLocaleString()}</td>`;
126+
});
127+
html += '</tr></tbody>';
128+
129+
table.innerHTML = html;
130+
</script>
131+
</body>
132+
</html>

0 commit comments

Comments
 (0)