Building a Dashboard with Charts
Aggregate your storage data, render it live on a page, and keep it fast. The dashboard pattern end to end.
A dashboard is a page backed by a few well-chosen queries: counts, sums, recent items, and grouped stats. This tutorial assembles one: data first, then rendering, then keeping it fast.
Step 1, Get the Data
Dashboards read. Never write. Build a function per metric (or one function returning an object with all of them):
- Counts:
function_searchwith thehitsout-pin (total matching documents), one per filtered query: open tasks, shipped orders, this week's signups. - Recent items:
function_search+query_sort_fieldon_meta.createddescending +limit10. See search tips. - Grouped stats: aggregations where the storage supports them; for anything heavy, precompute counters on write instead (see performance below).
Return everything from one function as an object built with object_new_fields. One call, one payload for the page.
Step 2, Render the Page
- A
state_pagefor the dashboard URL, scoped for your team (*loggedinor a custom scope). - On load, run the metrics function from the render flow and pass results into state elements: number tiles (styled elements), a recent-items list (iterate the array), and your chart component.
- For real charts, mount a custom React component in the page and feed it the metrics object. See Components and RUAL Library for passing data to components.
- Want it live? Real-time search updates the metrics as documents change: worth it on shared boards, overkill on quiet data (see real-time vs polling).
Step 3, Keep It Fast
- Cache the metrics function with a
cache_keyonfunction_searchand a short TTL via Redis. The dashboard loads instantly even with thousands of documents. See caching patterns. - Precompute counters on write: increment a stats document on each create (
mutations_increment_by_field) instead of counting at read time; reads become a singlefunction_get_document. - Avoid dashboard-side loops. If the page needs per-item computation, do it in the function with
array_map, not in the render. - Watch out for the aggregation traps in Common Pitfalls.
- One metrics function returning one object.
- Sort + limit on every "recent" list.
- Cache key on expensive searches; counters for hot stats.
- Scope set intentionally (no accidental
*publicdashboards).
