116 lines
3.1 KiB
Python
116 lines
3.1 KiB
Python
from nicegui import ui
|
|
import pandas as pd
|
|
import numpy as np
|
|
from ex4nicegui import bi
|
|
from ex4nicegui.reactive import rxui
|
|
from ex4nicegui import effect, effect_refreshable
|
|
from pyecharts.charts import Bar
|
|
|
|
|
|
# data ready
|
|
def gen_data():
|
|
np.random.seed(265)
|
|
field1 = ["a1", "a2", "a3", "a4"]
|
|
field2 = [f"name{i}" for i in range(1, 11)]
|
|
df = (
|
|
pd.MultiIndex.from_product([field1, field2], names=["cat", "name"])
|
|
.to_frame()
|
|
.reset_index(drop=True)
|
|
)
|
|
df[["idc1", "idc2"]] = np.random.randint(50, 1000, size=(len(df), 2))
|
|
return df
|
|
|
|
|
|
df = gen_data()
|
|
|
|
# 创建数据源
|
|
ds = bi.data_source(df)
|
|
|
|
# ui
|
|
ui.query(".nicegui-content").classes("items-stretch no-wrap")
|
|
|
|
with ui.row().classes("justify-evenly"):
|
|
# 基于数据源 `ds` 创建界面组件
|
|
ds.ui_select("cat").classes("min-w-[10rem]")
|
|
ds.ui_select("name").classes("min-w-[10rem]")
|
|
|
|
|
|
with ui.grid(columns=2):
|
|
# 使用字典配置图表
|
|
@ds.ui_echarts
|
|
def bar1(data: pd.DataFrame):
|
|
data = data.groupby("name").agg({"idc1": "sum", "idc2": "sum"}).reset_index()
|
|
|
|
return {
|
|
"xAxis": {"type": "value"},
|
|
"yAxis": {
|
|
"type": "category",
|
|
"data": data["name"].tolist(),
|
|
"inverse": True,
|
|
},
|
|
"legend": {"textStyle": {"color": "gray"}},
|
|
"series": [
|
|
{"type": "bar", "name": "idc1", "data": data["idc1"].tolist()},
|
|
{"type": "bar", "name": "idc2", "data": data["idc2"].tolist()},
|
|
],
|
|
}
|
|
|
|
bar1.classes("h-[20rem]")
|
|
|
|
# 使用pyecharts配置图表
|
|
@ds.ui_echarts
|
|
def bar2(data: pd.DataFrame):
|
|
data = data.groupby("name").agg({"idc1": "sum", "idc2": "sum"}).reset_index()
|
|
|
|
return (
|
|
Bar()
|
|
.add_xaxis(data["name"].tolist())
|
|
.add_yaxis("idc1", data["idc1"].tolist())
|
|
.add_yaxis("idc2", data["idc2"].tolist())
|
|
)
|
|
|
|
bar2.classes("h-[20rem]")
|
|
|
|
# 绑定点击事件,即可实现跳转
|
|
@bar2.on_chart_click
|
|
def _(e: rxui.echarts.EChartsMouseEventArguments):
|
|
ui.open(f"/details/{e.name}", new_tab=True)
|
|
|
|
|
|
# 利用响应式机制,你可以随意组合原生 nicegui 组件
|
|
label_a1_total = ui.label("")
|
|
|
|
|
|
# 当 ds 有变化,都会触发此函数
|
|
@effect
|
|
def _():
|
|
# filtered_data 为过滤后的 DataFrame
|
|
df = ds.filtered_data
|
|
total = df[df["cat"] == "a1"]["idc1"].sum()
|
|
label_a1_total.text = f"idc1 total(cat==a1):{total}"
|
|
|
|
|
|
# 你也可以使用 `effect_refreshable`,但需要注意函数中的组件每次都被重建
|
|
@effect_refreshable
|
|
def _():
|
|
df = ds.filtered_data
|
|
total = df[df["cat"] == "a2"]["idc1"].sum()
|
|
ui.label(f"idc1 total(cat==a2):{total}")
|
|
|
|
|
|
# 当点击图表系列时,跳转的页面
|
|
@ui.page("/details/{name}")
|
|
def details_page(name: str):
|
|
ui.label("This table data will not change")
|
|
ui.aggrid.from_pandas(ds.data.query(f'name=="{name}"'))
|
|
|
|
ui.label("This table will change when the homepage data changes. ")
|
|
|
|
@bi.data_source
|
|
def new_ds():
|
|
return ds.filtered_data[["name", "idc1", "idc2"]]
|
|
|
|
new_ds.ui_aggrid()
|
|
|
|
|
|
ui.run() |