primer journey visualizer
Primer Learning Journey Visualizer — “Primer Print”
Section titled “Primer Learning Journey Visualizer — “Primer Print””Created: 2026-02-27
Last updated: 2026-02-28
Status: v3 — print-ready, approved for study group distribution
Output template: primer_journey.html (single self-contained HTML, no dependencies)
Related: lessons · primer · participant feedback
Confirmed name: “Primer Print” (approved by Patrick 2026-02-28)
Concept
Section titled “Concept”An interactive visualization of individual learner paths through the 79-lesson Primer curriculum. Each learner’s progression is a continuous thread weaving through lessons on a vertical spine. Reveals linear vs. spiral engagement patterns at a glance.
Core pedagogical insight made visible: Baseworks cannot be learned linearly. The expected pattern is recursive — forward into new material, then looping back to re-experience earlier lessons with accumulated understanding.
“No two Primer Prints are the same.”
Visual Design
Section titled “Visual Design”Colors
Section titled “Colors”- 🔵 Theory:
#4A3F8F— deep violet-indigo - 🟠 Key Points:
#B85C1A— terracotta - 🔵 Practice:
#2785a4— teal
79 lesson dots, vertical, color-coded by type. Unvisited dots are faint gray.
Thread geometry (Option F)
Section titled “Thread geometry (Option F)”- Exits each dot horizontally (tangential) → smooth S-curves everywhere, no sharp peaks
- Moving to a different lesson: thread crosses to opposite side → true S-curve
- Amplitude is semantic:
- Sequential step (idx+1) or natural segment boundary (e.g. 2.12→3.1): narrow (AMP_SEQUENTIAL)
- Within-segment non-sequential revisit: medium (AMP_IN_SEGMENT)
- Cross-segment jump: grows per segment gap (AMP_PER_SEG), capped at 580
- Same-lesson repeat: slim vertical oval loop on current side, no side-flip
- Multiple consecutive same-lesson repeats: nested loops, growing wider+taller, fading opacity
Layout
Section titled “Layout”- White background (
#ffffff), print-optimized - Two columns: 292px sidebar (lesson list + visit counts) | viz area (SVG)
- Header: Baseworks logo + title “Baseworks Primer Print” + legend
- Footer: 6 stats + learner name (bottom right, italic serif)
- Fully static — no scrollable containers, renders cleanly to PDF
Key Code Architecture
Section titled “Key Code Architecture”Template file structure
Section titled “Template file structure”Single HTML file. All data injected at top of <script> block. No external dependencies except Google Fonts.
Three variables to customize per user
Section titled “Three variables to customize per user”const USER_NAME = ''; // e.g. "Sofia M."const TOTAL_MINUTES = 694; // sum of Duration (min) from CSV
const LOG_RAW = [ ["2026-01-16 0:47:00", "1.1-The-Problem"], // ... one entry per lesson view: [timestamp_string, label_string]];Lesson matching (fuzzy — handles messy LMS labels)
Section titled “Lesson matching (fuzzy — handles messy LMS labels)”function findLesson(label) { // 1. Exact normName match (lowercased, punctuation normalized) // 2. Prefix match on "X.Y" number (e.g. "3.8" matches any lesson starting with 3.8) // 3. Partial substring match (first 12 chars) // Returns lesson object or null}function normName(s) { // lowercase, replace –/–/—/: with space, collapse whitespace}Amplitude constants (current values, tuned for print)
Section titled “Amplitude constants (current values, tuned for print)”const AMP_SEQUENTIAL = 26; // narrow: sequential or seg boundary forwardconst AMP_IN_SEGMENT = 52; // medium: within-segment non-sequentialconst AMP_PER_SEG = 110; // per segment gap for cross-segment jumps// max cap: 580Path builder logic
Section titled “Path builder logic”// State: side = +1 (right) or -1 (left); flips on every different-lesson move// consecutiveSameCount: how many same-lesson loops drawn before a different move
// Same lesson → oval loop on current side:// W = 28 + n*20 (width), H = 11 + n*8 (half-height), n = 0-indexed repeat// opacity = max(0.22, 0.72 - n*0.18)// path: M 0 y0 C ox*.5 y0-H*1.2, ox y0-H, ox y0 C ox y0+H, ox*.5 y0+H*1.2, 0 y1
// Different lesson → S-curve:// amp = segAmp(fromLesson, toLesson, newSide)// path: M 0 y0 C amp y0, amp y1, 0 y1 ← both CPs at x=amp → tangential entry+exitSVG sizing (critical — controls print height)
Section titled “SVG sizing (critical — controls print height)”const DOT_R = 6;const STEP_Y = 20; // vertical px between lessonsconst SVG_H = 78 * STEP_Y + 60; // = 1620px — always fixedconst SVG_W = 1400; // canvas half-width; arcs go ±580px from spine
// In render():svg.setAttribute('width', '100%'); // fills columnsvg.setAttribute('height', SVG_H); // fixed pxsvg.setAttribute('viewBox', `-700 0 1400 ${SVG_H}`);svg.setAttribute('preserveAspectRatio', 'xMidYMin meet');svg.style.height = SVG_H + 'px'; // locked — prevents aspect-ratio shrinkagesvg.style.minHeight = SVG_H + 'px';Layout constants
Section titled “Layout constants”.body { grid-template-columns: 292px 1fr; } /* sidebar | viz */.viz-area { overflow: hidden; } /* no scrollbar */html, body { overflow-x: hidden; }Batch Generation (Claude Code)
Section titled “Batch Generation (Claude Code)”Look at the following files in the reports directory:
- primer_journey6.html
- generate_primer_prints.py
- primer stats_260228.csv
CSV format expected
Section titled “CSV format expected”First Name, Timestamp (Y-m-d H:i:s), Label, Duration (min)One row per lesson view. Multiple users in same file, identified by First Name column.
Instructions for Claude Code
Section titled “Instructions for Claude Code”Tell Claude Code:
Read
/Users/asiahome/Obsidian/baseworks-kb-shared-brain/02-areas/primer/reports/primer-journey-visualizer.mdfor full project context.Write a Python script that:
- Reads the CSV at
[path/to/your.csv]- Groups rows by
First Name- For each person: builds
LOG_RAWfrom their[Timestamp, Label]rows, sums theirDuration (min)forTOTAL_MINUTES- Takes the HTML template at
[path/to/primer_journey.html]- Replaces the
USER_NAME,TOTAL_MINUTES, andLOG_RAWvalues in the template- Writes one HTML file per person to an
outputs/folder, namedfirstname_primer_print.html
What the script needs to replace
Section titled “What the script needs to replace”The script does simple string replacement on these three sections in the HTML:
const USER_NAME = '';const TOTAL_MINUTES = 694;const LOG_RAW = [ ... ]; // entire array, from opening [ to closing ];Use regex to replace the LOG_RAW block:
import relog_raw_str = repr(list_of_tuples) # or build JS array string manuallycontent = re.sub(r'const LOG_RAW = \[.*?\];', f'const LOG_RAW = {log_raw_str};', content, flags=re.DOTALL)content = content.replace("const USER_NAME = '';", f"const USER_NAME = '{name}';")content = content.replace("const TOTAL_MINUTES = 694;", f"const TOTAL_MINUTES = {total_minutes};")Current Status (v3 — Feb 28 2026)
Section titled “Current Status (v3 — Feb 28 2026)”- ✅ Static HTML/SVG, single file, no dependencies
- ✅ 79-lesson spine, type-colored dots (indigo/terracotta/teal)
- ✅ Option F geometry: tangential S-curves, nested loops, segment-proportional arcs
- ✅ Smart amplitude: sequential/boundary moves = narrow arc
- ✅ Gradient coloring per segment
- ✅ Sidebar: truncated names + colored ×N counts
- ✅ Footer: views · revisits · unique · ratio · hours · days · learner name
- ✅ Baseworks logo (inline SVG from BW LOGO SVG 90.svg)
- ✅ White background, print-optimized
- ✅ No scrollbars — fully static layout
- ✅ Height locked at 1620px (matches full 79-lesson sidebar)
- ✅ Text sized for US Letter print
- ✅ Tested with real user data (Jan 16 – Feb 27 2026, segments 1.1–7.9)
Ideas & Next Steps
Section titled “Ideas & Next Steps”- Animation: draw thread chronologically (replay button) — the social share moment
- PDF/print button in UI
- Segment band labels on spine (subtle chapter markers)
- Learner archetype detection (linear / spiral / cluster / free ranger)
- Correlate visit patterns with segment_feedback.csv scores
- Population aggregate view: line thickness = transition frequency across users
- N8N automation: course completion → generate → deliver
Research Potential
Section titled “Research Potential”- Do deeper revisitors report more transformation in feedback?
- Critical junctures where learners tend to revisit across the population?
- Early navigation patterns as predictor of engagement depth?
- Connects to: affordance competition theory, motor learning stages, communicability framework