Results, charts, and dashboards#

Reading results#

Query results render as a sortable, paginated table right below the cell. Switch views with the tabs above the result:

View What you get
Table Raw rows, column sort, pagination
Chart Configured visualization (see below)
Stats Per-column cards with completeness, distinct counts, top values, histograms, and data-quality hints

Stats is the fast sanity check when you inherit a table you haven't profiled before. It profiles the rows currently loaded in the result (up to 1,000 when auto-limited). Wide tables use a column picker; flagged columns (high nulls, constants, likely IDs) surface first.

Click a column header in the table view to add a column description. Descriptions stick on the cell and show in a popover when you hover the header. Fill these in when someone else will read the report and won't know your naming conventions.

Charts#

Any result can be turned into a chart instead of a table. Pick a type based on what you're trying to show:

Type Use it for
Table Raw rows, when a chart wouldn't add anything
KPI / Value / Delta A single number, optionally compared against a previous value
Line / Area A metric over time
Bar / Horizontal bar Comparing a metric across categories
Scatter / Bubble Relationships between two (or three) numeric fields
Pie Share of a whole, for a small number of categories
Histogram Distribution of a single numeric column
Heatmap / Calendar heatmap Density across two dimensions, or across days
Funnel Drop-off across ordered stages
Box plot Spread and outliers across groups
Sankey Flow between categories
Custom Anything the above don't cover

The chart configurator picks sensible defaults from your columns. Adjust axes, color grouping, stacking, sort order, and secondary Y series from the panel. Save the config on the cell; markdown widgets can inherit it with ref=$cellName (see Markdoc reference).

Auto-suggested metrics#

After a query runs, Lunapad inspects column types (numeric, date, boolean, text), null ratios, and distinct counts. It may suggest derived metrics: rates, ratios, time-bucketed rollups. Accept a suggestion to add a new downstream cell pre-filled with the expression. Treat it as a starting point; read the SQL before you ship it.

Turning a notebook into a report or dashboard#

Markdown cells embed live widgets: tables, charts, metrics, badges, progress bars, tabs, filters, all backed by query results in the same notebook.

The markdown editor is Monaco with a toolbar and / slash commands.

You want What to type
A number inside a sentence {% $orders.revenue %} or {% currency($orders.revenue) %}
A KPI card /metric or toolbar → inserts {% metric value=$cell.value ... /%}
A chart /chart or configure the query cell's chart view and use ref=$cell in markdown
Pick a cell column Toolbar Insert ref or type $ for completions → inserts $orders.revenue for use in tag attributes (e.g. value=$orders.revenue)

Toggle preview on the cell to see the rendered report. The editor underlines broken $ refs and Markdoc parse errors before you publish.

Full syntax is in Markdoc reference.

Mini example. Three query cells:

# daily
from orders
derive { day = date_trunc("day", created_at) }
group day ( aggregate { revenue = sum amount } )
# monthly
from orders
derive { month = date_trunc("month", created_at) }
group month ( aggregate { revenue = sum amount } )
# regions
from orders
group region ( aggregate { revenue = sum amount } )

One markdown cell:

## Revenue

{% metric value=$monthly.revenue label="This month" format="currency" /%}
{% chart type="line" data=$daily.rows x="day" y="revenue" /%}
{% chart type="bar" data=$regions.rows x="region" y="revenue" /%}

Run the query cells first. The markdown cell updates when their results change.

Next#

The Markdoc reference for the complete widget syntax, or AI assistant if you want help building models.