Claude-skill-registry data-visualization

Build mathematically correct, visually prominent data visualizations for time-series charts. Use this skill when creating charts with mathematical overlays (trendlines, patterns, indicators), fixing visual artifacts (wavy lines, domain mismatches), or validating chart correctness. Focuses on technical correctness and progressive validation, not aesthetic design.

install
source · Clone the upstream repo
git clone https://github.com/majiayu000/claude-skill-registry
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/majiayu000/claude-skill-registry "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/data/data-visualization" ~/.claude/skills/majiayu000-claude-skill-registry-data-visualization-fe7b77 && rm -rf "$T"
manifest: skills/data/data-visualization/SKILL.md
source content

Data Visualization Skill

Focus: Mathematical correctness and visual prominence for time-series charts with overlays (trendlines, patterns, indicators).

When to use this skill:

  • Building charts with mathematical overlays (trendlines, moving averages, regressions)
  • Fixing visual artifacts (wavy lines at gaps, domain mismatches)
  • Validating chart correctness (progressive evidence)
  • Implementing pattern overlays (flags, wedges, triangles, H&S)
  • Working with Chart.js, D3.js, Recharts, or similar frameworks

When NOT to use this skill:

  • Aesthetic UI design (use
    frontend-design
    skill)
  • Telegram-specific UI patterns (use
    telegram-uiux
    skill)
  • General React/TypeScript patterns (use
    telegram-uiux
    skill)

Quick Reference

Problem: Trendlines appear wavy at weekend gaps Solution: Use timestamp-based regression (not index-based) → MATHEMATICAL-CORRECTNESS.md

Problem: Pattern overlays hard to see on chart Solution: Use shaded regions + bold lines + layer ordering → VISUAL-HIERARCHY.md

Problem: Custom polygon fill doesn't render in Chart.js Solution: Use framework's dataset-to-dataset fill feature → FRAMEWORK-PATTERNS.md

Problem: Chart works with perfect data but crashes on real data Solution: Test with edge cases (gaps, nulls, holidays) → VALIDATION.md


Decision Tree

User request involves data visualization?
├─ YES → Continue
└─ NO → Use different skill

Mathematical overlays (trendlines, patterns)?
├─ YES → Use this skill
└─ NO → Consider frontend-design (if aesthetic focus)

Problem type?
├─ Visual artifacts (wavy lines, curvature)
│  └─ Check: Domain compatibility [MATHEMATICAL-CORRECTNESS.md]
├─ Low visibility (patterns hard to see)
│  └─ Check: Visual hierarchy [VISUAL-HIERARCHY.md]
├─ Framework issues (custom code not working)
│  └─ Check: Framework patterns [FRAMEWORK-PATTERNS.md]
├─ Correctness validation (how to verify?)
│  └─ Check: Progressive validation [VALIDATION.md]
└─ General implementation
   └─ Read all sections for comprehensive approach

Core Principles

1. Visual Prominence Through Layering

Pattern: Shaded regions (fills) + bold trendlines + layer ordering

Why: Simple lines blend into busy charts; shaded areas create immediate recognition

See: VISUAL-HIERARCHY.md for opacity guidelines, layering strategy, Chart.js implementation


2. Domain Compatibility for Mathematical Correctness

Pattern: Regression domain must match visualization axis domain

Why: Domain mismatch creates visual artifacts (wavy lines at irregular spacing)

See: MATHEMATICAL-CORRECTNESS.md for timestamp vs index, testing strategy, common mismatches


3. Framework-Native Over Custom Solutions

Pattern: Use framework's built-in features instead of custom implementations

Why: Native features are tested, documented, maintained; custom solutions fragile

See: FRAMEWORK-PATTERNS.md for Chart.js patterns, research workflow, when custom is acceptable


4. Edge Cases Reveal Mathematical Bugs

Pattern: Test with irregular data (weekend gaps, holidays, nulls)

Why: Regular spacing hides domain mismatches; irregular spacing reveals bugs

See: VALIDATION.md for edge case examples, testing checklist, validation workflow


5. Progressive Evidence for UI Validation

Pattern: Validate through layers: visual → code → edge cases → mathematical

Why: Visual appearance alone doesn't prove correctness; need multiple validation levels

See: VALIDATION.md for 4-layer validation, evidence hierarchy, validation matrix


Workflow

Phase 1: Plan Implementation

  1. Understand requirements: What visualization? What overlays?
  2. Research framework: Does Chart.js/D3 have built-in feature?
  3. Choose approach: Native feature vs custom (prefer native)
  4. Identify domain: What's the X-axis? (time, categories, continuous)

Phase 2: Implement Visualization

  1. Start with data layer: Render base chart (candlesticks, line, etc.)
  2. Add mathematical overlays: Trendlines, patterns, indicators
  3. Apply visual hierarchy: Layer ordering (fills behind, lines front)
  4. Tune prominence: Adjust opacity (25-30% for web), line width (3px)

Phase 3: Validate Correctness

  1. Layer 1 (Visual): Does it look right? Take screenshots
  2. Layer 2 (Code): Using framework correctly? Review patterns
  3. Layer 3 (Edge): Test with weekend gaps, holidays, nulls
  4. Layer 4 (Math): Verify algorithm correctness (domain match?)

Phase 4: Debug Issues

If wavy lines:

  • Check domain compatibility (timestamp vs index regression)
  • Test with weekend gap data
  • Verify Chart.js axis type (
    type: 'time'
    )

If low visibility:

  • Add shaded fill regions (25-30% opacity)
  • Increase line width (3px)
  • Apply layer ordering (order: 1,2,3)

If framework issues:

  • Research native features (dataset-to-dataset fill)
  • Check documentation examples
  • Prefer configuration over code

Common Patterns

Pattern: Timestamp-Based Regression

Use when: Continuous time axis (Chart.js

type: 'time'
)

function fitLinearTrendline(points) {
    const n = points.length;

    // Use timestamps (p.x), not indices (i)
    const sumX = points.reduce((sum, p) => sum + p.x, 0);
    const sumXY = points.reduce((sum, p) => sum + p.x * p.y, 0);
    const sumX2 = points.reduce((sum, p) => sum + p.x * p.x, 0);

    const slope = (n * sumXY - sumX * sumY) / (n * sumX2 - sumX * sumX);
    const intercept = (sumY - slope * sumX) / n;

    return points.map(p => ({
        x: p.x,
        y: slope * p.x + intercept  // Timestamp-based
    }));
}

See: MATHEMATICAL-CORRECTNESS.md


Pattern: Shaded Region with Layering

Use when: Overlaying patterns on busy charts

const datasets = [];

// Layer 3: Fill area (behind)
datasets.push({
    label: 'Pattern Area',
    data: polygonPoints,
    backgroundColor: 'rgba(38, 166, 154, 0.25)',  // 25% opacity
    fill: true,
    borderColor: 'transparent',
    order: 3,  // Behind
    pointRadius: 0
});

// Layer 2: Trendline (front)
datasets.push({
    label: 'Trendline',
    data: trendlinePoints,
    borderColor: '#26A69A',
    borderWidth: 3,  // Bold
    fill: false,
    order: 2,  // Front
    pointRadius: 0
});

// Layer 1: Data (highest priority)
datasets.push({
    type: 'candlestick',
    data: ohlcData,
    order: 1  // Front-most
});

See: VISUAL-HIERARCHY.md


Pattern: Dataset-to-Dataset Fill (Chart.js)

Use when: Filling area between two lines

const datasets = [];

// Draw lower boundary first
const lowerIndex = datasets.length;
datasets.push({
    label: 'Support',
    data: lowerLine,
    borderColor: '#26A69A',
    fill: false,
    order: 2
});

// Draw upper boundary with fill TO lower
datasets.push({
    label: 'Resistance',
    data: upperLine,
    borderColor: '#26A69A',
    backgroundColor: 'rgba(38, 166, 154, 0.25)',
    fill: lowerIndex,  // Fill to support dataset (Chart.js native)
    order: 2
});

See: FRAMEWORK-PATTERNS.md


Pattern: Edge Case Testing

Use when: Validating mathematical correctness

// Test data with weekend gap
const testData = [
    { x: Date.parse('2024-01-01'), y: 100 },  // Mon
    { x: Date.parse('2024-01-02'), y: 102 },  // Tue
    { x: Date.parse('2024-01-03'), y: 104 },  // Wed
    // Weekend gap (Thu-Sun missing)
    { x: Date.parse('2024-01-08'), y: 106 },  // Mon (5 days later!)
    { x: Date.parse('2024-01-09'), y: 108 },  // Tue
];

const trendline = fitLinearTrendline(testData);

// Validation: Line should stay straight
// If wavy → domain mismatch bug

See: VALIDATION.md


Anti-Patterns

❌ Index-Based Regression on Time Axis

// BAD: Using array indices on continuous time axis
const sumX = points.reduce((sum, p, i) => sum + i, 0);
return { x: p.x, y: slope * i + intercept };
// Result: Wavy lines at weekend gaps

Fix: Use timestamp-based regression → MATHEMATICAL-CORRECTNESS.md


❌ Custom Polygon Fill (Chart.js)

// BAD: Concatenating reversed arrays
const polygon = [...upperLine, ...lowerLine.reverse()];
datasets.push({ data: polygon, fill: true });
// Result: Doesn't render correctly in Chart.js

Fix: Use dataset-to-dataset fill → FRAMEWORK-PATTERNS.md


❌ Visual-Only Validation

// BAD: Stopping at "looks good"
console.log('Screenshot looks good! Ship it!');
// Missing: Code review, edge cases, math verification

Fix: Progressive validation (4 layers) → VALIDATION.md


❌ Same Layer Order for All Elements

// BAD: Random rendering order
datasets.push({ order: 1 });  // Fill
datasets.push({ order: 1 });  // Line
datasets.push({ order: 1 });  // Data
// Result: Unpredictable z-index

Fix: Explicit layering (1=data, 2=lines, 3=fills) → VISUAL-HIERARCHY.md


Integration with Other Skills

Complements:

  • frontend-design
    : Aesthetic UI design (this skill: technical correctness)
  • telegram-uiux
    : Telegram-specific patterns (this skill: general data viz)
  • testing-workflow
    : General testing (this skill: visualization-specific validation)

References:

  • See
    docs/frontend/UI_PRINCIPLES.md
    for comprehensive principles
  • See
    .claude/implementations/2026-01-05-shaded-pattern-visualization.md
    for implementation case study
  • See
    .claude/implementations/2026-01-05-proper-pattern-trendlines-all-types.md
    for pattern-specific details

Real-World Example

Problem: Chart pattern trendlines appeared wavy at weekends, user feedback "I don't like the look"

Root causes:

  1. Visual: Simple thin lines blended into chart (low contrast)
  2. Mathematical: Index-based regression on continuous time axis (domain mismatch)

Solutions applied:

  1. Visual: Shaded regions (25% opacity) + bold lines (3px) + layer ordering
  2. Mathematical: Timestamp-based regression (domain match)
  3. Validation: Tested with weekend gap data (edge cases)

Outcome: ✅ Patterns 3-5x more visible, ✅ Straight lines across gaps, ✅ Professional appearance

See:

.claude/evolution/2026-01-05-data-visualization-principles.md
for full case study


Quick Checklist

Before implementation:

  • Research framework features (Chart.js docs, examples)
  • Identify axis domain (time, categories, continuous)
  • Plan layer ordering (data=1, lines=2, fills=3)

During implementation:

  • Use framework-native features (dataset-to-dataset fill)
  • Match regression domain to axis domain (timestamps for time axis)
  • Apply visual hierarchy (shaded regions, bold lines)

After implementation:

  • Visual validation (screenshot, looks right?)
  • Code review (framework patterns correct?)
  • Edge case testing (weekend gaps, nulls, holidays)
  • Mathematical verification (domain match, formula correct?)

See detailed documentation:


Last Updated: 2026-01-05 Version: 1.0.0 Source: Distilled from candlestick chart pattern visualization work