Plot blocks
A chart in PlotPress is a fenced code block in markdown:
```plot view=monthly_revenuePlot.barY(data, { x: "month", y: "revenue" })```The fence info string declares which view feeds the block. The body is an Observable Plot expression.
Available bindings
Section titled “Available bindings”Inside the block body:
| Binding | What it is |
|---|---|
data | The rows returned by the named view, as an array of objects. |
params | The current parameter values (defaults + any viewer overrides). |
Plot | The Observable Plot module. |
d3 | A small d3 subset (d3-array, d3-time-format, d3-scale). |
If the block body is a single expression, it’s wrapped in a default Plot.plot({ marks: [...] }). To override the wrapping config, return a full plot config:
```plot view=monthly_revenue({ marginLeft: 60, y: { grid: true, label: "Revenue (USD)" }, marks: [ Plot.barY(data, { x: "month", y: "revenue", fill: "currency" }), Plot.ruleY([0]), ],})```Fence info attributes
Section titled “Fence info attributes”plot view=NAME [params.KEY=VALUE ...] [height=400] [class=...]| Attribute | Meaning |
|---|---|
view=NAME | Primary form. Name of a view exposed by the dashboard’s default connection. |
query=NAME | Fallback form. Filename in queries/ without .sql. See Authoring → Queries as fallback. |
connection=NAME | Override the dashboard’s default connection for this block only. |
params.KEY=VALUE | Default value for a parameter. |
height=NUMBER | Default plot height in pixels. |
view and query are mutually exclusive. Use view whenever the database can express the slice you want — that’s the primary path.
Viewer-controlled parameters
Section titled “Viewer-controlled parameters”Declare inputs in the fence body using the inputs helper:
```plot view=monthly_revenueinputs({ year: { type: "select", options: [2024, 2025, 2026], default: 2026 },})
Plot.barY(data, { x: "month", y: "revenue" })```The backend re-runs the view with the new params; the chart re-renders.
Why this shape
Section titled “Why this shape”- The author writes one expression. Not a component, not a JSX tree, not a config object with thirty keys. The 80% case is a one-liner.
- The author never writes a fetch. The runtime decides when to fetch, when to cache, and how to handle errors.
- The block is grep-able. “Where do we use
monthly_revenue?” isgrep -r "view=monthly_revenue".