Syntrex Claude Sonnet 4.6 commited on
Commit
e6a8789
·
1 Parent(s): 2bcaea3

Fix export PNG to use current sort state instead of default order

Browse files

The response_data path was unreliable — it returned None mid-interaction,
causing fallback to the old sort. Now we re-apply the session-state sort
model (always in sync with AgGrid) to the original data before returning,
so the exported PNG always matches what the user sees in the grid.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

Files changed (1) hide show
  1. visualization/betting_page.py +6 -14
visualization/betting_page.py CHANGED
@@ -348,6 +348,8 @@ def _build_cell_style_js(style_field: str, align_right: bool, emphasize: bool):
348
  def _render_sortable_grid(display_df: pd.DataFrame, numeric_df: pd.DataFrame, css_df: pd.DataFrame, *, family: str, side: str) -> tuple[pd.DataFrame, pd.DataFrame, pd.DataFrame]:
349
  sort_key = _get_sort_state_key(family, side)
350
  sort_model = st.session_state.get(sort_key) or []
 
 
351
  display_df, numeric_df, css_df = _apply_sort_model(display_df, numeric_df, css_df, sort_model)
352
  if AgGrid is None or GridOptionsBuilder is None:
353
  styler = display_df.style.apply(lambda _: css_df, axis=None)
@@ -404,20 +406,10 @@ def _render_sortable_grid(display_df: pd.DataFrame, numeric_df: pd.DataFrame, cs
404
  new_sort_model = _extract_sort_model(response)
405
  if new_sort_model:
406
  st.session_state[sort_key] = new_sort_model
407
- response_data = response.get("data") if isinstance(response, dict) else None
408
- if response_data is None:
409
- return display_df, numeric_df, css_df
410
- response_df = pd.DataFrame(response_data)
411
- if response_df.empty or "__row_key" not in response_df.columns:
412
- return display_df, numeric_df, css_df
413
- order = response_df["__row_key"].astype(str).tolist()
414
- keyed_display = display_df.assign(__row_key=numeric_df["player_event_market_key"].astype(str)).set_index("__row_key")
415
- keyed_numeric = numeric_df.assign(__row_key=numeric_df["player_event_market_key"].astype(str)).set_index("__row_key")
416
- keyed_css = css_df.assign(__row_key=numeric_df["player_event_market_key"].astype(str)).set_index("__row_key")
417
- order = [key for key in order if key in keyed_display.index]
418
- if not order:
419
- return display_df, numeric_df, css_df
420
- return keyed_display.loc[order].reset_index(drop=True), keyed_numeric.loc[order].reset_index(drop=True), keyed_css.loc[order].reset_index(drop=True)
421
 
422
 
423
  def _build_side_table(df: pd.DataFrame, book_cols: list[str], prev_snap: dict[str, float], steam_set: set[str], model_probs: pd.DataFrame | None) -> tuple[pd.DataFrame, pd.DataFrame]:
 
348
  def _render_sortable_grid(display_df: pd.DataFrame, numeric_df: pd.DataFrame, css_df: pd.DataFrame, *, family: str, side: str) -> tuple[pd.DataFrame, pd.DataFrame, pd.DataFrame]:
349
  sort_key = _get_sort_state_key(family, side)
350
  sort_model = st.session_state.get(sort_key) or []
351
+ # Keep originals so we can re-sort after the response updates the sort model
352
+ orig_display, orig_numeric, orig_css = display_df.copy(), numeric_df.copy(), css_df.copy()
353
  display_df, numeric_df, css_df = _apply_sort_model(display_df, numeric_df, css_df, sort_model)
354
  if AgGrid is None or GridOptionsBuilder is None:
355
  styler = display_df.style.apply(lambda _: css_df, axis=None)
 
406
  new_sort_model = _extract_sort_model(response)
407
  if new_sort_model:
408
  st.session_state[sort_key] = new_sort_model
409
+ # Re-apply the now-current sort model to the original data so the export
410
+ # PNG always reflects exactly what the grid is showing the user.
411
+ current_sort = st.session_state.get(sort_key) or []
412
+ return _apply_sort_model(orig_display, orig_numeric, orig_css, current_sort)
 
 
 
 
 
 
 
 
 
 
413
 
414
 
415
  def _build_side_table(df: pd.DataFrame, book_cols: list[str], prev_snap: dict[str, float], steam_set: set[str], model_probs: pd.DataFrame | None) -> tuple[pd.DataFrame, pd.DataFrame]: