You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: README.md
+82-21Lines changed: 82 additions & 21 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -155,7 +155,7 @@ st_pivot_table(
155
155
)
156
156
```
157
157
158
-
In the interactive toolbar, aggregation is edited inside the `Values` dropdown, and raw measure chips display the selected aggregation inline in a compact name-first format such as `Revenue (Sum)`.
158
+
In the interactive toolbar, aggregation is edited inside the **Settings Panel**. Open the panel, click the aggregation badge on a value chip to change it, then click **Apply**. Raw measure chips in the toolbar display the selected aggregation inline in a compact name-first format such as `Revenue (Sum)`.
159
159
160
160
### Synthetic Measures (V1)
161
161
@@ -473,7 +473,7 @@ st_pivot_table(
473
473
474
474
- Each group shows a subtotal row with a collapse/expand toggle (+/−).
475
475
- Collapsed groups hide child rows but keep the subtotal visible.
476
-
- Expand All / Collapse All controls are available in the Settings popover (gear icon in the toolbar).
476
+
- Expand All / Collapse All controls are available in the toolbar utility menu.
477
477
478
478
**Grouping vs. leaf dimensions:** When subtotals are on, all dimensions except
479
479
the innermost are *grouping dimensions*. They define collapsible groups and
@@ -569,7 +569,7 @@ st_pivot_table(
569
569
570
570
### Locked Mode
571
571
572
-
Use `locked=True` for a viewer-mode experience with exploration enabled. Toolbar config controls stay locked so end-users cannot change rows, columns, values, per-measure aggregation, or settings toggles. Reset, Swap, and config import/export are hidden, while data export remains available and the Settings gear stays visible for read-only display status plus Expand/Collapse All group controls. Header-menu sorting, filtering, and `Show Values As` remain available, and drill-down still works.
572
+
Use `locked=True` for a viewer-mode experience with exploration enabled. The Settings Panel and toolbar config controls are locked so end-users cannot change rows, columns, values, or per-measure aggregation. Reset, Swap, and config import/export are hidden, while data export remains available. Expand/Collapse All group controls remain accessible in the toolbar utility menu. Header-menu sorting, filtering, and `Show Values As` remain available, and drill-down still works.
573
573
574
574
```python
575
575
st_pivot_table(
@@ -582,9 +582,9 @@ st_pivot_table(
582
582
)
583
583
```
584
584
585
-
### Toolbar Utility Menu
585
+
### Toolbar and Settings Panel
586
586
587
-
When `interactive=True`, hovering over the top-right of the toolbar reveals utility actions:
587
+
When `interactive=True`, the toolbar displays read-only zone cards showing current **Rows**, **Columns**, and **Values** assignments. Hovering over the top-right reveals utility actions:
588
588
589
589
| Action | Description |
590
590
|--------|-------------|
@@ -593,28 +593,38 @@ When `interactive=True`, hovering over the top-right of the toolbar reveals util
593
593
|**Copy Config**| Copies the current config as JSON to clipboard |
594
594
|**Import Config**| Paste a JSON config to apply |
595
595
|**Export Data**| Open the export popover (Excel / CSV / TSV / Clipboard). Use `export_filename` to customize the download filename. |
596
+
|**Expand / Collapse All**| Expand or collapse all row/column groups (visible when subtotals are enabled or 2+ column dimensions exist) |
596
597
|**Fullscreen** (expand icon) | Toggles fullscreen mode — the table fills the entire viewport. Press Escape or click the collapse icon to exit. |
597
-
|**Settings** (gear icon) | Opens a popover with display toggles: Row Totals, Column Totals, Subtotals, Repeat Labels, Sticky Headers, and Expand/Collapse All group controls|
598
+
|**Settings** (pivot icon) | Opens the Settings Panel for full field configuration|
598
599
599
-
In **locked mode**, Reset, Swap, and config import/export are hidden. `Export Data` remains available as a viewer action. The Settings gear remains visible, its popover shows read-only display status plus group expand/collapse actions, and header-menu sorting, filtering, and `Show Values As` stay enabled.
600
+
#### Settings Panel (Staged Commit UX)
600
601
601
-
### Toolbar Field Search
602
+
The Settings Panel is the primary authoring surface for pivot configuration. Changes are staged locally and only applied when you click **Apply**. Click **Cancel** or press **Escape** to discard.
602
603
603
-
When a toolbar picker has more than **8 available fields**, the `Rows`, `Columns`, or `Values` dropdown automatically shows a field search input at the top of the panel.
604
+
The panel contains:
604
605
605
-
- Typing filters the available field list in place.
606
-
-`ArrowDown` from the search box moves focus into the first matching option.
607
-
-`Escape` closes the dropdown, even when the current query has zero matches.
608
-
- In the `Values` dropdown, search only filters the field checklist. Synthetic-measure actions and per-measure aggregation controls remain visible below it.
606
+
-**Available Fields** — unassigned columns shown as draggable chips. Click a chip's menu to add it to Rows, Columns, or Values. When more than 8 fields are available, a search input appears.
607
+
-**Rows / Columns / Values** drop zones — drag chips to reorder within a zone, drag between zones, or use the `x` button to remove. Value chips show an aggregation picker (click the badge to change).
608
+
-**Synthetic Measures** — click **+ Add measure** to create derived metrics (ratio of sums, difference of sums) with optional format patterns.
External config changes (toolbar DnD, Reset, Swap, config import) while the panel is open will close it and discard uncommitted edits.
612
+
613
+
In **locked mode**, Reset, Swap, and config import/export are hidden. `Export Data` remains available as a viewer action. The Settings icon shows read-only display status, and header-menu sorting, filtering, and `Show Values As` stay enabled.
614
+
615
+
### Field Search
616
+
617
+
When the Settings Panel has more than **8 available fields**, a search input appears at the top of the Available Fields section. Typing filters the field chips in place. The container maintains its initial height even when search reduces the visible chips.
609
618
610
619
This is a frontend-only convenience feature; no Python parameter is needed to enable it.
611
620
612
621
### Drag-and-Drop Field Configuration
613
622
614
-
When `interactive=True`, each chip in the Rows, Columns, and Values toolbar zones has a **grip-dots drag handle** on its left side. Drag chips to:
623
+
Drag-and-drop is available in two contexts:
615
624
616
-
-**Reorder within a zone** — change the grouping hierarchy (e.g., swap which dimension is the outer vs. inner group in Rows).
617
-
-**Move between zones** — drag a chip from Rows to Columns (or vice versa), or between Rows/Columns and Values. The Values zone only accepts numeric columns; non-numeric drops are silently rejected.
625
+
**Toolbar DnD:** Each chip in the Rows, Columns, and Values toolbar zones has a **grip-dots drag handle**. Drag to reorder within a zone or move between zones. These are immediate (non-staged) changes.
626
+
627
+
**Settings Panel DnD:** Inside the Settings Panel, chips in Available Fields and all zone sections are draggable. Drag from Available Fields into a zone, reorder within zones, or move between zones. These changes are staged and applied on **Apply**.
618
628
619
629
**Visual feedback:**
620
630
- A floating overlay chip follows the cursor during drag.
@@ -624,9 +634,11 @@ When `interactive=True`, each chip in the Rows, Columns, and Values toolbar zone
624
634
625
635
**Constraints:**
626
636
-`frozen_columns` render without drag handles and cannot be dragged.
627
-
- Synthetic measures cannot be dragged to other zones.
637
+
- Non-numeric fields are rejected from the Values zone.
638
+
- Rows and Columns are mutually exclusive (a field cannot be in both).
639
+
- A field can be in Values and one dimension zone simultaneously.
628
640
- When `locked=True`, drag-and-drop is fully disabled.
629
-
- A 5 px activation distance distinguishes clicks from drags, so remove buttons and dropdown toggles work normally.
641
+
- A 5 px activation distance distinguishes clicks from drags.
630
642
631
643
**Config cleanup on move:** When fields move between zones, related config properties (aggregation, sort, collapsed groups, subtotals, conditional formatting, show-values-as, per-measure totals) are automatically synchronized.
632
644
@@ -712,13 +724,62 @@ The component follows WAI-ARIA patterns for all interactive elements:
712
724
-**Drag-and-drop**: Space to pick up a chip, arrow keys to move, Space to drop at the new position. Screen reader announcements provided by dnd-kit.
-**Export/Import popovers**: Focus is automatically placed on the first interactive element when opened. Tab/Shift+Tab moves between controls; tabbing out closes the popover.
715
-
-**Settings popover** (gear icon): Focus moves to first checkbox on open. Escape closes. Tab navigates between toggles.
727
+
-**Settings Panel** (pivot icon): Focus moves into the panel on open. Escape closes and discards staged changes. Tab navigates between fields, zones, toggles, and buttons. Aggregation dropdowns support Enter/Space for keyboard selection.
-**Drill-down panel**: Focus moves to the close button on open. Escape closes.
718
730
-**Data cells**: Focusable via Tab. Space/Enter triggers cell click.
719
731
720
732
---
721
733
734
+
## Performance: Using Fragments
735
+
736
+
Streamlit reruns the entire script whenever a widget's state changes. In apps with multiple pivot tables or expensive data preparation, this means every toolbar change, sort, or filter in one table triggers a full rerun — including all other tables.
737
+
738
+
Wrapping each pivot table in [`@st.fragment`](https://docs.streamlit.io/develop/api-reference/execution-flow/st.fragment) scopes reruns to just the fragment that changed, leaving the rest of the app untouched.
739
+
740
+
### Basic pattern
741
+
742
+
```python
743
+
import streamlit as st
744
+
from streamlit_pivot import st_pivot_table
745
+
746
+
df = load_data() # runs once per full rerun, not on fragment reruns
747
+
748
+
@st.fragment
749
+
defsales_pivot():
750
+
result = st_pivot_table(df, key="sales", rows=["Region"], values=["Revenue"])
Interacting with "sales" only re-executes `sales_pivot()` — the data load and `product_pivot()` are not re-executed.
764
+
765
+
### When fragments help
766
+
767
+
| Scenario | Benefit |
768
+
|---|---|
769
+
| App with multiple pivot tables | Interactions in one table don't re-execute the others |
770
+
| Expensive data loading / transformation | Data prep runs only on full reruns, not on every config change |
771
+
| Hybrid drilldown (`execution_mode="threshold_hybrid"`) | Server round-trips for drill-down are scoped to the fragment |
772
+
773
+
### Caveats
774
+
775
+
-**Return values**: Streamlit ignores fragment return values during fragment reruns. Code that reads the result of `st_pivot_table()` should live inside the same fragment, or use `st.session_state[key]` instead.
776
+
-**Data prep with randomness**: Keep DataFrame generation that uses random seeds outside the fragment to avoid non-deterministic data on fragment reruns.
777
+
-**Callbacks**: `on_config_change` and `on_cell_click` fire during fragment reruns, which is the expected behavior.
778
+
779
+
The demo app (`streamlit_app.py`) wraps each of its 19 sections in `@st.fragment` as a reference implementation.
The example app (`streamlit_app.py`) contains 18 sections covering the major features and usage patterns with interactive examples and inline documentation.
799
+
The example app (`streamlit_app.py`) contains 19 sections covering the major features and usage patterns with interactive examples and inline documentation.
0 commit comments