Skip to content

Pivot & Chart Views

Pivot and Chart are analytics view types — they aggregate a model’s records into a cross-tab table (Pivot) or a chart (Chart) instead of listing them. Every reporting module ships both behind a single “Analysis” window action (CRM, Sales, Purchase, Invoicing, POS, Helpdesk and their enterprise add-ons), almost always pointed at a flat line model (SaleOrderLine, CrmLead, …) so the aggregates are meaningful.

Both types are interactive: the arch only supplies sensible defaults. At runtime the user changes rows, columns, measures, chart type and grouping from the toolbar — those controls live in the view, not the arch. Grouping is shared with the Search view (the group elements and groupFields state), so the same drop-downs that group a List also drive Pivot rows and Chart slices.

A reporting action lists the Pivot and Chart views together and sets the analytics defaults via action_ctx.view (view.groups, view.filters). modes enumerates the analytics view types the toolbar offers.

- data_type: WindowAction
name: Sales Analysis
identifier: sales_reports_action
model: SaleOrderLine
default_view: sales_reports_pivot_view
modes: Pivot, Chart
action_ctx:
view:
groups:
- sales_reports_product # a `group` identifier from the search view
filters:
- sales_reports_confirmed # a `filter` identifier from the search view
views:
- - R
- - sales_reports_pivot_view
- sales_reports_chart_view
search_view: sales_reports_search_view
global_filter: (Q(display_type__eq='Product'))

The search_view supplies the filter, browsepanel and group elements that both analytics views reuse — define grouping options there once (see Other View Types). global_filter is an always-applied Q-expression that scopes every aggregation.

A Pivot view renders a multi-level cross-tab: records are grouped down the rows, optionally across the columns, and each cell shows one or more measures. Rows, columns and the heatmap are all interactive — the arch is just the starting layout.

- data_type: UiView
name: sales_reports_pivot_view
identifier: sales_reports_pivot_view
type: Pivot
model: SaleOrderLine
arch:
- row_fields:
- field: product_variant
measures:
- Sum_of_subtotal
- Sum_of_quantity
- Count
heatmap: true

With a column grouping (date buckets across the top):

- data_type: UiView
name: crm_reports_pivot_view
identifier: crm_reports_pivot_view
type: Pivot
model: CrmLead
arch:
- row_fields:
- field: stage
column_fields:
- field: created_date
interval: month
measures:
- Sum_of_opportunity_amount
- Count
heatmap: false

The arch is a single-element list; the first element holds the pivot config (the Pivot view reads arch[0]).

KeyTypeDescription
row_fieldsarrayDefault row groupings. Each entry is { field: <name> } (plus interval for dates). Applied unless the action’s view.groups already set the grouping.
column_fieldsarrayDefault column groupings, same shape as row_fields. Omit for a rows-only pivot.
measuresarrayDefault measures to aggregate in each cell (see below).
heatmapbooleanDefault heatmap shading on/off.

Each entry in row_fields / column_fields is an object:

KeyDescription
fieldField name to group by. Char, Selection, ManyToOne and OneToOne group directly; Date/Datetime require an interval.
intervalFor Date/Datetime fields: day, week, month, quarter, or year.

measures is a list of measure tokens. The token format is what the renderer and server both expect — Count, or <Op>_of_<field> where the field is a numeric column (Float, Monetary, or non-id Integer):

TokenMeaning
CountNumber of records in the cell
Sum_of_<field>Sum of the numeric field
Average_of_<field>Average of the numeric field
Min_of_<field>Minimum value
Max_of_<field>Maximum value

For example Sum_of_opportunity_amount sums the opportunity_amount field. If no measures are supplied the view defaults to ['Count'].

:::note Server-side aggregation Pivot data is aggregated on the server (mode: 'pivot') and returned as a pre-built row/column tree, so deep groupings stay fast. The arch only seeds the initial rows, columns, measures and heatmap; expanding/collapsing levels and adding row/column groupings happen live in the toolbar. :::

A Chart view aggregates the same line model and plots it. The arch is usually empty (arch: []) — the chart type, mode, measure and grouping are all chosen from the toolbar — but you can pre-seed those defaults with a config element. The Chart view type is distinct from the dashboard Chart widget (ChartWidget, configured per Dashboard Views): the view aggregates live records, the widget renders a JSON field on a form.

Minimal (all defaults chosen at runtime):

- data_type: UiView
name: sales_reports_chart_view
identifier: sales_reports_chart_view
type: Chart
model: SaleOrderLine
arch: []

With seeded defaults:

- data_type: UiView
name: crm_reports_chart_view
identifier: crm_reports_chart_view
type: Chart
model: CrmLead
arch:
- chart_type: bar
mode: sum
measure: opportunity_amount
group_by:
- field: stage
stacked: true

As with Pivot, the config lives in arch[0].

KeyTypeDescription
chart_typestringDefault chart: donut, area, bar, or radar. Defaults to donut.
modestringAggregation: count, sum, average, min, or max. Defaults to count.
measurestringField name to aggregate (used by every mode except count).
group_byarrayDefault groupings, same { field, interval } shape as Pivot row fields.
stackedbooleanFor bar charts, stack the series. Defaults to true.

When mode is count no measure is needed; otherwise measure names the numeric field being summed/averaged/etc. Grouping comes from the shared group elements in the search_view, exactly as in Pivot.