|
1079 | 1079 | language="python", |
1080 | 1080 | ) |
1081 | 1081 |
|
| 1082 | +# --------------------------------------------------------------------------- |
| 1083 | +# Section 14: Server-Side Drill-Down (Hybrid Mode) |
| 1084 | +# --------------------------------------------------------------------------- |
| 1085 | +st.divider() |
| 1086 | +st.subheader("14. Server-Side Drill-Down (Hybrid Mode)") |
| 1087 | + |
| 1088 | +st.markdown( |
| 1089 | + """ |
| 1090 | +When datasets are large enough to trigger **threshold_hybrid** mode, the pivot |
| 1091 | +data is pre-aggregated on the server before being sent to the browser. In this |
| 1092 | +mode, drill-down works via a **server round-trip**: clicking a cell sends a |
| 1093 | +request to Python, which filters the *original* un-aggregated DataFrame and |
| 1094 | +returns the matching rows. |
| 1095 | +
|
| 1096 | +Because large cells can match thousands of rows, the results are **paginated** |
| 1097 | +(500 rows per page) with **Prev / Next** controls. |
| 1098 | +
|
| 1099 | +**Try it:** |
| 1100 | +- Click any data cell — after a brief round-trip the drill-down panel appears. |
| 1101 | +- If the cell has more than 500 matching rows, use the **← Prev / Next →** |
| 1102 | + buttons at the bottom of the panel to page through all results. |
| 1103 | +- The header shows a range like "1–500 of 2,340 records" and the current page. |
| 1104 | +
|
| 1105 | +**API parameter used:** `execution_mode` (set to `"threshold_hybrid"` here to |
| 1106 | +force hybrid mode on a smaller dataset for demonstration purposes) |
| 1107 | +""" |
| 1108 | +) |
| 1109 | + |
| 1110 | +import numpy as np # noqa: E402 |
| 1111 | + |
| 1112 | +_rng = np.random.default_rng(42) |
| 1113 | +_n = 50_000 |
| 1114 | +df_hybrid = pd.DataFrame( |
| 1115 | + { |
| 1116 | + "Region": _rng.choice(["North", "South", "East", "West"], _n), |
| 1117 | + "Category": _rng.choice( |
| 1118 | + ["Electronics", "Clothing", "Food", "Furniture", "Toys"], _n |
| 1119 | + ), |
| 1120 | + "Year": _rng.choice([2022, 2023, 2024], _n), |
| 1121 | + "Channel": _rng.choice(["Online", "Retail", "Wholesale"], _n), |
| 1122 | + "Revenue": _rng.uniform(10, 5000, _n).round(2), |
| 1123 | + "Profit": _rng.uniform(-500, 2000, _n).round(2), |
| 1124 | + } |
| 1125 | +) |
| 1126 | + |
| 1127 | +st_pivot_table( |
| 1128 | + df_hybrid, |
| 1129 | + key="hybrid_drilldown_demo", |
| 1130 | + rows=["Region", "Category"], |
| 1131 | + columns=["Year"], |
| 1132 | + values=["Revenue", "Profit"], |
| 1133 | + aggregation={"Revenue": "sum", "Profit": "sum"}, |
| 1134 | + number_format={"Revenue": "$,.0f", "Profit": "$,.0f"}, |
| 1135 | + show_totals=True, |
| 1136 | + show_subtotals=True, |
| 1137 | + enable_drilldown=True, |
| 1138 | + execution_mode="threshold_hybrid", |
| 1139 | +) |
| 1140 | + |
| 1141 | +with st.expander("View Code"): |
| 1142 | + st.code( |
| 1143 | + """ |
| 1144 | +import numpy as np |
| 1145 | +
|
| 1146 | +rng = np.random.default_rng(42) |
| 1147 | +n = 50_000 |
| 1148 | +df_hybrid = pd.DataFrame({ |
| 1149 | + "Region": rng.choice(["North", "South", "East", "West"], n), |
| 1150 | + "Category": rng.choice(["Electronics", "Clothing", "Food", "Furniture", "Toys"], n), |
| 1151 | + "Year": rng.choice([2022, 2023, 2024], n), |
| 1152 | + "Channel": rng.choice(["Online", "Retail", "Wholesale"], n), |
| 1153 | + "Revenue": rng.uniform(10, 5000, n).round(2), |
| 1154 | + "Profit": rng.uniform(-500, 2000, n).round(2), |
| 1155 | +}) |
| 1156 | +
|
| 1157 | +st_pivot_table( |
| 1158 | + df_hybrid, |
| 1159 | + key="hybrid_drilldown_demo", |
| 1160 | + rows=["Region", "Category"], |
| 1161 | + columns=["Year"], |
| 1162 | + values=["Revenue", "Profit"], |
| 1163 | + aggregation={"Revenue": "sum", "Profit": "sum"}, |
| 1164 | + number_format={"Revenue": "$,.0f", "Profit": "$,.0f"}, |
| 1165 | + show_totals=True, |
| 1166 | + show_subtotals=True, |
| 1167 | + enable_drilldown=True, |
| 1168 | + execution_mode="threshold_hybrid", |
| 1169 | +) |
| 1170 | +# Click any cell to see paginated server-side drill-down. |
| 1171 | +""", |
| 1172 | + language="python", |
| 1173 | + ) |
| 1174 | + |
| 1175 | +st.caption( |
| 1176 | + f"Dataset: {len(df_hybrid):,} rows × {len(df_hybrid.columns)} columns — " |
| 1177 | + "forced to threshold_hybrid mode for demonstration." |
| 1178 | +) |
| 1179 | + |
| 1180 | + |
1082 | 1181 | # --------------------------------------------------------------------------- |
1083 | 1182 | # Footer: Raw Data |
1084 | 1183 | # --------------------------------------------------------------------------- |
|
0 commit comments