Core Concepts
Three-step workflow
Every chart follows the same workflow regardless of chart type:
1. Extract field metadata
fields-metadata MetadataExtractor
──────────────────────────────────► dict[str, FieldMetadata]
│
2. Instantiate a FigureStrategy │
FigureStrategy(fields_metadata, ...) ◄──────────┘
│
3. Get query params, execute, build
strategy.get_query_params() ──► dict[str, QueryParams] (you execute these)
strategy.build(dfs, tr, theme) ──► FigureView ← honours pre/post callbacks
strategy.plot(dfs, tr, theme) ──► FigureView ← raw render, no callbacks
Step 1 — Extract field metadata
Use fields-metadata's MetadataExtractor on your domain model to produce a
dict[str, FieldMetadata] (a FieldsMetadataMap). This map drives field validation inside
each strategy: categorical fields go to categorical variables, numeric fields go to numeric
variables, and so on.
Step 2 — Instantiate a strategy
Choose the appropriate FigureStrategy subclass and pass it the field metadata, your chosen
variables, options, and optional color rules. The constructor validates all inputs immediately.
Step 3 — Query, then plot
Call get_query_params() to obtain a dict[str, QueryParams]. Execute each query using your
data layer (MongoDB, Polars, SQL — orama is agnostic) and collect the results as Polars
DataFrames in a dict keyed by the same names.
Pass that dict to build(dfs, tr, theme) to obtain a FigureView (recommended — honours any
registered callbacks). Use plot(dfs, tr, theme) for a raw render with no callback side-effects.
Key types
| Type | Description |
|---|---|
FieldMetadata |
Metadata for a single field (categorical, numeric, derived, etc.) |
FieldsMetadataMap |
dict[str, FieldMetadata] produced by MetadataExtractor |
FigureStrategy |
Base class for all chart strategies |
QueryParams |
Group-by fields, aggregations, and expected DataFrame schema for one query |
FigureView |
Holds the rendered go.Figure plus caption, description, storytelling_context |