mirror of
https://github.com/olehomelchenko/chart-sins.git
synced 2026-08-08 02:22:43 +00:00
a3ab9f8a79
Adopt Carbon at the design-token level (the component libraries ship JS and target app UIs; this is a static content site): - IBM Plex Sans/Mono, self-hosted via @fontsource (no external requests) - Carbon color tokens + layered White / Gray 100 themes - 8px spacing scale, productive/expressive type, motion tokens, square geometry, 2px focus ring - UI-shell header, tile grid, Carbon tags, geometric severity meter, breadcrumb, colophon crediting Carbon - Charts themed with IBM Plex + Carbon's data-visualization palette (validated colorblind-safe/contrast) on a fixed light canvas so the build-time SVG stays legible in both themes Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XPEvmMbac2fCvKXpQcovj8
100 lines
4.2 KiB
Markdown
100 lines
4.2 KiB
Markdown
# 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](https://astro.build) and styled on the
|
|
[Carbon Design System](https://carbondesignsystem.com). Charts are authored as
|
|
[Vega-Lite](https://vega.github.io/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:
|
|
|
|
```yaml
|
|
---
|
|
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`.
|