@blueprint-chart/docs 0.1.18

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +29 -0
  3. package/dist/api.d.ts +13 -0
  4. package/dist/api.js +29 -0
  5. package/dist/manifest.json +242 -0
  6. package/package.json +63 -0
  7. package/src/charts/area-stacked.md +64 -0
  8. package/src/charts/area.md +65 -0
  9. package/src/charts/bar-grouped.md +60 -0
  10. package/src/charts/bar-horizontal.md +71 -0
  11. package/src/charts/bar-multi.md +64 -0
  12. package/src/charts/bar-split.md +61 -0
  13. package/src/charts/bar-stacked.md +62 -0
  14. package/src/charts/bar-vertical.md +71 -0
  15. package/src/charts/column-stacked.md +57 -0
  16. package/src/charts/donut.md +66 -0
  17. package/src/charts/index.md +36 -0
  18. package/src/charts/line-multi.md +64 -0
  19. package/src/charts/line.md +65 -0
  20. package/src/charts/pie.md +63 -0
  21. package/src/guide/accessibility.md +196 -0
  22. package/src/guide/data-transforms.md +191 -0
  23. package/src/guide/dsl-editor.md +218 -0
  24. package/src/guide/embed.md +208 -0
  25. package/src/guide/getting-started.md +159 -0
  26. package/src/guide/palettes.md +207 -0
  27. package/src/guide/scenes.md +223 -0
  28. package/src/handbook/accessibility.md +109 -0
  29. package/src/handbook/annotations.md +143 -0
  30. package/src/handbook/anti-patterns.md +85 -0
  31. package/src/handbook/axes.md +116 -0
  32. package/src/handbook/choosing.md +120 -0
  33. package/src/handbook/color.md +141 -0
  34. package/src/handbook/design-principles.md +111 -0
  35. package/src/handbook/frame-elements.md +98 -0
  36. package/src/handbook/index.md +91 -0
  37. package/src/handbook/labels.md +117 -0
  38. package/src/handbook/tooltips.md +98 -0
  39. package/src/handbook/typography.md +93 -0
  40. package/src/reference/api/index.md +245 -0
  41. package/src/reference/dsl/annotations.md +135 -0
  42. package/src/reference/dsl/index.md +137 -0
  43. package/src/reference/dsl/properties.md +79 -0
  44. package/src/reference/dsl/scenes-and-transforms.md +97 -0
  45. package/src/reference/index.md +18 -0
@@ -0,0 +1,208 @@
1
+ # Embedding Charts
2
+
3
+ Blueprint Chart is **static-first**: every chart is a self-contained artifact independent of any vendor server. There are three ways to put one on a page, and they all run entirely in the browser.
4
+
5
+ ::: tip Data sovereignty
6
+ Charts render in-page (or in a sandboxed `srcdoc` iframe). Data never leaves the visitor's browser by default — no backend call, no analytics ping, no third-party SaaS. This is a structural property, not a marketing claim.
7
+ :::
8
+
9
+ ## Option 1 — Drop in a `<script>` tag
10
+
11
+ The simplest path. Load the standalone runtime once per page, then add one `<script type="application/blueprint-chart">` per chart.
12
+
13
+ ```html
14
+ <script src="https://unpkg.com/@blueprint-chart/lib/dist/lib/lib.iife.js"></script>
15
+
16
+ <script type="application/blueprint-chart">
17
+ chart line-multi {
18
+ title = "Wind and solar are catching up to hydroelectric power"
19
+ description = "Share of electricity generation by source (%)"
20
+ source = "IEA"
21
+ sourceUrl = "https://iea.org"
22
+ colors = "#59a14f, #edc949, #4e79a7"
23
+ legend = false
24
+ lineSymbols = true
25
+ lineSymbolShowOn = "last"
26
+ tooltips = true
27
+
28
+ data {
29
+ _series = "Hydro","Wind","Solar"
30
+ "2010" = 16.0,1.6,0.3
31
+ "2012" = 16.2,2.4,0.6
32
+ "2014" = 16.3,3.3,1.1
33
+ "2016" = 16.4,4.0,1.5
34
+ "2018" = 15.8,4.8,2.4
35
+ "2020" = 16.8,6.2,3.7
36
+ "2022" = 15.0,7.8,4.5
37
+ "2024" = 14.8,9.5,6.2
38
+ }
39
+ }
40
+ </script>
41
+ ```
42
+
43
+ ::: tip From the sample library
44
+ This is `packages/lib/src/samples/renewable-energy.bpc` — a multi-series line with explicit per-series colours and a single trailing symbol on the last datapoint of each series. Pasted verbatim into a page, it renders to a self-contained iframe with no extra wiring.
45
+ :::
46
+
47
+ The runtime auto-runs on `DOMContentLoaded`, finds every chart script tag, and replaces it with a sandboxed iframe (`sandbox="allow-scripts"`) sized via `postMessage` to match the rendered chart.
48
+
49
+ ### Re-running after a dynamic insert
50
+
51
+ If you insert chart scripts after page load (SPA navigation, late-injected content) call the runtime explicitly:
52
+
53
+ ```html
54
+ <script>
55
+ // Available globally as `BlueprintChart` when loaded via the IIFE bundle.
56
+ BlueprintChart.initBlueprint()
57
+ </script>
58
+ ```
59
+
60
+ ## Option 2 — Embed export from the editor
61
+
62
+ The hosted editor at [blueprintchart.com](https://blueprintchart.com) ships an **Embed** export tab that produces a ready-to-paste snippet — runtime script tag + the chart source — that you can drop directly into any HTML page, CMS rich-text block, or newsletter template.
63
+
64
+ Choose **Embed** in the export panel and copy the snippet. Nothing else needs to be installed on the host page.
65
+
66
+ ## Option 3 — Programmatic ESM API
67
+
68
+ For full control — server-side rendering, custom render passes, or wiring into your own component framework — use the ESM API directly.
69
+
70
+ ```ts
71
+ import {
72
+ parse,
73
+ buildChartOptions,
74
+ parseData,
75
+ registerChart,
76
+ getChart,
77
+ } from '@blueprint-chart/lib'
78
+
79
+ const ast = parse(source) // BPC text → AST
80
+ const data = parseData(ast) // AST → ChartData
81
+ const options = buildChartOptions(ast) // AST → ChartOptions
82
+
83
+ const renderer = getChart(ast.chartType) // → ChartRenderer
84
+ renderer.render({ data, options, container })
85
+ ```
86
+
87
+ See the [API reference](/reference/api/) for the full surface area, including frame/canvas/legend primitives and the chart-type registry.
88
+
89
+ ## Static-site integrations
90
+
91
+ Each integration is a thin wrapper around the runtime script tag. Current status:
92
+
93
+ | Generator | Status | Notes |
94
+ | --- | --- | --- |
95
+ | Plain HTML | ✅ Ships in `lib` | The `<script>` pattern above. |
96
+ | Hugo | ⏳ Planned | Phase 2 GTM deliverable. Shortcode wrapping the runtime. |
97
+ | Astro | ⏳ Planned | `<BlueprintChart>` Astro component. |
98
+ | Eleventy | ⏳ Planned | Shortcode + plugin. |
99
+ | Next.js | ⏳ Planned | React component wrapping the runtime in `useEffect`. |
100
+
101
+ If you need one of these now, the pattern is small enough to write inline: load the IIFE bundle once, then render a `<script type="application/blueprint-chart">` with the chart source in the body of your template.
102
+
103
+ ## Self-hosting the runtime
104
+
105
+ The `unpkg.com` URL is convenient for prototyping; for production embeds, host the bundle yourself to avoid the third-party request and to pin a known version.
106
+
107
+ ```bash
108
+ # Copy the IIFE bundle into your site's static assets directory
109
+ cp node_modules/@blueprint-chart/lib/dist/lib/lib.iife.js public/vendor/
110
+ ```
111
+
112
+ ```html
113
+ <script src="/vendor/lib.iife.js"></script>
114
+ ```
115
+
116
+ ## Real-world embeds
117
+
118
+ Two end-to-end examples drawn straight from the lib's sample library — paste either snippet into an HTML page that already loads `lib.iife.js` and the runtime does the rest.
119
+
120
+ ### Donut: share of energy by source
121
+
122
+ ```html
123
+ <script type="application/blueprint-chart">
124
+ chart donut {
125
+ title = "Coal still generates a third of the world's electricity"
126
+ description = "Share by source, 2024"
127
+ source = "IEA"
128
+ sourceUrl = "https://iea.org"
129
+ colors = "#76b7b2, #4e79a7, #59a14f, #f28e2b, #edc949, #e15759, #b07aa1"
130
+ legendPosition = "right"
131
+ tooltips = true
132
+ displayAsPercentage = true
133
+
134
+ data {
135
+ "Coal" = 34.2
136
+ "Natural Gas" = 22.1
137
+ "Hydro" = 14.8
138
+ "Nuclear" = 9.4
139
+ "Wind" = 9.5
140
+ "Solar" = 6.2
141
+ "Other" = 3.8
142
+ }
143
+ }
144
+ </script>
145
+ ```
146
+
147
+ ::: tip From the sample library
148
+ This is `packages/lib/src/samples/energy-sources.bpc` — a donut chart with an explicit categorical palette, right-anchored legend, and percentage display.
149
+ :::
150
+
151
+ ### Line: a single-series time series with an annotation
152
+
153
+ ```html
154
+ <script type="application/blueprint-chart">
155
+ chart line {
156
+ title = "US inflation peaked at 9.1% before retreating to near 3%"
157
+ description = "Consumer Price Index, year-over-year change (%)"
158
+ source = "Bureau of Labor Statistics"
159
+ sourceUrl = "https://bls.gov/cpi/"
160
+ colors = "#f28e2b"
161
+ lineSymbols = true
162
+ lineSymbolShape = "circle"
163
+ lineSymbolShowOn = "all"
164
+ verticalNumberFormat = ".1f"
165
+ tooltips = true
166
+
167
+ annotation "Jun 2022" {
168
+ text = "Peak: 9.1%"
169
+ dy = -12
170
+ showArrow = true
171
+ }
172
+
173
+ data {
174
+ "Jan 2021" = 1.4
175
+ "Jun 2021" = 5.4
176
+ "Jan 2022" = 7.5
177
+ "Jun 2022" = 9.1
178
+ "Jan 2023" = 6.4
179
+ "Jun 2023" = 3.0
180
+ "Jan 2024" = 3.1
181
+ "Jun 2024" = 3.0
182
+ "Jan 2025" = 3.0
183
+ }
184
+ }
185
+ </script>
186
+ ```
187
+
188
+ ::: tip From the sample library
189
+ This is `packages/lib/src/samples/inflation-rate.bpc` — a single-series line with circular symbols on every datapoint, a pinned annotation on the peak, and a one-decimal vertical number format.
190
+ :::
191
+
192
+ ## Security model
193
+
194
+ - The chart iframe uses `sandbox="allow-scripts"` only — no same-origin, no top-navigation, no forms.
195
+ - The chart source is inserted via `srcdoc` after HTML-entity escaping.
196
+ - The runtime does no network requests for rendering. All chart logic runs locally.
197
+ - The parent page communicates with the iframe only via a single `postMessage` channel used to resize the iframe to fit content.
198
+
199
+ ## Troubleshooting
200
+
201
+ **The chart doesn't appear.**
202
+ Check the browser console for parse errors. The runtime keeps the original DSL visible inside a `.blueprint-chart-placeholder` div if rendering fails, so the source remains diff-able.
203
+
204
+ **The iframe height doesn't match the chart.**
205
+ The runtime listens for `blueprint-chart-resize` messages and resizes accordingly. A Content Security Policy that blocks inline scripts inside iframes will break this — the `srcdoc` iframe needs `script-src 'unsafe-inline'` or a matching `'sha256-…'` directive.
206
+
207
+ **My CMS strips `<script>` tags.**
208
+ Use the editor's standalone HTML export instead and host it as a static asset.
@@ -0,0 +1,159 @@
1
+ # Getting Started
2
+
3
+ Blueprint Chart is published as three packages on NPM. Pick the one that matches what you're building.
4
+
5
+ <table>
6
+ <thead><tr><th>Package</th><th>When to use it</th></tr></thead>
7
+ <tbody>
8
+ <tr><td nowrap><a href="https://www.npmjs.com/package/@blueprint-chart/lib"><code>@blueprint-chart/lib</code></a></td><td>Pure TypeScript chart engine — render charts from data + options or from a <code>.bpc</code> source. No Vue.</td></tr>
9
+ <tr><td nowrap><a href="https://www.npmjs.com/package/@blueprint-chart/ui"><code>@blueprint-chart/ui</code></a></td><td>Vue 3 component library — forms, panels, navigation, scene timeline, layout primitives.</td></tr>
10
+ <tr><td nowrap><a href="https://www.npmjs.com/package/@blueprint-chart/editor"><code>@blueprint-chart/editor</code></a></td><td>The full SPA — runs on top of <code>lib</code> + <code>ui</code>. Deployed at <a href="https://blueprintchart.com">blueprintchart.com</a>.</td></tr>
11
+ </tbody>
12
+ </table>
13
+
14
+ ## Install
15
+
16
+ ::: code-group
17
+
18
+ ```bash [pnpm]
19
+ pnpm add @blueprint-chart/lib
20
+ ```
21
+
22
+ ```bash [npm]
23
+ npm install @blueprint-chart/lib
24
+ ```
25
+
26
+ ```bash [yarn]
27
+ yarn add @blueprint-chart/lib
28
+ ```
29
+
30
+ :::
31
+
32
+ ## Render a chart from a BPC source
33
+
34
+ ```ts
35
+ import { parse, buildChartOptions, parseData } from '@blueprint-chart/lib'
36
+
37
+ const source = `
38
+ chart line {
39
+ title = "Bitcoin surged past $90,000 in 2024"
40
+ description = "USD, year-end closing price"
41
+ source = "CoinGecko"
42
+ sourceUrl = "https://www.coingecko.com"
43
+ colors = "#f7931a"
44
+ lineSymbols = true
45
+ lineSymbolShowOn = "all"
46
+ lineSymbolShape = "diamond"
47
+ verticalNumberFormat = ",.0f"
48
+ tooltips = true
49
+
50
+ annotation "2021" {
51
+ text = "All-time high cycle"
52
+ dy = -12
53
+ showArrow = true
54
+ }
55
+
56
+ data {
57
+ "2016" = 963
58
+ "2017" = 13880
59
+ "2018" = 3742
60
+ "2019" = 7194
61
+ "2020" = 28949
62
+ "2021" = 46306
63
+ "2022" = 16547
64
+ "2023" = 42258
65
+ "2024" = 93429
66
+ }
67
+ }
68
+ `
69
+
70
+ const ast = parse(source)
71
+ const data = parseData(ast)
72
+ const options = buildChartOptions(ast)
73
+ ```
74
+
75
+ ::: tip From the sample library
76
+ This is `packages/lib/src/samples/bitcoin-price.bpc` — a single-series line chart with a fixed-colour brand override (`colors = "#f7931a"`), diamond symbols on every datapoint, and a pinned annotation marking the 2021 peak.
77
+ :::
78
+
79
+ From here you wire the `data` and `options` into the renderer of your choice — `@blueprint-chart/lib` exposes the building blocks (`createFrame`, `createCanvas`, `renderLegend`, `renderHorizontalAxis`, `renderVerticalAxis`) plus a chart-type registry (`registerChart` / `getChart`). See [the API reference](/reference/api/).
80
+
81
+ ## Drop a chart into any page
82
+
83
+ If you don't need the programmatic API, use the bundled runtime. It picks up every `<script type="application/blueprint-chart">` tag and replaces it with a sandboxed iframe containing the rendered chart.
84
+
85
+ ```html
86
+ <script src="https://unpkg.com/@blueprint-chart/lib/dist/runtime.iife.js"></script>
87
+
88
+ <script type="application/blueprint-chart">
89
+ chart donut {
90
+ title = "Coal still generates a third of the world's electricity"
91
+ description = "Share by source, 2024"
92
+ source = "IEA"
93
+ sourceUrl = "https://iea.org"
94
+ colors = "#76b7b2, #4e79a7, #59a14f, #f28e2b, #edc949, #e15759, #b07aa1"
95
+ legendPosition = "right"
96
+ tooltips = true
97
+ displayAsPercentage = true
98
+
99
+ data {
100
+ "Coal" = 34.2
101
+ "Natural Gas" = 22.1
102
+ "Hydro" = 14.8
103
+ "Nuclear" = 9.4
104
+ "Wind" = 9.5
105
+ "Solar" = 6.2
106
+ "Other" = 3.8
107
+ }
108
+ }
109
+ </script>
110
+
111
+ <script>
112
+ blueprintChart.initBlueprint()
113
+ </script>
114
+ ```
115
+
116
+ ::: tip From the sample library
117
+ This is `packages/lib/src/samples/energy-sources.bpc` — a donut chart with a hand-picked categorical palette, percentage display, and a right-anchored legend.
118
+ :::
119
+
120
+ See the [embedding guide](/guide/embed) for static sites, CMS integrations, and the base64 iframe pattern.
121
+
122
+ ## Try the editor instead
123
+
124
+ The fastest way to author a chart is in the hosted editor.
125
+
126
+ - Open <https://blueprintchart.com>
127
+ - Pick a sample or paste your own CSV / data
128
+ - Tweak in the panel, watch the live preview, then export as a standalone HTML file or an embeddable `<script>` tag
129
+
130
+ The editor runs entirely in your browser — no account, no server upload, no telemetry.
131
+
132
+ ## Build from source
133
+
134
+ If you want to contribute or develop against an unreleased build, see the [repository README](https://github.com/blueprint-chart/blueprint-chart#readme) and `AGENTS.md` for canonical conventions.
135
+
136
+ ```bash
137
+ git clone git@github.com:blueprint-chart/blueprint-chart.git
138
+ cd blueprint-chart
139
+ make install
140
+ make dev # editor at http://localhost:5555
141
+ make dev-docs # these docs at http://localhost:4445
142
+ ```
143
+
144
+ ## Try these samples
145
+
146
+ The lib ships ~40 ready-to-run `.bpc` files under `packages/lib/src/samples/`. They double as canonical examples and as integration-test fixtures. A handful worth opening first:
147
+
148
+ - `bitcoin-price.bpc` — single-series line with a brand colour, year-by-year diamond symbols, and an annotation on the 2021 peak.
149
+ - `co2-emissions-story.bpc` — a bar chart with three scenes, each highlighting a different country to walk a reader through the same data.
150
+ - `farm-compass.bpc` — a multi-scene narrative where later scenes swap the chart type (area → line → area-stacked) without rewriting the source.
151
+ - `browser-market.bpc` — a donut driven by the named `Heep` palette, with right-anchored legend and percentage display.
152
+ - `medal-count.bpc` — `bar-multi` with a gold / silver / bronze custom palette, sorted descending, top-anchored legend.
153
+ - `temperature-anomaly.bpc` — single-series line tuned for dark mode (`autoContrast = false`, `allowDarkMode = true`) with a curved annotation calling out the 2015 Paris Agreement.
154
+
155
+ ## Next steps
156
+
157
+ - [BPC DSL specification](/reference/dsl/) — the full language reference.
158
+ - [Embedding charts](/guide/embed) — embed flows, CMS integrations, runtime details.
159
+ - [API reference](/reference/api/) — every exported symbol from `@blueprint-chart/lib`.
@@ -0,0 +1,207 @@
1
+ ---
2
+ title: Palettes
3
+ ---
4
+
5
+ # Palettes
6
+
7
+ > 50+ curated categorical palettes, plus the helpers to resolve, audit, and adjust them for the background you render against.
8
+
9
+ ## Why this matters
10
+
11
+ Color is the second most powerful encoding after position — and the easiest to misuse. Blueprint Chart ships a curated catalogue of palettes (sourced from [pypalettes](https://github.com/y-sunflower/pypalettes), MIT) so chart authors can pick a tested set instead of hand-rolling one. Each palette is perceptually balanced enough to read at small sizes; the accompanying helpers let you contrast-check and CVD-check before publishing.
12
+
13
+ ## Quickstart
14
+
15
+ Pick a palette by name in a `.bpc` document:
16
+
17
+ ```bpc
18
+ chart donut {
19
+ title = "Chrome dominates with two-thirds of the desktop browser market"
20
+ description = "Worldwide, January 2025"
21
+ source = "StatCounter"
22
+ sourceUrl = "https://gs.statcounter.com"
23
+ colorPalette = "Heep"
24
+ legendPosition = "right"
25
+ tooltips = true
26
+ displayAsPercentage = true
27
+
28
+ data {
29
+ "Chrome" = 65.7
30
+ "Edge" = 13.1
31
+ "Safari" = 8.9
32
+ "Firefox" = 6.3
33
+ "Opera" = 3.1
34
+ "Others" = 2.9
35
+ }
36
+ }
37
+ ```
38
+
39
+ ::: tip From the sample library
40
+ This is `packages/lib/src/samples/browser-market.bpc` — a donut chart driven entirely by the named `Heep` palette. Each slice picks up the next colour from the resolved palette array.
41
+ :::
42
+
43
+ Or pull the colours into TypeScript:
44
+
45
+ ```ts
46
+ import { resolvePalette, listPalettes } from '@blueprint-chart/lib'
47
+
48
+ resolvePalette('Egypt')
49
+ // → ['#dd5129', '#0f7ba2', '#43b284', '#fab255']
50
+
51
+ listPalettes()
52
+ // → PaletteEntry[] with every palette currently registered
53
+ ```
54
+
55
+ `resolvePalette()` returns a mutable copy of the underlying readonly array, so you can safely shuffle, slice, or reorder.
56
+
57
+ ## How it works
58
+
59
+ Palettes are pure data — `packages/lib/src/charts/palettes.ts` declares a `PALETTES` array of `{ name, label, colors }` entries, indexed into a `PALETTE_MAP` for O(1) lookup. At render time:
60
+
61
+ 1. The chart's `colorPalette` property (a palette `name`) is resolved by `resolvePalette()` into an array of hex strings.
62
+ 2. Each series is mapped to a palette entry by `resolveSeriesColor`. Per-series overrides — `colors`, `series { color = … }`, `colorize "<name>"` — take precedence.
63
+ 3. When `autoContrast = true`, `adjustColorsForBackground(colors, bg)` nudges the lightness of each colour until every series clears WCAG AA against the frame background **and** every adjacent pair has at least CIE2000 ΔE ≥ 12. Hue and saturation are preserved.
64
+
65
+ The library uses [chroma-js](https://gka.github.io/chroma.js/) under the hood for parsing, deltaE, and perceptual interpolation. See the [color handbook](/handbook/color) for the underlying theory (sequential vs. diverging vs. categorical, the perceptual-uniformity trap, ten ways to use less colour).
66
+
67
+ ## Recipes
68
+
69
+ ### Use a hand-picked colour
70
+
71
+ The `colorPalette` property accepts any registered palette `name`. For a one-off brand-coloured chart, drop `colors = "<hex>"` (single value) and skip the palette entirely:
72
+
73
+ ```bpc
74
+ chart line {
75
+ title = "Bitcoin surged past $90,000 in 2024"
76
+ description = "USD, year-end closing price"
77
+ source = "CoinGecko"
78
+ colors = "#f7931a"
79
+ lineSymbols = true
80
+ lineSymbolShowOn = "all"
81
+ lineSymbolShape = "diamond"
82
+
83
+ data {
84
+ "2016" = 963
85
+ "2020" = 28949
86
+ "2022" = 16547
87
+ "2024" = 93429
88
+ }
89
+ }
90
+ ```
91
+
92
+ ::: tip From the sample library
93
+ This is `packages/lib/src/samples/bitcoin-price.bpc` — Bitcoin orange (`#f7931a`) hard-coded as the single series colour, so the chart matches the brand regardless of the active palette.
94
+ :::
95
+
96
+ For multi-series charts, pass a comma-separated list (`colors = "#a","#b","#c"`) — `medal-count.bpc` does exactly this with gold, silver, and bronze for the Olympic ranking.
97
+
98
+ ### Override a single category
99
+
100
+ `colorize "<name>"` re-paints one entry without disturbing the rest of the palette. `letter-frequency.bpc` uses it to make the winning entry pop in red against the named `London` palette:
101
+
102
+ ```bpc
103
+ chart bar-vertical {
104
+ title = "E is the most frequent letter in English"
105
+ description = "How often each letter appears in typical English text"
106
+ colorPalette = "London"
107
+ sort = descending
108
+ valueLabels = true
109
+
110
+ colorize "E" {
111
+ color = "#e15759"
112
+ }
113
+
114
+ data {
115
+ "E" = 12.70
116
+ "T" = 9.06
117
+ "A" = 8.17
118
+ "O" = 7.51
119
+ "I" = 6.97
120
+ "N" = 6.75
121
+ }
122
+ }
123
+ ```
124
+
125
+ ::: tip From the sample library
126
+ This is `packages/lib/src/samples/letter-frequency.bpc` — every other bar takes its colour from `London`; only `E` is overridden, drawing the eye to the headline finding.
127
+ :::
128
+
129
+ ### Auto-tune the palette to the frame background
130
+
131
+ Opt a chart into automatic contrast adjustment by setting `autoContrast = true`. The renderer reads the effective background colour through `resolveBackgroundColor(container)` and nudges each palette entry until WCAG AA and a minimum perceptual distance are both satisfied — useful when the same chart ships in both light and dark themes.
132
+
133
+ ### Audit a palette before shipping
134
+
135
+ The contrast and CVD helpers run outside any chart instance, which makes them handy for build-time linting:
136
+
137
+ ```ts
138
+ import {
139
+ resolvePalette,
140
+ wcagContrastRatio,
141
+ wcagLevel,
142
+ checkCvdColors,
143
+ } from '@blueprint-chart/lib'
144
+
145
+ const palette = resolvePalette('Egypt')!
146
+ const bg = '#ffffff'
147
+
148
+ for (const color of palette) {
149
+ const ratio = wcagContrastRatio(color, bg)
150
+ console.log(color, ratio.toFixed(2), wcagLevel(ratio))
151
+ }
152
+
153
+ const issues = checkCvdColors(palette)
154
+ // issues[].pairs lists colours that collapse under each dichromacy
155
+ ```
156
+
157
+ See [Accessibility](/guide/accessibility) for the full audit workflow.
158
+
159
+ ### Browse the catalogue at runtime
160
+
161
+ `listPalettes()` returns every entry currently registered, including its human-readable `label`. Drop it into a picker, a Histoire story, or a unit test:
162
+
163
+ ```ts
164
+ import { listPalettes } from '@blueprint-chart/lib'
165
+
166
+ const options = listPalettes().map((p) => ({
167
+ value: p.name,
168
+ label: p.label,
169
+ swatch: p.colors,
170
+ }))
171
+ ```
172
+
173
+ A small sampling of the catalogue (run `listPalettes()` for the current full list):
174
+
175
+ | name | label | colours |
176
+ | --- | --- | --- |
177
+ | `Blueprint` | Blueprint | 6 |
178
+ | `JosefAlbers` | Albers | 5 |
179
+ | `Egypt` | Egypt | 4 |
180
+ | `Klimt` | Klimt | 6 |
181
+ | `Maya` | Maya | 5 |
182
+ | `Sunset` | Sunset | 7 |
183
+ | `TheovanDoesburg` | Van Doesburg | 5 |
184
+
185
+ ## API surface
186
+
187
+ Exported from `@blueprint-chart/lib`:
188
+
189
+ | Symbol | One-liner |
190
+ | --- | --- |
191
+ | `resolvePalette(name)` | Returns a mutable `string[]` of hex colours for a palette name, or `undefined`. |
192
+ | `listPalettes()` | Returns every `PaletteEntry` currently registered. |
193
+ | `PaletteEntry` (type) | `{ name: string, label: string, colors: readonly string[] }`. |
194
+ | `resolveSeriesColor(...)` | Resolves a series to its final colour, respecting overrides. |
195
+ | `resolveSeriesInterpolation(...)` | Resolves the interpolation function for a series (line / area charts). |
196
+ | `isSeriesHidden(...)` | Whether a series is hidden by a scene or override. |
197
+ | `resolveBackgroundColor(el)` | Walks ancestors until it finds a non-transparent background. |
198
+ | `adjustColorsForBackground(colors, bg)` | Returns a legibility-tuned copy of the palette for the given background. |
199
+
200
+ For the accessibility helpers (`wcagContrastRatio`, `wcagLevel`, `checkCvdColors`, …) see the [Accessibility guide](/guide/accessibility).
201
+
202
+ ## See also
203
+
204
+ - [Accessibility](/guide/accessibility) — WCAG and CVD utilities.
205
+ - [Colour handbook](/handbook/color) — palette theory and reduction techniques.
206
+ - [BPC DSL — Color directives](/reference/dsl/annotations#color-directives) for `colorize`, `highlight`, `areafill`.
207
+ - [API reference](/reference/api/#palettes) for the full export list.