Skill: Data Visualization
Choose the right chart for the story, not just the data shape. Every chart should make an argument.
Staleness Watch: See EXTERNAL-API-REGISTRY.md for source URLs and recheck cadence
Metadata
| Field |
Value |
| Skill ID |
data-visualization |
| Version |
1.0.0 |
| Category |
Data Analytics |
| Difficulty |
Intermediate |
| Prerequisites |
None |
| Related Skills |
data-analysis, dashboard-design, data-storytelling, chart-interpretation, executive-storytelling, slide-design, graphic-design |
Overview
Data visualization is not chart generation -- it is visual argumentation. The chart type, color palette, annotation, and title are all rhetorical choices that either strengthen or weaken the story.
Core Principles
| Principle |
Rule |
| Title = Insight |
Chart titles state the takeaway, not the data label. "California leads with 39M" not "Population by State" |
| Story-Intent First |
Ask "what story?" before "what chart?" |
| Data-Ink Ratio |
Every pixel of ink should represent data. Remove everything else (Tufte) |
| 3-Second Test |
If a viewer can't grasp the point in 3 seconds, redesign |
| Annotation = Argument |
Callouts carry the story; the chart is evidence, the annotation is the argument |
Module 1: Story-Intent Chart Selection
The primary axis for chart selection is what story the user wants to tell. Data shape is a secondary constraint.
Step 1 -- Identify Story Intent
| Story Intent |
Question Being Answered |
Primary Charts |
Advanced Charts |
| Compare |
"How do these items rank or differ?" |
Bar, Horizontal Bar, Grouped Bar, Radar |
Beeswarm, Parallel Coordinates |
| Change Over Time |
"How has this evolved?" |
Line, Area, Stacked Area |
Streamgraph, Ridgeline |
| Part-to-Whole |
"What share does each segment hold?" |
Donut, Stacked Bar, Pie |
Waffle, Sunburst |
| Distribution |
"How is this spread? What's normal vs. outlier?" |
Histogram, Scatter |
Violin, Beeswarm, Ridgeline |
| Relationship |
"How are these variables connected?" |
Scatter, Bubble |
Chord, Network Graph, Parallel Coords |
| Flow / Process |
"Where does it go? What are the paths?" |
Horizontal Bar (stages) |
Sankey, Chord |
| Hierarchy |
"How is this organized in levels?" |
Treemap |
Sunburst |
| Spatial Pattern |
"Where are the concentrations?" |
Heatmap |
Network Graph |
| Deviation |
"What deviates from the baseline?" |
Bar (diverging), Line (+ reference line) |
Beeswarm |
Step 2 -- Narrow by Data Shape
| Data Shape |
Compatible Intents |
Ruled Out |
| Categorical + numeric |
Compare, Part-to-Whole, Distribution |
Flow (unless sequential) |
| Two numeric variables |
Relationship, Distribution |
Part-to-Whole |
| Time series |
Change Over Time, Deviation |
Hierarchy |
| Network / adjacency |
Relationship, Flow |
Part-to-Whole, Change Over Time |
| Hierarchical (parent-child) |
Hierarchy, Part-to-Whole |
Change Over Time, Distribution |
| Flow matrix (source-target) |
Flow, Relationship |
Compare (use grouped bar) |
Step 3 -- Audience & Context Filter
| Choose Standard When |
Choose Advanced When |
| Audience expects familiar shapes |
Complex relationships (flows, networks) |
| Tooltip interactivity is critical |
Distribution shape matters more than values |
| Chart.js handles the data shape |
Hierarchical structure needs multi-level view |
| Dashboard has 3+ charts (consistency) |
Single hero viz to anchor a story |
| Executive audience (30s scan) |
Analyst audience (exploration expected) |
Story-Intent Detection Heuristics
When the user doesn't state intent explicitly, infer from language:
| User Language |
Inferred Intent |
| "rank", "compare", "versus", "top", "best/worst" |
Compare |
| "over time", "trend", "growth", "decline", "monthly" |
Change Over Time |
| "share", "proportion", "breakdown", "percent of" |
Part-to-Whole |
| "spread", "range", "outlier", "normal", "distribution" |
Distribution |
| "correlation", "relationship", "predict", "affects" |
Relationship |
| "flow", "path", "from X to Y", "conversion", "funnel" |
Flow / Process |
| "hierarchy", "drill down", "parent/child", "levels" |
Hierarchy |
| "where", "hotspot", "concentration", "geographic" |
Spatial Pattern |
| "deviation", "variance", "above/below target", "gap" |
Deviation |
Module 2: Narrative Chart Pairing
A single chart tells one point. Paired charts reinforce the insight from a second angle.
| Primary Chart |
Good Pair |
Why |
| Bar (compare) |
Donut (proportion) |
Shows both absolute and relative size |
| Line (trend) |
Bar (change amount) |
Shows direction and magnitude |
| Scatter (relationship) |
Histogram (distribution) |
Shows correlation and individual spread |
| Treemap (hierarchy) |
Table (detail) |
Shows structure and precise values |
| Sankey (flow) |
Stacked bar (proportions at each stage) |
Shows paths and stage composition |
The Inverted Pyramid Pattern
From population.html reference -- arrange visuals in absorption order:
| Layer |
Component |
Time to Absorb |
Purpose |
| 1 |
KPI cards |
2 seconds |
"What's the big picture?" |
| 2 |
Hero chart |
10 seconds |
Full distribution, interactive |
| 3 |
Supporting charts |
15 seconds |
Same data, different lens |
| 4 |
Table |
As needed |
Precise values for analysts |
| 5 |
Drill-down |
On click |
Detail without clutter |
Module 3: Color Theory
Mandatory: Colorblind-Safe Palette
All chart output MUST use a colorblind-safe palette. The canonical palette for all Alex charting skills is Tableau 10, verified against deuteranopia, protanopia, and tritanopia:
#4e79a7 Blue-Steel (primary)
#f28e2b Orange
#e15759 Coral
#76b7b2 Teal
#59a14f Sage
#edc948 Gold
#b07aa1 Mauve
#ff9da7 Rose
#9c755f Brown
#bab0ac Warm Gray
| Palette |
Colors |
Use Case |
| Categorical (default) |
First N colors from the canonical 10 above |
Unordered categories |
| Sequential Blue |
#deebf7 → #08519c |
Low-to-high numeric |
| Diverging RdBu |
#b2182b → #f7f7f7 → #2166ac |
Above/below midpoint |
| Semantic Region |
Consistent color per category across all charts on a page |
Region, department, status |
Color Rules (Non-Negotiable)
| Rule |
Explanation |
| Always colorblind-safe |
Never use a palette that has not been tested for deuteranopia, protanopia, and tritanopia |
| Semantic consistency |
Same color = same meaning across all charts on a page |
| Highlight, don't decorate |
Use saturated color for the key data point; mute everything else |
| Sequential for ordered data |
Light-to-dark for low-to-high |
| Diverging for deviation |
Two hues diverging from neutral midpoint |
| Never rely on color alone |
Add patterns, labels, or shapes for accessibility |
| Test with Sim Daltonism |
Verify with protanopia and deuteranopia simulation |
WCAG Contrast Requirements
| Context |
Minimum Ratio |
| Text on background |
4.5:1 (AA), 7:1 (AAA) |
| Chart labels |
4.5:1 minimum |
| Data vs. background |
3:1 for graphical elements |
Module 4: Decluttering (Tufte's Data-Ink Ratio)
Every element must earn its place. Remove anything that doesn't carry data.
| Remove |
Replace With |
| Gridlines |
Light reference lines only if needed |
| Borders around chart area |
White space separation |
| Legends (when possible) |
Direct labels on data |
| Background fills |
Transparent / minimal |
| 3D effects |
Never. Always flat. |
| Redundant axis labels |
Context in title or subtitle |
Before/After Anti-Patterns
| Anti-Pattern |
Problem |
Fix |
| Rainbow palette |
No semantic meaning |
Use 2-3 purposeful colors |
| Every bar labeled |
Visual noise |
Label key values only |
| Dual Y axes |
Misleading correlation |
Two separate charts |
| Pie with 8+ slices |
Unreadable |
Horizontal bar, sorted |
| Missing axis zero |
Exaggerated differences |
Start at zero or note truncation |
Module 5: Annotation Hierarchy
| Element |
Content |
Rule |
| Title |
The insight ("Sales peaked at $4.2M in Q3") |
Never a data label |
| Subtitle |
Context ("Quarterly revenue, FY 2024-2025") |
Who, what, when |
| Callout |
The exception ("Q1 2025: +31% jump -- pricing change?") |
Arrow or highlight |
| Footnote |
Caveats ("Excludes returns. Source: SAP ERP.") |
Small, bottom |
| Source |
Data provenance |
Always present |
Module 6: Small Multiples
Use faceted views when a single chart would be overloaded.
| Use Small Multiples When |
Use Overlay When |
| 5+ series on one chart |
2-3 series that interact |
| Each series has its own pattern |
Comparison is the point |
| Reader needs to see individual shapes |
Relative position matters |
Implementation
Grid: 2x3 or 3x4 panels
Each panel: Same axes, same scale (critical!)
Difference: One variable changes per panel (category, time period, cohort)
Module 7: Accessibility
| Requirement |
Implementation |
| Alt text |
Describe the chart's insight, not its structure ("Revenue grew 34% in 2024" not "Bar chart showing revenue") |
| Patterns |
Add hatching or shapes alongside color |
| Keyboard |
Tab-navigable data points in interactive charts |
| Screen reader |
aria-label on chart container, data table fallback |
| High contrast |
Test in Windows High Contrast mode |
Module 8: Tool Targets
| Target |
Library |
Output |
When |
| HTML (self-contained) |
Chart.js 4.x via CDN |
.html file |
Default -- zero-config dashboards |
| HTML (advanced) |
Raw Canvas 2D API |
.html file |
Sankey, Chord, Sunburst, etc. |
| Python |
Plotly |
Interactive HTML/notebook |
Data science workflows |
| Python (static) |
Matplotlib + Seaborn |
PNG/SVG |
Publications, reports |
| Markdown |
Mermaid |
Inline in docs |
Documentation, PRs |
| Power BI |
DAX measures + visuals |
.pbix |
Enterprise BI |
Chart.js Configuration Defaults
// Standard Chart.js defaults for all data-viz skills
Chart.defaults.font.family = "'Segoe UI', system-ui, sans-serif";
Chart.defaults.font.size = 13;
Chart.defaults.plugins.legend.display = false; // prefer direct labels
Chart.defaults.scales.x.grid.display = false; // declutter
Chart.defaults.scales.y.grid.color = "rgba(255,255,255,0.06)"; // subtle
Chart.defaults.plugins.tooltip.backgroundColor = "rgba(0,0,0,0.85)";
Module 9: Advanced Canvas Charts
10 chart types rendered with raw Canvas 2D API -- no extra dependencies beyond the browser.
| Chart |
Story Intent |
Data Shape |
Key Technique |
| Sankey |
Flow |
Source-target-value |
Bezier curves between stacked bars |
| Chord |
Relationship |
Adjacency matrix |
Circular arcs with ribbons |
| Streamgraph |
Change Over Time |
Multi-series time |
Stacked area with centered baseline |
| Sunburst |
Hierarchy |
Parent-child |
Concentric arcs, angular proportion |
| Parallel Coordinates |
Compare (multi-dim) |
Many numeric columns |
Vertical axes, polylines |
| Beeswarm |
Distribution |
Categorical + numeric |
Force-separated dots on axis |
| Ridgeline |
Distribution (compare) |
Series of distributions |
Overlapping density curves |
| Waffle |
Part-to-Whole |
Percentages |
Grid of colored squares |
| Network Graph |
Relationship |
Nodes + edges |
Force-directed layout |
| Violin |
Distribution |
Grouped distributions |
Mirrored density curves |
Canvas Rendering Pattern
// Standard pattern for all advanced charts
const canvas = document.getElementById("chart");
const ctx = canvas.getContext("2d");
const dpr = window.devicePixelRatio || 1;
canvas.width = canvas.clientWidth * dpr;
canvas.height = canvas.clientHeight * dpr;
ctx.scale(dpr, dpr);
// ... render logic
Reference Implementations
| File |
Charts |
Pattern |
visuals.html |
14 standard types |
Card grid, mini/full pairs, per-chart metadata |
adv_visuals.html |
10 advanced types |
Canvas-only rendering, zero dependencies |
population.html |
4 dashboard charts |
Inverted pyramid, narrative flow, drill-down |
Anti-Patterns
| Anti-Pattern |
Why It Fails |
Fix |
| "Chart type first, data second" |
Picks visual before understanding the story |
Start with story intent |
| Title just labels axes |
No argument, no insight |
Write a sentence the viewer should conclude |
| Rainbow palette on categories |
No semantic meaning, accessibility failure |
Max 2-3 purposeful hues |
| Dual Y axes |
Implies false correlation |
Two separate charts |
| Pie chart with 8+ slices |
Unreadable, angle perception is poor |
Sorted horizontal bar |
| 3D anything |
Distorts perception, adds zero information |
Always flat |
| Default gridlines |
Clutter that competes with data |
Remove or make very subtle |
1---2name: data-visualization3description: Story-intent chart selection, color theory, annotation patterns, decluttering rules, and the "title = insight" principle for data-driven visuals4---56# Skill: Data Visualization78> Choose the right chart for the story, not just the data shape. Every chart should make an argument.910> **Staleness Watch**: See [EXTERNAL-API-REGISTRY.md](../../EXTERNAL-API-REGISTRY.md) for source URLs and recheck cadence1112## Metadata1314| Field | Value |15| ------------------ | ------------------------------------------------------------------------------------------------------------------------------ |16| **Skill ID** | data-visualization |17| **Version** | 1.0.0 |18| **Category** | Data Analytics |19| **Difficulty** | Intermediate |20| **Prerequisites** | None |21| **Related Skills** | data-analysis, dashboard-design, data-storytelling, chart-interpretation, executive-storytelling, slide-design, graphic-design |2223## Overview2425Data visualization is not chart generation -- it is **visual argumentation**. The chart type, color palette, annotation, and title are all rhetorical choices that either strengthen or weaken the story.2627### Core Principles2829| Principle | Rule |30| ------------------------- | ---------------------------------------------------------------------------------------------------------- |31| **Title = Insight** | Chart titles state the takeaway, not the data label. "California leads with 39M" not "Population by State" |32| **Story-Intent First** | Ask "what story?" before "what chart?" |33| **Data-Ink Ratio** | Every pixel of ink should represent data. Remove everything else (Tufte) |34| **3-Second Test** | If a viewer can't grasp the point in 3 seconds, redesign |35| **Annotation = Argument** | Callouts carry the story; the chart is evidence, the annotation is the argument |3637## Module 1: Story-Intent Chart Selection3839The primary axis for chart selection is **what story the user wants to tell**. Data shape is a secondary constraint.4041### Step 1 -- Identify Story Intent4243| Story Intent | Question Being Answered | Primary Charts | Advanced Charts |44| -------------------- | ------------------------------------------------ | ---------------------------------------- | ------------------------------------- |45| **Compare** | "How do these items rank or differ?" | Bar, Horizontal Bar, Grouped Bar, Radar | Beeswarm, Parallel Coordinates |46| **Change Over Time** | "How has this evolved?" | Line, Area, Stacked Area | Streamgraph, Ridgeline |47| **Part-to-Whole** | "What share does each segment hold?" | Donut, Stacked Bar, Pie | Waffle, Sunburst |48| **Distribution** | "How is this spread? What's normal vs. outlier?" | Histogram, Scatter | Violin, Beeswarm, Ridgeline |49| **Relationship** | "How are these variables connected?" | Scatter, Bubble | Chord, Network Graph, Parallel Coords |50| **Flow / Process** | "Where does it go? What are the paths?" | Horizontal Bar (stages) | Sankey, Chord |51| **Hierarchy** | "How is this organized in levels?" | Treemap | Sunburst |52| **Spatial Pattern** | "Where are the concentrations?" | Heatmap | Network Graph |53| **Deviation** | "What deviates from the baseline?" | Bar (diverging), Line (+ reference line) | Beeswarm |5455### Step 2 -- Narrow by Data Shape5657| Data Shape | Compatible Intents | Ruled Out |58| --------------------------- | ------------------------------------ | ------------------------------- |59| Categorical + numeric | Compare, Part-to-Whole, Distribution | Flow (unless sequential) |60| Two numeric variables | Relationship, Distribution | Part-to-Whole |61| Time series | Change Over Time, Deviation | Hierarchy |62| Network / adjacency | Relationship, Flow | Part-to-Whole, Change Over Time |63| Hierarchical (parent-child) | Hierarchy, Part-to-Whole | Change Over Time, Distribution |64| Flow matrix (source-target) | Flow, Relationship | Compare (use grouped bar) |6566### Step 3 -- Audience & Context Filter6768| Choose Standard When | Choose Advanced When |69| ------------------------------------- | --------------------------------------------- |70| Audience expects familiar shapes | Complex relationships (flows, networks) |71| Tooltip interactivity is critical | Distribution shape matters more than values |72| Chart.js handles the data shape | Hierarchical structure needs multi-level view |73| Dashboard has 3+ charts (consistency) | Single hero viz to anchor a story |74| Executive audience (30s scan) | Analyst audience (exploration expected) |7576### Story-Intent Detection Heuristics7778When the user doesn't state intent explicitly, infer from language:7980| User Language | Inferred Intent |81| ------------------------------------------------------ | ---------------- |82| "rank", "compare", "versus", "top", "best/worst" | Compare |83| "over time", "trend", "growth", "decline", "monthly" | Change Over Time |84| "share", "proportion", "breakdown", "percent of" | Part-to-Whole |85| "spread", "range", "outlier", "normal", "distribution" | Distribution |86| "correlation", "relationship", "predict", "affects" | Relationship |87| "flow", "path", "from X to Y", "conversion", "funnel" | Flow / Process |88| "hierarchy", "drill down", "parent/child", "levels" | Hierarchy |89| "where", "hotspot", "concentration", "geographic" | Spatial Pattern |90| "deviation", "variance", "above/below target", "gap" | Deviation |9192## Module 2: Narrative Chart Pairing9394A single chart tells one point. Paired charts reinforce the insight from a second angle.9596| Primary Chart | Good Pair | Why |97| ---------------------- | --------------------------------------- | --------------------------------------- |98| Bar (compare) | Donut (proportion) | Shows both absolute and relative size |99| Line (trend) | Bar (change amount) | Shows direction and magnitude |100| Scatter (relationship) | Histogram (distribution) | Shows correlation and individual spread |101| Treemap (hierarchy) | Table (detail) | Shows structure and precise values |102| Sankey (flow) | Stacked bar (proportions at each stage) | Shows paths and stage composition |103104### The Inverted Pyramid Pattern105106From `population.html` reference -- arrange visuals in absorption order:107108| Layer | Component | Time to Absorb | Purpose |109| ----- | ----------------- | -------------- | ------------------------------ |110| 1 | KPI cards | 2 seconds | "What's the big picture?" |111| 2 | Hero chart | 10 seconds | Full distribution, interactive |112| 3 | Supporting charts | 15 seconds | Same data, different lens |113| 4 | Table | As needed | Precise values for analysts |114| 5 | Drill-down | On click | Detail without clutter |115116## Module 3: Color Theory117118### Mandatory: Colorblind-Safe Palette119120All chart output MUST use a colorblind-safe palette. The canonical palette for all Alex charting skills is **Tableau 10**, verified against deuteranopia, protanopia, and tritanopia:121122```123#4e79a7 Blue-Steel (primary)124#f28e2b Orange125#e15759 Coral126#76b7b2 Teal127#59a14f Sage128#edc948 Gold129#b07aa1 Mauve130#ff9da7 Rose131#9c755f Brown132#bab0ac Warm Gray133```134135| Palette | Colors | Use Case |136| ------------------------- | --------------------------------------------------------- | -------------------------- |137| **Categorical (default)** | First N colors from the canonical 10 above | Unordered categories |138| **Sequential Blue** | `#deebf7 → #08519c` | Low-to-high numeric |139| **Diverging RdBu** | `#b2182b → #f7f7f7 → #2166ac` | Above/below midpoint |140| **Semantic Region** | Consistent color per category across all charts on a page | Region, department, status |141142### Color Rules (Non-Negotiable)143144| Rule | Explanation |145| ------------------------------- | ----------------------------------------------------------------------------------------- |146| **Always colorblind-safe** | Never use a palette that has not been tested for deuteranopia, protanopia, and tritanopia |147| **Semantic consistency** | Same color = same meaning across all charts on a page |148| **Highlight, don't decorate** | Use saturated color for the key data point; mute everything else |149| **Sequential for ordered data** | Light-to-dark for low-to-high |150| **Diverging for deviation** | Two hues diverging from neutral midpoint |151| **Never rely on color alone** | Add patterns, labels, or shapes for accessibility |152| **Test with Sim Daltonism** | Verify with protanopia and deuteranopia simulation |153154### WCAG Contrast Requirements155156| Context | Minimum Ratio |157| ------------------- | -------------------------- |158| Text on background | 4.5:1 (AA), 7:1 (AAA) |159| Chart labels | 4.5:1 minimum |160| Data vs. background | 3:1 for graphical elements |161162## Module 4: Decluttering (Tufte's Data-Ink Ratio)163164Every element must earn its place. Remove anything that doesn't carry data.165166| Remove | Replace With |167| ------------------------- | ------------------------------------ |168| Gridlines | Light reference lines only if needed |169| Borders around chart area | White space separation |170| Legends (when possible) | Direct labels on data |171| Background fills | Transparent / minimal |172| 3D effects | Never. Always flat. |173| Redundant axis labels | Context in title or subtitle |174175### Before/After Anti-Patterns176177| Anti-Pattern | Problem | Fix |178| ------------------ | ----------------------- | -------------------------------- |179| Rainbow palette | No semantic meaning | Use 2-3 purposeful colors |180| Every bar labeled | Visual noise | Label key values only |181| Dual Y axes | Misleading correlation | Two separate charts |182| Pie with 8+ slices | Unreadable | Horizontal bar, sorted |183| Missing axis zero | Exaggerated differences | Start at zero or note truncation |184185## Module 5: Annotation Hierarchy186187| Element | Content | Rule |188| ------------ | ------------------------------------------------------- | ------------------ |189| **Title** | The insight ("Sales peaked at $4.2M in Q3") | Never a data label |190| **Subtitle** | Context ("Quarterly revenue, FY 2024-2025") | Who, what, when |191| **Callout** | The exception ("Q1 2025: +31% jump -- pricing change?") | Arrow or highlight |192| **Footnote** | Caveats ("Excludes returns. Source: SAP ERP.") | Small, bottom |193| **Source** | Data provenance | Always present |194195## Module 6: Small Multiples196197Use faceted views when a single chart would be overloaded.198199| Use Small Multiples When | Use Overlay When |200| ------------------------------------- | ------------------------- |201| 5+ series on one chart | 2-3 series that interact |202| Each series has its own pattern | Comparison is the point |203| Reader needs to see individual shapes | Relative position matters |204205### Implementation206207```208Grid: 2x3 or 3x4 panels209Each panel: Same axes, same scale (critical!)210Difference: One variable changes per panel (category, time period, cohort)211```212213## Module 7: Accessibility214215| Requirement | Implementation |216| ----------------- | ------------------------------------------------------------------------------------------------------------ |217| **Alt text** | Describe the chart's insight, not its structure ("Revenue grew 34% in 2024" not "Bar chart showing revenue") |218| **Patterns** | Add hatching or shapes alongside color |219| **Keyboard** | Tab-navigable data points in interactive charts |220| **Screen reader** | `aria-label` on chart container, data table fallback |221| **High contrast** | Test in Windows High Contrast mode |222223## Module 8: Tool Targets224225| Target | Library | Output | When |226| --------------------- | ---------------------- | ------------------------- | --------------------------------- |227| HTML (self-contained) | Chart.js 4.x via CDN | `.html` file | Default -- zero-config dashboards |228| HTML (advanced) | Raw Canvas 2D API | `.html` file | Sankey, Chord, Sunburst, etc. |229| Python | Plotly | Interactive HTML/notebook | Data science workflows |230| Python (static) | Matplotlib + Seaborn | PNG/SVG | Publications, reports |231| Markdown | Mermaid | Inline in docs | Documentation, PRs |232| Power BI | DAX measures + visuals | .pbix | Enterprise BI |233234### Chart.js Configuration Defaults235236```javascript237// Standard Chart.js defaults for all data-viz skills238Chart.defaults.font.family = "'Segoe UI', system-ui, sans-serif";239Chart.defaults.font.size = 13;240Chart.defaults.plugins.legend.display = false; // prefer direct labels241Chart.defaults.scales.x.grid.display = false; // declutter242Chart.defaults.scales.y.grid.color = "rgba(255,255,255,0.06)"; // subtle243Chart.defaults.plugins.tooltip.backgroundColor = "rgba(0,0,0,0.85)";244```245246## Module 9: Advanced Canvas Charts24724810 chart types rendered with raw Canvas 2D API -- no extra dependencies beyond the browser.249250| Chart | Story Intent | Data Shape | Key Technique |251| ------------------------ | ---------------------- | ----------------------- | ----------------------------------- |252| **Sankey** | Flow | Source-target-value | Bezier curves between stacked bars |253| **Chord** | Relationship | Adjacency matrix | Circular arcs with ribbons |254| **Streamgraph** | Change Over Time | Multi-series time | Stacked area with centered baseline |255| **Sunburst** | Hierarchy | Parent-child | Concentric arcs, angular proportion |256| **Parallel Coordinates** | Compare (multi-dim) | Many numeric columns | Vertical axes, polylines |257| **Beeswarm** | Distribution | Categorical + numeric | Force-separated dots on axis |258| **Ridgeline** | Distribution (compare) | Series of distributions | Overlapping density curves |259| **Waffle** | Part-to-Whole | Percentages | Grid of colored squares |260| **Network Graph** | Relationship | Nodes + edges | Force-directed layout |261| **Violin** | Distribution | Grouped distributions | Mirrored density curves |262263### Canvas Rendering Pattern264265```javascript266// Standard pattern for all advanced charts267const canvas = document.getElementById("chart");268const ctx = canvas.getContext("2d");269const dpr = window.devicePixelRatio || 1;270canvas.width = canvas.clientWidth * dpr;271canvas.height = canvas.clientHeight * dpr;272ctx.scale(dpr, dpr);273// ... render logic274```275276## Reference Implementations277278| File | Charts | Pattern |279| ------------------ | ------------------ | ---------------------------------------------- |280| `visuals.html` | 14 standard types | Card grid, mini/full pairs, per-chart metadata |281| `adv_visuals.html` | 10 advanced types | Canvas-only rendering, zero dependencies |282| `population.html` | 4 dashboard charts | Inverted pyramid, narrative flow, drill-down |283284## Anti-Patterns285286| Anti-Pattern | Why It Fails | Fix |287| ------------------------------- | ------------------------------------------- | ------------------------------------------- |288| "Chart type first, data second" | Picks visual before understanding the story | Start with story intent |289| Title just labels axes | No argument, no insight | Write a sentence the viewer should conclude |290| Rainbow palette on categories | No semantic meaning, accessibility failure | Max 2-3 purposeful hues |291| Dual Y axes | Implies false correlation | Two separate charts |292| Pie chart with 8+ slices | Unreadable, angle perception is poor | Sorted horizontal bar |293| 3D anything | Distorts perception, adds zero information | Always flat |294| Default gridlines | Clutter that competes with data | Remove or make very subtle |