Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
173 commits
Select commit Hold shift + click to select a range
bc7754f
fix: use Math.max for pyramid chart right-bar palette fallback
fix2015 Jul 27, 2026
7eec229
Merge pull request #77 from fix2015/fix/pyramid-palette-color-index
Chenglong-MS Jul 27, 2026
5999d65
minor fix
Chenglong-MS Jul 27, 2026
5671899
fixes for excel
Chenglong-MS Jul 27, 2026
9ce2eb4
histogram group
Chenglong-MS Jul 28, 2026
cd77a81
docs: quote pip extras install examples
nyxst4ck Jul 28, 2026
dc8984f
cleanup
Chenglong-MS Jul 28, 2026
52e3f18
Merge branch 'dev' into nyxst4ck/auto-quote-pip-extras-20260728-095216
Chenglong-MS Jul 28, 2026
ab6c514
Merge pull request #78 from nyxst4ck/nyxst4ck/auto-quote-pip-extras-2…
Chenglong-MS Jul 28, 2026
222c9b5
Merge branch 'dev' of github.com:microsoft/flint-chart into dev
Chenglong-MS Jul 28, 2026
c73d597
theme research
Chenglong-MS Jul 29, 2026
55c138c
theme research
Chenglong-MS Jul 30, 2026
5e7afe6
theme R2: fix radial charts under furniture and data labels; add R2/g…
Chenglong-MS Jul 30, 2026
8c731a9
theme(r2): gate always-labels on legibility; readable R2 tiles at 300…
Chenglong-MS Jul 30, 2026
4d2baf6
theme(r2): fix nyt dotted lines — withhold redundant dash under direc…
Chenglong-MS Jul 30, 2026
9212ba0
theme(r2): park scatter-color-n50 and pie-25 in theme-lab-gaps
Chenglong-MS Jul 30, 2026
4ade020
theme: a violin/density plot summarises a distribution, so it prints …
Chenglong-MS Jul 30, 2026
59d3af4
waterfall: pin x-axis title to the field so the synthetic __wf_lead c…
Chenglong-MS Jul 30, 2026
9be350f
histogram: declare the binned x as a banded index axis so a right/top…
Chenglong-MS Jul 30, 2026
7ab69aa
theme: hoist the facet when a zero rule turns a faceted unit into a l…
Chenglong-MS Jul 30, 2026
8e55baf
theme-lab-gaps: park grouped-color-continuous (datawrapper ramp washe…
Chenglong-MS Jul 30, 2026
f88288c
mckinsey: add diverging ramp so signed measures keep their sign
Chenglong-MS Jul 30, 2026
f6b54c8
theme: two realize placement fixes for faceted tables and dual keys
Chenglong-MS Jul 30, 2026
e368ec3
fix(vegalite): carry resolved axis titles into the waterfall layers
zl190 Jul 30, 2026
9207c69
fix(flint-py): point run_full_eval at the moved fixture corpus
zl190 Jul 30, 2026
f168ad9
theme: clear printed bar labels with scale headroom; wrap wide legends
Chenglong-MS Jul 30, 2026
0e306b8
theme: fit-gate bar value labels, pie small-slice suppression, flush-…
Chenglong-MS Jul 30, 2026
066c26f
bump: end labels at the last drawn band; landscape panel for readable…
Chenglong-MS Jul 30, 2026
42d369d
Themed slope charts: house-aware end labels, legend, and band-step floor
Chenglong-MS Jul 30, 2026
5c9ddf2
Stacked-area band labels: stack the text, and end at the real last re…
Chenglong-MS Jul 30, 2026
a1b7d02
Themed bars on a time axis take the house gap (width band), not fill …
Chenglong-MS Jul 30, 2026
e0ff6df
Revert "Themed bars on a time axis take the house gap (width band), n…
Chenglong-MS Jul 30, 2026
b3880f6
Themed bars on a continuous-banded axis: re-cut the layout's size to …
Chenglong-MS Jul 30, 2026
3e3b18c
Themed dodged bars take the house gap on the lane, not just the group
Chenglong-MS Jul 30, 2026
a6cbff6
Datawrapper separator: skip the edge stroke when bars are too thin to…
Chenglong-MS Jul 30, 2026
a86a36a
Loosen dodged boxplot lane fill so grouped boxes separate
Chenglong-MS Jul 30, 2026
478c63b
Relax grouped-box lane-fill assertions to the new 0.7 target
Chenglong-MS Jul 30, 2026
7964b7f
Drop the category-axis spine on bar tables
Chenglong-MS Jul 30, 2026
a5bc7f4
fix(site): reset scroll position when navigating between docs
yelper Jul 30, 2026
77b08f0
revert package-lock.json changes
yelper Jul 30, 2026
ab844fb
fixes
Chenglong-MS Jul 30, 2026
3576f96
theme: give each house a distinct layout envelope
Chenglong-MS Jul 31, 2026
e9e907b
playground: add theme reference-examples tab
Chenglong-MS Jul 31, 2026
1a336ce
theme(economist): right-hand measure axis is the house default
Chenglong-MS Jul 31, 2026
3e24164
Revert "playground: add theme reference-examples tab"
Chenglong-MS Jul 31, 2026
778cb2d
Merge pull request #79 from zl190/fix/waterfall-titles
Chenglong-MS Jul 31, 2026
8060c3c
theme: add Power BI (light) house
Chenglong-MS Jul 31, 2026
8782e3c
theme: make title-block vertical rhythm a per-house lever
Chenglong-MS Jul 31, 2026
09ed692
feat(chartjs): add Lollipop Chart template
zl190 Jul 18, 2026
a0ce619
playground(theme-lab): add Power BI (light) redesigns; drop redundant…
Chenglong-MS Jul 31, 2026
901b7c4
playground(theme-lab): fit modal charts to their pane, wrap instead o…
Chenglong-MS Jul 31, 2026
838f7bd
playground(theme-lab): simplify coverage section to plain bullets, re…
Chenglong-MS Jul 31, 2026
6d2a3ca
Grouped boxplot bands stretch to fill their lanes
Chenglong-MS Jul 31, 2026
dfdb6c6
Tiered palettes + share-ordered "other" overflow for high cardinality
Chenglong-MS Jul 31, 2026
4d493a7
Others(N) overflow legend + universal overflow inks + labs colour panel
Chenglong-MS Jul 31, 2026
7ca968c
theme: merge pie overflow tail into one slice; fix hub spikes and fla…
Chenglong-MS Jul 31, 2026
5df4771
theme: size a folded colour legend for its K+1 keys, not the field's …
Chenglong-MS Jul 31, 2026
8ee6119
theme: complete colour spec — McKinsey extended palette, distinct par…
Chenglong-MS Jul 31, 2026
c6b9a2a
theme(mckinsey): document that the near-black single ink is authentic…
Chenglong-MS Jul 31, 2026
adbf862
theme(radial): seat outside pie labels clear of the arc (gap 14→22)
Chenglong-MS Jul 31, 2026
8990ee0
theme: fix donut-as-pie, radar legend loss, and waterfall title leak
Chenglong-MS Jul 31, 2026
8841803
theme: keep candlestick price axis, show pie share %, stop legend tru…
Chenglong-MS Jul 31, 2026
dfe91a0
playground: add "Theme lab real" page — real datasets × all houses
Chenglong-MS Jul 31, 2026
b046c8d
theme: bin economist diverging heatmap into stepped quantize scale
Chenglong-MS Jul 31, 2026
bb2e4df
theme: keep measure axis left when series names sit at the line ends
Chenglong-MS Jul 31, 2026
ee52b4d
theme: keep the size value-key legend when a chart names no series
Chenglong-MS Jul 31, 2026
86424e2
playground: add Swiss lab with hand-authored Vega-Lite mockups
Chenglong-MS Aug 1, 2026
e97f078
theme: add Swiss (International Typographic Style) preset
Chenglong-MS Aug 1, 2026
13771f7
theme: drop the Swiss header rule
Chenglong-MS Aug 1, 2026
47f5a11
theme: keep the band baseline continuous under bar edge strokes
Chenglong-MS Aug 1, 2026
8b45a77
theme: give McKinsey lollipop stems a solid connector ink
Chenglong-MS Aug 1, 2026
aea55bd
theme: redraw the category baseline over stroked bars; widen lollipop…
Chenglong-MS Aug 1, 2026
9756611
theme: draw the Economist masthead tab over the title, not under it
Chenglong-MS Aug 1, 2026
b096de5
theme: size a bar-table's legend to the whole table, not just the bar…
Chenglong-MS Aug 1, 2026
cdc6610
theme: lengthen the Economist masthead line to ~1/10 of the chart width
Chenglong-MS Aug 1, 2026
5c80262
Refine Economist theme from the 2017 chart style guide
Chenglong-MS Aug 1, 2026
0a6fade
feat(theme): canvas-anchored masthead tab (graphic-left, gutter-indep…
Chenglong-MS Aug 1, 2026
8e6bf00
Fix Power BI dark-theme structural-mark visibility
Chenglong-MS Aug 2, 2026
d96f923
Add playful Cartoon theme + rounded-bar mark lever
Chenglong-MS Aug 2, 2026
fbc21ff
Revert Cartoon theme; add Cartoon lab + group theme-lab nav
Chenglong-MS Aug 2, 2026
3bb5864
Add Cartoon theme + generalizable outline & cornerRadius mark levers
Chenglong-MS Aug 2, 2026
9601350
Load display fonts in the r2 harness so sheets show each house's real…
Chenglong-MS Aug 2, 2026
f70475d
Guard the mark outline on thin bars and drop it from grid cells
Chenglong-MS Aug 2, 2026
e08f70c
axis fixes
Chenglong-MS Aug 2, 2026
7154fbe
Merge origin/dev into theme-experiment
Chenglong-MS Aug 2, 2026
0805d15
Close the last two gaps in Vega-Lite theme coverage
Chenglong-MS Aug 2, 2026
2556cd8
theme: dumbbell connectors, plot edges, dividers, dark-surface legibi…
Chenglong-MS Aug 3, 2026
3a9facd
theme: a house switch in the gallery and the MCP app
Chenglong-MS Aug 3, 2026
63f9011
theme: let the house's own measure and branding reach the widgets
Chenglong-MS Aug 3, 2026
d32d3e0
theme: let a new house speak over options nobody really chose
Chenglong-MS Aug 3, 2026
38bb58d
site: give the MCP app mockup charts worth theming
Chenglong-MS Aug 3, 2026
99e60a9
theme: draw the preview at the size it will be seen
Chenglong-MS Aug 3, 2026
584bd64
theme: every house says how big its dots are
Chenglong-MS Aug 3, 2026
a0857dd
theme: a dot size that reaches only the dots it meant
Chenglong-MS Aug 3, 2026
8682029
site: one style-references page instead of two identical labs
Chenglong-MS Aug 3, 2026
b127a7a
site: theme the whole demo wall at once, and let the playground shut up
Chenglong-MS Aug 3, 2026
72f6a5c
charts: let the reader turn value labels on or off
Chenglong-MS Aug 3, 2026
860a925
charts: value labels are Flint's, not a house's
Chenglong-MS Aug 3, 2026
3e866db
charts: label each bar in a group, and each segment in a stack
Chenglong-MS Aug 3, 2026
92c81b3
charts: print a number a reader can take off the mark
Chenglong-MS Aug 3, 2026
9373579
fix
Chenglong-MS Aug 4, 2026
7ac0f8a
charts: a value label may not contradict the mark it sits on
Chenglong-MS Aug 4, 2026
a2aadd7
site: drop the number lab
Chenglong-MS Aug 4, 2026
9647433
site: illustrate the theme switch, and open the menu the figure means
Chenglong-MS Aug 4, 2026
354dfe0
theme: a legend row is packed, not ruled into columns
Chenglong-MS Aug 4, 2026
e1f247f
charts: two tick numbers may not read as one
Chenglong-MS Aug 4, 2026
aa1750c
site: a mosaic that shows a whole house at once
Chenglong-MS Aug 4, 2026
d169ab1
site: the mosaic shows a style, not twenty charts
Chenglong-MS Aug 4, 2026
268a4cc
site: the wall stops cropping and starts fitting
Chenglong-MS Aug 4, 2026
5567c28
site: a chart is resized, never reshaped
Chenglong-MS Aug 4, 2026
658bd7b
Replace theme mosaic with a demo-wall-style theme wall
Chenglong-MS Aug 4, 2026
c348b8f
Give the theme wall its own captions, measured to fit a tile
Chenglong-MS Aug 4, 2026
9b4a95b
Let the theme wall move the headline into the chart
Chenglong-MS Aug 4, 2026
275a57a
Cap the size key at three anchors by default
Chenglong-MS Aug 4, 2026
e2db7ab
Give a painted canvas a margin its own type can clear
Chenglong-MS Aug 4, 2026
93e4677
Stop exports measuring one font and drawing another
Chenglong-MS Aug 4, 2026
8aa2915
Let the chart frame take the chart's own paper
Chenglong-MS Aug 4, 2026
dd5a1e5
Let a value key say what its numbers count
Chenglong-MS Aug 4, 2026
356428f
Keep swapped heatmap labels renderable
Chenglong-MS Aug 4, 2026
df81568
Make the heatmap illustration visibly transpose
Chenglong-MS Aug 4, 2026
6fa7067
Keep the illustration heatmap rectangular
Chenglong-MS Aug 4, 2026
7c4d686
Draw missing heatmap values as cells
Chenglong-MS Aug 4, 2026
95dab21
Separate temporal heatmaps from categorical grids
Chenglong-MS Aug 4, 2026
4fb1ec1
Restore temporal bands as a layout invariant
Chenglong-MS Aug 4, 2026
25806e8
Lift Power BI colors for dark surfaces
Chenglong-MS Aug 4, 2026
e5a898e
Place band-end names inset or outset as a set
Chenglong-MS Aug 4, 2026
ed5590c
Give the showcase charts a headline and room to fill their pane
Chenglong-MS Aug 4, 2026
ddc9149
Note why the faceted showcase uses two columns
Chenglong-MS Aug 4, 2026
4b49668
Promote the theme wall to a public /themes page
Chenglong-MS Aug 5, 2026
8ad197b
Fix the themes wall to 6x3 and tell the reader how to use a theme
Chenglong-MS Aug 5, 2026
337c02d
Polish the themes page copy
Chenglong-MS Aug 5, 2026
9bd3640
Explain each theme in the picker
Chenglong-MS Aug 5, 2026
8d198ef
Explain how Flint themes shape compilation
Chenglong-MS Aug 5, 2026
e87927c
Show themes as compiler-wide design systems
Chenglong-MS Aug 5, 2026
fe8974a
Add markers to theme principles
Chenglong-MS Aug 5, 2026
01ff991
Simplify the themes page language
Chenglong-MS Aug 5, 2026
3bdaaca
Clarify the three levels of a Flint theme
Chenglong-MS Aug 5, 2026
ee273bb
Join theme bullets with vertical guides
Chenglong-MS Aug 5, 2026
c0e7d7f
Move theme bullets to the introduction
Chenglong-MS Aug 5, 2026
04a560c
Remove bullets from the themes introduction
Chenglong-MS Aug 5, 2026
e6ebfd6
Refine the Flint theme introduction
Chenglong-MS Aug 5, 2026
e619576
Lead the themes page with the specification
Chenglong-MS Aug 5, 2026
5311586
Place Swiss beside the editorial themes
Chenglong-MS Aug 5, 2026
54cb63a
Resolve every documentation navigation label
Chenglong-MS Aug 5, 2026
0399ad6
Teach preset, custom, and inherited ThemeSpecs
Chenglong-MS Aug 5, 2026
5d02b30
Pair ThemeSpec code with a live chart preview
Chenglong-MS Aug 5, 2026
7cc1151
Keep chart context beside the ThemeSpec preview
Chenglong-MS Aug 5, 2026
14c1008
Give the custom ThemeSpec a blue canvas
Chenglong-MS Aug 5, 2026
a7e762a
Move ThemeSpec into Quick start
Chenglong-MS Aug 5, 2026
b073450
Frame ThemeSpec around its three compiler levels
Chenglong-MS Aug 5, 2026
2a15810
Rename ThemeSpec guide to Using themes
Chenglong-MS Aug 5, 2026
f68281f
Use house icons throughout the themes guide
Chenglong-MS Aug 5, 2026
0c89a26
Introduce themes in Getting started
Chenglong-MS Aug 5, 2026
b8bb005
Introduce themes on the About page
Chenglong-MS Aug 5, 2026
1ff93cd
Focus the theme introduction on brand consistency
Chenglong-MS Aug 5, 2026
8aee2f5
Brighten the new themes signal
Chenglong-MS Aug 5, 2026
10bf98e
List themes beside rendering backends
Chenglong-MS Aug 5, 2026
fdd0796
Emphasize coherent brand design across charts
Chenglong-MS Aug 5, 2026
12f666b
Link theme roster to matching previews
Chenglong-MS Aug 5, 2026
c955da1
Remove theme wall case descriptions
Chenglong-MS Aug 5, 2026
5fd7bf2
Remove captions from About showcase
Chenglong-MS Aug 5, 2026
146bbb9
Simplify theme specification copy
Chenglong-MS Aug 5, 2026
9deea74
Clarify theme comparison example
Chenglong-MS Aug 5, 2026
4cac179
Rename visual themes action
Chenglong-MS Aug 5, 2026
bdfa221
Link theme demo to usage guide
Chenglong-MS Aug 5, 2026
26c68c7
Center theme wall introduction
Chenglong-MS Aug 5, 2026
0a849d6
Refine theme wall introduction
Chenglong-MS Aug 5, 2026
88554ac
Prepare formal themes for Flint 0.5
Chenglong-MS Aug 5, 2026
399039f
Add Flint 0.5 to About updates
Chenglong-MS Aug 5, 2026
254693c
fix
Chenglong-MS Aug 5, 2026
0d3abfb
Merge pull request #82 from yelper/dev/alsarika/fix-docs-scroll-position
Chenglong-MS Aug 5, 2026
a3768cd
Merge pull request #81 from zl190/fix/eval-fixtures-path
Chenglong-MS Aug 5, 2026
8863ce3
Merge pull request #59 from zl190/feat/chartjs-lollipop
Chenglong-MS Aug 5, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
69 changes: 69 additions & 0 deletions .github/release-notes/0.5.0.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
Flint 0.5 introduces formal visual themes: one specification can now carry
layout behavior, semantic presentation, and visual identity across an entire
chart library.

### Define the visual system once

Add `theme_spec` beside `chart_spec`. The chart spec continues to define what
the chart means; the theme defines how that meaning is presented.

```json
{
"chart_spec": {
"chartType": "Bar Chart",
"encodings": {
"x": { "field": "region" },
"y": { "field": "revenue" }
}
},
"theme_spec": "economist"
}
```

Themes participate in compilation. They can guide spacing and density, labels
and legends, axes and annotations, mark geometry, typography, color, and chart
furniture while adapting those decisions to each chart.

### Start from nine visual themes

Flint ships New York Times, Economist, Swiss, Nature, McKinsey, Datawrapper,
Power BI, Power BI Light, and Cartoon presets. The
[visual-theme wall](https://microsoft.github.io/flint-chart/#/themes) applies
each preset to the same set of charts for direct comparison.

### Create a brand theme

Pass a custom `ThemeSpec`, or inherit a built-in preset and override only the
decisions that should differ:

```json
{
"theme_spec": {
"extends": "economist",
"id": "our-brand",
"ink": {
"series": {
"single": "#6b3fa0"
}
}
}
}
```

Nested objects merge; arrays and scalar values replace inherited values. See
[Using themes](https://microsoft.github.io/flint-chart/#/documentation/theme-spec)
for the complete vocabulary and examples.

### Use themes with agents

The MCP server adds `list_themes` so an agent can inspect the available visual
systems and their authoring guidance. The interactive MCP App also exposes a
theme picker for Vega-Lite charts.

ThemeSpec is currently realized by the Vega-Lite backend. Other backends
continue to accept the shared Flint input but do not yet apply `theme_spec`.

See the [changelog](https://github.com/microsoft/flint-chart/blob/main/CHANGELOG.md)
for the complete technical summary.

**Full Changelog**: https://github.com/microsoft/flint-chart/compare/0.4.1...0.5.0
22 changes: 22 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,28 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Added

- Formal visual themes for Vega-Lite through the new top-level `theme_spec`
field. Callers can select one of nine built-in presets, provide a custom
`ThemeSpec`, or inherit a preset with `extends` and override selected fields.
Nested objects merge while arrays and scalar values replace inherited values.
- A semantic theme-grounding system that applies layout behavior, presentation
rules, mark geometry, typography, color, labels, legends, axes, annotations,
and chart furniture as one visual system across chart types and data shapes.
- Public theme APIs: `ThemeSpec`, `ThemePreset`, `THEME_PRESETS`,
`listThemePresets()`, and `resolveThemeSpec()`.
- Theme discovery in the MCP server through `list_themes`, plus preset selection
in the interactive MCP App.
- A public visual-theme wall, a complete **Using themes** guide, and
preset/custom/inherited live examples on the Flint project site.

### Changed

- Vega-Lite assembly now grounds the selected theme before layout and realizes
its decisions throughout compilation instead of applying a post-render style
layer. Existing inputs without `theme_spec` retain Flint's default behavior.

## [0.4.1] - 2026-07-27

### Changed
Expand Down
43 changes: 42 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
[![CI](https://github.com/microsoft/flint-chart/actions/workflows/ci.yml/badge.svg)](https://github.com/microsoft/flint-chart/actions/workflows/ci.yml)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)

**Please visit:** [**Flint Project Site**](https://microsoft.github.io/flint-chart/) | [**MCP Server Guide**](https://microsoft.github.io/flint-chart/#/mcp) | [**中文主页**](https://microsoft.github.io/flint-chart/#/zh)
**Please visit:** [**Flint Project Site**](https://microsoft.github.io/flint-chart/) | [**Visual Themes**](https://microsoft.github.io/flint-chart/#/themes) | [**MCP Server Guide**](https://microsoft.github.io/flint-chart/#/mcp) | [**中文主页**](https://microsoft.github.io/flint-chart/#/zh)

Flint is a visualization intermediate language that lets **AI agents create
expressive, polished visualizations from simple, human-editable chart specs**.
Expand Down Expand Up @@ -38,6 +38,9 @@ This repo contains two main components:
semantic types such as `Rank`, `Temperature`, `Price`, or `Country`.
- **Automatic layout.** Flint adapts sizing, spacing, labels, marks, and legends
to the data cardinality, chart design, and canvas constraints.
- **Formal visual themes.** Define layout behavior, semantic presentation, and
visual identity once, then apply them across a chart library with a preset,
custom `ThemeSpec`, or inherited theme.
- **Multiple backends.** Compile one input to backend-native output across
[Vega-Lite](https://vega.github.io/vega-lite/),
[ECharts](https://echarts.apache.org/),
Expand Down Expand Up @@ -110,6 +113,43 @@ const plotlyFigure = assemblePlotly(input);
const excelArtifact = assembleExcel(input);
```

## Apply Visual Themes

`theme_spec` sits beside `chart_spec`: the chart spec defines what the chart
means, while the theme defines how that meaning is presented. A theme can guide
layout, labels, legends, axes, mark geometry, typography, and color as one
coherent visual system.

Use one of Flint's nine built-in presets:

```ts
const themedSpec = assembleVegaLite({
...input,
theme_spec: 'economist',
});
```

Or inherit a preset and override only the decisions that belong to your brand:

```ts
const brandedSpec = assembleVegaLite({
...input,
theme_spec: {
extends: 'economist',
id: 'our-brand',
ink: {
series: { single: '#6b3fa0' },
},
},
});
```

Nested objects merge; arrays and scalar values replace the inherited value.
ThemeSpec currently affects Vega-Lite output. Compare all presets on the
[theme wall](https://microsoft.github.io/flint-chart/#/themes) and see
[Using themes](docs/theme-spec.md) for the complete custom and inherited-theme
reference.

See the [API reference](docs/api-reference.md), backend references for
[Vega-Lite](docs/reference-vegalite.md), [ECharts](docs/reference-echarts.md),
[Chart.js](docs/reference-chartjs.md), [Plotly](docs/reference-plotly.md), and
Expand Down Expand Up @@ -160,6 +200,7 @@ flint-chart/
The [project site](https://microsoft.github.io/flint-chart/) is the main entry
point for examples, the live editor, and concept docs. For source-level
references, start with the [API reference](docs/api-reference.md), the
[theme guide](docs/theme-spec.md), the
[Flint MCP project page](https://microsoft.github.io/flint-chart/#/mcp), or the
[Development guide](docs/DEVELOPMENT.md). See the [changelog](CHANGELOG.md) for
notable changes in each release.
Expand Down
81 changes: 77 additions & 4 deletions agent-skills/flint-chart-author/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,15 +83,19 @@ published, use the npm package or MCP server for released workflows.
interface ChartAssemblyInput {
// Bound by the HOST or by you, depending on the situation (see below).
data: { values: any[] } | { url: string };
semantic_types?: Record<string, string>; // field → semantic type ← you write this
semantic_types?: Record<string, string | SemanticAnnotation>; // field → type ( ← you write this)
chart_spec: { // ← you write this
chartType: string; // e.g. "Scatter Plot"
title?: string; // the headline — write one
subtitle?: string; // what is measured, of whom, when, in what units
encodings: Record<string, EncodingValue>; // channel → { field, ... } (or array)
baseSize?: { width: number; height: number }; // target layout size, default 400×320
canvasSize?: { width: number; height: number }; // optional hard ceiling on stretch
chartProperties?: Record<string, any>; // per-chart tuning (optional)
};
options?: Record<string, any>; // global layout options (rarely needed)
field_display_names?: Record<string, string>; // field → readable axis/legend title
theme_spec?: string | ThemeSpec; // design language, e.g. "economist" (Vega-Lite only)
}
```

Expand Down Expand Up @@ -167,6 +171,49 @@ For a Vega-Lite-specific style tweak:
This edited Vega-Lite spec is no longer a portable Flint spec. Do not send it to
`render_chart`; use `render_chart` only for Flint `ChartAssemblyInput`.

## Write a headline

Set `chart_spec.title` to the finding, in a sentence, and `chart_spec.subtitle`
to the reading of it — what is measured, of whom, when, in what units:

```
title: "A pyramid that is no longer a pyramid"
subtitle: "United States population by age and sex, 2020, millions"
```

`Jan`, `Cairo`, `Chrome` name their own kind; `26`, `5,300`, `0.42` do not, and
the headline is where they get named. Leave it out only where the chart is not
read on its own — a sparkline in a cell, a tile under its own caption. Nothing
breaks: with no headline to lean on, the compiler keeps the axis titles instead.

## Design languages (`theme_spec`)

Name a house Flint ships and the compiler styles the chart to it:

```json
{ "chart_spec": { ... }, "theme_spec": "economist" }
```

| id | what it is for |
| --- | --- |
| `nyt` | Newsroom graphics: headline states the finding, values on the marks, series named at their ends. |
| `economist` | Print weekly: compact, flat headline over a deck, units repeated down the ruler. |
| `swiss` | International Typographic Style: strong grid structure, black typography, and a focused red accent. |
| `nature` | Journal figure: small panel, axis titles with units, statistics beside the fit. |
| `mckinsey` | Consulting deck: wide bands, every value printed, headline states the takeaway. |
| `datawrapper` | Embedded web chart: narrow column, plain headline and deck, rule under the footer. |
| `powerbi` | Dashboard tile: compact, legend to the right, latest point emphasised. |
| `powerbi-light` | Light dashboard tile: white canvas, fine gridlines, and bright categorical color. |
| `cartoon` | Playful illustration: warm paper, rounded type, bold outlines, and bright color. |

A house governs the visual only — you still choose the fields, the aggregation
and the sort. Where a house depends on something only you can supply, it says
so: call `list_themes` with an `id` for that house's guidance, and read it
*before* writing the chart spec, since it may change how you prepare the data.
Vega-Lite only for now. You can also pass a custom `ThemeSpec`, or use
`{ "extends": "economist", ... }` to inherit a preset and override selected
fields.

## Step 1 — pick `chartType`

Use one of the registered names **exactly**. Vega-Lite is the default and
Expand Down Expand Up @@ -250,8 +297,8 @@ support a subset (verify if targeting a non-VL backend):
`"Funnel"`, `"Treemap"`, `"Sunburst"`, `"Sankey"`,
`"Parallel Coordinates"`, `"Graph"`, `"Tree"`.
- **Chart.js** supports: Scatter, Bubble, Bar, Grouped Bar, Stacked Bar,
Combo, Line, Bump, Area, Range Area, Pie, Doughnut, Histogram, Radar, Rose,
Slope, Connected Scatter.
Lollipop, Bump, Combo, Line, Area, Range Area, Pie, Doughnut, Histogram,
Radar, Rose, Slope, Connected Scatter.

You do not need to call the library or inspect its source to author the
input — pick from this table.
Expand Down Expand Up @@ -333,6 +380,29 @@ What choosing well gets you (automatically):
If you don't know, use `Quantity` for numbers, `Category` for strings,
`Date`/`DateTime` for date-shaped values. Do **not** invent type names.

### Saying more than the type name

A field's entry can be an object instead of a string when the type alone
understates what you know:

```json
"semantic_types": {
"anomaly": { "semanticType": "Quantity", "unit": "°C", "divergingMidpoint": 0 },
"rating": { "semanticType": "Score", "intrinsicDomain": [1, 5] }
}
```

- `unit` — the unit or currency code: `"USD"`, `"°C"`, `"kg"`.
- `intrinsicDomain` — the field's own bounds, for bounded scales only: `[1, 5]`
for a five-star rating, `[0, 100]` for a percentage score. Not for
open-ended measures.
- `divergingMidpoint` — where the middle colour of a diverging scale sits.
Set it if you can tell what the reader is comparing against; leave it out if
you can't.
- `sortOrder` — the order the categories should appear in, when the order in
the data is not the one you want and it isn't alphabetical either:
`["Low", "Medium", "High"]`. For a handful of categories, not a long list.

## Chart-level properties (`chartProperties`)

`chartProperties` is an optional per-chart tuning map. Set a property only
Expand Down Expand Up @@ -365,7 +435,8 @@ derived). Values are clamped to the ranges shown.
| Lollipop | `dotSize` | 20–300 (80) | Circle size (px) |
| Waterfall | `cornerRadius` | 0–8 (0) | Round bar corners |
| Waterfall | `totals` | `auto` \| `none` \| `first` \| `last` \| `both` (`auto`) | Which bars anchor to zero as totals (only when no Type column) |
| Waterfall | `showTextLabels` | boolean (false) | Render value labels on bars |
| Waterfall | `showTextLabels` | boolean (false) | Legacy spelling of `showValueLabels`; still accepted |
| Bar / Grouped Bar / Stacked Bar / Lollipop / Pyramid / Pie / Donut / Heatmap / Waterfall | `showValueLabels` | boolean | Print the numbers on the marks. Works with or without a theme: unset, it follows the house's own habit at this density (and with no house named, stays off), so the default the compiler reports is always the honest one. Set it to overrule that for one chart. Reported inapplicable (and ignored) where the marks are too dense to carry readable numbers, or where the template already writes its own text, so it is never a control that does nothing. On a stacked bar each segment prints its own value in the middle of the segment (at the edge it would read as the running total); segments too thin to hold a line of text go unlabelled, and a normalized stack prints each segment's share rather than its raw value, since the share is what the length shows. The printed number is rounded to roughly three significant figures — with a k/M suffix once the values get long, and enough decimals that the smallest value in the series still says something — so a raw `3.14159265` lands as `3.14` and a series of `0.001` to `5000` reads at both ends. Rounding never goes so far that two marks of different size print the same number, or that a non-zero value prints as `0`; where a house asked for a coarser precision than that, the digits are raised until the labels agree with the marks. |
| Regression | `regressionMethod` | `linear` \| `log` \| `exp` \| `pow` \| `quad` \| `poly` (`linear`) | Fit method |
| Regression | `polyOrder` | 1–5 (3) | Polynomial order (when `poly`) |
| Radar | `filled` | boolean (true) | Fill the polygon |
Expand Down Expand Up @@ -395,6 +466,8 @@ default:
- **Sort a category axis by its measure:** `encodings.x = { field: "name", sortBy: "y", sortOrder: "descending" }`.
- **Pick a color scheme:** `encodings.color = { field: "region", scheme: "tableau10" }`.
- **Override an inferred type:** `encodings.x = { field: "year", type: "ordinal" }` (e.g. treat a year as discrete bands).
- **Use readable field titles:** `field_display_names = { percentageOfCountries: "Percentage of countries" }`.
Keep encodings bound to the real column name; Flint uses the display name for axis titles and legend headers.
- **Resize the chart:** Flint sizes from two numbers — `baseSize` (the *target*
it aims for, default 400×320) and `canvasSize` (a *hard ceiling* it may never
exceed). With dense data the chart stretches from base toward the ceiling.
Expand Down
4 changes: 3 additions & 1 deletion docs/DEVELOPMENT.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,5 +68,7 @@ Start with the guide that matches the surface you want to extend:
## Test coverage

- **Smoke tests:** `packages/flint-js/tests/smoke.test.ts`
- **Visual coverage:** [Gallery](/gallery), driven by `TEST_GENERATORS` in test-data
- **Complete visual coverage:** [Full test cases](/playground/full-test-cases), driven by `TEST_GENERATORS` in `packages/flint-js/src/test-data/`
- **Curated examples:** [Gallery](/gallery)
- **Shared fixtures:** `shared/test-data/`, consumed by JS and Python tests
- **Coverage matrices and authoring workflow:** [Chart engine test plan](/documentation/test-plan)
5 changes: 5 additions & 0 deletions docs/adding-a-backend.md
Original file line number Diff line number Diff line change
Expand Up @@ -111,9 +111,13 @@ Register in `templates/index.ts`: import defs, add them to the category map, and
# §5 Site and gallery

- **Gallery dev server:** `npm run site` from the repo root, then open `/gallery`
- **Full visual matrix:** open `/playground/full-test-cases`; it renders every generator registered in `packages/flint-js/src/test-data/index.ts`
- **Supported backends:** update `site/src/shared/supported-backends.ts` if the new backend should appear in the UI
- **Renderers:** only add a new React view (`site/src/components/`) when the spec format cannot reuse `VegaLiteView`, `EChartsView`, or `ChartjsView`. `TripleChart` currently covers VL + ECharts + Chart.js.

Use the [Chart engine test plan](/documentation/test-plan) to choose normal,
semantic, density, and edge-case coverage for backend bring-up.

Optional: wire the assembler into `agent-skills/mcp-server/` if MCP clients should be able to call it.

---
Expand All @@ -134,5 +138,6 @@ A backend is ready when:
# §7 Related

- [Extending chart templates](/documentation/adding-a-chart-template) — `ChartTemplateDef` authoring
- [Chart engine test plan](/documentation/test-plan) — shared cases and backend bring-up coverage
- [Auto Layout Algorithm](/documentation/layout-model) — what `computeLayout()` expects
- [API reference](/documentation/api-reference) — `ChartAssemblyInput` and assembler entry points
21 changes: 21 additions & 0 deletions docs/api-reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,8 @@ interface ChartAssemblyInput {
semantic_types?: Record<string, string | SemanticAnnotation>;
chart_spec: {
chartType: string;
title?: string; // headline
subtitle?: string; // deck: what is measured, of whom, when, in what units
encodings: Record<string, ChartEncoding | string>; // string = field shorthand
baseSize?: { width: number; height: number }; // target layout size, default 400×320
canvasSize?: { width: number; height: number }; // optional hard ceiling on stretch
Expand All @@ -137,11 +139,30 @@ interface ChartAssemblyInput {

Maps column name → semantic type. This drives encoding type, formatting, aggregation defaults, color class, and layout. See [Semantic Type](/documentation/semantic-types).

### `field_display_names`

Maps raw column names to readable presentation labels used for axis titles and
legend headers. Keep encodings bound to the original field names:

```ts
{
field_display_names: {
percentageOfCountries: 'Percentage of countries'
},
chart_spec: {
chartType: 'Bar Chart',
encodings: { x: 'country', y: 'percentageOfCountries' }
}
}
```

### `chart_spec`

| Field | Description |
|-------|-------------|
| `chartType` | Template name — must match a backend registry entry (`"Bar Chart"`, `"Heatmap"`, …) |
| `title` | The headline. Write one: `Jan` and `Cairo` name their own kind, `26` and `5,300` do not, and a theme that omits axis titles is delegating that naming to the headline. Vega-Lite only for now; where no headline is given, the compiler puts the axis titles back. |
| `subtitle` | The deck — what is measured, of whom, when, in what units. |
| `encodings` | Channel → encoding map |
| `baseSize` | **Target** layout size in pixels (default 400×320): the size the chart aims for with typical data. Dense data may stretch past it, up to the ceiling. |
| `canvasSize` | **Hard ceiling:** the maximum size the chart may ever reach, including faceted grids. If omitted, the ceiling is `baseSize × options.maxStretch` (default 1.5×). Per-dimension caps are `βx = canvasSize.width / baseSize.width`, `βy = canvasSize.height / baseSize.height` (each ≥ 1). The base is clamped to the ceiling, so a `canvasSize` on its own acts as a fixed box the chart fills and shrinks to fit without overflowing. |
Expand Down
Loading
Loading