Pivot Data Grid

A cross-tabulation: one field down the side, another across the top, and a worked-out value where they cross. This is the one grid whose columns come from the data rather than from a declaration — a grouped grid still has the columns you wrote down, where a pivot grows a column for every value it finds.

Default

A BbPivotField goes in Rows or Columns and a BbPivotValue in Values. Which axis a field belongs to comes from the fragment it is written in, so moving a field between them is moving it in the markup. Totals defaults to PivotTotals.Grand: a total column at the end of every row and a total row under every column.

Nesting and Subtotals

Stack two fields on an axis and the second nests inside the first, which is when the subtotal flags start doing something. Read the names as totals of the thing named: RowTotals is a column at the end of every row, ColumnTotals is a row at the bottom, and the two subtotal flags do the same one level in. PivotTotals.All turns the lot on. Setting Height pins the headings while the body scrolls, which is what makes a wide cross-tabulation readable.

Two Values in Every Cell

Declare two BbPivotValue entries and every cell holds two numbers. One value puts its name in the corner; two or more add a last row of column headings naming each one. AggregateFunction.Count is the one function that works without a Value selector.

Label Formats, It Does Not Group

A field can be bucketed or formatted while still grouping — and therefore sorting — on the real value. Here the grouping stays on the month number, so the months come out Jan, Feb, Mar rather than the alphabetical Apr, Aug, Dec that grouping on the formatted string would give. Comparer and Descending change the order of a level without touching the label.

A Custom Aggregate Gets the Items, Not the Cells

Aggregate works the cell's value out itself. It is called once per cell and once per total, and a total is handed every item beneath it rather than the cells it covers — which is what lets a win rate come out right where an average of averages would not. Compare the two columns: the rate is worked out from the raw deals every time.

Field Picker, Paging, Templates and a Drill-Down

ShowFieldPicker turns declared fields and values on and off without the markup changing; its state lives in the component, so a field hidden there comes back without touching the markup. PageSize counts outermost row groups rather than rows, so a group is never split across a boundary and its subtotal always lands with it. OnCellClick makes the cells buttons and hands over the items behind one — including behind a total, where the items are everything beneath it. Click any cell. OnBuilt reports the table when the built result changes, which is the line under the grid.

No Column Axis

The Columns fragment may be empty. With no column fields the table has one column, which makes it a grouped summary rather than a cross-tabulation — useful when the shape you want is a roll-up with a total row under it.

Grid Lines, Alternating Rows and the Empty State

GridLines chooses which rules are drawn between cells — Horizontal suits a table with few columns, where the vertical rules only add noise. AlternatingRows tints every other row. Loading shows a waiting state, and EmptyMessage replaces the localized “Nothing to cross-tabulate”.