Claude 761e048811 Work the five delivered sources into the pages
The source-request loop paid for itself immediately — two of the five
corrected something rather than confirming it.

The Economist piece settles V1, the riskiest live claim, but our note
had over-claimed: truncating the scale is its *first* example, not one
of "several." Note rewritten to quote her. The same article turned out
to contain a dual-axis chart she caught herself on, now cited.

Datawrapper's color-scale part 1 refuted the assumption behind a queued
sin outright: it makes no argument against rainbow scales and endorses
multi-hue sequential gradients. The rainbow entry is now marked as
having no verified source at all, rather than ample backing.

The dual-axis post independently draws the same line we drew last turn
— of four uses only the alternative-scale case survives, their example
being F against C — and led to two references worth more than the blog
post: the Isenberg et al. study that tested dual-scale charts, and Few's
article working through the cases. Both ship without full metadata
rather than guessed metadata; queued.

Pie and stacked posts gave verbatim support, plus one correction: a
100%-stacked chart has two readable baselines, not one.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ULE5RRxdQE1ebwefEd2eCM
2026-08-05 17:37:47 +00:00
2026-08-05 12:41:00 +00:00

Chart Sins

A catalogue of data-visualization sins — for each one: the chart that misleads, why it fools the eye, and the honest version that fixes it.

Built with Astro and styled on the Carbon Design System. Charts are authored as Vega-Lite specs and rendered to static SVG at build time, so pages ship with zero client-side JavaScript.

Tech stack

Concern Choice
Framework Astro 5 (static output)
Content Markdown/MDX via Astro Content Collections
Charts Vega-Lite specs → SVG at build (headless Vega)
Design Carbon Design System — tokens, type scale, spacing, motion, themes
Typeface IBM Plex Sans / Mono (self-hosted via @fontsource)
Styling Token-driven CSS (src/styles/global.css)
Hosting GitHub Pages (via GitHub Actions)
Language TypeScript

On the Carbon adoption

Carbon ships React/web-component libraries built for application UIs and they ship JavaScript; this is a static content site, so instead of the component runtime we adopt Carbon at the design-token level — its color tokens and White/Gray-100 themes, the 8px spacing scale, the productive/expressive type distinction (IBM Plex), motion tokens, square geometry, the focus ring, and Carbon's data-visualization palette for the charts (validated for colorblind-safety and contrast on the chart surface).

Project layout

src/
├── content.config.ts        # typed frontmatter schema for a "sin"
├── content/sins/            # one Markdown file per sin
├── charts/                  # Vega-Lite JSON specs (bad + fixed)
├── components/VegaChart.astro   # build-time Vega-Lite → SVG renderer
├── layouts/BaseLayout.astro
├── lib/charts.ts            # spec lookup + severity helper
├── pages/
│   ├── index.astro          # the gallery
│   └── sins/[...slug].astro # a sin's detail page
└── styles/global.css

Adding a new sin

  1. Author two Vega-Lite specs in src/charts/, e.g. my-sin-bad.json and my-sin-fixed.json.

    Omit $schema, config, and outer width/height tuning you don't need — keep specs focused on the data and encoding.

  2. Create src/content/sins/my-sin.md with frontmatter:

    ---
    title: "My Sin"
    summary: "One-line description shown on the gallery."
    category: "Misleading Scales"
    severity: 3            # 1 (venial) … 5 (mortal)
    tags: ["bar chart"]
    badChart: "my-sin-bad"      # basename in src/charts/, no .json
    fixedChart: "my-sin-fixed"
    date: 2026-08-05
    ---
    
    Prose explaining the sin, why it deceives, and the repentance.
    
  3. npm run dev and check it. The typed schema will flag a mistyped field or a missing chart spec at build time.

Making a chart interactive (opt-in)

Charts are static SVG by default. To make one interactive, render it client-side with vega-embed in a small Astro island (client:visible) on that page only, instead of using <VegaChart>. This keeps the default fast while allowing hover/zoom where a specific sin benefits from it.

Commands

Command Action
npm install Install dependencies
npm run dev Start the dev server at localhost:4321
npm run build Build the static site to ./dist
npm run preview Preview the production build locally

Deployment

Pushing to main triggers .github/workflows/deploy.yml, which builds the site and publishes it to GitHub Pages. Enable it once under Settings → Pages → Build and deployment → Source: GitHub Actions.

The site is configured for the project path https://olehomelchenko.github.io/chart-sins (site + base in astro.config.mjs). If you move to a custom domain, set site to it and remove base.

S
Description
website to shame you for your chart sins
Readme 676 KiB
Languages
TypeScript 37.1%
CSS 34%
Astro 28.3%
JavaScript 0.6%