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-designskill) - •Telegram-specific UI patterns (use
telegram-uiuxskill) - •General React/TypeScript patterns (use
telegram-uiuxskill)
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
- •Understand requirements: What visualization? What overlays?
- •Research framework: Does Chart.js/D3 have built-in feature?
- •Choose approach: Native feature vs custom (prefer native)
- •Identify domain: What's the X-axis? (time, categories, continuous)
Phase 2: Implement Visualization
- •Start with data layer: Render base chart (candlesticks, line, etc.)
- •Add mathematical overlays: Trendlines, patterns, indicators
- •Apply visual hierarchy: Layer ordering (fills behind, lines front)
- •Tune prominence: Adjust opacity (25-30% for web), line width (3px)
Phase 3: Validate Correctness
- •Layer 1 (Visual): Does it look right? Take screenshots
- •Layer 2 (Code): Using framework correctly? Review patterns
- •Layer 3 (Edge): Test with weekend gaps, holidays, nulls
- •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
});
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.mdfor comprehensive principles - •See
.claude/implementations/2026-01-05-shaded-pattern-visualization.mdfor implementation case study - •See
.claude/implementations/2026-01-05-proper-pattern-trendlines-all-types.mdfor pattern-specific details
Real-World Example
Problem: Chart pattern trendlines appeared wavy at weekends, user feedback "I don't like the look"
Root causes:
- •Visual: Simple thin lines blended into chart (low contrast)
- •Mathematical: Index-based regression on continuous time axis (domain mismatch)
Solutions applied:
- •Visual: Shaded regions (25% opacity) + bold lines (3px) + layer ordering
- •Mathematical: Timestamp-based regression (domain match)
- •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:
- •VISUAL-HIERARCHY.md - Layering, prominence, opacity
- •MATHEMATICAL-CORRECTNESS.md - Domain compatibility, regression, edge cases
- •FRAMEWORK-PATTERNS.md - Chart.js patterns, native features
- •VALIDATION.md - Progressive validation, 4-layer evidence
Last Updated: 2026-01-05 Version: 1.0.0 Source: Distilled from candlestick chart pattern visualization work