Add pivot tables to perfetto docs
Added pivot tables design document and a pivot table usage section in
the Perfetto UI Tips and Tricks.
Bug: 149193812
Change-Id: I4a05d2c25bd6c94b46946eca18b40b54d5096bce
diff --git a/docs/design-docs/pivot-tables.md b/docs/design-docs/pivot-tables.md
new file mode 100644
index 0000000..9794e19
--- /dev/null
+++ b/docs/design-docs/pivot-tables.md
@@ -0,0 +1,206 @@
+# Pivot Tables
+
+_**Project Plan**: [Perfetto: Pivot tables for slices](https://docs.google.com/document/d/1RuEGQKLgOA8YWjZJHD6CTA3ghRRg6o5Phg3_rFCJEDE/)
+_**How to Use**: [Pivot Table Usage](/docs/visualization/perfetto-ui#pivot-tables)
+_**For Googlers**: [Perfetto: Pivot Table Use Cases](https://docs.google.com/document/d/1_iR-JjD7m19Q9GQtMk1_5NLSYXFicB_gg4S9D-6Q8lU/)
+
+## Objective
+Pivot tables give a simplified aggregated view of more complex data. They are
+made up of a number of pivots and aggregations that are grouped around these
+pivots. You can add more columns/aggregations and drag and drop the columns to
+explore the underlying data.
+
+## Motivation
+Pivot tables are useful in debugging hangs, stalls, and digging into traces
+which usually have too much data to clearly see the problems.
+The pivot table allows users to create custom tables to view specific
+information about traces in a summarized and less complex way.
+
+## Main Components
+
+
+
+### Details Panel (Frontend)
+The [DetailsPanel](https://cs.android.com/android/_/android/platform/external/perfetto/+/0ae7c36fd528824ee9fdea6cfd4494e9f05183b5:ui/src/frontend/details_panel.ts)
+searches for active PivotTables to display on screen. It also syncs the
+PivotTableHelper with data from the State. (PivotTableHelper only syncs when the
+PivotTableEditor modal is not open).
+
+
+### Pivot Table (Frontend)
+The [PivotTable](https://cs.android.com/android/_/android/platform/external/perfetto/+/0ae7c36fd528824ee9fdea6cfd4494e9f05183b5:ui/src/frontend/pivot_table.ts) builds
+the pivot table tab and the table. It also handles user requests (like opening
+the pivot table editor, drag and drop columns, expand, etc…) by calling the
+PivotTableHelper and updating the table.
+
+
+### PivotTableEditor (Frontend)
+The [PivotTableEditor](https://cs.android.com/android/_/android/platform/external/perfetto/+/0ae7c36fd528824ee9fdea6cfd4494e9f05183b5:ui/src/frontend/pivot_table_editor.ts)
+consists of ColumnPicker and ColumnDisplay classes.
+ColumnPicker allows the user to select column type, name and aggregation. Edits
+made through the ColumnPicker are saved temporarily in the PivotTableHelper
+without updating the state.
+ColumnDisplay displays the selected column from the ColumnPicker, it also allows
+users to manipulate the columns after selection (like delete, reorder, change
+the default sorting, etc...).
+In this stage the user is able to query the selected columns and update the
+table or discard the changes made and the PivotTableHelper will resync with the
+data in state.
+
+
+### PivotTableHelper (Frontend)
+The [PivotTableHelper](https://cs.android.com/android/_/android/platform/external/perfetto/+/0ae7c36fd528824ee9fdea6cfd4494e9f05183b5:ui/src/frontend/pivot_table_helper.ts)
+is created by every PivotTableController for every PivotTableId. It stores a
+copy of the selectedPivots and selectedAggregations from state. It also holds
+the logic for manipulating the data locally, which are used by the PivotTable
+and PivotTableEditor.
+It also replaces the data in the State with the changes upon request.
+The PivotTableHelper also checks for special “stack” columns, called stackPivots
+("name (stack)" for [slice table](/docs/analysis/sql-tables.autogen#slice) is
+currently the only special column), as it sets the column attributes which are
+then used to identify them by other components.
+
+
+### State (Common)
+[PivotTableState](https://cs.android.com/android/_/android/platform/external/perfetto/+/0ae7c36fd528824ee9fdea6cfd4494e9f05183b5:ui/src/common/state.ts;l=303) holds the
+information that needs to be transferred to and from the frontend and the
+controller for each pivot table instance (PivotTableId). It also includes the
+global PivotTableConfigs (like the availableColumns and availableAggregations).
+
+
+### PivotTableController (Controller)
+A new [PivotTableController](https://cs.android.com/android/_/android/platform/external/perfetto/+/0ae7c36fd528824ee9fdea6cfd4494e9f05183b5:ui/src/controller/pivot_table_controller.ts)
+is created for every PivotTableId.
+The PivotTableController handles the setup of the pivot table once added, it
+queries for the columns for all tables and sets the PivotTableConfig. It also
+creates and initializes a PivotTableHelper for every PivotTableId and publishes
+it to the frontend.
+Additionally, the PivotTableController handles the collection and the
+computation of all data needed by the PivotTableQueryGenerator.
+It constantly checks if a request has been set in the PivotTableState and acts
+on it if so.
+It decides what columns to query, what whereFilters and tables to include and
+how to reformat the query result into a PivotTableQueryResponse based on the
+request type.
+
+There are four types of requests implemented in the controller:
+
+**_QUERY:_**
+Queries the first pivot of the selectedPivots and all the aggregations,
+including any global or table-wide whereFilters (Like the start and end
+timestamp and selected track_ids that are set by the pivot table generated
+through area selection).
+It also adds a whereFilter (Filter in the where clause of the query) if the
+pivot is a stackPivot to restrict the result to the top level slices only, since
+descendants can be generated by expanding the cell and issuing the DESCENDANTS
+request, and returns the result as a PivotTableQueryResponse.
+
+
+
+Returned PivotTableQueryResponse:
+
+```typescript
+pivotTableQueryResponse = {
+ columns: ['slice type', 'slice category', 'slice name'];
+ rows: [
+ {
+ row: 'internal_slice',
+ expandableColumns: ['slice type'],
+ expandedRows = [],
+ }, {
+ row: 'thread_slice',
+ expandableColumns: ['slice type'],
+ expandedRows = [],
+ };
+ ]
+}
+```
+
+**_EXPAND:_**
+The [PivotTableBody](https://cs.android.com/android/_/android/platform/external/perfetto/+/a9118d769009349da7f264abb392f4207e66602b:ui/src/frontend/pivot_table.ts;l=235;drc=0bc8ff07f372a58ca4d0399d88567a66ef5b591b) generates the nested structure by
+recursively displaying the rows and checking if the row contains any expanded
+rows with the isExpanded flag set to true. As it goes through the nested rows,
+it passes the row index that it's about to expand, along with the column it's
+expanding for till it reaches a [PivotTableRow](https://cs.android.com/android/_/android/platform/external/perfetto/+/0ae7c36fd528824ee9fdea6cfd4494e9f05183b5:ui/src/frontend/pivot_table.ts;l=192).
+The PivotTableRow creates a cell for each column. If the cell is at a column
+that can be expanded, it is created as an [ExpandableCell](https://cs.android.com/android/_/android/platform/external/perfetto/+/0ae7c36fd528824ee9fdea6cfd4494e9f05183b5:ui/src/frontend/pivot_table.ts;l=121).
+When an 'EXPAND' request is issued on an ExpandableCell, it sets the
+requestedAction in the PivotTableState and provides it with the SubQueryAttrs.
+
+Given a columnIdx, value, and an array of rowIndicies (SubQueryAttrs) from
+the requestedAction in the PivotTableState, it finds the exact row that called
+this request from the main PivotTableQueryResponse, and finds the next pivot
+to query. It then generates the query similarly to the ‘QUERY’ request, but
+includes the whereFilter of the previous column (column name = column value).
+The rows of the query result are then nested into the caller row’s expandedRows,
+to build a tree view structure while expanding.
+
+
+
+Passed value:
+
+```typescript
+subQueryAttrs = {
+ rowIndices: [0, 3],
+ columnIdx: 1,
+ value: 'blink,benchmark',
+ expandedRowColumns: ['slice category'],
+}
+```
+
+Returned expanded rows:
+
+```typescript
+rows = [
+ {
+ row: 'LocalFrameView::RunAccessibilityLifecyclePhase',
+ expandableColumns: [],
+ expandedRows: []
+ },
+ {
+ row: 'LocalFrameView::RunCompositingInputsLifecyclePhase',
+ expandableColumns: [],
+ expandedRows: []
+ },
+ {
+ row: 'LocalFrameView::RunStyleAndLayoutLifecyclePhases',
+ expandableColumns: [],
+ expandedRows: []
+ },
+ ...
+]
+```
+
+The returned rows are saved inside the caller row expandedRows map.
+
+```typescript
+rows = {
+ row: 'blink,benchmark',
+ expandableColumns: ['slice category'],
+ expandedRows: [
+ 'slice name' => {
+ isExpanded: true,
+ rows
+ }
+ ]
+}
+```
+
+**_UNEXPAND:_**
+Sets the caller row’s isExpanded flag to false, to hide it from the display but
+also keeping its expandedRows saved so as to not have to query them again if
+requested.
+
+**_DESCENDANTS:_**
+Should only be called for stackPivots, generates a query containing the
+stackPivot and the next pivot, if it exists, and all the aggregations. It also
+requests the PivotTableQueryGenerator to order by depth first, which is then
+used to refactor the resulting rows into the PivotTableQueryResponse tree view
+structure.
+The returned format is similar to the EXPAND request.
+
+### PivotTableQueryGenerator (Common)
+[PivotTableQueryGenerator](https://cs.android.com/android/_/android/platform/external/perfetto/+/0ae7c36fd528824ee9fdea6cfd4494e9f05183b5:ui/src/common/pivot_table_query_generator.ts)
+generates an sql query based on the given data, along with any hidden columns
+that may need to be added. It also creates an alias for each pivot and
+aggregation that is used to identify the resulting cells in the rows.
diff --git a/docs/images/pivot-tables/pivot-table-area-selection.png b/docs/images/pivot-tables/pivot-table-area-selection.png
new file mode 100644
index 0000000..f2c84d3
--- /dev/null
+++ b/docs/images/pivot-tables/pivot-table-area-selection.png
Binary files differ
diff --git a/docs/images/pivot-tables/pivot-table-design.png b/docs/images/pivot-tables/pivot-table-design.png
new file mode 100644
index 0000000..e38da25
--- /dev/null
+++ b/docs/images/pivot-tables/pivot-table-design.png
Binary files differ
diff --git a/docs/images/pivot-tables/pivot-table-editor.png b/docs/images/pivot-tables/pivot-table-editor.png
new file mode 100644
index 0000000..8db7ff9
--- /dev/null
+++ b/docs/images/pivot-tables/pivot-table-editor.png
Binary files differ
diff --git a/docs/images/pivot-tables/pivot-table-expanded-cell.png b/docs/images/pivot-tables/pivot-table-expanded-cell.png
new file mode 100644
index 0000000..4628272
--- /dev/null
+++ b/docs/images/pivot-tables/pivot-table-expanded-cell.png
Binary files differ
diff --git a/docs/images/pivot-tables/pivot-table-query.png b/docs/images/pivot-tables/pivot-table-query.png
new file mode 100644
index 0000000..e50ae9d
--- /dev/null
+++ b/docs/images/pivot-tables/pivot-table-query.png
Binary files differ
diff --git a/docs/images/pivot-tables/pivot-table.png b/docs/images/pivot-tables/pivot-table.png
new file mode 100644
index 0000000..3e842f9
--- /dev/null
+++ b/docs/images/pivot-tables/pivot-table.png
Binary files differ
diff --git a/docs/visualization/perfetto-ui.md b/docs/visualization/perfetto-ui.md
index 426f2dc..c977a01 100644
--- a/docs/visualization/perfetto-ui.md
+++ b/docs/visualization/perfetto-ui.md
@@ -71,3 +71,25 @@
Note: There is no equivalent debug counters feature yet, but the feature request
is tracked on [b/168886909](http://b/168886909)).
+
+### Pivot Tables
+
+To use pivot tables in the Perfetto UI, you will need to enable the
+"Pivot tables" feature flag in the "Flags" tab under "Support" in the Sidebar.
+You can pop up a pivot table over the entire trace when clicking "p" on your
+keyboard. The "Edit" button opens a pop up window to add/remove and reorder
+columns and change the default sorting of aggregations.
+
+
+
+Clicking on "Query" generates a table with the selected columns.
+Table cells with the expand icon can be expanded to show the next column values.
+The "name (stack)" column displays top level slices that can be expanded to show
+their descendants down to the last child.
+
+
+
+Area selection pops up a pre-filled pivot table restricted over the selected
+timestamps and track ids.
+
+