Files
timeline-svg/CLAUDE.md
tegwick cefbf96a82 feat: add folder picker for automatic project file loading
- Add "Load Project Folder" button with folder selection (webkitdirectory)
- Automatically load all project files (JSON, CSV, SVG, CSS) from selected folder
- Eliminate need to manually upload each file individually
- Show clear errors if referenced files are missing from folder
- Update all documentation to explain folder picker usage

This solves the browser security limitation where uploading a single
project.json doesn't allow automatic access to other files in the same
directory. Users can now select an entire project folder and all files
load automatically in one click.

Changes:
- index.html: Add folder input with webkitdirectory attribute and UI
- engine.js: Add folderInput event handler to process all files from folder
- README.md: Document folder picker as primary loading method
- WINDOWS_USAGE.md: Add folder picker as recommended Option 1
- TROUBLESHOOTING.md: Add section explaining project files not auto-loading
- CLAUDE.md: Document folder picker architecture for future instances
- Makefile: Update DIST_README.md template to mention folder picker

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-23 16:34:35 +01:00

11 KiB

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

Overview

TimelineSvg is a browser-based system for generating multi-lane timelines as SVG graphics from CSV data. It processes everything client-side using vanilla JavaScript, with no build pipeline or backend required. The system uses a template-based architecture where SVG templates define the visual appearance and data is mapped through a project configuration file.

Troubleshooting: If you encounter issues during development, check TROUBLESHOOTING.md first. It contains solutions for common problems including npm installation failures, CORS errors, template validation issues, and more.

Commands

Installation

make install             # Install development dependencies

Important - Node.js v24 on WSL: If you encounter ERR_SSL_CIPHER_OPERATION_FAILED errors during npm install, this is a known issue with Node.js v24 and OpenSSL 3.x in WSL environments. The Makefile automatically applies the workaround using NODE_OPTIONS="--openssl-legacy-provider". If installing manually without make:

export NODE_OPTIONS="--openssl-legacy-provider" && npm install

Testing

npm test                  # Run all tests once
npm run test:watch       # Run tests in watch mode
npm run test:coverage    # Generate coverage report
npm run test:ui          # Run Vitest UI

The project uses Vitest with jsdom for testing. Tests are located in /test/ and cover the generator, engine, and integration scenarios.

Development

make serve               # Start local development server (auto-detects Python/npx)
# or manually:
python3 -m http.server 8000

# Then open http://localhost:8000

The application must be served via HTTP (not opened as file://) due to CORS restrictions when loading CSV, CSS, and SVG files.

Distribution

make dist                # Build distribution package in dist/
make dist-zip            # Build distribution and create archive

The distribution package includes:

  • All runtime files (HTML, JS, CSS)
  • Example projects (example/, example-1/, my-project/)
  • Documentation (README.md, TEMPLATE_V2_GUIDE.md, TROUBLESHOOTING.md)
  • Startup scripts for Windows (start-server.bat) and Linux/Mac (start-server.sh)

Use this to deploy the application to Windows or other environments. The distribution is self-contained and requires only a web browser and Python (for the local server).

For Windows deployment from WSL: See WINDOWS_USAGE.md for detailed instructions on building the distribution in WSL, transferring to Windows, and running the application on Windows OS.

Architecture

Core Components

1. engine.js - Application controller and data loading

  • Manages project configuration loading (auto-loads from binect/, my-project/, or example/ folders)
  • Handles CSV parsing using PapaParse library
  • Manages file uploads and overrides
  • Provides debug information panel
  • Controls view modes (internal vs external)
  • Implements zoom functionality for SVG viewer

2. generator.js - Timeline rendering engine

  • Implements template-v2 architecture
  • Extracts template elements from <defs> section: month-template, lane-template, item-template
  • Replaces placeholders with calculated values and CSV data
  • Handles layout calculations (positioning months, lanes, items)
  • Generates final SVG by cloning templates and replacing {{MONTHS}} and {{LANES}} macros

3. index.html - UI and browser entry point

  • Loads PapaParse from CDN for CSV parsing
  • Provides file upload controls
  • Contains viewer with zoom controls
  • Shows debug information panel with field mappings and data preview

Data Flow

  1. Project Configuration (project.json) defines:

    • Data source (CSV file path)
    • Stylesheet (CSS file path)
    • SVG template (template-v2.svg file path)
    • Field mappings (CSV columns → timeline fields)
    • Optional placeholder mappings (override default ITEM_* convention)
    • Settings (timeline duration, etc.)
  2. CSV Data is parsed and mapped to timeline items:

    • Required fields: id, title, due, lane
    • Date parsing supports multiple formats: YYYY-MM-DD, YYYY/MM/DD, DD.MM.YYYY
    • Items without valid title or due date are filtered out
  3. Template System (template-v2 architecture):

    • Templates are standard SVG files editable in Inkscape, Illustrator, or Figma
    • Three required template elements in <defs> section:
      • <g id="month-template"> - Defines month column rendering
      • <g id="lane-template"> - Defines lane/epic row rendering
      • <g id="item-template"> - Defines individual task rendering
    • Templates contain placeholders like {{MONTH_X}}, {{LANE_NAME}}, {{ITEM_TITLE}}
    • Generator extracts templates, replaces placeholders, and injects into main SVG
  4. Placeholder System:

    • Layout placeholders: {{MONTH_X}}, {{LANE_Y}}, {{ITEM_X}}, etc. (calculated by generator)
    • Data placeholders: Automatically created from CSV columns using ITEM_{PROPERTY} convention
    • Custom mappings: Use placeholderMapping in project.json to override default names (e.g., TASK_ID instead of ITEM_ID)
    • All CSV properties (except due) are available as placeholders in templates

Key Concepts

Template-v2 Architecture: The current system (migrated from older macro-based approach) uses proper SVG template elements that are cloned and customized. This makes templates more maintainable and editable in visual SVG editors.

Field Mapping: CSV columns don't need to match exact names. The fieldMapping object in project.json maps CSV column names to the internal timeline model:

{
  "fieldMapping": {
    "id": "ID",           // CSV column "ID" maps to item.id
    "title": "Title",     // CSV column "Title" maps to item.title
    "lane": "Lane",       // CSV column "Lane" maps to item.lane
    "due": ["Due"]        // CSV column "Due" maps to item.due (array for fallbacks)
  }
}

Placeholder Mapping: When templates use non-standard placeholder names (common when migrating from other tools), use placeholderMapping to override the default ITEM_* convention:

{
  "placeholderMapping": {
    "id": "TASK_ID",       // Use {{TASK_ID}} instead of {{ITEM_ID}}
    "title": "TASK_NAME"   // Use {{TASK_NAME}} instead of {{ITEM_TITLE}}
  }
}

Layout Constants (generator.js:41-45): Control overall positioning

  • left: 220 - Left margin
  • top: 140 - Top margin
  • monthWidth: 120 - Width of each month column
  • laneHeight: 80 - Height of each lane/epic row
  • laneGap: 16 - Vertical gap between lanes

View Modes:

  • Internal view: Shows item IDs (for development/review)
  • External view: Hides item IDs (for presentations/exports)

Project Loading Methods:

  • Auto-load: When served via HTTP, attempts to load from binect/, my-project/, or example/ folders
  • Folder picker: User selects entire project folder - all files load automatically (uses webkitdirectory attribute)
  • Individual files: User manually uploads project.json, then CSV/SVG/CSS separately

The folder picker was added to solve the browser security limitation where uploading a single project.json doesn't allow automatic access to other files in the same directory.

Project Structure

/
├── index.html              # Main application entry point
├── engine.js               # Application controller & data loading
├── generator.js            # SVG generation & template processing
├── vitest.config.js        # Test configuration
├── test/
│   ├── setup.js           # Test environment setup
│   ├── generator.test.js  # Generator unit tests
│   ├── engine.test.js     # Engine unit tests
│   └── integration.test.js # End-to-end tests
├── example/               # Example project
│   ├── project.json       # Project configuration
│   ├── sample.csv         # Sample data
│   ├── style.css          # Custom styling
│   └── template-v2.svg    # SVG template
└── TEMPLATE_V2_GUIDE.md   # Comprehensive template documentation

Testing Guidelines

When writing tests:

  • Use Vitest's describe() and it() structure
  • Mock browser APIs (localStorage, fetch) using jsdom
  • Test template validation separately from rendering
  • Test date parsing for all supported formats
  • Test field mapping edge cases (missing fields, null values)
  • Integration tests should cover full project loading → CSV parsing → SVG generation flow

Important Implementation Details

Template Validation (generator.js:54-70): Always validate templates before attempting to generate SVG. Check for all three required template IDs.

Template Extraction (generator.js:73-82): Use regex to extract template elements from <defs>. Throws error if extraction fails (indicates malformed template).

XML Escaping (generator.js:216-223): Always escape user data (titles, lane names) when injecting into SVG to prevent malformed XML.

Date Parsing (engine.js:385-408): Supports multiple formats with fallback to new Date(). Returns null for invalid dates, which causes items to be filtered out.

Project Base Path Resolution (engine.js:148-157): Relative paths in project.json are resolved relative to the project folder (e.g., example/). This enables projects to reference their own resources.

Debug Information Panel: Shows field mappings, template placeholders, and CSV preview to help diagnose configuration issues. Automatically displayed when project loads.

Common Development Tasks

When adding new placeholder types:

  1. Add to placeholder documentation in TEMPLATE_V2_GUIDE.md
  2. Update generator.js placeholder replacement logic if needed
  3. Update example templates to demonstrate usage
  4. Add tests for the new placeholder type

When modifying layout:

  1. Update layout constants in generator.js:41-45
  2. Update placeholder value calculations in generateFromTemplates()
  3. Update TEMPLATE_V2_GUIDE.md with new dimensions
  4. Regenerate example SVGs to verify

When adding CSV field support:

  1. Update fieldMapping documentation in README.md
  2. Update example project.json files
  3. Add to processCsv() in engine.js
  4. Update generator to expose as placeholder
  5. Add tests for field mapping

Template Development

See TEMPLATE_V2_GUIDE.md for comprehensive template creation and customization documentation. Key points:

  • Templates must have all three required <g id="*-template"> elements in <defs>
  • Use style="display:none" on template elements to hide them
  • All placeholders use {{UPPERCASE_NAME}} format
  • Templates are standard SVG - edit in any SVG editor
  • Test templates by loading them in the UI and checking debug panel

Migration Notes

The codebase uses template-v2 architecture. Legacy template-v1 (macro-based) is deprecated. When working with old projects:

  • Convert macro-based templates to template-v2 format
  • Move template definitions into <defs> section
  • Update placeholder names to match conventions
  • Use placeholderMapping if preserving legacy placeholder names