Charts & dashboards for DuckDB — the grammar of graphics, straight from SQL. You
write ordinary DuckDB SQL and tag output columns with ::ROLE casts; each
annotated SELECT becomes a panel (chart / KPI / table / input), rendered to
SVG by the ggplot-rs engine. No JS
charting library, no bespoke config — the SQL is the dashboard.
Important
This extension is in early development, so bugs and breaking changes are expected. Please use the issues page to report bugs or request features.
LOAD anofox_visualization;
-- Convenience macros: pass columns, get one SVG per group.
WITH sales AS (SELECT * FROM (VALUES ('app',30),('web',22),('api',12)) t(ch,n))
SELECT anofox_bar(ch, n) FROM sales; -- <svg> bar chart▶ Live demo — the full builder running in your browser on DuckDB-Wasm.
Cast the measure column with the chart role; add ::XAXIS / ::CATEGORY for
the axes and colour series.
| Family | Roles |
|---|---|
| Bars | ::BARCHART, _STACKED, _PERCENT, _STACKED_PERCENT, ::FLIP (horizontal) |
| Lines & areas | ::LINECHART, _PERCENT, ::STEP, ::SMOOTH (trend), ::AREACHART, _STACKED |
| Points | ::SCATTER, ::BUBBLE (sized), ::JITTER |
| Part-to-whole | ::PIE, ::DONUTCHART |
| Distribution | ::HISTOGRAM, ::DENSITY, ::BOXPLOT, ::VIOLIN, ::QQ |
| Matrix / geo | ::HEATMAP, calendar heatmap, ::MAP (WKT-geometry choropleth) |
| Finance | ::CANDLESTICK, ::OHLC, ::SPARKLINE |
| Gauge / radar | ::GAUGE (+ ::RANGE, ::COLORS zones), ::RADAR |
| Annotations | ::REFLINE/::XLINE reference lines, ::BAND_LOWER/::BAND_UPPER bands |
| Group | Roles |
|---|---|
| KPI tiles | ::METRIC, ::MONEY, ::PERCENT, ::COMPACT (+ ::LABEL caption, ::DELTA arrow) |
| Text | ::TEXT_SMALL/_MEDIUM/_LARGE, ::MARKDOWN |
| Tables | ::TABLE, ::PAGED (SQL-paginated), ::COLORSCALE, ::BADGE, ::TREND, ::SPARKLINE, ::DOWNLOAD_CSV/_XLSX/_PDF |
| Group | Roles / behaviour |
|---|---|
| Inputs | ::DROPDOWN, ::MULTISELECT, ::NUMBER, ::DATE, ::TEXT, ::DATERANGE → each is a DuckDB variable read with getvariable('name') |
| Layout | 12-column grid (::COLUMNS/::COL/::HEIGHT), ::GROUP boxes, tabs (::TAB/::SUBTAB) |
| Interactivity | hover tooltips, click-to-cross-filter, range zoom, brush/value filters, dark mode, share links — pure DOM, so it works on exported HTML too |
| Formatting | ggplot2-style axis formatters (::YFORMAT '€', ::XFORMAT '$', percent, compact) |
- Three surfaces, one renderer — a core library (annotated result → SVG, wasm-compatible), a DuckDB extension (render + serve), and a browser builder on DuckDB-Wasm.
- Serve locked, read-only dashboards (from-source build) — hand a folder of
.sqlfiles to untrusted consumers; the server owns the SQL (allow-listed/query) over a read-only snapshot. - Any DuckDB source — CSV / Parquet / JSON / Arrow, MotherDuck, Postgres / MySQL / SQLite via
ATTACH, remote HTTP, and spatial layers (ST_AsText→ WKT →::MAP). - Authoring aids — a
dashboard --checklinter (structure +design/*quality checks) and abuild-dashboardagent skill that writes dashboards from a prompt.
All rendering functions use the anofox_ prefix.
LOAD anofox_visualization;
-- 1) Convenience macros — pass columns, get one SVG per group.
WITH sales AS (SELECT * FROM (VALUES ('app',30),('web',22),('api',12)) t(ch,n))
SELECT anofox_bar(ch, n) FROM sales; -- <svg> bar chart
-- also anofox_line / _scatter / _area(x, y),
-- anofox_xy(x, y, kind := 'VIOLIN', width := 640, height := 400),
-- anofox_xyc(x, y, series) -- coloured by series
-- 2) The raw spec (rows + role annotations) — the same JSON the browser uses:
SELECT anofox_render('{"rows":[{"c0":"a","c1":3}],"roles":[[0,"XAXIS"],[1,"BARCHART"]]}');
-- 3) A dashboard panel — annotate the SELECT list with ::ROLE casts:
SELECT week::XAXIS, channel::CATEGORY, sum(n)::BARCHART_STACKED, 'Sessions'::TITLE
FROM sessions GROUP BY ALL ORDER BY ALL;Note
The community extension you install (below) provides rendering only —
anofox_render and the anofox_bar/_line/_scatter/_area/_xy/_xyc macros that
turn SQL into SVG. The serving and builder features below embed a web UI +
HTTP server and are not in the community binary — they come with a
from-source build (see Installation → From source).
From a from-source build you also get an in-browser builder and locked, read-only serving:
-- Interactive builder wired to THIS database, DuckDB-UI style (localhost only):
SELECT anofox_serve(8080); -- http://localhost:8080
-- Serve a folder of .sql dashboards locked + read-only to consumers:
SELECT anofox_serve_dashboards('dashboards', 8095);
-- http://127.0.0.1:8095/ a list of the folder's dashboards
-- http://127.0.0.1:8095/d/<name> one dashboard — full UI, editor removed…plus a dashboard CLI (cargo run --bin dashboard -- file.sql) and the
standalone browser app (web/).
Once accepted into the DuckDB Community Extensions repository:
INSTALL anofox_visualization FROM community;
LOAD anofox_visualization;Provides: rendering only — anofox_render and the anofox_bar/_line/_scatter/_area/_xy/_xyc
macros (SQL → SVG). Serving and the builder are not included (see below).
The from-source build is the full toolkit: rendering plus anofox_serve,
anofox_serve_dashboards, the dashboard CLI, and the web builder. DuckDB must
be started with -unsigned (the binary is not signed by the DuckDB Foundation).
git clone --recurse-submodules https://github.com/DataZooDE/anofox-visualization
cd anofox-visualization
make # → build/release/extension/anofox_visualization/anofox_visualization.duckdb_extensionLOAD './build/release/extension/anofox_visualization/anofox_visualization.duckdb_extension';- Annotation model & role reference — every
::ROLE, layout, and serving mode. - Dashboard design principles — what makes a dashboard good (enforced by
dashboard --check). - Visual review rubric — the appearance gate.
- Secure serving — the trust model for locked serving.
build-dashboardskill — an agent that authors dashboards from a prompt.
- DuckDB: v1.4.x LTS or v1.5.x (latest)
- Rust: stable toolchain (for building from source)
- ggplot-rs: the grammar-of-graphics rendering engine
- plotters / image / ab_glyph: SVG & raster backends (via Cargo)
This extension collects no telemetry — no usage data, no query contents, nothing leaves your machine.
This project is licensed under the Business Source License 1.1 (BSL 1.1).
- Usage Grant: free to use, modify, and distribute for development, testing, research, and internal use
- Production Use: hosted / embedded redistribution to third parties requires a commercial license until the Change Date
- Change Date: five years after first publication
- Change License: Mozilla Public License 2.0
See LICENSE for full terms.
The BSL keeps the source open for development, research, and internal use, and converts to a fully open licence over time — while protecting the project's long-term viability. For commercial hosted/embedded use before the Change Date, contact contact@datazoo.de.
Contributions are welcome:
- Fork the repository
- Create a feature branch
- Make your changes with tests (
cargo test;dashboard --checkfor example dashboards) - Submit a pull request
- New chart kinds and roles
- Additional
design/*lint checks and the visual-review loop - Documentation, guides, and example dashboards
- Bug reports and fixes; performance work
- Documentation: docs/
- Issues: GitHub Issues
- Discussions: GitHub Discussions
- Email: contact@datazoo.de
@software{anofox_visualization,
title = {Anofox Visualization: Charts & Dashboards for DuckDB from SQL},
author = {DataZoo DE},
year = {2025},
url = {https://github.com/DataZooDE/anofox-visualization}
}- DuckDB Team — the database and extension framework
- ggplot-rs — the grammar-of-graphics rendering engine
- Open Source Community — for contributions and feedback
© DataZoo GmbH.