Skip to content

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