Graphs - SVG Charts
GRAPH generates a chart as a pure <svg> element — no wrapping page, no HTML boilerplate. The output is a real Value::Html fragment, the same native node type built for OcaltQL HTML — embed it directly via HTML APPEND, or emit it as raw SVG markup.
Syntax
GRAPH TYPE "bar" WITH ?data
TITLE "My Chart"
FORMAT 800 BY 400
THEME "dark"
AXIS X "Month" AND Y "Revenue"
SET ?svg
All modifiers are optional. Minimal form:
GRAPH TYPE "pie" WITH ["school" AS 35 AND "home" AS 50 AND "play" AS 15] SET ?svg
(* Raw relative values — the renderer computes proportions itself *)
Modifiers
| Modifier | Syntax | Description |
|---|---|---|
TITLE | TITLE "string" | Chart title displayed above the graph |
FORMAT | FORMAT 800 BY 400 | Width by height, in pixels |
THEME | THEME "dark" | Colour palette. Options: "dark", "light", "ocean", "pastel" |
AXIS | AXIS X "label" AND Y "label" AND Z "label" | Axis labels. Z for 3D/contour types. |
Data Tiers
Tier 1 — inline key/value pairs, built with the confirmed object-literal bracket syntax (pie, donut, funnel, gauge, waffle, progress):
GRAPH TYPE "pie" WITH ["sales" AS 40 AND "ops" AS 35 AND "dev" AS 25] SET ?svg
Tier 2 — single-series variable (bar, line, area, scatter, histogram, sparkline, wave, etc.). Shape: ["labels" AS [...] AND "values" AS [...]].
NEW ARRAY SET ?labels
AFTER APPEND "Jan" TO ?labels
AFTER APPEND "Feb" TO ?labels
AFTER APPEND "Mar" TO ?labels
AFTER NEW ARRAY SET ?values
AFTER APPEND 1200 TO ?values
AFTER APPEND 1900 TO ?values
AFTER APPEND 1500 TO ?values
AFTER NEW OBJECT SET ?data
AFTER SET ?data("labels") AS ?labels
AFTER SET ?data("values") AS ?values
AFTER GRAPH TYPE "line" WITH ?data TITLE "Q1 Revenue" SET ?svg
Tier 3 — multi-series variable (bar-grouped, stacked area, radar, candlestick, sankey, tree, etc.). Shape: ["labels" AS [...] AND "series" AS [["name" AS ... AND "values" AS [...]]]].
GRAPH TYPE "bar-grouped" WITH ?data TITLE "Regional Sales" SET ?svg
Charting Data Straight from the Database
GROUP BY "status" FROM DB "shopdb" TABLE "orders" SET ?grouped
AFTER NEW ARRAY SET ?labels
AFTER NEW ARRAY SET ?values
AFTER FOREACH ?grouped SET ?row
OPEN
APPEND ?row("status") TO ?labels
AFTER APPEND ?row("count") TO ?values
CLOSE
AFTER NEW OBJECT SET ?data
AFTER SET ?data("labels") AS ?labels
AFTER SET ?data("values") AS ?values
AFTER GRAPH TYPE "bar" WITH ?data TITLE "Orders by Status" SET ?svg
Embedding the Result
NEW HTML SET ?page
AFTER HTML "h1" TEXT "Sales Report"
AFTER HTML APPEND ?svg TO ?page
AFTER EMIT ?page
GRAPH TYPE "pie" WITH ["school" AS 35 AND "home" AS 50 AND "play" AS 15] SET ?svg
AFTER EMIT ?svg
Reopening a Saved Chart
A chart emitted to a file is ordinary SVG. GRAPH OPEN reads one back into the same native Value::Html fragment GRAPH TYPE produces — so a chart written by one script can be embedded, appended to, or re-emitted by another, using the same tree machinery as HTML REVERSE.
GRAPH TYPE "bar" WITH ?data TITLE "Q1 Revenue" SET ?svg
AFTER FILE WRITE "/root/charts/q1.svg" CONTENT ?svg
(* ...a later script... *)
GRAPH OPEN "/root/charts/q1.svg" SET ?svg
AFTER NEW HTML SET ?page
AFTER HTML APPEND ?svg TO ?page
AFTER EMIT ?page
Graph Types
| Type string | Tier | Data shape |
|---|---|---|
bar | 2 | ["labels" AS [...] AND "values" AS [...]] |
bar-grouped | 3 | ["labels" AS [...] AND "series" AS [["name" AS ... AND "values" AS [...]]]] |
bar-stacked | 3 | ["labels" AS [...] AND "series" AS [["name" AS ... AND "values" AS [...]]]] |
line | 2 | ["labels" AS [...] AND "values" AS [...]] |
line-multi | 3 | ["labels" AS [...] AND "series" AS [["name" AS ... AND "values" AS [...]]]] |
area | 2 | ["labels" AS [...] AND "values" AS [...]] |
area-stacked | 3 | ["labels" AS [...] AND "series" AS [["name" AS ... AND "values" AS [...]]]] |
scatter | 2 | ["points" AS [["x" AS ... AND "y" AS ...]]] |
bubble | 2 | ["points" AS [["x" AS ... AND "y" AS ... AND "size" AS ...]]] |
histogram | 2 | ["values" AS [...]] |
box | 3 | ["labels" AS [...] AND "series" AS [["name" AS ... AND "values" AS [...]]]] |
violin | 3 | ["labels" AS [...] AND "series" AS [["name" AS ... AND "values" AS [...]]]] |
dot | 2 | ["labels" AS [...] AND "values" AS [...]] |
heatmap | 3 | ["x_labels" AS [...] AND "y_labels" AS [...] AND "matrix" AS [[...]]] |
treemap | 3 | ["nodes" AS [["name" AS ... AND "value" AS ... AND "parent" AS ...]]] |
waffle | 1/2 | inline, or ["segments" AS [["name" AS ... AND "value" AS ...]]] |
sparkline | 2 | ["values" AS [...]] |
pie | 1/2 | inline, or ["segments" AS [["name" AS ... AND "value" AS ...]]] |
donut | 1/2 | inline, or ["segments" AS [["name" AS ... AND "value" AS ...]]] |
funnel | 1/2 | inline, or ["stages" AS [["name" AS ... AND "value" AS ...]]] |
waterfall | 2 | ["labels" AS [...] AND "values" AS [...]] (negative values allowed) |
sunburst | 3 | ["nodes" AS [["name" AS ... AND "value" AS ... AND "parent" AS ...]]] |
radar | 3 | ["axes" AS [...] AND "series" AS [["name" AS ... AND "values" AS [...]]]] |
gauge | 1/2 | inline, or ["value" AS ... AND "min" AS ... AND "max" AS ...] |
polar | 3 | ["labels" AS [...] AND "series" AS [["name" AS ... AND "values" AS [...]]]] |
candlestick | 3 | ["labels" AS [...] AND "series" AS [["name" AS ... AND "ohlc" AS [["o" AS ... AND "h" AS ... AND "l" AS ... AND "c" AS ...]]]]] |
ohlc | 3 | same as candlestick |
sankey | 3 | ["nodes" AS [["name" AS ...]] AND "links" AS [["source" AS ... AND "target" AS ... AND "value" AS ...]]] |
node-edge | 3 | ["nodes" AS [["id" AS ... AND "label" AS ...]] AND "edges" AS [["from" AS ... AND "to" AS ... AND "label" AS ...]]] |
force | 3 | same as node-edge |
tree | 3 | ["nodes" AS [["id" AS ... AND "label" AS ... AND "parent" AS ...]]] |
flowchart | 3 | ["nodes" AS [["id" AS ... AND "label" AS ... AND "type" AS ...]] AND "edges" AS [["from" AS ... AND "to" AS ... AND "label" AS ...]]] |
state | 3 | ["states" AS [["id" AS ... AND "label" AS ...]] AND "transitions" AS [["from" AS ... AND "to" AS ... AND "label" AS ...]] AND "initial" AS ...] |
wave | 2 | ["values" AS [...] AND "sample_rate" AS ...] |
error-bar | 3 | ["labels" AS [...] AND "series" AS [["name" AS ... AND "values" AS [...] AND "errors" AS [...]]]] |
contour | 3 | ["x" AS [...] AND "y" AS [...] AND "z" AS [[...]]] |
gantt | 3 | ["tasks" AS [["name" AS ... AND "start" AS ... AND "end" AS ... AND "group" AS ...]]] |
timeline | 3 | ["events" AS [["label" AS ... AND "date" AS ... AND "group" AS ...]]] |
calendar-heat | 2 | ["points" AS [["date" AS ... AND "value" AS ...]]] |
progress | 1/2 | inline, or ["value" AS ... AND "max" AS ...] |
step | 2 | ["labels" AS [...] AND "values" AS [...]] |
bullet | 2 | ["value" AS ... AND "target" AS ... AND "ranges" AS [...]] |