import pandas as pd from dash import html def ordinal(n: int) -> str: """Return the ordinal suffix for a day (e.g., 1 -> 1st).""" if 10 <= n % 100 <= 20: suffix = "th" else: suffix = {1: "st", 2: "nd", 3: "rd"}.get(n % 10, "th") return f"{n}{suffix}" def format_date(dt: pd.Timestamp) -> str: """Format a pandas Timestamp into a readable string.""" return dt.strftime("%b") + f" {ordinal(dt.day)}, {dt.year}" def build_slider_marks(start_dt: pd.Timestamp, end_dt: pd.Timestamp): """Create slider marks for the range and all-time sliders.""" return [ {"value": int(start_dt.timestamp()), "label": start_dt.strftime("%b %Y")}, {"value": int(end_dt.timestamp()), "label": end_dt.strftime("%b %Y")}, ] def get_thumb_labels(values): """Generate thumb labels for the range slider.""" distance = abs(values[1] - values[0]) close = distance < 4 * 30 * 86400 # 4 months label_style = { "background": "#fff", "color": "#082030", "fontWeight": "bold", "fontSize": "13px", "borderRadius": "8px", "padding": "2px 8px", "boxShadow": "0 1px 4px rgba(8,32,48,0.10)", "position": "absolute", "left": "50%", "transform": "translateX(-50%)", "whiteSpace": "nowrap", "zIndex": 100, } if close: style_top_1 = label_style.copy() style_top_1["top"] = "-38px" style_top_2 = label_style.copy() style_top_2["top"] = "14px" else: style_top_1 = label_style.copy() style_top_1["top"] = "14px" style_top_2 = label_style.copy() style_top_2["top"] = "14px" return [ html.Div(pd.to_datetime(values[0], unit="s").strftime("%b %d, %Y"), style=style_top_1), html.Div(pd.to_datetime(values[1], unit="s").strftime("%b %d, %Y"), style=style_top_2), ] def get_thumb_label_single(value): """Generate thumb label for the all-time slider.""" label_style = { "background": "#fff", "color": "#082030", "fontWeight": "bold", "fontSize": "13px", "borderRadius": "8px", "padding": "2px 8px", "boxShadow": "0 1px 4px rgba(8,32,48,0.10)", "position": "absolute", "left": "50%", "transform": "translateX(-50%)", "whiteSpace": "nowrap", "zIndex": 100, "top": "14px", } return [html.Div(pd.to_datetime(value, unit="s").strftime("%b %d, %Y"), style=label_style)] def format_large_number(n: int) -> str: """Shorten large numbers, e.g. 5,000,000 -> '5 million'.""" if n >= 1_000_000_000: return f"{n / 1_000_000_000:.1f} billion" if n >= 1_000_000: return f"{n / 1_000_000:.1f} million" if n >= 1_000: return f"{n / 1_000:.1f}k" return str(int(n))