Levin-Aleksey's picture
start
e36a311
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)