Revenue cube without a report
Closed won revenue by region and quarter, totals on both axes, computed live from opportunities.
Overview
Closed won revenue by region and quarter, totals on both axes, computed live from opportunities. No report builder, no dashboard. The whole tab is one Pivot Table Dynamic Component on a Lightning app page, aggregating Opportunity records through a Query data source. This tutorial rebuilds the Revenue tab of the Sales app in your own org.
What you build

The Revenue tab opens on one pivot: five regions down, four quarters across, the sum of the deals in every cell, totals on both axes and a grand total of 3,700,500 in the corner.
The header reads
FY2026 · by region and quarteraboveClosed won revenue.Every number is a whole dollar amount, no decimals, under a column labeled
Sum Revenue (USD).It reads the opportunities directly, so it is current the second a deal closes.
Before you start
The Avonni Experience Components package, which carries Dynamic Components, is installed. Whoever builds the component needs the Avonni Experiences Admin permission set; the people who use the page need a license and Avonni Dynamic Components User. See Installation & Licenses Management.
A Lightning app with an app page for the pivot. The examples below use the Sales app and its Revenue tab.
Three fields on the standard Opportunity object, next to the standard ones the pivot reads:
Opportunity
StageName
Standard picklist
Only Closed Won deals count
CloseDate
Standard date
Scopes the cube to the year
Amount
Standard currency
The deal value, as the rest of the org uses it
Region__c
Picklist: North America, EMEA, APAC, LATAM, Nordics
The rows
Quarter__c
Picklist: Q1, Q2, Q3, Q4
The columns, see step 1
Revenue__c
Number, 18 digits, 0 decimal places
The measure: a whole-dollar copy of Amount, see step 1
Sample data. Forty closed won opportunities, two per region and quarter, all closed in 2026. Revenue equals Amount on every one, and Quarter follows the close date:
Meridian Foods platform rollout
APAC
Jan 28, 2026
65,500
Copperline Energy annual renewal
APAC
Mar 5, 2026
125,500
Northwind Distribution pilot conversion
APAC
May 13, 2026
168,500
Lantern Financial platform rollout
APAC
Jun 4, 2026
89,000
Northwind Distribution seat expansion
APAC
Aug 12, 2026
38,000
Copperline Energy pilot conversion
APAC
Sep 2, 2026
97,000
Vantage Analytics pilot conversion
APAC
Oct 7, 2026
32,500
Vantage Analytics platform rollout
APAC
Dec 3, 2026
64,500
Northwind Distribution platform rollout
EMEA
Feb 11, 2026
62,500
Trailhead Outfitters platform rollout
EMEA
Mar 5, 2026
145,500
Orchard Health seat expansion
EMEA
Apr 9, 2026
47,500
Blue Harbor Group seat expansion
EMEA
Jun 4, 2026
149,500
Northwind Distribution annual renewal
EMEA
Aug 12, 2026
26,000
Meridian Foods annual renewal
EMEA
Sep 2, 2026
115,500
Blue Harbor Group annual renewal
EMEA
Nov 10, 2026
53,500
Trailhead Outfitters platform rollout
EMEA
Dec 3, 2026
157,500
Orchard Health platform rollout
LATAM
Feb 11, 2026
103,500
Trailhead Outfitters pilot conversion
LATAM
Mar 5, 2026
179,500
Trailhead Outfitters seat expansion
LATAM
Apr 22, 2026
89,500
Blue Harbor Group annual renewal
LATAM
Jun 4, 2026
115,500
Sable & Finch pilot conversion
LATAM
Aug 12, 2026
67,000
Lantern Financial pilot conversion
LATAM
Sep 2, 2026
131,000
Trailhead Outfitters seat expansion
LATAM
Nov 10, 2026
89,000
Copperline Energy seat expansion
LATAM
Dec 3, 2026
36,000
Lantern Financial platform rollout
Nordics
Feb 11, 2026
146,000
Orchard Health platform rollout
Nordics
Mar 5, 2026
96,000
Cascade Logistics annual renewal
Nordics
May 13, 2026
175,500
Meridian Foods seat expansion
Nordics
Jun 4, 2026
132,000
Copperline Energy seat expansion
Nordics
Jul 21, 2026
46,000
Copperline Energy pilot conversion
Nordics
Sep 2, 2026
53,000
Vantage Analytics seat expansion
Nordics
Oct 20, 2026
72,000
Orchard Health seat expansion
Nordics
Dec 3, 2026
41,000
Sable & Finch pilot conversion
North America
Jan 15, 2026
116,000
Cascade Logistics annual renewal
North America
Mar 5, 2026
127,000
Copperline Energy pilot conversion
North America
May 13, 2026
63,500
Meridian Foods pilot conversion
North America
Jun 4, 2026
95,500
Blue Harbor Group platform rollout
North America
Jul 8, 2026
139,500
Copperline Energy annual renewal
North America
Sep 2, 2026
100,000
Sable & Finch pilot conversion
North America
Nov 10, 2026
20,500
Trailhead Outfitters platform rollout
North America
Dec 3, 2026
28,000
If your org already holds closed won opportunities for the year, the pivot adds them in. Read the totals in the figure as what the forty deals above produce on their own.
Permissions. Users need Read on Opportunity and on the three custom fields. The pivot only aggregates the records Salesforce lets each user see.
Build it
Create the three fields and load the deals
In Setup, open Object Manager, then Opportunity, and add the Region picklist, the Quarter picklist and the Revenue number field listed above.
Load the forty sample opportunities, with Stage
Closed Won, Revenue equal to Amount, and Quarter set from the close date (Q1for January to March, and so on).
Why two extra fields when the data is already there:
Quarter is a picklist rather than a date grouping so that the column headers read
Q1toQ4. The pivot can also group Close Date by quarter directly (see Take it further), but the header then shows the quarter number,1to4.Revenue is a Number field rather than Amount because a currency measure renders with the currency symbol and two decimals,
$191,000.00, and no setting of the pivot changes that. A Number field with 0 decimal places renders191,000. The unit moves into the column label instead.
Create the Dynamic Component and add the Pivot Table
From the App Launcher, open the Avonni Components App and click New Component.
Name it
Revenue cubeand leave Target Page Object empty: the pivot lives on an app page.Drag Pivot Table onto the canvas and select it. The Edit Pivot Table panel opens on the right with the Properties and Interactions tabs.

Connect the query
In the Data Source section, click Create Query.
Choose the Opportunity object.
Under Filters, add
StageNameequalsClosed WonandCloseDate=THIS_YEAR, combined with AND.Click Done.
Why: the pivot only ever sees what the query returns, so the filter is where "closed won, this year" lives. The Pivot Table's query has no Order By and no limit to set: it aggregates on the server and sorts the result itself. The sample deals close in 2026; in a later year, filter on the year they closed. See Query for the filter operators.

Map the rows, the columns and the measure
In the Data Mappings section:
Under Group Rows, add an entry with Field
Region__c.Under Group Columns, add an entry with Field
Quarter__c.Under Aggregations, add an entry with Field
Revenue__cand Measure Sum. Turn on Custom Label and enterRevenue (USD).
Why: the column header is the measure followed by the field label, so the custom label makes it read Sum Revenue (USD): the unit the currency symbol would have carried. Rows and columns combined are limited to three grouping fields; this cube uses two.

Turn on the totals
In the Content section, turn on Show Grand Total. Leave Show Subtotals off.
Why: Show Grand Total adds the Total column, the Total row and the corner. Subtotals only exist with more than one row group or more than one column group, so on this cube the switch has no effect.

Save, activate, add to the page
Click Save, then Activate.
In Lightning App Builder, open the app page, drag AX - Dynamic Component onto it and select
Revenue cubein its Properties Panel.Click Save, then Activate the page for the app. See Publishing your Dynamic Components.
The settings that matter
Group Rows Field (groupRows[].field)
Region__c
The vertical axis, one row per region, sorted by value
Group Columns Field (groupColumns[].field)
Quarter__c
The horizontal axis, Q1 to Q4
Aggregations Field and Measure (aggregations[].field, aggregations[].measure)
Revenue__c, Sum, labeled Revenue (USD)
The value in every cell. A Number field renders whole numbers where a Currency field renders $191,000.00
Show Grand Total (showGrandTotal)
on
The Total column, the Total row and the grand total in the corner
Try it
Open the Revenue tab. Five rows, APAC to North America, four columns, Q1 to Q4, a Total column and a Total row. The column totals read 1,167,000, 1,126,000, 813,000 and 594,500, and the corner 3,700,500.
Click the arrow next to Region in the top left corner: the rows sort the other way, North America first. Click it again.
Open the APAC deal
Copperline Energy pilot conversion(Sep 2, 2026), change Revenue from97,000to100,000and save. Back on the tab, APAC Q3 reads 138,000, the APAC total 683,500 and the corner 3,703,500. No report was refreshed. Put the value back.
Take it further
The same pivot exists on two other Avonni surfaces:
Pivot Table for Flow Screen Components, inside a screen flow.
Pivot Table for LWC Components, as the
avonni-dd-pivot-tabletag in your own component.
Four variations worth trying:
Group the columns on the date instead of the picklist: under Group Columns, set Field to
CloseDateand Group to Quarter. No Quarter field to maintain, and the headers read1to4.Add a second row group, for instance
Account.IndustryunderRegion__c, then turn on Show Subtotals: each region gets a subtotal row.Turn on Detail Rows in Content: clicking a cell lists the deals behind it, with their Revenue in a column.
Add
Region__cunder Filters in Data Mappings: a filter appears above the pivot, and the cube narrows to the regions the end user picks.
Troubleshooting
The pivot is empty although the query returns records
No row group, column group or aggregation is set.
In Data Mappings, add at least one Group Rows entry and one Aggregations entry with a numeric field and a measure.
Every cell shows a currency symbol and two decimals
The aggregated field is a Currency field. The pivot renders a currency measure in the org's currency format, two decimals included, and has no decimals setting.
Aggregate a Number field with 0 decimal places, such as Revenue__c, and name the unit in the custom label.
The columns read 1, 2, 3, 4 instead of Q1 to Q4
The column group is Close Date with Group set to Quarter. A date group labels its columns with the calendar quarter number.
Group on the Quarter__c picklist, or keep the date group and read the numbers as quarters.
A quarter is missing from the columns
No closed won deal in that quarter matched the query. The pivot only shows the values present in the records it aggregates.
Nothing to fix on the pivot: the column appears with the first deal. Check the query filter if deals exist.
Show Subtotals is on and nothing changes
Subtotals need more than one row group or more than one column group. With one group per axis, the only total is the grand total.
Add a second group on one axis, or rely on Show Grand Total.
Was this helpful?

