Loading...
Loading...
Compare original and translation side by side
undefinedundefinedundefinedundefinedfrom dash import Dash, html, dcc
import plotly.express as px
import pandas as pdfrom dash import Dash, html, dcc
import plotly.express as px
import pandas as pd
**Run the app:**
```bash
python app.py
**运行应用:**
```bash
python app.pyundefinedundefinedfrom dash import Dash, html, dcc, callback, Output, Input
import plotly.express as px
import pandas as pd
app = Dash(__name__)from dash import Dash, html, dcc, callback, Output, Input
import plotly.express as px
import pandas as pd
app = Dash(__name__)html.Label("Select Category:"),
dcc.Dropdown(
id="category-dropdown",
options=[{"label": c, "value": c} for c in df["category"].unique()],
value="A",
clearable=False
),
dcc.Graph(id="line-chart")html.Label("选择类别:"),
dcc.Dropdown(
id="category-dropdown",
options=[{"label": c, "value": c} for c in df["category"].unique()],
value="A",
clearable=False
),
dcc.Graph(id="line-chart")fig = px.line(
filtered_df,
x="date",
y="value",
title=f"Values for Category {selected_category}"
)
return fig
**Multiple Inputs and Outputs:**
```python
from dash import Dash, html, dcc, callback, Output, Input
import plotly.express as px
import pandas as pd
app = Dash(__name__)fig = px.line(
filtered_df,
x="date",
y="value",
title=f"类别 {selected_category} 的数值"
)
return fig
**多输入与多输出:**
```python
from dash import Dash, html, dcc, callback, Output, Input
import plotly.express as px
import pandas as pd
app = Dash(__name__)html.Div([
html.Div([
html.Label("Category"),
dcc.Dropdown(
id="category-filter",
options=[{"label": c, "value": c} for c in df["category"].unique()],
value=["A", "B", "C"],
multi=True
)
], style={"width": "45%", "display": "inline-block"}),
html.Div([
html.Label("Region"),
dcc.Dropdown(
id="region-filter",
options=[{"label": r, "value": r} for r in df["region"].unique()],
value=["North", "South", "East", "West"],
multi=True
)
], style={"width": "45%", "display": "inline-block", "marginLeft": "5%"})
]),
html.Div([
html.Div([
dcc.Graph(id="trend-chart")
], style={"width": "60%", "display": "inline-block"}),
html.Div([
dcc.Graph(id="pie-chart")
], style={"width": "38%", "display": "inline-block", "marginLeft": "2%"})
]),
html.Div(id="summary-stats")# Trend chart
trend = filtered.groupby("date")["value"].sum().reset_index()
trend_fig = px.line(trend, x="date", y="value", title="Value Trend")
# Pie chart
by_category = filtered.groupby("category")["value"].sum().reset_index()
pie_fig = px.pie(by_category, values="value", names="category", title="By Category")
# Summary stats
stats = html.Div([
html.H4("Summary Statistics"),
html.P(f"Total records: {len(filtered):,}"),
html.P(f"Total value: {filtered['value'].sum():,}"),
html.P(f"Average value: {filtered['value'].mean():.2f}")
])
return trend_fig, pie_fig, stats
**Chained Callbacks:**
```python
from dash import Dash, html, dcc, callback, Output, Input
import pandas as pd
app = Dash(__name__)html.Div([
html.Div([
html.Label("类别"),
dcc.Dropdown(
id="category-filter",
options=[{"label": c, "value": c} for c in df["category"].unique()],
value=["A", "B", "C"],
multi=True
)
], style={"width": "45%", "display": "inline-block"}),
html.Div([
html.Label("区域"),
dcc.Dropdown(
id="region-filter",
options=[{"label": r, "value": r} for r in df["region"].unique()],
value=["North", "South", "East", "West"],
multi=True
)
], style={"width": "45%", "display": "inline-block", "marginLeft": "5%"})
]),
html.Div([
html.Div([
dcc.Graph(id="trend-chart")
], style={"width": "60%", "display": "inline-block"}),
html.Div([
dcc.Graph(id="pie-chart")
], style={"width": "38%", "display": "inline-block", "marginLeft": "2%"})
]),
html.Div(id="summary-stats")# 趋势图
trend = filtered.groupby("date")["value"].sum().reset_index()
trend_fig = px.line(trend, x="date", y="value", title="数值趋势")
# 饼图
by_category = filtered.groupby("category")["value"].sum().reset_index()
pie_fig = px.pie(by_category, values="value", names="category", title="按类别统计")
# 汇总统计
stats = html.Div([
html.H4("汇总统计"),
html.P(f"总记录数: {len(filtered):,}"),
html.P(f"总数值: {filtered['value'].sum():,}"),
html.P(f"平均数值: {filtered['value'].mean():.2f}")
])
return trend_fig, pie_fig, stats
**链式回调:**
```python
from dash import Dash, html, dcc, callback, Output, Input
import pandas as pd
app = Dash(__name__)html.Label("Country"),
dcc.Dropdown(id="country-dropdown"),
html.Label("State/Province"),
dcc.Dropdown(id="state-dropdown"),
html.Label("City"),
dcc.Dropdown(id="city-dropdown"),
html.Div(id="selection-output")html.Label("国家"),
dcc.Dropdown(id="country-dropdown"),
html.Label("州/省"),
dcc.Dropdown(id="state-dropdown"),
html.Label("城市"),
dcc.Dropdown(id="city-dropdown"),
html.Div(id="selection-output")undefinedundefinedfrom dash import htmlfrom dash import html# Lists
html.Ul([
html.Li("Item 1"),
html.Li("Item 2"),
html.Li("Item 3")
]),
# Links
html.A("Click here", href="https://example.com", target="_blank"),
# Images
html.Img(src="/assets/logo.png", style={"width": "200px"}),
# Tables
html.Table([
html.Thead([
html.Tr([html.Th("Name"), html.Th("Value")])
]),
html.Tbody([
html.Tr([html.Td("Item 1"), html.Td("100")]),
html.Tr([html.Td("Item 2"), html.Td("200")])
])
])
**Core Components (dcc):**
```python
from dash import dcc# 列表
html.Ul([
html.Li("项目1"),
html.Li("项目2"),
html.Li("项目3")
]),
# 链接
html.A("点击这里", href="https://example.com", target="_blank"),
# 图片
html.Img(src="/assets/logo.png", style={"width": "200px"}),
# 表格
html.Table([
html.Thead([
html.Tr([html.Th("名称"), html.Th("数值")])
]),
html.Tbody([
html.Tr([html.Td("项目1"), html.Td("100")]),
html.Tr([html.Td("项目2"), html.Td("200")])
])
])
**核心组件(dcc):**
```python
from dash import dcc# Multi-select dropdown
dcc.Dropdown(
id="multi-dropdown",
options=[{"label": f"Option {i}", "value": i} for i in range(10)],
value=[1, 2, 3],
multi=True
),
# Slider
dcc.Slider(
id="slider",
min=0,
max=100,
step=5,
value=50,
marks={0: "0", 25: "25", 50: "50", 75: "75", 100: "100"}
),
# Range slider
dcc.RangeSlider(
id="range-slider",
min=0,
max=100,
step=1,
value=[20, 80],
marks={i: str(i) for i in range(0, 101, 20)}
),
# Input
dcc.Input(
id="text-input",
type="text",
placeholder="Enter text...",
debounce=True # Wait for typing to stop
),
# Textarea
dcc.Textarea(
id="textarea",
placeholder="Enter longer text...",
style={"width": "100%", "height": "100px"}
),
# Checklist
dcc.Checklist(
id="checklist",
options=[
{"label": "Option 1", "value": "1"},
{"label": "Option 2", "value": "2"},
{"label": "Option 3", "value": "3"}
],
value=["1"],
inline=True
),
# Radio items
dcc.RadioItems(
id="radio",
options=[
{"label": "Small", "value": "s"},
{"label": "Medium", "value": "m"},
{"label": "Large", "value": "l"}
],
value="m",
inline=True
),
# Date picker
dcc.DatePickerSingle(
id="date-picker",
date="2025-01-01",
display_format="YYYY-MM-DD"
),
# Date range picker
dcc.DatePickerRange(
id="date-range",
start_date="2025-01-01",
end_date="2025-12-31",
display_format="YYYY-MM-DD"
),
# Upload
dcc.Upload(
id="upload",
children=html.Div(["Drag and Drop or ", html.A("Select Files")]),
style={
"width": "100%",
"height": "60px",
"lineHeight": "60px",
"borderWidth": "1px",
"borderStyle": "dashed",
"borderRadius": "5px",
"textAlign": "center"
}
),
# Tabs
dcc.Tabs(id="tabs", value="tab-1", children=[
dcc.Tab(label="Tab 1", value="tab-1"),
dcc.Tab(label="Tab 2", value="tab-2")
]),
# Loading indicator
dcc.Loading(
id="loading",
type="default", # default, graph, cube, circle, dot
children=html.Div(id="loading-output")
),
# Interval (for periodic updates)
dcc.Interval(
id="interval-component",
interval=1000, # milliseconds
n_intervals=0
),
# Store (client-side data storage)
dcc.Store(id="data-store", storage_type="session"), # memory, session, local
# Graph
dcc.Graph(
id="graph",
config={
"displayModeBar": True,
"displaylogo": False,
"modeBarButtonsToRemove": ["lasso2d", "select2d"]
}
)undefined# 多选下拉菜单
dcc.Dropdown(
id="multi-dropdown",
options=[{"label": f"选项{i}", "value": i} for i in range(10)],
value=[1, 2, 3],
multi=True
),
# 滑块
dcc.Slider(
id="slider",
min=0,
max=100,
step=5,
value=50,
marks={0: "0", 25: "25", 50: "50", 75: "75", 100: "100"}
),
# 范围滑块
dcc.RangeSlider(
id="range-slider",
min=0,
max=100,
step=1,
value=[20, 80],
marks={i: str(i) for i in range(0, 101, 20)}
),
# 输入框
dcc.Input(
id="text-input",
type="text",
placeholder="输入文本...",
debounce=True # 等待输入停止后触发
),
# 文本域
dcc.Textarea(
id="textarea",
placeholder="输入较长文本...",
style={"width": "100%", "height": "100px"}
),
# 复选框
dcc.Checklist(
id="checklist",
options=[
{"label": "选项1", "value": "1"},
{"label": "选项2", "value": "2"},
{"label": "选项3", "value": "3"}
],
value=["1"],
inline=True
),
# 单选按钮
dcc.RadioItems(
id="radio",
options=[
{"label": "小", "value": "s"},
{"label": "中", "value": "m"},
{"label": "大", "value": "l"}
],
value="m",
inline=True
),
# 日期选择器
dcc.DatePickerSingle(
id="date-picker",
date="2025-01-01",
display_format="YYYY-MM-DD"
),
# 日期范围选择器
dcc.DatePickerRange(
id="date-range",
start_date="2025-01-01",
end_date="2025-12-31",
display_format="YYYY-MM-DD"
),
# 文件上传
dcc.Upload(
id="upload",
children=html.Div(["拖拽文件或 ", html.A("选择文件")]),
style={
"width": "100%",
"height": "60px",
"lineHeight": "60px",
"borderWidth": "1px",
"borderStyle": "dashed",
"borderRadius": "5px",
"textAlign": "center"
}
),
# 标签页
dcc.Tabs(id="tabs", value="tab-1", children=[
dcc.Tab(label="标签页1", value="tab-1"),
dcc.Tab(label="标签页2", value="tab-2")
]),
# 加载指示器
dcc.Loading(
id="loading",
type="default", # default, graph, cube, circle, dot
children=html.Div(id="loading-output")
),
# 定时器(用于周期性更新)
dcc.Interval(
id="interval-component",
interval=1000, # 毫秒
n_intervals=0
),
# 存储(客户端数据存储)
dcc.Store(id="data-store", storage_type="session"), # memory, session, local
# 图表
dcc.Graph(
id="graph",
config={
"displayModeBar": True,
"displaylogo": False,
"modeBarButtonsToRemove": ["lasso2d", "select2d"]
}
)undefinedfrom dash import Dash, html, dcc, callback, Output, Input
import dash_bootstrap_components as dbc
import plotly.express as px
import pandas as pdfrom dash import Dash, html, dcc, callback, Output, Input
import dash_bootstrap_components as dbc
import plotly.express as px
import pandas as pd# Metrics row
dbc.Row([
dbc.Col([
dbc.Card([
dbc.CardBody([
html.H4("Total Sales", className="card-title"),
html.H2(f"${df['sales'].sum():,}", className="text-success")
])
])
], md=4),
dbc.Col([
dbc.Card([
dbc.CardBody([
html.H4("Total Orders", className="card-title"),
html.H2(f"{df['orders'].sum():,}", className="text-info")
])
])
], md=4),
dbc.Col([
dbc.Card([
dbc.CardBody([
html.H4("Avg Order Value", className="card-title"),
html.H2(f"${df['sales'].sum() / df['orders'].sum():.2f}", className="text-warning")
])
])
], md=4)
], className="mb-4"),
# Filters
dbc.Row([
dbc.Col([
dbc.Card([
dbc.CardHeader("Filters"),
dbc.CardBody([
dbc.Label("Date Range"),
dcc.DatePickerRange(
id="date-range",
start_date=df["date"].min(),
end_date=df["date"].max(),
className="mb-3"
),
dbc.Label("Metric"),
dcc.Dropdown(
id="metric-dropdown",
options=[
{"label": "Sales", "value": "sales"},
{"label": "Orders", "value": "orders"}
],
value="sales"
)
])
])
], md=3),
dbc.Col([
dcc.Graph(id="main-chart")
], md=9)
]),
# Tabs
dbc.Row([
dbc.Col([
dbc.Tabs([
dbc.Tab(label="Daily Data", tab_id="daily"),
dbc.Tab(label="Summary", tab_id="summary")
], id="tabs", active_tab="daily"),
html.Div(id="tab-content", className="mt-3")
])
], className="mt-4")fig = px.line(
filtered,
x="date",
y=metric,
title=f"{metric.title()} Over Time"
)
fig.update_layout(template="plotly_white")
return figundefined# 指标行
dbc.Row([
dbc.Col([
dbc.Card([
dbc.CardBody([
html.H4("总销售额", className="card-title"),
html.H2(f"${df['sales'].sum():,}", className="text-success")
])
])
], md=4),
dbc.Col([
dbc.Card([
dbc.CardBody([
html.H4("总订单数", className="card-title"),
html.H2(f"{df['orders'].sum():,}", className="text-info")
])
])
], md=4),
dbc.Col([
dbc.Card([
dbc.CardBody([
html.H4("平均订单价值", className="card-title"),
html.H2(f"${df['sales'].sum() / df['orders'].sum():.2f}", className="text-warning")
])
])
], md=4)
], className="mb-4"),
# 过滤器
dbc.Row([
dbc.Col([
dbc.Card([
dbc.CardHeader("过滤器"),
dbc.CardBody([
dbc.Label("日期范围"),
dcc.DatePickerRange(
id="date-range",
start_date=df["date"].min(),
end_date=df["date"].max(),
className="mb-3"
),
dbc.Label("指标"),
dcc.Dropdown(
id="metric-dropdown",
options=[
{"label": "销售额", "value": "sales"},
{"label": "订单数", "value": "orders"}
],
value="sales"
)
])
])
], md=3),
dbc.Col([
dcc.Graph(id="main-chart")
], md=9)
]),
# 标签页
dbc.Row([
dbc.Col([
dbc.Tabs([
dbc.Tab(label="每日数据", tab_id="daily"),
dbc.Tab(label="汇总", tab_id="summary")
], id="tabs", active_tab="daily"),
html.Div(id="tab-content", className="mt-3")
])
], className="mt-4")fig = px.line(
filtered,
x="date",
y=metric,
title=f"{metric.title()} 趋势"
)
fig.update_layout(template="plotly_white")
return figundefinedmy_dash_app/
├── app.py # Main entry point
├── pages/
│ ├── __init__.py
│ ├── home.py
│ ├── analytics.py
│ └── settings.py
├── components/
│ ├── __init__.py
│ ├── navbar.py
│ └── footer.py
├── utils/
│ ├── __init__.py
│ └── data.py
└── assets/
├── style.css
└── logo.pngfrom dash import Dash, html, dcc, page_container
import dash_bootstrap_components as dbc
app = Dash(
__name__,
use_pages=True,
external_stylesheets=[dbc.themes.BOOTSTRAP]
)my_dash_app/
├── app.py # 主入口
├── pages/
│ ├── __init__.py
│ ├── home.py
│ ├── analytics.py
│ └── settings.py
├── components/
│ ├── __init__.py
│ ├── navbar.py
│ └── footer.py
├── utils/
│ ├── __init__.py
│ └── data.py
└── assets/
├── style.css
└── logo.pngfrom dash import Dash, html, dcc, page_container
import dash_bootstrap_components as dbc
app = Dash(
__name__,
use_pages=True,
external_stylesheets=[dbc.themes.BOOTSTRAP]
)
**Home Page (pages/home.py):**
```python
from dash import html, register_page
import dash_bootstrap_components as dbc
register_page(__name__, path="/", name="Home")
layout = dbc.Container([
dbc.Row([
dbc.Col([
html.H1("Welcome to the Dashboard"),
html.P("Select a page from the navigation bar to get started."),
dbc.Card([
dbc.CardBody([
html.H4("Quick Links"),
dbc.ListGroup([
dbc.ListGroupItem("Analytics", href="/analytics"),
dbc.ListGroupItem("Settings", href="/settings")
])
])
])
])
])
])from dash import html, dcc, callback, Output, Input, register_page
import dash_bootstrap_components as dbc
import plotly.express as px
import pandas as pd
register_page(__name__, path="/analytics", name="Analytics")
**首页(pages/home.py):**
```python
from dash import html, register_page
import dash_bootstrap_components as dbc
register_page(__name__, path="/", name="Home")
layout = dbc.Container([
dbc.Row([
dbc.Col([
html.H1("欢迎来到仪表盘"),
html.P("从导航栏选择页面开始使用。"),
dbc.Card([
dbc.CardBody([
html.H4("快速链接"),
dbc.ListGroup([
dbc.ListGroupItem("分析", href="/analytics"),
dbc.ListGroupItem("设置", href="/settings")
])
])
])
])
])
])from dash import html, dcc, callback, Output, Input, register_page
import dash_bootstrap_components as dbc
import plotly.express as px
import pandas as pd
register_page(__name__, path="/analytics", name="Analytics")dbc.Row([
dbc.Col([
dbc.Label("Chart Type"),
dcc.Dropdown(
id="chart-type",
options=[
{"label": "Line", "value": "line"},
{"label": "Bar", "value": "bar"},
{"label": "Area", "value": "area"}
],
value="line"
)
], md=4)
], className="mb-4"),
dcc.Graph(id="analytics-chart")return figundefineddbc.Row([
dbc.Col([
dbc.Label("图表类型"),
dcc.Dropdown(
id="chart-type",
options=[
{"label": "折线图", "value": "line"},
{"label": "柱状图", "value": "bar"},
{"label": "面积图", "value": "area"}
],
value="line"
)
], md=4)
], className="mb-4"),
dcc.Graph(id="analytics-chart")return figundefinedfrom dash import Dash, html, dcc
import dash_auth
app = Dash(__name__)from dash import Dash, html, dcc
import dash_auth
app = Dash(__name__)
**Custom Login (with session):**
```python
from dash import Dash, html, dcc, callback, Output, Input, State
import dash_bootstrap_components as dbc
from flask import session
app = Dash(__name__, external_stylesheets=[dbc.themes.BOOTSTRAP])
app.server.secret_key = "your-secret-key-here"
**自定义登录(带会话):**
```python
from dash import Dash, html, dcc, callback, Output, Input, State
import dash_bootstrap_components as dbc
from flask import session
app = Dash(__name__, external_stylesheets=[dbc.themes.BOOTSTRAP])
app.server.secret_key = "your-secret-key-here"undefinedundefinedfrom dash import Dash, html, dcc, callback, Output, Input
import dash_bootstrap_components as dbc
import plotly.express as px
import plotly.graph_objects as go
from plotly.subplots import make_subplots
import pandas as pd
import numpy as np
from datetime import datetime, timedeltafrom dash import Dash, html, dcc, callback, Output, Input
import dash_bootstrap_components as dbc
import plotly.express as px
import plotly.graph_objects as go
from plotly.subplots import make_subplots
import pandas as pd
import numpy as np
from datetime import datetime, timedelta# Date filter
dbc.Row([
dbc.Col([
dbc.Card([
dbc.CardBody([
dbc.Row([
dbc.Col([
dbc.Label("Date Range"),
dcc.DatePickerRange(
id="date-filter",
start_date="2025-01-01",
end_date="2025-12-31",
display_format="YYYY-MM-DD"
)
], md=4),
dbc.Col([
dbc.Label("Region"),
dcc.Dropdown(
id="region-filter",
options=[{"label": r, "value": r} for r in df["region"].unique()],
value=df["region"].unique().tolist(),
multi=True
)
], md=4),
dbc.Col([
dbc.Label("Category"),
dcc.Dropdown(
id="category-filter",
options=[{"label": c, "value": c} for c in df["category"].unique()],
value=df["category"].unique().tolist(),
multi=True
)
], md=4)
])
])
])
])
], className="mb-4"),
# KPI Cards
dbc.Row([
dbc.Col([
dbc.Card([
dbc.CardBody([
html.H6("Total Revenue", className="text-muted"),
html.H3(id="kpi-revenue", className="text-success"),
html.Small(id="kpi-revenue-change", className="text-muted")
])
], color="light")
], md=3),
dbc.Col([
dbc.Card([
dbc.CardBody([
html.H6("Total Orders", className="text-muted"),
html.H3(id="kpi-orders", className="text-info"),
html.Small(id="kpi-orders-change", className="text-muted")
])
], color="light")
], md=3),
dbc.Col([
dbc.Card([
dbc.CardBody([
html.H6("Unique Customers", className="text-muted"),
html.H3(id="kpi-customers", className="text-warning"),
html.Small(id="kpi-customers-change", className="text-muted")
])
], color="light")
], md=3),
dbc.Col([
dbc.Card([
dbc.CardBody([
html.H6("Avg Order Value", className="text-muted"),
html.H3(id="kpi-aov", className="text-primary"),
html.Small(id="kpi-aov-change", className="text-muted")
])
], color="light")
], md=3)
], className="mb-4"),
# Charts Row 1
dbc.Row([
dbc.Col([
dbc.Card([
dbc.CardHeader("Revenue Trend"),
dbc.CardBody([
dcc.Graph(id="revenue-trend")
])
])
], md=8),
dbc.Col([
dbc.Card([
dbc.CardHeader("Revenue by Category"),
dbc.CardBody([
dcc.Graph(id="category-pie")
])
])
], md=4)
], className="mb-4"),
# Charts Row 2
dbc.Row([
dbc.Col([
dbc.Card([
dbc.CardHeader("Regional Performance"),
dbc.CardBody([
dcc.Graph(id="regional-bar")
])
])
], md=6),
dbc.Col([
dbc.Card([
dbc.CardHeader("Orders vs Customers"),
dbc.CardBody([
dcc.Graph(id="scatter-chart")
])
])
], md=6)
], className="mb-4"),
# Data Table
dbc.Row([
dbc.Col([
dbc.Card([
dbc.CardHeader("Detailed Data"),
dbc.CardBody([
html.Div(id="data-table")
])
])
])
])# 日期过滤器
dbc.Row([
dbc.Col([
dbc.Card([
dbc.CardBody([
dbc.Row([
dbc.Col([
dbc.Label("日期范围"),
dcc.DatePickerRange(
id="date-filter",
start_date="2025-01-01",
end_date="2025-12-31",
display_format="YYYY-MM-DD"
)
], md=4),
dbc.Col([
dbc.Label("区域"),
dcc.Dropdown(
id="region-filter",
options=[{"label": r, "value": r} for r in df["region"].unique()],
value=df["region"].unique().tolist(),
multi=True
)
], md=4),
dbc.Col([
dbc.Label("类别"),
dcc.Dropdown(
id="category-filter",
options=[{"label": c, "value": c} for c in df["category"].unique()],
value=df["category"].unique().tolist(),
multi=True
)
], md=4)
])
])
])
])
], className="mb-4"),
# KPI卡片
dbc.Row([
dbc.Col([
dbc.Card([
dbc.CardBody([
html.H6("总销售额", className="text-muted"),
html.H3(id="kpi-revenue", className="text-success"),
html.Small(id="kpi-revenue-change", className="text-muted")
])
], color="light")
], md=3),
dbc.Col([
dbc.Card([
dbc.CardBody([
html.H6("总订单数", className="text-muted"),
html.H3(id="kpi-orders", className="text-info"),
html.Small(id="kpi-orders-change", className="text-muted")
])
], color="light")
], md=3),
dbc.Col([
dbc.Card([
dbc.CardBody([
html.H6("独立客户数", className="text-muted"),
html.H3(id="kpi-customers", className="text-warning"),
html.Small(id="kpi-customers-change", className="text-muted")
])
], color="light")
], md=3),
dbc.Col([
dbc.Card([
dbc.CardBody([
html.H6("平均订单价值", className="text-muted"),
html.H3(id="kpi-aov", className="text-primary"),
html.Small(id="kpi-aov-change", className="text-muted")
])
], color="light")
], md=3)
], className="mb-4"),
# 图表行1
dbc.Row([
dbc.Col([
dbc.Card([
dbc.CardHeader("销售额趋势"),
dbc.CardBody([
dcc.Graph(id="revenue-trend")
])
])
], md=8),
dbc.Col([
dbc.Card([
dbc.CardHeader("按类别销售额"),
dbc.CardBody([
dcc.Graph(id="category-pie")
])
])
], md=4)
], className="mb-4"),
# 图表行2
dbc.Row([
dbc.Col([
dbc.Card([
dbc.CardHeader("区域表现"),
dbc.CardBody([
dcc.Graph(id="regional-bar")
])
])
], md=6),
dbc.Col([
dbc.Card([
dbc.CardHeader("订单数 vs 客户数"),
dbc.CardBody([
dcc.Graph(id="scatter-chart")
])
])
], md=6)
], className="mb-4"),
# 数据表格
dbc.Row([
dbc.Col([
dbc.Card([
dbc.CardHeader("详细数据"),
dbc.CardBody([
html.Div(id="data-table")
])
])
])
])# KPIs
revenue = f"${filtered['revenue'].sum():,.0f}"
orders = f"{filtered['orders'].sum():,}"
customers = f"{filtered['customers'].sum():,}"
aov = f"${filtered['revenue'].sum() / filtered['orders'].sum():.2f}" if filtered['orders'].sum() > 0 else "$0"
# Revenue trend
daily_revenue = filtered.groupby("date")["revenue"].sum().reset_index()
trend_fig = px.line(
daily_revenue,
x="date",
y="revenue",
title=None
)
trend_fig.update_layout(
margin=dict(l=0, r=0, t=0, b=0),
hovermode="x unified"
)
# Category pie
by_category = filtered.groupby("category")["revenue"].sum().reset_index()
pie_fig = px.pie(
by_category,
values="revenue",
names="category",
title=None
)
pie_fig.update_layout(margin=dict(l=0, r=0, t=0, b=0))
# Regional bar
by_region = filtered.groupby("region").agg({
"revenue": "sum",
"orders": "sum"
}).reset_index()
bar_fig = px.bar(
by_region,
x="region",
y="revenue",
color="region",
title=None
)
bar_fig.update_layout(
margin=dict(l=0, r=0, t=0, b=0),
showlegend=False
)
# Scatter
scatter_fig = px.scatter(
filtered.groupby("date").agg({"orders": "sum", "customers": "sum"}).reset_index(),
x="orders",
y="customers",
title=None,
trendline="ols"
)
scatter_fig.update_layout(margin=dict(l=0, r=0, t=0, b=0))
# Table
table = dbc.Table.from_dataframe(
filtered.groupby(["region", "category"]).agg({
"revenue": "sum",
"orders": "sum",
"customers": "sum"
}).reset_index().round(2),
striped=True,
bordered=True,
hover=True,
responsive=True
)
return revenue, orders, customers, aov, trend_fig, pie_fig, bar_fig, scatter_fig, tableundefined# KPIs
revenue = f"${filtered['revenue'].sum():,.0f}"
orders = f"{filtered['orders'].sum():,}"
customers = f"{filtered['customers'].sum():,}"
aov = f"${filtered['revenue'].sum() / filtered['orders'].sum():.2f}" if filtered['orders'].sum() > 0 else "$0"
# 销售额趋势
daily_revenue = filtered.groupby("date")["revenue"].sum().reset_index()
trend_fig = px.line(
daily_revenue,
x="date",
y="revenue",
title=None
)
trend_fig.update_layout(
margin=dict(l=0, r=0, t=0, b=0),
hovermode="x unified"
)
# 类别饼图
by_category = filtered.groupby("category")["revenue"].sum().reset_index()
pie_fig = px.pie(
by_category,
values="revenue",
names="category",
title=None
)
pie_fig.update_layout(margin=dict(l=0, r=0, t=0, b=0))
# 区域柱状图
by_region = filtered.groupby("region").agg({
"revenue": "sum",
"orders": "sum"
}).reset_index()
bar_fig = px.bar(
by_region,
x="region",
y="revenue",
color="region",
title=None
)
bar_fig.update_layout(
margin=dict(l=0, r=0, t=0, b=0),
showlegend=False
)
# 散点图
scatter_fig = px.scatter(
filtered.groupby("date").agg({"orders": "sum", "customers": "sum"}).reset_index(),
x="orders",
y="customers",
title=None,
trendline="ols"
)
scatter_fig.update_layout(margin=dict(l=0, r=0, t=0, b=0))
# 表格
table = dbc.Table.from_dataframe(
filtered.groupby(["region", "category"]).agg({
"revenue": "sum",
"orders": "sum",
"customers": "sum"
}).reset_index().round(2),
striped=True,
bordered=True,
hover=True,
responsive=True
)
return revenue, orders, customers, aov, trend_fig, pie_fig, bar_fig, scatter_fig, tableundefinedfrom dash import Dash, html, dcc, callback, Output, Input
import dash_bootstrap_components as dbc
import plotly.graph_objects as go
from collections import deque
import random
from datetime import datetime
app = Dash(__name__, external_stylesheets=[dbc.themes.CYBORG])from dash import Dash, html, dcc, callback, Output, Input
import dash_bootstrap_components as dbc
import plotly.graph_objects as go
from collections import deque
import random
from datetime import datetime
app = Dash(__name__, external_stylesheets=[dbc.themes.CYBORG])# Status indicators
dbc.Row([
dbc.Col([
dbc.Card([
dbc.CardBody([
html.H6("CPU Usage"),
html.H2(id="cpu-value", className="text-info"),
dbc.Progress(id="cpu-progress", value=0, max=100)
])
])
], md=4),
dbc.Col([
dbc.Card([
dbc.CardBody([
html.H6("Memory Usage"),
html.H2(id="memory-value", className="text-warning"),
dbc.Progress(id="memory-progress", value=0, max=100)
])
])
], md=4),
dbc.Col([
dbc.Card([
dbc.CardBody([
html.H6("Network I/O"),
html.H2(id="network-value", className="text-success"),
dbc.Progress(id="network-progress", value=0, max=100)
])
])
], md=4)
], className="mb-4"),
# Charts
dbc.Row([
dbc.Col([
dbc.Card([
dbc.CardHeader("System Metrics (Last 50 Updates)"),
dbc.CardBody([
dcc.Graph(id="live-graph", animate=True)
])
])
])
]),
# Interval component for updates
dcc.Interval(
id="interval-component",
interval=1000, # 1 second
n_intervals=0
)# Update data stores
time_data.append(datetime.now())
cpu_data.append(cpu)
memory_data.append(memory)
network_data.append(network)
# Create figure
fig = go.Figure()
fig.add_trace(go.Scatter(
x=list(time_data),
y=list(cpu_data),
name="CPU",
mode="lines",
line=dict(color="#17a2b8")
))
fig.add_trace(go.Scatter(
x=list(time_data),
y=list(memory_data),
name="Memory",
mode="lines",
line=dict(color="#ffc107")
))
fig.add_trace(go.Scatter(
x=list(time_data),
y=list(network_data),
name="Network",
mode="lines",
line=dict(color="#28a745")
))
fig.update_layout(
template="plotly_dark",
paper_bgcolor="rgba(0,0,0,0)",
plot_bgcolor="rgba(0,0,0,0)",
yaxis=dict(range=[0, 100], title="Usage %"),
xaxis=dict(title="Time"),
legend=dict(orientation="h", yanchor="bottom", y=1.02),
margin=dict(l=50, r=20, t=30, b=50),
uirevision="constant" # Preserve zoom/pan on update
)
return (
f"{cpu:.1f}%",
f"{memory:.1f}%",
f"{network:.1f}%",
cpu,
memory,
network,
fig
)undefined# 状态指示器
dbc.Row([
dbc.Col([
dbc.Card([
dbc.CardBody([
html.H6("CPU使用率"),
html.H2(id="cpu-value", className="text-info"),
dbc.Progress(id="cpu-progress", value=0, max=100)
])
])
], md=4),
dbc.Col([
dbc.Card([
dbc.CardBody([
html.H6("内存使用率"),
html.H2(id="memory-value", className="text-warning"),
dbc.Progress(id="memory-progress", value=0, max=100)
])
])
], md=4),
dbc.Col([
dbc.Card([
dbc.CardBody([
html.H6("网络I/O"),
html.H2(id="network-value", className="text-success"),
dbc.Progress(id="network-progress", value=0, max=100)
])
])
], md=4)
], className="mb-4"),
# 图表
dbc.Row([
dbc.Col([
dbc.Card([
dbc.CardHeader("系统指标(最近50次更新)"),
dbc.CardBody([
dcc.Graph(id="live-graph", animate=True)
])
])
])
]),
# 用于更新的定时器组件
dcc.Interval(
id="interval-component",
interval=1000, # 1秒
n_intervals=0
)# 更新数据存储
time_data.append(datetime.now())
cpu_data.append(cpu)
memory_data.append(memory)
network_data.append(network)
# 创建图表
fig = go.Figure()
fig.add_trace(go.Scatter(
x=list(time_data),
y=list(cpu_data),
name="CPU",
mode="lines",
line=dict(color="#17a2b8")
))
fig.add_trace(go.Scatter(
x=list(time_data),
y=list(memory_data),
name="内存",
mode="lines",
line=dict(color="#ffc107")
))
fig.add_trace(go.Scatter(
x=list(time_data),
y=list(network_data),
name="网络",
mode="lines",
line=dict(color="#28a745")
))
fig.update_layout(
template="plotly_dark",
paper_bgcolor="rgba(0,0,0,0)",
plot_bgcolor="rgba(0,0,0,0)",
yaxis=dict(range=[0, 100], title="使用率 %"),
xaxis=dict(title="时间"),
legend=dict(orientation="h", yanchor="bottom", y=1.02),
margin=dict(l=50, r=20, t=30, b=50),
uirevision="constant" # 更新时保留缩放/平移状态
)
return (
f"{cpu:.1f}%",
f"{memory:.1f}%",
f"{network:.1f}%",
cpu,
memory,
network,
fig
)undefinedfrom dash import Dash, html, callback, Output, Input
import dash_ag_grid as dag
import dash_bootstrap_components as dbc
import pandas as pd
import numpy as np
app = Dash(__name__, external_stylesheets=[dbc.themes.BOOTSTRAP])from dash import Dash, html, callback, Output, Input
import dash_ag_grid as dag
import dash_bootstrap_components as dbc
import pandas as pd
import numpy as np
app = Dash(__name__, external_stylesheets=[dbc.themes.BOOTSTRAP])dbc.Row([
dbc.Col([
dbc.Input(
id="search-input",
placeholder="Quick search...",
className="mb-3"
)
], md=4),
dbc.Col([
dbc.Button("Export CSV", id="export-btn", color="primary")
], md=2)
]),
dag.AgGrid(
id="inventory-grid",
columnDefs=column_defs,
rowData=df.to_dict("records"),
defaultColDef={
"sortable": True,
"filter": True,
"resizable": True,
"floatingFilter": True
},
dashGridOptions={
"pagination": True,
"paginationPageSize": 20,
"rowSelection": "multiple",
"animateRows": True
},
style={"height": "600px"}
),
html.Div(id="selection-output", className="mt-3")undefineddbc.Row([
dbc.Col([
dbc.Input(
id="search-input",
placeholder="快速搜索...",
className="mb-3"
)
], md=4),
dbc.Col([
dbc.Button("导出CSV", id="export-btn", color="primary")
], md=2)
]),
dag.AgGrid(
id="inventory-grid",
columnDefs=column_defs,
rowData=df.to_dict("records"),
defaultColDef={
"sortable": True,
"filter": True,
"resizable": True,
"floatingFilter": True
},
dashGridOptions={
"pagination": True,
"paginationPageSize": 20,
"rowSelection": "multiple",
"animateRows": True
},
style={"height": "600px"}
),
html.Div(id="selection-output", className="mt-3")undefinedundefinedundefined
```bash
```bashundefinedundefinedundefinedundefined
```yaml
```yamlundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedfrom dash import callback, Output, Input
from dash.exceptions import PreventUpdate
@callback(
Output("output", "children"),
Input("input", "value")
)
def safe_callback(value):
if value is None:
raise PreventUpdate
try:
result = process(value)
return result
except Exception as e:
return html.Div(f"Error: {str(e)}", className="text-danger")from dash import callback, Output, Input
from dash.exceptions import PreventUpdate
@callback(
Output("output", "children"),
Input("input", "value")
)
def safe_callback(value):
if value is None:
raise PreventUpdate
try:
result = process(value)
return result
except Exception as e:
return html.Div(f"错误: {str(e)}", className="text-danger")undefinedundefined
**Issue: Slow initial load**
```python
**问题:初始加载缓慢**
```python
**Issue: Memory leaks**
```python
**问题:内存泄漏**
```python
**Issue: Multiple callback outputs**
```python
**问题:多个回调输出**
```pythonundefinedundefined