QAway-to commited on
Commit
7897e32
·
1 Parent(s): 49d9149

New tabs and functions v3.6

Browse files
Files changed (3) hide show
  1. app.py +36 -16
  2. core/crypto_dashboard.py +17 -16
  3. core/styles/crypto_dashboard.css +30 -8
app.py CHANGED
@@ -81,34 +81,54 @@ with gr.Blocks(css=base_css) as demo:
81
 
82
  # --- Crypto Intelligence Dashboard (Plotly Edition + KPI line) ---
83
  with gr.TabItem("Crypto Intelligence Dashboard"):
 
84
  gr.HTML(f"<style>{crypto_css}</style>")
85
- gr.Markdown("### 💹 Coinlore Market Dashboard (Plotly Edition)")
86
 
87
- # KPI line (фиксированная строка, без скачков)
88
- with gr.Row():
89
- kpi_line = gr.HTML(elem_id="kpi_line") # "BTC $xx (Δ%), ETH $xx (Δ%), ..."
90
-
91
- # Controls
92
- with gr.Row():
93
- top_slider = gr.Slider(label="Top N coins", minimum=20, maximum=100, step=10, value=50, scale=70)
 
 
 
 
 
 
 
94
  load_btn = gr.Button("Generate Dashboard", variant="primary", scale=30)
95
 
96
- # Treemap + AI Summary
97
- with gr.Row(equal_height=True):
98
  with gr.Column(scale=70):
99
  treemap_plot = gr.Plot(label="Market Composition")
100
  with gr.Column(scale=30):
101
- ai_box = gr.Textbox(label="AI Market Summary", lines=18, elem_id="ai_summary_sidebar")
102
-
103
- # Lower charts
104
- with gr.Row(equal_height=True):
 
 
 
 
105
  movers_plot = gr.Plot(label="Top Movers", scale=50)
106
  scatter_plot = gr.Plot(label="Market Cap vs Volume", scale=50)
107
 
 
 
108
  def run_dash(n):
109
  fig_treemap, fig_bar, fig_bubble, ai_comment, kpi_text = build_crypto_dashboard(n)
110
- # kpi_text уже готовая строка "BTC $.. (..%), ETH $.. (..%), ..."
111
- return fig_treemap, fig_bar, fig_bubble, ai_comment, f"<div class='kpi-line'>{kpi_text}</div>"
 
 
 
 
 
 
 
112
 
113
  load_btn.click(
114
  fn=run_dash,
 
81
 
82
  # --- Crypto Intelligence Dashboard (Plotly Edition + KPI line) ---
83
  with gr.TabItem("Crypto Intelligence Dashboard"):
84
+ # Подключаем стили вкладки
85
  gr.HTML(f"<style>{crypto_css}</style>")
 
86
 
87
+ # KPI line (фиксированная строка без скачков, с минимальными отступами)
88
+ with gr.Row(elem_id="kpi_row"):
89
+ kpi_line = gr.HTML(elem_id="kpi_line")
90
+
91
+ # Controls (Top N slider + кнопка)
92
+ with gr.Row(elem_id="controls_row"):
93
+ top_slider = gr.Slider(
94
+ label="Top N coins",
95
+ minimum=20,
96
+ maximum=100,
97
+ step=10,
98
+ value=50,
99
+ scale=70,
100
+ )
101
  load_btn = gr.Button("Generate Dashboard", variant="primary", scale=30)
102
 
103
+ # Основной контент графики и текстовый инсайт
104
+ with gr.Row(equal_height=True, elem_id="main_charts_row"):
105
  with gr.Column(scale=70):
106
  treemap_plot = gr.Plot(label="Market Composition")
107
  with gr.Column(scale=30):
108
+ ai_box = gr.Textbox(
109
+ label="AI Market Summary",
110
+ lines=18,
111
+ elem_id="ai_summary_sidebar",
112
+ )
113
+
114
+ # Нижний ряд с двумя графиками
115
+ with gr.Row(equal_height=True, elem_id="bottom_charts_row"):
116
  movers_plot = gr.Plot(label="Top Movers", scale=50)
117
  scatter_plot = gr.Plot(label="Market Cap vs Volume", scale=50)
118
 
119
+
120
+ # === Callback ===
121
  def run_dash(n):
122
  fig_treemap, fig_bar, fig_bubble, ai_comment, kpi_text = build_crypto_dashboard(n)
123
+ # KPI-строка уже готова, возвращаем её с обёрткой <div>
124
+ return (
125
+ fig_treemap,
126
+ fig_bar,
127
+ fig_bubble,
128
+ ai_comment,
129
+ f"<div class='kpi-line'>{kpi_text}</div>",
130
+ )
131
+
132
 
133
  load_btn.click(
134
  fn=run_dash,
core/crypto_dashboard.py CHANGED
@@ -1,6 +1,8 @@
1
  """
2
- Crypto Dashboard — Plotly Edition + KPI Line (clean version)
3
- Удалены встроенные заголовки из графиков.
 
 
4
  """
5
  import requests
6
  import pandas as pd
@@ -19,7 +21,7 @@ def fetch_coinlore_data(limit=100):
19
 
20
 
21
  def _kpi_line(df) -> str:
22
- """Возвращает строку KPI: BTC $xx (Δ%), ETH $yy (Δ%), ..."""
23
  tracked = ["BTC", "ETH", "SOL", "DOGE"]
24
  parts = []
25
  for sym in tracked:
@@ -31,8 +33,8 @@ def _kpi_line(df) -> str:
31
  arrow = "↑" if ch > 0 else "↓"
32
  color = "#4ade80" if ch > 0 else "#f87171"
33
  parts.append(
34
- f"<span class='kpi-item'><b>{sym}</b> ${price:,.0f} "
35
- f"<span style='color:{color}'>{arrow} {abs(ch):.2f}%</span></span>"
36
  )
37
  return " , ".join(parts)
38
 
@@ -40,7 +42,7 @@ def _kpi_line(df) -> str:
40
  def build_crypto_dashboard(top_n=50):
41
  df = fetch_coinlore_data(top_n)
42
 
43
- # === Treemap (чистый, без заголовка) ===
44
  fig_treemap = px.treemap(
45
  df,
46
  path=["symbol"],
@@ -50,15 +52,15 @@ def build_crypto_dashboard(top_n=50):
50
  height=420,
51
  )
52
  fig_treemap.update_layout(
53
- title=None, # 🔹 Убираем встроенный заголовок
54
  template="plotly_dark",
55
- autosize=True,
56
  margin=dict(l=5, r=5, t=5, b=5),
57
  paper_bgcolor="rgba(0,0,0,0)",
58
  plot_bgcolor="rgba(0,0,0,0)",
59
  )
60
 
61
- # === Top Gainers (24h) ===
62
  top = df.sort_values("percent_change_24h", ascending=False).head(12)
63
  fig_bar = px.bar(
64
  top,
@@ -70,15 +72,15 @@ def build_crypto_dashboard(top_n=50):
70
  height=320,
71
  )
72
  fig_bar.update_layout(
73
- title=None, # 🔹 убран встроенный title
74
  template="plotly_dark",
75
- autosize=True,
76
  margin=dict(l=40, r=10, t=5, b=18),
77
  paper_bgcolor="rgba(0,0,0,0)",
78
  plot_bgcolor="rgba(0,0,0,0)",
79
  )
80
 
81
- # === Market Cap vs Volume ===
82
  fig_bubble = px.scatter(
83
  df.head(60),
84
  x="market_cap_usd",
@@ -92,18 +94,17 @@ def build_crypto_dashboard(top_n=50):
92
  height=320,
93
  )
94
  fig_bubble.update_layout(
95
- title=None, # 🔹 убран встроенный title
96
  template="plotly_dark",
97
- autosize=True,
98
  margin=dict(l=36, r=10, t=5, b=18),
99
  paper_bgcolor="rgba(0,0,0,0)",
100
  plot_bgcolor="rgba(0,0,0,0)",
101
  )
102
 
103
- # === AI summary ===
104
  summary = _ai_summary(df)
105
  kpi_text = _kpi_line(df)
106
-
107
  return fig_treemap, fig_bar, fig_bubble, summary, kpi_text
108
 
109
 
 
1
  """
2
+ Crypto Dashboard — Plotly Edition (clean layout)
3
+ убраны colorbar заголовки (percent_change_*)
4
+ • уменьшены отступы KPI
5
+ • без глобального Markdown-заголовка
6
  """
7
  import requests
8
  import pandas as pd
 
21
 
22
 
23
  def _kpi_line(df) -> str:
24
+ """Формирует компактную KPI-строку без лишних пробелов"""
25
  tracked = ["BTC", "ETH", "SOL", "DOGE"]
26
  parts = []
27
  for sym in tracked:
 
33
  arrow = "↑" if ch > 0 else "↓"
34
  color = "#4ade80" if ch > 0 else "#f87171"
35
  parts.append(
36
+ f"<b>{sym}</b> ${price:,.0f} "
37
+ f"<span style='color:{color}'>{arrow} {abs(ch):.2f}%</span>"
38
  )
39
  return " , ".join(parts)
40
 
 
42
  def build_crypto_dashboard(top_n=50):
43
  df = fetch_coinlore_data(top_n)
44
 
45
+ # === Treemap ===
46
  fig_treemap = px.treemap(
47
  df,
48
  path=["symbol"],
 
52
  height=420,
53
  )
54
  fig_treemap.update_layout(
55
+ title=None,
56
  template="plotly_dark",
57
+ coloraxis_colorbar=dict(title=None), # 🔹 убираем надпись percent_change_24h
58
  margin=dict(l=5, r=5, t=5, b=5),
59
  paper_bgcolor="rgba(0,0,0,0)",
60
  plot_bgcolor="rgba(0,0,0,0)",
61
  )
62
 
63
+ # === Bar chart (Top gainers) ===
64
  top = df.sort_values("percent_change_24h", ascending=False).head(12)
65
  fig_bar = px.bar(
66
  top,
 
72
  height=320,
73
  )
74
  fig_bar.update_layout(
75
+ title=None,
76
  template="plotly_dark",
77
+ coloraxis_colorbar=dict(title=None), # 🔹 убираем надпись percent_change_24h
78
  margin=dict(l=40, r=10, t=5, b=18),
79
  paper_bgcolor="rgba(0,0,0,0)",
80
  plot_bgcolor="rgba(0,0,0,0)",
81
  )
82
 
83
+ # === Scatter (Market Cap vs Volume) ===
84
  fig_bubble = px.scatter(
85
  df.head(60),
86
  x="market_cap_usd",
 
94
  height=320,
95
  )
96
  fig_bubble.update_layout(
97
+ title=None,
98
  template="plotly_dark",
99
+ coloraxis_colorbar=dict(title=None), # 🔹 убираем надпись percent_change_7d
100
  margin=dict(l=36, r=10, t=5, b=18),
101
  paper_bgcolor="rgba(0,0,0,0)",
102
  plot_bgcolor="rgba(0,0,0,0)",
103
  )
104
 
105
+ # === LLM summary ===
106
  summary = _ai_summary(df)
107
  kpi_text = _kpi_line(df)
 
108
  return fig_treemap, fig_bar, fig_bubble, summary, kpi_text
109
 
110
 
core/styles/crypto_dashboard.css CHANGED
@@ -1,29 +1,51 @@
1
  /* === KPI fixed line (строка с метриками) === */
 
 
 
 
 
2
  #kpi_line {
3
  width: 100%;
4
- padding: 4px 8px;
 
5
  background: transparent;
6
  color: #f0f6fc;
7
  font-family: 'JetBrains Mono', monospace;
 
 
8
  white-space: nowrap;
9
  overflow: hidden;
10
  text-overflow: ellipsis;
11
  display: flex;
12
  align-items: center;
13
  justify-content: flex-start;
14
- min-height: 26px;
15
  border-bottom: 1px solid #30363d;
 
16
  }
 
 
17
  .kpi-item {
18
- margin-right: 16px;
19
- font-size: 14px;
20
- letter-spacing: 0.1px;
21
  transition: opacity 0.2s ease;
22
  }
23
  .kpi-item:hover {
24
  opacity: 0.85;
25
  }
26
 
 
 
 
 
 
 
 
 
 
 
 
 
27
  /* === Plot containers — плотное выравнивание === */
28
  [data-testid="plot-container"] {
29
  width: 100% !important;
@@ -77,7 +99,7 @@
77
 
78
  /* === Ряды между графиками === */
79
  .gr-row {
80
- gap: 12px !important;
81
- margin-top: 4px !important;
82
- margin-bottom: 4px !important;
83
  }
 
1
  /* === KPI fixed line (строка с метриками) === */
2
+ #kpi_row {
3
+ margin-top: 0 !important;
4
+ margin-bottom: 0 !important;
5
+ padding: 0 !important;
6
+ }
7
  #kpi_line {
8
  width: 100%;
9
+ margin: 0 !important;
10
+ padding: 2px 6px !important;
11
  background: transparent;
12
  color: #f0f6fc;
13
  font-family: 'JetBrains Mono', monospace;
14
+ font-size: 14px;
15
+ line-height: 1.2;
16
  white-space: nowrap;
17
  overflow: hidden;
18
  text-overflow: ellipsis;
19
  display: flex;
20
  align-items: center;
21
  justify-content: flex-start;
22
+ min-height: 24px;
23
  border-bottom: 1px solid #30363d;
24
+ transition: all 0.2s ease-in-out;
25
  }
26
+
27
+ /* KPI items */
28
  .kpi-item {
29
+ margin-right: 14px;
30
+ letter-spacing: 0.2px;
 
31
  transition: opacity 0.2s ease;
32
  }
33
  .kpi-item:hover {
34
  opacity: 0.85;
35
  }
36
 
37
+ /* === Controls (slider + button) — минимальные отступы === */
38
+ #controls_row {
39
+ margin-top: 2px !important;
40
+ margin-bottom: 2px !important;
41
+ padding: 0 !important;
42
+ }
43
+ #controls_row .gr-button,
44
+ #controls_row .gr-slider {
45
+ margin-top: 0 !important;
46
+ margin-bottom: 0 !important;
47
+ }
48
+
49
  /* === Plot containers — плотное выравнивание === */
50
  [data-testid="plot-container"] {
51
  width: 100% !important;
 
99
 
100
  /* === Ряды между графиками === */
101
  .gr-row {
102
+ gap: 10px !important;
103
+ margin-top: 2px !important;
104
+ margin-bottom: 2px !important;
105
  }