import streamlit as st import pandas as pd import plotly.express as px import matplotlib matplotlib.use('Agg') import matplotlib.pyplot as plt import json import os st.set_page_config(page_title="Crypto Dash", layout="wide") def load_data() -> dict: app_dir = os.path.dirname(os.path.abspath(__file__)) data_path = os.path.join(app_dir, "data.json") with open(data_path, "r", encoding="utf-8") as f: payload = json.load(f) return payload[0] if isinstance(payload, list) else payload def build_cohorts_df(data: dict) -> pd.DataFrame: raw = data.get("users_by_cohorts", []) if not raw: return pd.DataFrame(columns=["cohort_day", "user_count"]) df = pd.DataFrame(raw) df["cohort_day"] = pd.to_numeric(df["cohort_day"], errors="coerce") df["user_count"] = pd.to_numeric(df["user_count"], errors="coerce") return df.dropna().sort_values("cohort_day").reset_index(drop=True) try: data = load_data() except Exception as e: st.error(f"Ошибка загрузки data.json: {e}") st.stop() st.title("📊 Blockchain Dashboard") # KPI c1, c2, c3 = st.columns(3) c1.metric("Total TX", f"{data['total_tx_amount']:,}") c2.metric("DAU", f"{data['dau']:,}") c3.metric("New Wallets", f"{data['new_wallets_amount']:,}") # Chart st.subheader("User Activity by Cohort Day") df = build_cohorts_df(data) if df.empty: st.warning("Нет данных для графика.") else: # 1. Plotly (primary) fig = px.area(df, x="cohort_day", y="user_count", title="Cohort Activity", template="plotly_white") fig.update_layout(height=400, margin=dict(l=20, r=20, t=40, b=20)) st.plotly_chart(fig, use_container_width=True) # 2. Matplotlib PNG (server-side, always visible) mpl_fig, ax = plt.subplots(figsize=(10, 3)) ax.fill_between(df["cohort_day"], df["user_count"], alpha=0.4) ax.plot(df["cohort_day"], df["user_count"], linewidth=2) ax.set_xlabel("Cohort Day") ax.set_ylabel("Users") ax.set_title("Cohort Activity (server-rendered)") ax.grid(alpha=0.3) st.pyplot(mpl_fig) plt.close(mpl_fig) # Raw data with st.expander("Raw Data"): st.write(data)