Generate editable .excalidraw chart scenes from a small Vega-Lite-style spec and CSV data.
Charts feel native to Excalidraw: sketchy, presentation-friendly, and easy to tweak after generation.
Gallery
See examples/ for the full set of example specs, generated .excalidraw scenes, and PNG exports.
Why This Exists
Excalidraw supports charts, but currently only supports bar charts. This library fills supports a wider variety, configured with a standard JSON schema (Vega Lite).
What You Get
Input:
chart.jsondata.csv
Output:
chart.excalidraw- optional
chart.pngexport
Supported chart types:
lineareastacked-areacolumnstacked-columnscatter
Quick Start
Install the CLI locally from this repo:
Render one of the included examples:
excalicharts render examples/stacked-area-spotify-catalogue
Validate a chart spec without generating output:
excalicharts validate examples/stacked-area-spotify-catalogue
Export a generated scene to PNG:
./excalidraw-export.sh examples/stacked-area-spotify-catalogue/chart.excalidraw
Regenerate the full example set:
npm run generate:examples npm run validate:examples npm run test:validation ./excalidraw-export.sh -f -r examples
If you do not want to install the linked CLI, you can still run the underlying script directly with node scripts/chart-cli.mjs ....
Example Spec
ExcaliCharts conforms to a focused subset of the Vega-Lite specification. The example below uses that subset rather than a fully custom chart format.
chart.json
{
"$schema": "https://vega.github.io/schema/vega-lite/v5.json",
"data": { "url": "./data.csv", "format": "csv" },
"mark": "area",
"title": {
"text": "Spotify Catalogue Size",
"subtitle": "Illustrative split of total catalogue size into human- and AI-generated songs over time."
},
"encoding": {
"x": { "field": "year", "type": "ordinal", "title": "Year" },
"y": { "field": "songs", "type": "quantitative", "title": "Songs in catalogue", "stack": true },
"color": {
"field": "source",
"type": "nominal",
"scale": { "domain": ["Human-generated songs", "AI-generated songs"] }
}
}
}data.csv
year,source,songs 2015,Human-generated songs,30000000 2015,AI-generated songs,0 2016,Human-generated songs,35000000 2016,AI-generated songs,2000
Workflow
- Author
chart.jsonanddata.csv. - Run the CLI to generate
chart.excalidraw. - Open the result in Excalidraw.
- Keep editing the chart like any other Excalidraw scene.
- Export to PNG if needed.
This is currently a generator-first workflow, not an in-editor Excalidraw plugin.
CLI
excalicharts validate <dir> excalicharts validate --chart path/to/chart.json [--data path/to/data.csv] excalicharts render <dir> excalicharts render --chart path/to/chart.json [--data path/to/data.csv] [--out path/to/chart.excalidraw] excalicharts render-examples
Current install path:
That exposes the excalicharts command from this checkout. If the package is published later, the same CLI name will carry over.
Supported Spec Surface
The input format is a focused Vega-Lite-style subset documented in schemas/chart.schema.json.
Supported marks:
lineareabarpoint
Supported fields and options:
titleas a string or{ text, subtitle }data.urlencoding.x.fieldencoding.y.fieldencoding.color.fieldencoding.x.titleencoding.y.titleencoding.y.stackencoding.color.scale.domainencoding.color.legendencoding.tooltip.fieldfor scatter labels
Mark behavior:
line: multi-series line charts over ordered categorical or temporal x-valuesarea: single-series area or stacked area viaencoding.y.stackbar: vertical columns or stacked columns viaencoding.y.stackpoint: scatter plots with quantitative x/y axes
Current Assumptions
- CSV files must include a header row
- numeric fields must parse cleanly as numbers
- stacked charts assume non-negative values
- categorical x-axes use row order
- line and area charts treat x as ordered categories rather than continuous scales
- when rendering a directory,
data.urlis resolved relative tochart.json
Not Supported Yet
- transforms
- layers
- facets and concatenation
- grouped bars
- pie or arc marks
- log scales
- size, shape, or opacity channels
- conditional encodings
- custom legend layout
- arbitrary axis configuration blocks