TOP

fac 相关仪表盘笔记

依赖安装

dash==2.18.2
feffery_antd_charts==0.1.5
feffery_antd_components==0.3.15
feffery_dash_utils==0.2.3
feffery_utils_components==0.2.0rc27
fpdf2
Pillow

基础模板相关演示

相关的方法, 几个默认的卡片

欢迎卡片, 背景卡片, 指标卡片, 简单图表卡片

from feffery_dash_utils.template_utils.dashboard_components import (
    welcome_card,
    blank_card,
    index_card,
    simple_chart_card
)

代码

import dash
import random
from dash import html
import feffery_antd_charts as fact
import feffery_antd_components as fac
from feffery_dash_utils.style_utils import style

from feffery_dash_utils.template_utils.dashboard_components import (
    welcome_card,
    blank_card,
    index_card,
    simple_chart_card
)

app = dash.Dash(__name__)

app.layout = html.Div(
    [
        fac.AntdRow(
            [
                # 欢迎卡片
                fac.AntdCol(
                    welcome_card(
                        title="欢迎",
                        description="今天好",
                        avatar=fac.AntdAvatar(
                            icon="antd-user", size=72, style=style(background="#4551f5"),
                        ),
                        extra=fac.AntdButton("更多", type="link")
                    ),
                    span=24,
                ),
                # 空白卡片
                fac.AntdCol(blank_card("测试数据" * 200), span=12),
                fac.AntdCol(blank_card("测试数据" * 200), span=12),
                # 指标卡片
                *([fac.AntdCol(index_card(
                    index_name="成功率", index_value="99.68%",
                    index_description="指标描述",
                    extra_content=fact.AntdTinyArea(
                        data=[random.randint(50, 100) for _ in range(20)],
                        height=60,
                        smooth=True,
                    ),
                    footer_content="同比增长200%"
                ), span=6)] * 4),
                # 简单图标卡片
                fac.AntdCol(simple_chart_card(
                    title="某某某某某",
                    description="某图的实例",
                    chart=fact.AntdColumn(
                        data=[{'date': f'2020-0{i}', 'y': random.randint(50, 100)} for i in range(1, 10)],
                        xField='date',
                        yField='y',
                        slider={},
                    ),
                    extra=fac.AntdButton("更多", type="link"),
                    height=250,
                ), span=8),

            ],
            gutter=[18, 18]
        )
    ],
    style=style(padding=50, background="#f5f5f5", minHeight="calc(100vh - 100px)")
)

if __name__ == '__main__':
    app.run(debug=True)

演示效果

 演示仪表盘效果展示

# 这是一个最基础的空白Dash应用模板,由feffery-dash-snippets自动生成

import dash
import random
from dash import html, set_props
import feffery_antd_charts as fact
from dash.dependencies import Input
import feffery_antd_components as fac
from feffery_dash_utils.style_utils import style
from feffery_dash_utils.template_utils.dashboard_components import (
    welcome_card,
    blank_card,
    index_card,
    simple_chart_card,
)

app = dash.Dash(__name__)


def layout():
    return html.Div(
        [
            # 消息提示输出目标
            fac.Fragment(id="message-target"),
            # 回到顶部
            fac.AntdBackTop(),
            # 仪表盘网格布局
            fac.AntdRow(
                [
                    # 欢迎卡片
                    fac.AntdCol(
                        welcome_card(
                            title="欢迎访问本应用,用户:张三",
                            description=fac.AntdText(
                                [
                                    "您有5个事项待处理,点击",
                                    html.A("此处", id="demo-link1"),
                                    "查看。",
                                ]
                            ),
                            avatar=fac.AntdAvatar(
                                src="/assets/demo-avatar.png",
                                mode="image",
                                size=72,
                                style=style(background="#1890ff"),
                            ),
                            extra=fac.AntdButton(
                                "更多信息", id="demo-link2", type="link"
                            ),
                        ),
                        span=24,
                    ),
                    # 指标卡片示例
                    fac.AntdCol(
                        index_card(
                            index_name="总销售额",
                            index_value="¥ 126560",
                            index_description="这是总销售额的指标描述示例内容",
                            extra_content=fac.AntdText(
                                [
                                    "周同比12%",
                                    fac.AntdIcon(
                                        icon="antd-caret-up",
                                        style=style(color="#f5222d"),
                                    ),
                                    ",日同比11%",
                                    fac.AntdIcon(
                                        icon="antd-caret-down",
                                        style=style(color="#52c41a"),
                                    ),
                                ]
                            ),
                            footer_content="日销售额 ¥12423",
                        ),
                        span=6,
                    ),
                    fac.AntdCol(
                        index_card(
                            index_name="访问量",
                            index_value=8846,
                            index_description="这是访问量的指标描述示例内容",
                            extra_content=fact.AntdTinyArea(
                                data=[random.randint(50, 100) for _ in range(20)],
                                height=60,
                                smooth=True,
                            ),
                            footer_content="日访问量 1234",
                        ),
                        span=6,
                    ),
                    fac.AntdCol(
                        index_card(
                            index_name="支付笔数",
                            index_value=6560,
                            index_description="这是支付笔数的指标描述示例内容",
                            extra_content=fact.AntdTinyColumn(
                                data=[random.randint(50, 100) for _ in range(20)],
                                height=60,
                                color="#2389ff",
                                columnWidthRatio=0.75,
                            ),
                            footer_content="转化率 60%",
                        ),
                        span=6,
                    ),
                    fac.AntdCol(
                        index_card(
                            index_name="运营活动效果",
                            index_value="78%",
                            index_description="这是运营活动效果的指标描述示例内容",
                            extra_content=fac.AntdCenter(
                                fac.AntdProgress(
                                    percent=78,
                                    status="active",
                                    strokeColor={"from": "#128ee7", "to": "#6cc085"},
                                ),
                                style=style(height="100%"),
                            ),
                            footer_content=fac.AntdText(
                                [
                                    "周同比8%",
                                    fac.AntdIcon(
                                        icon="antd-caret-up",
                                        style=style(color="#f5222d"),
                                    ),
                                    ",日同比3%",
                                    fac.AntdIcon(
                                        icon="antd-caret-down",
                                        style=style(color="#52c41a"),
                                    ),
                                ]
                            ),
                        ),
                        span=6,
                    ),
                    # 图表卡片示例
                    fac.AntdCol(
                        simple_chart_card(
                            title="销售额类别占比",
                            description="时间范围:当月",
                            chart=fact.AntdPie(
                                data=[
                                    {
                                        "type": "家用电器",
                                        "value": 4544,
                                    },
                                    {
                                        "type": "食用酒水",
                                        "value": 3321,
                                    },
                                    {
                                        "type": "个护健康",
                                        "value": 3113,
                                    },
                                    {
                                        "type": "服饰箱包",
                                        "value": 2341,
                                    },
                                    {
                                        "type": "母婴产品",
                                        "value": 1231,
                                    },
                                    {
                                        "type": "其他",
                                        "value": 1231,
                                    },
                                ],
                                colorField="type",
                                angleField="value",
                                radius=0.8,
                                innerRadius=0.6,
                                label={"type": "spider"},
                            ),
                            height=450,
                        ),
                        span=12,
                    ),
                    fac.AntdCol(
                        simple_chart_card(
                            title="流量转化情况",
                            description="时间范围:当月",
                            chart=fact.AntdColumn(
                                data=[
                                    {
                                        "action": "浏览网站",
                                        "pv": 50000,
                                    },
                                    {
                                        "action": "放入购物车",
                                        "pv": 35000,
                                    },
                                    {
                                        "action": "生成订单",
                                        "pv": 25000,
                                    },
                                    {
                                        "action": "支付订单",
                                        "pv": 15000,
                                    },
                                    {
                                        "action": "完成交易",
                                        "pv": 8500,
                                    },
                                ],
                                xField="action",
                                yField="pv",
                                conversionTag={},
                                color="#2e8fff",
                            ),
                            height=450,
                        ),
                        span=12,
                    ),
                    fac.AntdCol(
                        simple_chart_card(
                            title="流量转化具体链路",
                            description="时间范围:当月",
                            chart=fact.AntdSankey(
                                data=[
                                    {
                                        "source": "首次打开",
                                        "target": "首页 UV",
                                        "value": 160,
                                    },
                                    {
                                        "source": "结果页",
                                        "target": "首页 UV",
                                        "value": 40,
                                    },
                                    {
                                        "source": "验证页",
                                        "target": "首页 UV",
                                        "value": 10,
                                    },
                                    {
                                        "source": "我的",
                                        "target": "首页 UV",
                                        "value": 10,
                                    },
                                    {"source": "朋友", "target": "首页 UV", "value": 8},
                                    {
                                        "source": "其他来源",
                                        "target": "首页 UV",
                                        "value": 27,
                                    },
                                    {
                                        "source": "首页 UV",
                                        "target": "理财",
                                        "value": 30,
                                    },
                                    {
                                        "source": "首页 UV",
                                        "target": "扫一扫",
                                        "value": 40,
                                    },
                                    {
                                        "source": "首页 UV",
                                        "target": "服务",
                                        "value": 35,
                                    },
                                    {
                                        "source": "首页 UV",
                                        "target": "蚂蚁森林",
                                        "value": 25,
                                    },
                                    {
                                        "source": "首页 UV",
                                        "target": "跳失",
                                        "value": 10,
                                    },
                                    {
                                        "source": "首页 UV",
                                        "target": "借呗",
                                        "value": 30,
                                    },
                                    {
                                        "source": "首页 UV",
                                        "target": "花呗",
                                        "value": 40,
                                    },
                                    {
                                        "source": "首页 UV",
                                        "target": "其他流向",
                                        "value": 45,
                                    },
                                ],
                                sourceField="source",
                                targetField="target",
                                weightField="value",
                                nodeWidthRatio=0.008,
                                nodePaddingRatio=0.03,
                                nodeDraggable=True,
                            ),
                            height=375,
                        ),
                        span=24,
                    ),
                    fac.AntdCol(
                        simple_chart_card(
                            title="内容运营情况",
                            description="时间范围:近10天",
                            chart=fact.AntdArea(
                                data=[
                                    {
                                        "date": date,
                                        "type": type,
                                        "value": random.randint(50, 1000),
                                    }
                                    for date in [
                                        "03-01",
                                        "03-02",
                                        "03-03",
                                        "03-04",
                                        "03-05",
                                        "03-06",
                                        "03-07",
                                        "03-08",
                                        "03-09",
                                        "03-10",
                                    ]
                                    for type in [
                                        "内容生产量",
                                        "内容点击量",
                                        "内容曝光量",
                                        "活跃用户数",
                                    ]
                                ],
                                xField="date",
                                yField="value",
                                seriesField="type",
                                smooth=True,
                                isStack=True,
                                legend={"position": "top"},
                            ),
                            height=500,
                        ),
                        span=16,
                    ),
                    fac.AntdCol(
                        simple_chart_card(
                            title="近期热门内容",
                            description="时间范围:近10天",
                            chart=fac.AntdTable(
                                columns=[
                                    {
                                        "title": "标题",
                                        "dataIndex": "title",
                                        "key": "title",
                                    },
                                    {
                                        "title": "点击量",
                                        "dataIndex": "click",
                                        "key": "click",
                                    },
                                    {
                                        "title": "内容链接",
                                        "dataIndex": "link",
                                        "key": "link",
                                        "renderOptions": {
                                            "renderType": "link",
                                        },
                                    },
                                ],
                                data=[
                                    {
                                        "title": "示例内容标题xxx",
                                        "click": random.randint(100, 10000),
                                        "link": {
                                            "content": "点击访问",
                                            "href": "https://fact.feffery.tech/",
                                        },
                                    }
                                    for i in range(18)
                                ],
                                size="small",
                                pagination=False,
                                tableLayout="fixed",
                                maxHeight=325,
                                bordered=True,
                            ),
                            height=500,
                        ),
                        span=8,
                    ),
                    # 空白卡片示例
                    fac.AntdCol(
                        blank_card(
                            fac.AntdCenter(
                                fac.AntdText(
                                    [
                                        fac.AntdText("玩转Dash", italic=True),
                                        "知识星球出品",
                                    ]
                                )
                            )
                        ),
                        span=24,
                    ),
                ],
                gutter=[18, 18],
            ),
        ],
        style=style(
            padding=50, background="#f5f5f5", minHeight="100vh", boxSizing="border-box"
        ),
    )


app.layout = layout


@app.callback([Input("demo-link1", "n_clicks"), Input("demo-link2", "nClicks")])
def link_click_demo(*args):
    """链接点击交互演示"""

    set_props(
        "message-target",
        {
            "children": fac.AntdMessage(
                content="你点击了链接 " + dash.ctx.triggered_id, type="info"
            )
        },
    )


if __name__ == "__main__":
    app.run(debug=False)

演示效果

所有的图可进行交互, 单选多选反选等

仪表盘数据交互式切换案例

import time
import random
import dash
from dash import html
from typing import Literal
import feffery_antd_charts as fact
import feffery_antd_components as fac
from dash.dependencies import Input, Output
from feffery_dash_utils.style_utils import style
from feffery_dash_utils.template_utils.dashboard_components import blank_card, simple_chart_card


def sales_data(series: Literal["全部渠道", "线上", "门店"]):
    """模拟销售额示例数据切换"""
    if series == "全部渠道":
        return [
            {"type": "家用电器", "value": random.randint(1, 1000)},
            {"type": "食用酒水", "value": random.randint(1, 1000)},
            {"type": "个护健康", "value": random.randint(1, 1000)},
            {"type": "服饰箱包", "value": random.randint(1, 1000)},
            {"type": "母婴产品", "value": random.randint(1, 1000)},
            {"type": "其他", "value": random.randint(1, 1000)},
        ]

    elif series == "线上":
        return [
            {"type": "家用电器", "value": random.randint(1, 200)},
            {"type": "食用酒水", "value": random.randint(1, 200)},
            {"type": "个护健康", "value": random.randint(1, 200)},
            {"type": "服饰箱包", "value": random.randint(1, 200)},
            {"type": "母婴产品", "value": random.randint(1, 200)},
            {"type": "其他", "value": random.randint(1, 200)},
        ]

    elif series == "门店":
        return [
            {"type": "家用电器", "value": random.randint(300, 800)},
            {"type": "食用酒水", "value": random.randint(300, 800)},
            {"type": "个护健康", "value": random.randint(300, 800)},
            {"type": "服饰箱包", "value": random.randint(300, 800)},
            {"type": "母婴产品", "value": random.randint(300, 800)},
            {"type": "其他", "value": random.randint(300, 800)},
        ]


def flow_conversion_data(series: Literal["当月", "上月"]):
    """模拟流量转化示例数据切换"""
    if series == "当月":
        return [
            {"action": "浏览网站", "pv": random.randint(100, 300)},
            {"action": "放入购物车", "pv": random.randint(100, 300)},
            {"action": "生成订单", "pv": random.randint(100, 300)},
            {"action": "支付订单", "pv": random.randint(100, 300)},
            {"action": "完成交易", "pv": random.randint(100, 300)},
        ]

    elif series == "上月":
        return [
            {"action": "浏览网站", "pv": random.randint(300, 800)},
            {"action": "放入购物车", "pv": random.randint(300, 800)},
            {"action": "生成订单", "pv": random.randint(300, 800)},
            {"action": "支付订单", "pv": random.randint(300, 800)},
            {"action": "完成交易", "pv": random.randint(300, 800)},
        ]


def content_operation_data():
    """模拟生成内容运营示例数据"""
    return [
        {"date": date, "type": _type, "value": random.randint(50, 1000)}
        for date in ["03-01", "03-02", "03-03", "03-04", "03-05", "03-06", "03-07", "03-08", "03-09", "03-10"]
        for _type in ["内容生产量", "内容点击量", "内容曝光量", "活跃用户数"]
    ]


def hot_content_data():
    """模拟生成热门内容示例数据"""
    return [{
        "title": "示例内容标题xxx",
        "click": random.randint(100, 10000),
        "link": {"content": "点击访问", "href": "https://fact.feffery.tech/"},
    } for _ in range(random.randint(15, 25))]


app = dash.Dash(__name__, suppress_callback_exceptions=True)


def layout():
    return html.Div(
        [
            # 仪表盘网格布局
            fac.AntdRow(
                [
                    # 图表卡片示例
                    fac.AntdCol(
                        simple_chart_card(
                            title="销售额类别占比",
                            description="时间范围:当月",
                            chart=fact.AntdPie(
                                id="sales-pie-chart",
                                data=sales_data(series="全部渠道"),
                                colorField="type",
                                angleField="value",
                                radius=0.8,
                                innerRadius=0.6,
                                label={"type": "spider"},
                            ),
                            extra=fac.AntdRadioGroup(
                                id="update-sales-pie-chart-data",
                                options=["全部渠道", "线上", "门店"],
                                optionType="button",
                                value="全部渠道",
                            ),
                            height=450,
                        ),
                        span=12,
                    ),
                    fac.AntdCol(
                        simple_chart_card(
                            title="流量转化情况",
                            description=fac.AntdSpace(
                                [
                                    "时间范围:",
                                    fac.AntdSelect(
                                        id="update-flow-conversion-column-chart-data",
                                        options=["当月", "上月"],
                                        value="当月",
                                        allowClear=False,
                                        size="small",
                                        variant="filled",
                                    ),
                                ],
                                size=0,
                            ),
                            chart=fact.AntdColumn(
                                id="flow-conversion-column-chart",
                                data=flow_conversion_data(series="当月"),
                                xField="action",
                                yField="pv",
                                conversionTag={},
                                color="#2e8fff",
                            ),
                            height=450,
                        ),
                        span=12,
                    ),
                    fac.AntdCol(
                        simple_chart_card(
                            title="内容运营情况",
                            description="时间范围:近10天",
                            chart=fac.AntdTabs(
                                id="content-operation-tabs",
                                items=[
                                    {
                                        "label": series,
                                        "key": series,
                                        "children": fact.AntdArea(
                                            data=content_operation_data(),
                                            xField="date",
                                            yField="value",
                                            seriesField="type",
                                            smooth=True,
                                            isStack=True,
                                            legend={"position": "top"},
                                        ),
                                    }
                                    for series in ["抖音", "小红书", "快手"]
                                ],
                                tabPosition="left",
                                size="small",
                                destroyInactiveTabPane=True,
                            ),
                            height=500,
                        ),
                        span=16,
                    ),
                    fac.AntdCol(
                        simple_chart_card(
                            title="近期热门内容",
                            description="时间范围:近10天",
                            chart=fac.AntdTable(
                                id="hot-content-table",
                                columns=[
                                    {
                                        "title": "标题",
                                        "dataIndex": "title",
                                        "key": "title",
                                    },
                                    {
                                        "title": "点击量",
                                        "dataIndex": "click",
                                        "key": "click",
                                    },
                                    {
                                        "title": "内容链接",
                                        "dataIndex": "link",
                                        "key": "link",
                                        "renderOptions": {
                                            "renderType": "link",
                                        },
                                    },
                                ],
                                data=hot_content_data(),
                                size="small",
                                pagination=False,
                                tableLayout="fixed",
                                maxHeight=325,
                                bordered=True,
                            ),
                            extra=fac.AntdSegmented(
                                id="update-hot-content-table-data",
                                options=[
                                    {"label": series, "value": series}
                                    for series in ["抖音", "小红书", "快手"]
                                ],
                                value="抖音",
                            ),
                            height=500,
                        ),
                        span=8,
                    ),
                    # 空白卡片示例
                    fac.AntdCol(
                        blank_card(
                            fac.AntdCenter(
                                fac.AntdText(
                                    [
                                        fac.AntdText("玩转Dash", italic=True),
                                        "知识星球出品",
                                    ]
                                )
                            )
                        ),
                        span=24,
                    ),
                ],
                gutter=[18, 18],
            ),
        ],
        style=style(
            padding=50, background="#f5f5f5", minHeight="100vh", boxSizing="border-box"
        ),
    )


app.layout = layout


@app.callback(
    Output("sales-pie-chart", "data"),
    Input("update-sales-pie-chart-data", "value"),
    prevent_initial_call=True)
def update_sales_pie_chart_data(series):
    """控制示例销售额饼图的数据系列切换"""
    return sales_data(series=series)


@app.callback(
    Output("flow-conversion-column-chart", "data"),
    Input("update-flow-conversion-column-chart-data", "value"),
    prevent_initial_call=True)
def update_flow_conversion_column_chart_data(series):
    """控制示例流量转化柱状图的数据系列切换"""
    return flow_conversion_data(series=series)


@app.callback(
    Output("hot-content-table", "data"),
    Input("update-hot-content-table-data", "value"),
    running=[[Output("hot-content-table", "loading"), True, False]],
    prevent_initial_call=True)
def update_hot_content_table_data(series):
    """控制示例热门内容表格的数据系列切换"""
    time.sleep(0.5)  # 模拟计算耗时
    return hot_content_data()


# 联动更新, 利用上下文去识别当前被激活的选项, 然后对其他需要联动更新的一并进行更新
@app.callback([Output("content-operation-tabs", "activeKey"), Output("update-hot-content-table-data", "value")],
              [Input("content-operation-tabs", "activeKey"), Input("update-hot-content-table-data", "value")],
              prevent_initial_call=True, )
def sync_content_series(active_key, value):
    """控制示例内容运营与热门内容之间的系列同步切换"""
    if dash.ctx.triggered_id == "content-operation-tabs":
        return dash.no_update, active_key
    return value, dash.no_update


if __name__ == "__main__":
    app.run(debug=True)

演示效果

 带导出功能的仪表盘案例

import io
import dash
import random
import pandas as pd  # 注意excel表格导出额外需安装隐式依赖openpyxl
import feffery_antd_charts as fact
from dash import html, set_props, dcc
import feffery_antd_components as fac
from dash.dependencies import Input, State
from feffery_dash_utils.style_utils import style
from feffery_dash_utils.template_utils.dashboard_components import (
    welcome_card,
    blank_card,
    index_card,
    simple_chart_card,
)

app = dash.Dash(__name__, suppress_callback_exceptions=True)


def layout():
    return html.Div(
        [
            # 全局统一下载
            dcc.Download(id="global-download"),
            # 消息提示输出目标
            fac.Fragment(id="message-target"),
            # 回到顶部
            fac.AntdBackTop(),
            # 批量下载按钮
            fac.AntdFloatButton(
                id="batch-export-data",
                shape="square",
                icon=fac.AntdIcon(icon="antd-download"),
                tooltip="批量下载数据",
                style=style(bottom="calc(100vh - 120px)", right=5),
            ),
            # 仪表盘网格布局
            fac.AntdRow(
                [
                    # 欢迎卡片
                    fac.AntdCol(
                        welcome_card(
                            title="欢迎访问本应用,用户:张三",
                            description=fac.AntdText(
                                [
                                    "您有5个事项待处理,点击",
                                    html.A("此处", id="demo-link1"),
                                    "查看。",
                                ]
                            ),
                            avatar=fac.AntdAvatar(
                                src="/assets/demo-avatar.png",
                                mode="image",
                                size=72,
                                style=style(background="#1890ff"),
                            ),
                            extra=fac.AntdButton(
                                "更多信息", id="demo-link2", type="link"
                            ),
                        ),
                        span=24,
                    ),
                    # 指标卡片示例
                    fac.AntdCol(
                        index_card(
                            index_name="总销售额",
                            index_value="¥ 126560",
                            index_description="这是总销售额的指标描述示例内容",
                            extra_content=fac.AntdText(
                                [
                                    "周同比12%",
                                    fac.AntdIcon(icon="antd-caret-up", style=style(color="#f5222d")),
                                    ",日同比11%",
                                    fac.AntdIcon(icon="antd-caret-down", style=style(color="#52c41a")),
                                ]
                            ),
                            footer_content="日销售额 ¥12423",
                        ),
                        span=6,
                    ),
                    fac.AntdCol(
                        index_card(
                            index_name="访问量",
                            index_value=8846,
                            index_description="这是访问量的指标描述示例内容",
                            extra_content=fact.AntdTinyArea(
                                data=[random.randint(50, 100) for _ in range(20)],
                                height=60,
                                smooth=True,
                            ),
                            footer_content="日访问量 1234",
                        ),
                        span=6,
                    ),
                    fac.AntdCol(
                        index_card(
                            index_name="支付笔数",
                            index_value=6560,
                            index_description="这是支付笔数的指标描述示例内容",
                            extra_content=fact.AntdTinyColumn(
                                data=[random.randint(50, 100) for _ in range(20)],
                                height=60,
                                color="#2389ff",
                                columnWidthRatio=0.75,
                            ),
                            footer_content="转化率 60%",
                        ),
                        span=6,
                    ),
                    fac.AntdCol(
                        index_card(
                            index_name="运营活动效果",
                            index_value="78%",
                            index_description="这是运营活动效果的指标描述示例内容",
                            extra_content=fac.AntdCenter(
                                fac.AntdProgress(
                                    percent=78,
                                    status="active",
                                    strokeColor={"from": "#128ee7", "to": "#6cc085"},
                                ),
                                style=style(height="100%"),
                            ),
                            footer_content=fac.AntdText(
                                [
                                    "周同比8%",
                                    fac.AntdIcon(icon="antd-caret-up", style=style(color="#f5222d")),
                                    ",日同比3%",
                                    fac.AntdIcon(icon="antd-caret-down", style=style(color="#52c41a")),
                                ]
                            ),
                        ),
                        span=6,
                    ),
                    # 图表卡片示例
                    fac.AntdCol(
                        simple_chart_card(
                            title="销售额类别占比",
                            description="时间范围:当月",
                            chart=fact.AntdPie(
                                id="sales-chart",
                                data=[
                                    {"type": "家用电器", "value": 4544},
                                    {"type": "食用酒水", "value": 3321},
                                    {"type": "个护健康", "value": 3113},
                                    {"type": "服饰箱包", "value": 2341},
                                    {"type": "母婴产品", "value": 1231},
                                    {"type": "其他", "value": 1214}

                                ],
                                colorField="type",
                                angleField="value",
                                radius=0.8,
                                innerRadius=0.6,
                                label={"type": "spider"},
                            ),
                            extra=fac.AntdTooltip(
                                fac.AntdButton(
                                    id="export-sales-data",
                                    icon=fac.AntdIcon(icon="antd-download"),
                                    type="text",
                                ),
                                title="导出数据",
                            ),
                            height=450,
                        ),
                        span=12,
                    ),
                    fac.AntdCol(
                        simple_chart_card(
                            title="流量转化情况",
                            description="时间范围:当月",
                            chart=fact.AntdColumn(
                                id="flow-conversion-chart",
                                data=[
                                    {"action": "浏览网站", "pv": 50000},
                                    {"action": "放入购物车", "pv": 35000},
                                    {"action": "生成订单", "pv": 25000},
                                    {"action": "支付订单", "pv": 15000},
                                    {"action": "完成交易", "pv": 8500},
                                ],
                                xField="action",
                                yField="pv",
                                conversionTag={},
                                color="#2e8fff",
                            ),
                            extra=fac.AntdTooltip(
                                fac.AntdButton(
                                    id="export-flow-conversion-data",
                                    icon=fac.AntdIcon(icon="antd-download"),
                                    type="text",
                                ),
                                title="导出数据",
                            ),
                            height=450,
                        ),
                        span=12,
                    ),
                    fac.AntdCol(
                        simple_chart_card(
                            title="流量转化具体链路",
                            description="时间范围:当月",
                            chart=fact.AntdSankey(
                                data=[
                                    {"source": "首次打开", "target": "首页 UV", "value": 160},
                                    {"source": "结果页", "target": "首页 UV", "value": 40},
                                    {"source": "验证页", "target": "首页 UV", "value": 10},
                                    {"source": "我的", "target": "首页 UV", "value": 10},
                                    {"source": "朋友", "target": "首页 UV", "value": 8},
                                    {"source": "其他来源", "target": "首页 UV", "value": 27},
                                    {"source": "首页 UV", "target": "理财", "value": 30},
                                    {"source": "首页 UV", "target": "扫一扫", "value": 40},
                                    {"source": "首页 UV", "target": "服务", "value": 35},
                                    {"source": "首页 UV", "target": "蚂蚁森林", "value": 25},
                                    {"source": "首页 UV", "target": "跳失", "value": 10, },
                                    {"source": "首页 UV", "target": "借呗", "value": 30},
                                    {"source": "首页 UV", "target": "花呗", "value": 40},
                                    {"source": "首页 UV", "target": "其他流向", "value": 45},
                                ],
                                sourceField="source",
                                targetField="target",
                                weightField="value",
                                nodeWidthRatio=0.008,
                                nodePaddingRatio=0.03,
                                nodeDraggable=True,
                            ),
                            height=375,
                        ),
                        span=24,
                    ),
                    fac.AntdCol(
                        simple_chart_card(
                            title="内容运营情况",
                            description="时间范围:近10天",
                            chart=fact.AntdArea(
                                data=[
                                    {"date": date, "type": _type, "value": random.randint(50, 1000)}
                                    for date in [
                                        "03-01", "03-02", "03-03", "03-04", "03-05",
                                        "03-06", "03-07", "03-08", "03-09", "03-10",
                                    ]
                                    for _type in ["内容生产量", "内容点击量", "内容曝光量", "活跃用户数"]
                                ],
                                xField="date",
                                yField="value",
                                seriesField="type",
                                smooth=True,
                                isStack=True,
                                legend={"position": "top"},
                            ),
                            height=500,
                        ),
                        span=16,
                    ),
                    fac.AntdCol(
                        simple_chart_card(
                            title="近期热门内容",
                            description="时间范围:近10天",
                            chart=fac.AntdTable(
                                columns=[
                                    {"title": "标题", "dataIndex": "title", "key": "title"},
                                    {"title": "点击量", "dataIndex": "click", "key": "click"},
                                    {"title": "内容链接", "dataIndex": "link", "key": "link",
                                     "renderOptions": {"renderType": "link"}},
                                ],
                                data=[
                                    {"title": "示例内容标题xxx", "click": random.randint(100, 10000),
                                     "link": {"content": "点击访问", "href": "https://fact.feffery.tech/"}}
                                    for _ in range(18)
                                ],
                                size="small",
                                pagination=False,
                                tableLayout="fixed",
                                maxHeight=325,
                                bordered=True,
                            ),
                            height=500,
                        ),
                        span=8,
                    ),
                    # 空白卡片示例
                    fac.AntdCol(
                        blank_card(
                            fac.AntdCenter(
                                fac.AntdText([fac.AntdText("玩转Dash", italic=True), "知识星球出品"])
                            )
                        ),
                        span=24,
                    ),
                ],
                gutter=[18, 18],
            ),
        ],
        style=style(
            padding=50, background="#f5f5f5", minHeight="100vh", boxSizing="border-box"
        ),
    )


app.layout = layout


@app.callback([Input("demo-link1", "n_clicks"), Input("demo-link2", "nClicks")])
def link_click_demo(*args):
    """链接点击交互演示"""
    set_props(
        "message-target", {"children": fac.AntdMessage(content="你点击了链接 " + dash.ctx.triggered_id, type="info")},
    )


@app.callback(Input("export-sales-data", "nClicks"), State("sales-chart", "data"))
def export_sales_data(n_clicks, data):
    temp_io = io.BytesIO()
    pd.DataFrame(data).to_excel(temp_io, index=False)
    set_props("global-download", {"data": dcc.send_bytes(temp_io.getvalue(), "销售额类别占比数据导出.xlsx")})


@app.callback(
    Input("export-flow-conversion-data", "nClicks"),
    State("flow-conversion-chart", "data"),
)
def export_flow_conversion_data(n_clicks, data):
    temp_io = io.BytesIO()
    pd.DataFrame(data).to_excel(temp_io, index=False)
    set_props("global-download", {"data": dcc.send_bytes(temp_io.getvalue(), "流量转化数据导出.xlsx")})


@app.callback(
    Input("batch-export-data", "nClicks"),
    [State("sales-chart", "data"), State("flow-conversion-chart", "data")])
def batch_export_data(n_clicks, sales_data, flow_conversion_data):
    """控制批量数据导出"""

    temp_io = io.BytesIO()
    writer = pd.ExcelWriter(temp_io)
    # 分别写入不同的工作表
    pd.DataFrame(sales_data).to_excel(writer, sheet_name="销售额类别占比数据", index=False)
    pd.DataFrame(flow_conversion_data).to_excel(writer, sheet_name="流量转化数据", index=False)
    # 关闭文件
    writer.close()
    set_props("global-download", {"data": dcc.send_bytes(temp_io.getvalue(), "批量数据导出结果.xlsx")})


if __name__ == "__main__":
    app.run(debug=True)

演示效果

批量下载则可以将所有的图标数据写在分别写入多个 sheet 中, 然后在一个表格中导出

 带全屏功能展示功能仪表盘案例

import json
import dash
import random
from dash import html, set_props
import feffery_antd_charts as fact
import feffery_antd_components as fac
import feffery_utils_components as fuc
from feffery_dash_utils.style_utils import style
from dash.dependencies import Input, Output, State, MATCH
from feffery_dash_utils.template_utils.dashboard_components import (
    welcome_card,
    blank_card,
    index_card,
    simple_chart_card,
)

app = dash.Dash(__name__)


def layout():
    return html.Div(
        [
            # 消息提示输出目标
            fac.Fragment(id="message-target"),
            # 全局图表全屏化目标控制
            fuc.FefferyFullscreen(id="fullscreen-target"),
            # 仪表盘网格布局
            fac.AntdRow(
                [
                    # 欢迎卡片
                    fac.AntdCol(
                        welcome_card(
                            title="欢迎访问本应用,用户:张三",
                            description=fac.AntdText(
                                [
                                    "您有5个事项待处理,点击",
                                    html.A("此处", id="demo-link1"),
                                    "查看。",
                                ]
                            ),
                            avatar=fac.AntdAvatar(
                                src="/assets/demo-avatar.png",
                                mode="image",
                                size=72,
                                style=style(background="#1890ff"),
                            ),
                            extra=fac.AntdButton(
                                "更多信息", id="demo-link2", type="link"
                            ),
                        ),
                        span=24,
                    ),
                    # 指标卡片示例
                    fac.AntdCol(
                        index_card(
                            index_name="总销售额",
                            index_value="¥ 126560",
                            index_description="这是总销售额的指标描述示例内容",
                            extra_content=fac.AntdText(
                                [
                                    "周同比12%",
                                    fac.AntdIcon(
                                        icon="antd-caret-up",
                                        style=style(color="#f5222d"),
                                    ),
                                    ",日同比11%",
                                    fac.AntdIcon(
                                        icon="antd-caret-down",
                                        style=style(color="#52c41a"),
                                    ),
                                ]
                            ),
                            footer_content="日销售额 ¥12423",
                        ),
                        span=6,
                    ),
                    fac.AntdCol(
                        index_card(
                            index_name="访问量",
                            index_value=8846,
                            index_description="这是访问量的指标描述示例内容",
                            extra_content=fact.AntdTinyArea(
                                data=[random.randint(50, 100) for _ in range(20)],
                                height=60,
                                smooth=True,
                            ),
                            footer_content="日访问量 1234",
                        ),
                        span=6,
                    ),
                    fac.AntdCol(
                        index_card(
                            index_name="支付笔数",
                            index_value=6560,
                            index_description="这是支付笔数的指标描述示例内容",
                            extra_content=fact.AntdTinyColumn(
                                data=[random.randint(50, 100) for _ in range(20)],
                                height=60,
                                color="#2389ff",
                                columnWidthRatio=0.75,
                            ),
                            footer_content="转化率 60%",
                        ),
                        span=6,
                    ),
                    fac.AntdCol(
                        index_card(
                            index_name="运营活动效果",
                            index_value="78%",
                            index_description="这是运营活动效果的指标描述示例内容",
                            extra_content=fac.AntdCenter(
                                fac.AntdProgress(
                                    percent=78,
                                    status="active",
                                    strokeColor={"from": "#128ee7", "to": "#6cc085"},
                                ),
                                style=style(height="100%"),
                            ),
                            footer_content=fac.AntdText(
                                [
                                    "周同比8%",
                                    fac.AntdIcon(
                                        icon="antd-caret-up",
                                        style=style(color="#f5222d"),
                                    ),
                                    ",日同比3%",
                                    fac.AntdIcon(
                                        icon="antd-caret-down",
                                        style=style(color="#52c41a"),
                                    ),
                                ]
                            ),
                        ),
                        span=6,
                    ),
                    # 图表卡片示例
                    fac.AntdCol(
                        simple_chart_card(
                            root_id={"type": "chart-card", "index": "chart-a"},
                            title="销售额类别占比",
                            description="时间范围:当月",
                            chart=fact.AntdPie(
                                data=[
                                    {
                                        "type": "家用电器",
                                        "value": 4544,
                                    },
                                    {
                                        "type": "食用酒水",
                                        "value": 3321,
                                    },
                                    {
                                        "type": "个护健康",
                                        "value": 3113,
                                    },
                                    {
                                        "type": "服饰箱包",
                                        "value": 2341,
                                    },
                                    {
                                        "type": "母婴产品",
                                        "value": 1231,
                                    },
                                    {
                                        "type": "其他",
                                        "value": 1231,
                                    },
                                ],
                                colorField="type",
                                angleField="value",
                                radius=0.8,
                                innerRadius=0.6,
                                label={"type": "spider"},
                            ),
                            extra=fac.AntdButton(
                                id={"type": "chart-card-toggle-fullscreen", "index": "chart-a"},
                                icon=fac.AntdIcon(
                                    id={"type": "chart-card-toggle-fullscreen-icon", "index": "chart-a"},
                                    icon="antd-full-screen",
                                ),
                                type="text",
                                size="large",
                            ),
                            height=450,
                        ),
                        span=12,
                    ),
                    fac.AntdCol(
                        simple_chart_card(
                            root_id={"type": "chart-card", "index": "chart-b"},
                            title="流量转化情况",
                            description="时间范围:当月",
                            chart=fact.AntdColumn(
                                data=[
                                    {
                                        "action": "浏览网站",
                                        "pv": 50000,
                                    },
                                    {
                                        "action": "放入购物车",
                                        "pv": 35000,
                                    },
                                    {
                                        "action": "生成订单",
                                        "pv": 25000,
                                    },
                                    {
                                        "action": "支付订单",
                                        "pv": 15000,
                                    },
                                    {
                                        "action": "完成交易",
                                        "pv": 8500,
                                    },
                                ],
                                xField="action",
                                yField="pv",
                                conversionTag={},
                                color="#2e8fff",
                                autoFit=True,
                            ),
                            extra=fac.AntdButton(
                                id={"type": "chart-card-toggle-fullscreen", "index": "chart-b"},
                                icon=fac.AntdIcon(
                                    id={"type": "chart-card-toggle-fullscreen-icon", "index": "chart-b"},
                                    icon="antd-full-screen",
                                ),
                                type="text",
                                size="large",
                            ),
                            height=450,
                        ),
                        span=12,
                    ),
                    fac.AntdCol(
                        simple_chart_card(
                            root_id={"type": "chart-card", "index": "chart-c"},
                            title="流量转化具体链路",
                            description="时间范围:当月",
                            chart=fact.AntdSankey(
                                data=[
                                    {
                                        "source": "首次打开",
                                        "target": "首页 UV",
                                        "value": 160,
                                    },
                                    {
                                        "source": "结果页",
                                        "target": "首页 UV",
                                        "value": 40,
                                    },
                                    {
                                        "source": "验证页",
                                        "target": "首页 UV",
                                        "value": 10,
                                    },
                                    {
                                        "source": "我的",
                                        "target": "首页 UV",
                                        "value": 10,
                                    },
                                    {"source": "朋友", "target": "首页 UV", "value": 8},
                                    {
                                        "source": "其他来源",
                                        "target": "首页 UV",
                                        "value": 27,
                                    },
                                    {
                                        "source": "首页 UV",
                                        "target": "理财",
                                        "value": 30,
                                    },
                                    {
                                        "source": "首页 UV",
                                        "target": "扫一扫",
                                        "value": 40,
                                    },
                                    {
                                        "source": "首页 UV",
                                        "target": "服务",
                                        "value": 35,
                                    },
                                    {
                                        "source": "首页 UV",
                                        "target": "蚂蚁森林",
                                        "value": 25,
                                    },
                                    {
                                        "source": "首页 UV",
                                        "target": "跳失",
                                        "value": 10,
                                    },
                                    {
                                        "source": "首页 UV",
                                        "target": "借呗",
                                        "value": 30,
                                    },
                                    {
                                        "source": "首页 UV",
                                        "target": "花呗",
                                        "value": 40,
                                    },
                                    {
                                        "source": "首页 UV",
                                        "target": "其他流向",
                                        "value": 45,
                                    },
                                ],
                                sourceField="source",
                                targetField="target",
                                weightField="value",
                                nodeWidthRatio=0.008,
                                nodePaddingRatio=0.03,
                                nodeDraggable=True,
                            ),
                            extra=fac.AntdButton(
                                id={"type": "chart-card-toggle-fullscreen", "index": "chart-c"},
                                icon=fac.AntdIcon(
                                    id={"type": "chart-card-toggle-fullscreen-icon", "index": "chart-c"},
                                    icon="antd-full-screen",
                                ),
                                type="text",
                                size="large",
                            ),
                            height=375,
                        ),
                        span=24,
                    ),
                    fac.AntdCol(
                        simple_chart_card(
                            root_id={"type": "chart-card", "index": "chart-d"},
                            title="内容运营情况",
                            description="时间范围:近10天",
                            chart=fact.AntdArea(
                                data=[
                                    {
                                        "date": date,
                                        "type": type,
                                        "value": random.randint(50, 1000),
                                    }
                                    for date in [
                                        "03-01",
                                        "03-02",
                                        "03-03",
                                        "03-04",
                                        "03-05",
                                        "03-06",
                                        "03-07",
                                        "03-08",
                                        "03-09",
                                        "03-10",
                                    ]
                                    for type in [
                                        "内容生产量",
                                        "内容点击量",
                                        "内容曝光量",
                                        "活跃用户数",
                                    ]
                                ],
                                xField="date",
                                yField="value",
                                seriesField="type",
                                smooth=True,
                                isStack=True,
                                legend={"position": "top"},
                            ),
                            extra=fac.AntdButton(
                                id={"type": "chart-card-toggle-fullscreen", "index": "chart-d"},
                                icon=fac.AntdIcon(
                                    id={"type": "chart-card-toggle-fullscreen-icon", "index": "chart-d"},
                                    icon="antd-full-screen",
                                ),
                                type="text",
                                size="large",
                            ),
                            height=500,
                        ),
                        span=16,
                    ),
                    fac.AntdCol(
                        simple_chart_card(
                            root_id={"type": "chart-card", "index": "chart-e"},
                            title="近期热门内容",
                            description="时间范围:近10天",
                            chart=fac.AntdTable(
                                columns=[
                                    {
                                        "title": "标题",
                                        "dataIndex": "title",
                                        "key": "title",
                                    },
                                    {
                                        "title": "点击量",
                                        "dataIndex": "click",
                                        "key": "click",
                                    },
                                    {
                                        "title": "内容链接",
                                        "dataIndex": "link",
                                        "key": "link",
                                        "renderOptions": {
                                            "renderType": "link",
                                        },
                                    },
                                ],
                                data=[
                                    {
                                        "title": "示例内容标题xxx",
                                        "click": random.randint(100, 10000),
                                        "link": {
                                            "content": "点击访问",
                                            "href": "https://fact.feffery.tech/",
                                        },
                                    }
                                    for i in range(18)
                                ],
                                size="small",
                                pagination=False,
                                tableLayout="fixed",
                                maxHeight=325,
                                bordered=True,
                            ),
                            extra=fac.AntdButton(
                                id={"type": "chart-card-toggle-fullscreen", "index": "chart-e"},
                                icon=fac.AntdIcon(
                                    id={"type": "chart-card-toggle-fullscreen-icon", "index": "chart-e"},
                                    icon="antd-full-screen",
                                ),
                                type="text",
                                size="large",
                            ),
                            height=500,
                        ),
                        span=8,
                    ),
                    # 空白卡片示例
                    fac.AntdCol(
                        blank_card(
                            fac.AntdCenter(
                                fac.AntdText(
                                    [
                                        fac.AntdText("玩转Dash", italic=True),
                                        "知识星球出品",
                                    ]
                                )
                            )
                        ),
                        span=24,
                    ),
                ],
                gutter=[18, 18],
            ),
        ],
        style=style(
            padding=50, background="#f5f5f5", minHeight="100vh", boxSizing="border-box"
        ),
    )


app.layout = layout


@app.callback([Input("demo-link1", "n_clicks"), Input("demo-link2", "nClicks")])
def link_click_demo(*args):
    """链接点击交互演示"""
    set_props(
        "message-target", {"children": fac.AntdMessage(content="你点击了链接 " + dash.ctx.triggered_id, type="info")},
    )


@app.callback(
    Output({"type": "chart-card-toggle-fullscreen-icon", "index": MATCH}, "icon"),
    Input({"type": "chart-card-toggle-fullscreen", "index": MATCH}, "nClicks"),
    State({"type": "chart-card-toggle-fullscreen-icon", "index": MATCH}, "icon"),
    prevent_initial_call=True,
)
def toggle_full_screen(n_clicks, icon):
    """控制任意图表卡片的全屏化切换"""

    # 获取本次回调触发来源id
    target_id = dash.ctx.triggered_id
    target_id["type"] = "chart-card"

    if icon == "antd-full-screen":
        # 切换下一个状态的按钮图标
        next_icon = "antd-full-screen-exit"
        # 切换下一个状态的全屏化控制相关参数
        is_full_screen = True
    else:
        # 切换下一个状态的按钮图标
        next_icon = "antd-full-screen"
        # 切换下一个状态的全屏化控制相关参数
        is_full_screen = False

    # 借助set_props()突破MATCH模式默认回调角色编排限制
    set_props("fullscreen-target", {
        "targetId": json.dumps(target_id, separators=(",", ":")),
        "isFullscreen": is_full_screen,
    })

    return next_icon


if __name__ == "__main__":
    app.run(debug=True)

演示效果

带图表数据查看功能仪表盘示例

import dash
import random
from dash import html, set_props
import feffery_antd_charts as fact
import feffery_antd_components as fac
from dash.dependencies import Input, State
from feffery_dash_utils.style_utils import style
from feffery_dash_utils.template_utils.dashboard_components import (
    welcome_card,
    blank_card,
    index_card,
    simple_chart_card,
)

app = dash.Dash(__name__, suppress_callback_exceptions=True)


def layout():
    return html.Div(
        [
            # 消息提示输出目标
            fac.Fragment(id="message-target"),
            # 回到顶部
            fac.AntdBackTop(),
            # 统一数据查看模态框
            fac.AntdModal(id="view-data-modal", title="查看数据"),
            # 仪表盘网格布局
            fac.AntdRow(
                [
                    # 欢迎卡片
                    fac.AntdCol(
                        welcome_card(
                            title="欢迎访问本应用,用户:张三",
                            description=fac.AntdText(
                                [
                                    "您有5个事项待处理,点击",
                                    html.A("此处", id="demo-link1"),
                                    "查看。",
                                ]
                            ),
                            avatar=fac.AntdAvatar(
                                src="/assets/demo-avatar.png",
                                mode="image",
                                size=72,
                                style=style(background="#1890ff"),
                            ),
                            extra=fac.AntdButton(
                                "更多信息", id="demo-link2", type="link"
                            ),
                        ),
                        span=24,
                    ),
                    # 指标卡片示例
                    fac.AntdCol(
                        index_card(
                            index_name="总销售额",
                            index_value="¥ 126560",
                            index_description="这是总销售额的指标描述示例内容",
                            extra_content=fac.AntdText(
                                [
                                    "周同比12%",
                                    fac.AntdIcon(
                                        icon="antd-caret-up",
                                        style=style(color="#f5222d"),
                                    ),
                                    ",日同比11%",
                                    fac.AntdIcon(
                                        icon="antd-caret-down",
                                        style=style(color="#52c41a"),
                                    ),
                                ]
                            ),
                            footer_content="日销售额 ¥12423",
                        ),
                        span=6,
                    ),
                    fac.AntdCol(
                        index_card(
                            index_name="访问量",
                            index_value=8846,
                            index_description="这是访问量的指标描述示例内容",
                            extra_content=fact.AntdTinyArea(
                                data=[random.randint(50, 100) for _ in range(20)],
                                height=60,
                                smooth=True,
                            ),
                            footer_content="日访问量 1234",
                        ),
                        span=6,
                    ),
                    fac.AntdCol(
                        index_card(
                            index_name="支付笔数",
                            index_value=6560,
                            index_description="这是支付笔数的指标描述示例内容",
                            extra_content=fact.AntdTinyColumn(
                                data=[random.randint(50, 100) for _ in range(20)],
                                height=60,
                                color="#2389ff",
                                columnWidthRatio=0.75,
                            ),
                            footer_content="转化率 60%",
                        ),
                        span=6,
                    ),
                    fac.AntdCol(
                        index_card(
                            index_name="运营活动效果",
                            index_value="78%",
                            index_description="这是运营活动效果的指标描述示例内容",
                            extra_content=fac.AntdCenter(
                                fac.AntdProgress(
                                    percent=78,
                                    status="active",
                                    strokeColor={"from": "#128ee7", "to": "#6cc085"},
                                ),
                                style=style(height="100%"),
                            ),
                            footer_content=fac.AntdText(
                                [
                                    "周同比8%",
                                    fac.AntdIcon(
                                        icon="antd-caret-up",
                                        style=style(color="#f5222d"),
                                    ),
                                    ",日同比3%",
                                    fac.AntdIcon(
                                        icon="antd-caret-down",
                                        style=style(color="#52c41a"),
                                    ),
                                ]
                            ),
                        ),
                        span=6,
                    ),
                    # 图表卡片示例
                    fac.AntdCol(
                        simple_chart_card(
                            title="销售额类别占比",
                            description="时间范围:当月",
                            chart=fact.AntdPie(
                                id="sales-chart",
                                data=[
                                    {
                                        "type": "家用电器",
                                        "value": 4544,
                                    },
                                    {
                                        "type": "食用酒水",
                                        "value": 3321,
                                    },
                                    {
                                        "type": "个护健康",
                                        "value": 3113,
                                    },
                                    {
                                        "type": "服饰箱包",
                                        "value": 2341,
                                    },
                                    {
                                        "type": "母婴产品",
                                        "value": 1231,
                                    },
                                    {
                                        "type": "其他",
                                        "value": 1231,
                                    },
                                ],
                                colorField="type",
                                angleField="value",
                                radius=0.8,
                                innerRadius=0.6,
                                label={"type": "spider"},
                            ),
                            extra=fac.AntdTooltip(
                                fac.AntdButton(
                                    id="view-sales-data",
                                    icon=fac.AntdIcon(icon="antd-table"),
                                    type="text",
                                ),
                                title="查看数据",
                            ),
                            height=450,
                        ),
                        span=12,
                    ),
                    fac.AntdCol(
                        simple_chart_card(
                            title="流量转化情况",
                            description="时间范围:当月",
                            chart=fact.AntdColumn(
                                id="flow-conversion-chart",
                                data=[
                                    {
                                        "action": "浏览网站",
                                        "pv": 50000,
                                    },
                                    {
                                        "action": "放入购物车",
                                        "pv": 35000,
                                    },
                                    {
                                        "action": "生成订单",
                                        "pv": 25000,
                                    },
                                    {
                                        "action": "支付订单",
                                        "pv": 15000,
                                    },
                                    {
                                        "action": "完成交易",
                                        "pv": 8500,
                                    },
                                ],
                                xField="action",
                                yField="pv",
                                conversionTag={},
                                color="#2e8fff",
                            ),
                            extra=fac.AntdTooltip(
                                fac.AntdButton(
                                    id="view-flow-conversion-data",
                                    icon=fac.AntdIcon(icon="antd-table"),
                                    type="text",
                                ),
                                title="查看数据",
                            ),
                            height=450,
                        ),
                        span=12,
                    ),
                    fac.AntdCol(
                        simple_chart_card(
                            title="流量转化具体链路",
                            description="时间范围:当月",
                            chart=fact.AntdSankey(
                                data=[
                                    {
                                        "source": "首次打开",
                                        "target": "首页 UV",
                                        "value": 160,
                                    },
                                    {
                                        "source": "结果页",
                                        "target": "首页 UV",
                                        "value": 40,
                                    },
                                    {
                                        "source": "验证页",
                                        "target": "首页 UV",
                                        "value": 10,
                                    },
                                    {
                                        "source": "我的",
                                        "target": "首页 UV",
                                        "value": 10,
                                    },
                                    {"source": "朋友", "target": "首页 UV", "value": 8},
                                    {
                                        "source": "其他来源",
                                        "target": "首页 UV",
                                        "value": 27,
                                    },
                                    {
                                        "source": "首页 UV",
                                        "target": "理财",
                                        "value": 30,
                                    },
                                    {
                                        "source": "首页 UV",
                                        "target": "扫一扫",
                                        "value": 40,
                                    },
                                    {
                                        "source": "首页 UV",
                                        "target": "服务",
                                        "value": 35,
                                    },
                                    {
                                        "source": "首页 UV",
                                        "target": "蚂蚁森林",
                                        "value": 25,
                                    },
                                    {
                                        "source": "首页 UV",
                                        "target": "跳失",
                                        "value": 10,
                                    },
                                    {
                                        "source": "首页 UV",
                                        "target": "借呗",
                                        "value": 30,
                                    },
                                    {
                                        "source": "首页 UV",
                                        "target": "花呗",
                                        "value": 40,
                                    },
                                    {
                                        "source": "首页 UV",
                                        "target": "其他流向",
                                        "value": 45,
                                    },
                                ],
                                sourceField="source",
                                targetField="target",
                                weightField="value",
                                nodeWidthRatio=0.008,
                                nodePaddingRatio=0.03,
                                nodeDraggable=True,
                            ),
                            height=375,
                        ),
                        span=24,
                    ),
                    fac.AntdCol(
                        simple_chart_card(
                            title="内容运营情况",
                            description="时间范围:近10天",
                            chart=fact.AntdArea(
                                data=[
                                    {
                                        "date": date,
                                        "type": type,
                                        "value": random.randint(50, 1000),
                                    }
                                    for date in [
                                        "03-01",
                                        "03-02",
                                        "03-03",
                                        "03-04",
                                        "03-05",
                                        "03-06",
                                        "03-07",
                                        "03-08",
                                        "03-09",
                                        "03-10",
                                    ]
                                    for type in [
                                        "内容生产量",
                                        "内容点击量",
                                        "内容曝光量",
                                        "活跃用户数",
                                    ]
                                ],
                                xField="date",
                                yField="value",
                                seriesField="type",
                                smooth=True,
                                isStack=True,
                                legend={"position": "top"},
                            ),
                            height=500,
                        ),
                        span=16,
                    ),
                    fac.AntdCol(
                        simple_chart_card(
                            title="近期热门内容",
                            description="时间范围:近10天",
                            chart=fac.AntdTable(
                                columns=[
                                    {
                                        "title": "标题",
                                        "dataIndex": "title",
                                        "key": "title",
                                    },
                                    {
                                        "title": "点击量",
                                        "dataIndex": "click",
                                        "key": "click",
                                    },
                                    {
                                        "title": "内容链接",
                                        "dataIndex": "link",
                                        "key": "link",
                                        "renderOptions": {
                                            "renderType": "link",
                                        },
                                    },
                                ],
                                data=[
                                    {
                                        "title": "示例内容标题xxx",
                                        "click": random.randint(100, 10000),
                                        "link": {
                                            "content": "点击访问",
                                            "href": "https://fact.feffery.tech/",
                                        },
                                    }
                                    for i in range(18)
                                ],
                                size="small",
                                pagination=False,
                                tableLayout="fixed",
                                maxHeight=325,
                                bordered=True,
                            ),
                            height=500,
                        ),
                        span=8,
                    ),
                    # 空白卡片示例
                    fac.AntdCol(
                        blank_card(
                            fac.AntdCenter(
                                fac.AntdText(
                                    [
                                        fac.AntdText("玩转Dash", italic=True),
                                        "知识星球出品",
                                    ]
                                )
                            )
                        ),
                        span=24,
                    ),
                ],
                gutter=[18, 18],
            ),
        ],
        style=style(
            padding=50, background="#f5f5f5", minHeight="100vh", boxSizing="border-box"
        ),
    )


app.layout = layout


@app.callback([Input("demo-link1", "n_clicks"), Input("demo-link2", "nClicks")])
def link_click_demo(*args):
    """链接点击交互演示"""

    set_props(
        "message-target",
        {
            "children": fac.AntdMessage(
                content="你点击了链接 " + dash.ctx.triggered_id, type="info"
            )
        },
    )


@app.callback(Input("view-sales-data", "nClicks"), State("sales-chart", "data"))
def view_sales_data(nClicks, data):
    set_props(
        "view-data-modal",
        {
            "visible": True,
            "children": fac.AntdTable(
                title="销售额类别占比数据",
                columns=[
                    {"dataIndex": "type", "title": "type"},
                    {"dataIndex": "value", "title": "value"},
                ],
                data=data,
                tableLayout="fixed",
                bordered=True,
                sortOptions={"sortDataIndexes": ["value"]},
            ),
        },
    )


@app.callback(
    Input("view-flow-conversion-data", "nClicks"),
    State("flow-conversion-chart", "data"),
)
def view_flow_conversion_data(nClicks, data):
    set_props(
        "view-data-modal",
        {
            "visible": True,
            "children": fac.AntdTable(
                title="流量转化情况数据",
                columns=[
                    {"dataIndex": "action", "title": "action"},
                    {"dataIndex": "pv", "title": "pv"},
                ],
                data=data,
                tableLayout="fixed",
                bordered=True,
            ),
        },
    )


if __name__ == "__main__":
    app.run(debug=True)

 演示效果

多端自动适配

import dash
import random
from dash import html, set_props
import feffery_antd_charts as fact
from dash.dependencies import Input
import feffery_antd_components as fac
from feffery_dash_utils.style_utils import style
from feffery_dash_utils.template_utils.dashboard_components import (
    blank_card,
    index_card,
    simple_chart_card,
)

app = dash.Dash(__name__, suppress_callback_exceptions=True)


def layout():
    return html.Div(
        [
            # 消息提示输出目标
            fac.Fragment(id="message-target"),
            # 回到顶部
            fac.AntdBackTop(),
            # 仪表盘网格布局
            fac.AntdRow(
                [
                    # 指标卡片示例
                    fac.AntdCol(
                        index_card(
                            index_name="总销售额",
                            index_value="¥ 126560",
                            index_description="这是总销售额的指标描述示例内容",
                            extra_content=fac.AntdText(
                                [
                                    "周同比12%",
                                    fac.AntdIcon(
                                        icon="antd-caret-up",
                                        style=style(color="#f5222d"),
                                    ),
                                    ",日同比11%",
                                    fac.AntdIcon(
                                        icon="antd-caret-down",
                                        style=style(color="#52c41a"),
                                    ),
                                ]
                            ),
                            footer_content="日销售额 ¥12423",
                        ),
                        xs=24,
                        sm=24,
                        md=12,
                        xl=6,
                    ),
                    fac.AntdCol(
                        index_card(
                            index_name="访问量",
                            index_value=8846,
                            index_description="这是访问量的指标描述示例内容",
                            extra_content=fact.AntdTinyArea(
                                data=[random.randint(50, 100) for _ in range(20)],
                                height=60,
                                smooth=True,
                            ),
                            footer_content="日访问量 1234",
                        ),
                        xs=24,
                        sm=24,
                        md=12,
                        xl=6,
                    ),
                    fac.AntdCol(
                        index_card(
                            index_name="支付笔数",
                            index_value=6560,
                            index_description="这是支付笔数的指标描述示例内容",
                            extra_content=fact.AntdTinyColumn(
                                data=[random.randint(50, 100) for _ in range(20)],
                                height=60,
                                color="#2389ff",
                                columnWidthRatio=0.75,
                            ),
                            footer_content="转化率 60%",
                        ),
                        xs=24,
                        sm=24,
                        md=12,
                        xl=6,
                    ),
                    fac.AntdCol(
                        index_card(
                            index_name="运营活动效果",
                            index_value="78%",
                            index_description="这是运营活动效果的指标描述示例内容",
                            extra_content=fac.AntdCenter(
                                fac.AntdProgress(
                                    percent=78,
                                    status="active",
                                    strokeColor={"from": "#128ee7", "to": "#6cc085"},
                                ),
                                style=style(height="100%"),
                            ),
                            footer_content=fac.AntdText(
                                [
                                    "周同比8%",
                                    fac.AntdIcon(
                                        icon="antd-caret-up",
                                        style=style(color="#f5222d"),
                                    ),
                                    ",日同比3%",
                                    fac.AntdIcon(
                                        icon="antd-caret-down",
                                        style=style(color="#52c41a"),
                                    ),
                                ]
                            ),
                        ),
                        xs=24,
                        sm=24,
                        md=12,
                        xl=6,
                    ),
                    # 图表卡片示例
                    fac.AntdCol(
                        simple_chart_card(
                            title="销售额类别占比",
                            description="时间范围:当月",
                            chart=fact.AntdPie(
                                data=[
                                    {
                                        "type": "家用电器",
                                        "value": 4544,
                                    },
                                    {
                                        "type": "食用酒水",
                                        "value": 3321,
                                    },
                                    {
                                        "type": "个护健康",
                                        "value": 3113,
                                    },
                                    {
                                        "type": "服饰箱包",
                                        "value": 2341,
                                    },
                                    {
                                        "type": "母婴产品",
                                        "value": 1231,
                                    },
                                    {
                                        "type": "其他",
                                        "value": 1231,
                                    },
                                ],
                                colorField="type",
                                angleField="value",
                                radius=0.8,
                                innerRadius=0.6,
                                label={"type": "spider"},
                            ),
                            height=450,
                        ),
                        xs=24,
                        sm=24,
                        md=24,
                        lg=24,
                        xl=12,
                    ),
                    fac.AntdCol(
                        simple_chart_card(
                            title="流量转化情况",
                            description="时间范围:当月",
                            chart=fact.AntdColumn(
                                data=[
                                    {
                                        "action": "浏览网站",
                                        "pv": 50000,
                                    },
                                    {
                                        "action": "放入购物车",
                                        "pv": 35000,
                                    },
                                    {
                                        "action": "生成订单",
                                        "pv": 25000,
                                    },
                                    {
                                        "action": "支付订单",
                                        "pv": 15000,
                                    },
                                    {
                                        "action": "完成交易",
                                        "pv": 8500,
                                    },
                                ],
                                xField="action",
                                yField="pv",
                                conversionTag={},
                                color="#2e8fff",
                            ),
                            height=450,
                        ),
                        xs=24,
                        sm=24,
                        md=24,
                        lg=24,
                        xl=12,
                    ),
                    fac.AntdCol(
                        simple_chart_card(
                            title="流量转化具体链路",
                            description="时间范围:当月",
                            chart=fact.AntdSankey(
                                data=[
                                    {
                                        "source": "首次打开",
                                        "target": "首页 UV",
                                        "value": 160,
                                    },
                                    {
                                        "source": "结果页",
                                        "target": "首页 UV",
                                        "value": 40,
                                    },
                                    {
                                        "source": "验证页",
                                        "target": "首页 UV",
                                        "value": 10,
                                    },
                                    {
                                        "source": "我的",
                                        "target": "首页 UV",
                                        "value": 10,
                                    },
                                    {"source": "朋友", "target": "首页 UV", "value": 8},
                                    {
                                        "source": "其他来源",
                                        "target": "首页 UV",
                                        "value": 27,
                                    },
                                    {
                                        "source": "首页 UV",
                                        "target": "理财",
                                        "value": 30,
                                    },
                                    {
                                        "source": "首页 UV",
                                        "target": "扫一扫",
                                        "value": 40,
                                    },
                                    {
                                        "source": "首页 UV",
                                        "target": "服务",
                                        "value": 35,
                                    },
                                    {
                                        "source": "首页 UV",
                                        "target": "蚂蚁森林",
                                        "value": 25,
                                    },
                                    {
                                        "source": "首页 UV",
                                        "target": "跳失",
                                        "value": 10,
                                    },
                                    {
                                        "source": "首页 UV",
                                        "target": "借呗",
                                        "value": 30,
                                    },
                                    {
                                        "source": "首页 UV",
                                        "target": "花呗",
                                        "value": 40,
                                    },
                                    {
                                        "source": "首页 UV",
                                        "target": "其他流向",
                                        "value": 45,
                                    },
                                ],
                                sourceField="source",
                                targetField="target",
                                weightField="value",
                                nodeWidthRatio=0.008,
                                nodePaddingRatio=0.03,
                                nodeDraggable=True,
                            ),
                            height=375,
                        ),
                        span=24,
                    ),
                    fac.AntdCol(
                        simple_chart_card(
                            title="内容运营情况",
                            description="时间范围:近10天",
                            chart=fact.AntdArea(
                                data=[
                                    {
                                        "date": date,
                                        "type": type,
                                        "value": random.randint(50, 1000),
                                    }
                                    for date in [
                                        "03-01",
                                        "03-02",
                                        "03-03",
                                        "03-04",
                                        "03-05",
                                        "03-06",
                                        "03-07",
                                        "03-08",
                                        "03-09",
                                        "03-10",
                                    ]
                                    for type in [
                                        "内容生产量",
                                        "内容点击量",
                                        "内容曝光量",
                                        "活跃用户数",
                                    ]
                                ],
                                xField="date",
                                yField="value",
                                seriesField="type",
                                smooth=True,
                                isStack=True,
                                legend={"position": "top"},
                            ),
                            height=500,
                        ),
                        xs=24,
                        sm=24,
                        md=24,
                        lg=24,
                        xl=16,
                    ),
                    fac.AntdCol(
                        simple_chart_card(
                            title="近期热门内容",
                            description="时间范围:近10天",
                            chart=fac.AntdTable(
                                columns=[
                                    {
                                        "title": "标题",
                                        "dataIndex": "title",
                                        "key": "title",
                                    },
                                    {
                                        "title": "点击量",
                                        "dataIndex": "click",
                                        "key": "click",
                                    },
                                    {
                                        "title": "内容链接",
                                        "dataIndex": "link",
                                        "key": "link",
                                        "renderOptions": {
                                            "renderType": "link",
                                        },
                                    },
                                ],
                                data=[
                                    {
                                        "title": "示例内容标题xxx",
                                        "click": random.randint(100, 10000),
                                        "link": {
                                            "content": "点击访问",
                                            "href": "https://fact.feffery.tech/",
                                        },
                                    }
                                    for i in range(18)
                                ],
                                size="small",
                                pagination=False,
                                tableLayout="fixed",
                                maxHeight=325,
                                bordered=True,
                            ),
                            height=500,
                        ),
                        xs=24,
                        sm=24,
                        md=24,
                        lg=24,
                        xl=8,
                    ),
                    # 空白卡片示例
                    fac.AntdCol(
                        blank_card(
                            fac.AntdCenter(
                                fac.AntdText(
                                    [
                                        fac.AntdText("玩转Dash", italic=True),
                                        "知识星球出品",
                                    ]
                                )
                            )
                        ),
                        span=24,
                    ),
                ],
                gutter=[18, 18],
            ),
        ],
        style=style(
            padding=50, background="#f5f5f5", minHeight="100vh", boxSizing="border-box"
        ),
    )


app.layout = layout


@app.callback([Input("demo-link1", "n_clicks"), Input("demo-link2", "nClicks")])
def link_click_demo(*args):
    """链接点击交互演示"""

    set_props(
        "message-target", {"children": fac.AntdMessage(content="你点击了链接 " + dash.ctx.triggered_id, type="info")},
    )


if __name__ == "__main__":
    app.run(debug=True)

演示效果

仪表盘导出为报告文件

import os
import io
import uuid
import dash
import random
import base64
from fpdf import FPDF
from PIL import Image
import feffery_antd_charts as fact
from dash import html, set_props, dcc
import feffery_antd_components as fac
import feffery_utils_components as fuc
from dash.dependencies import Input, Output
from feffery_dash_utils.style_utils import style
from feffery_dash_utils.template_utils.dashboard_components import (
    blank_card,
    index_card,
    simple_chart_card,
)

app = dash.Dash(__name__, suppress_callback_exceptions=True)


def layout():
    return html.Div(
        [
            # 全局统一下载
            dcc.Download(id="global-download"),
            # 消息提示输出目标
            fac.Fragment(id="message-target"),
            # 回到顶部
            fac.AntdBackTop(),
            # 批量下载按钮
            fac.AntdFloatButton(
                id="export-pdf",
                shape="square",
                icon=fac.AntdIcon(icon="antd-cloud-download"),
                tooltip="导出仪表盘为pdf",
                style=style(bottom="calc(100vh - 120px)", right=5),
            ),
            fuc.FefferyDom2Image(id="export-dashboard-to-image", scale=3),
            # 仪表盘网格布局
            fac.AntdRow(
                [
                    # 指标卡片示例
                    fac.AntdCol(
                        index_card(
                            index_name="总销售额",
                            index_value="¥ 126560",
                            index_description="这是总销售额的指标描述示例内容",
                            extra_content=fac.AntdText(
                                [
                                    "周同比12%",
                                    fac.AntdIcon(
                                        icon="antd-caret-up",
                                        style=style(color="#f5222d"),
                                    ),
                                    ",日同比11%",
                                    fac.AntdIcon(
                                        icon="antd-caret-down",
                                        style=style(color="#52c41a"),
                                    ),
                                ]
                            ),
                            footer_content="日销售额 ¥12423",
                        ),
                        span=6,
                    ),
                    fac.AntdCol(
                        index_card(
                            index_name="访问量",
                            index_value=8846,
                            index_description="这是访问量的指标描述示例内容",
                            extra_content=fact.AntdTinyArea(
                                data=[random.randint(50, 100) for _ in range(20)],
                                height=60,
                                smooth=True,
                            ),
                            footer_content="日访问量 1234",
                        ),
                        span=6,
                    ),
                    fac.AntdCol(
                        index_card(
                            index_name="支付笔数",
                            index_value=6560,
                            index_description="这是支付笔数的指标描述示例内容",
                            extra_content=fact.AntdTinyColumn(
                                data=[random.randint(50, 100) for _ in range(20)],
                                height=60,
                                color="#2389ff",
                                columnWidthRatio=0.75,
                            ),
                            footer_content="转化率 60%",
                        ),
                        span=6,
                    ),
                    fac.AntdCol(
                        index_card(
                            index_name="运营活动效果",
                            index_value="78%",
                            index_description="这是运营活动效果的指标描述示例内容",
                            extra_content=fac.AntdCenter(
                                fac.AntdProgress(
                                    percent=78,
                                    status="active",
                                    strokeColor={"from": "#128ee7", "to": "#6cc085"},
                                ),
                                style=style(height="100%"),
                            ),
                            footer_content=fac.AntdText(
                                [
                                    "周同比8%",
                                    fac.AntdIcon(
                                        icon="antd-caret-up",
                                        style=style(color="#f5222d"),
                                    ),
                                    ",日同比3%",
                                    fac.AntdIcon(
                                        icon="antd-caret-down",
                                        style=style(color="#52c41a"),
                                    ),
                                ]
                            ),
                        ),
                        span=6,
                    ),
                    # 图表卡片示例
                    fac.AntdCol(
                        simple_chart_card(
                            title="销售额类别占比",
                            description="时间范围:当月",
                            chart=fact.AntdPie(
                                data=[
                                    {
                                        "type": "家用电器",
                                        "value": 4544,
                                    },
                                    {
                                        "type": "食用酒水",
                                        "value": 3321,
                                    },
                                    {
                                        "type": "个护健康",
                                        "value": 3113,
                                    },
                                    {
                                        "type": "服饰箱包",
                                        "value": 2341,
                                    },
                                    {
                                        "type": "母婴产品",
                                        "value": 1231,
                                    },
                                    {
                                        "type": "其他",
                                        "value": 1231,
                                    },
                                ],
                                colorField="type",
                                angleField="value",
                                radius=0.8,
                                innerRadius=0.6,
                                label={"type": "spider"},
                            ),
                            height=450,
                        ),
                        span=12,
                    ),
                    fac.AntdCol(
                        simple_chart_card(
                            title="流量转化情况",
                            description="时间范围:当月",
                            chart=fact.AntdColumn(
                                data=[
                                    {
                                        "action": "浏览网站",
                                        "pv": 50000,
                                    },
                                    {
                                        "action": "放入购物车",
                                        "pv": 35000,
                                    },
                                    {
                                        "action": "生成订单",
                                        "pv": 25000,
                                    },
                                    {
                                        "action": "支付订单",
                                        "pv": 15000,
                                    },
                                    {
                                        "action": "完成交易",
                                        "pv": 8500,
                                    },
                                ],
                                xField="action",
                                yField="pv",
                                conversionTag={},
                                color="#2e8fff",
                            ),
                            height=450,
                        ),
                        span=12,
                    ),
                    fac.AntdCol(
                        simple_chart_card(
                            title="流量转化具体链路",
                            description="时间范围:当月",
                            chart=fact.AntdSankey(
                                data=[
                                    {
                                        "source": "首次打开",
                                        "target": "首页 UV",
                                        "value": 160,
                                    },
                                    {
                                        "source": "结果页",
                                        "target": "首页 UV",
                                        "value": 40,
                                    },
                                    {
                                        "source": "验证页",
                                        "target": "首页 UV",
                                        "value": 10,
                                    },
                                    {
                                        "source": "我的",
                                        "target": "首页 UV",
                                        "value": 10,
                                    },
                                    {"source": "朋友", "target": "首页 UV", "value": 8},
                                    {
                                        "source": "其他来源",
                                        "target": "首页 UV",
                                        "value": 27,
                                    },
                                    {
                                        "source": "首页 UV",
                                        "target": "理财",
                                        "value": 30,
                                    },
                                    {
                                        "source": "首页 UV",
                                        "target": "扫一扫",
                                        "value": 40,
                                    },
                                    {
                                        "source": "首页 UV",
                                        "target": "服务",
                                        "value": 35,
                                    },
                                    {
                                        "source": "首页 UV",
                                        "target": "蚂蚁森林",
                                        "value": 25,
                                    },
                                    {
                                        "source": "首页 UV",
                                        "target": "跳失",
                                        "value": 10,
                                    },
                                    {
                                        "source": "首页 UV",
                                        "target": "借呗",
                                        "value": 30,
                                    },
                                    {
                                        "source": "首页 UV",
                                        "target": "花呗",
                                        "value": 40,
                                    },
                                    {
                                        "source": "首页 UV",
                                        "target": "其他流向",
                                        "value": 45,
                                    },
                                ],
                                sourceField="source",
                                targetField="target",
                                weightField="value",
                                nodeWidthRatio=0.008,
                                nodePaddingRatio=0.03,
                                nodeDraggable=True,
                            ),
                            height=375,
                        ),
                        span=24,
                    ),
                    fac.AntdCol(
                        simple_chart_card(
                            title="内容运营情况",
                            description="时间范围:近10天",
                            chart=fact.AntdArea(
                                data=[
                                    {
                                        "date": date,
                                        "type": type,
                                        "value": random.randint(50, 1000),
                                    }
                                    for date in [
                                        "03-01",
                                        "03-02",
                                        "03-03",
                                        "03-04",
                                        "03-05",
                                        "03-06",
                                        "03-07",
                                        "03-08",
                                        "03-09",
                                        "03-10",
                                    ]
                                    for type in [
                                        "内容生产量",
                                        "内容点击量",
                                        "内容曝光量",
                                        "活跃用户数",
                                    ]
                                ],
                                xField="date",
                                yField="value",
                                seriesField="type",
                                smooth=True,
                                isStack=True,
                                legend={"position": "top"},
                            ),
                            height=500,
                        ),
                        span=16,
                    ),
                    fac.AntdCol(
                        simple_chart_card(
                            title="近期热门内容",
                            description="时间范围:近10天",
                            chart=fac.AntdTable(
                                columns=[
                                    {
                                        "title": "标题",
                                        "dataIndex": "title",
                                        "key": "title",
                                    },
                                    {
                                        "title": "点击量",
                                        "dataIndex": "click",
                                        "key": "click",
                                    },
                                    {
                                        "title": "内容链接",
                                        "dataIndex": "link",
                                        "key": "link",
                                        "renderOptions": {
                                            "renderType": "link",
                                        },
                                    },
                                ],
                                data=[
                                    {
                                        "title": "示例内容标题xxx",
                                        "click": random.randint(100, 10000),
                                        "link": {
                                            "content": "点击访问",
                                            "href": "https://fact.feffery.tech/",
                                        },
                                    }
                                    for i in range(18)
                                ],
                                size="small",
                                pagination=False,
                                tableLayout="fixed",
                                maxHeight=325,
                                bordered=True,
                            ),
                            height=500,
                        ),
                        span=8,
                    ),
                    # 空白卡片示例
                    fac.AntdCol(
                        blank_card(
                            fac.AntdCenter(
                                fac.AntdText(
                                    [
                                        fac.AntdText("玩转Dash", italic=True),
                                        "知识星球出品",
                                    ]
                                )
                            )
                        ),
                        span=24,
                    ),
                ],
                gutter=[18, 18],
            ),
        ],
        id="dashboard-container",
        style=style(
            padding=50, background="#f5f5f5", minHeight="100vh", boxSizing="border-box"
        ),
    )


app.layout = layout


@app.callback(
    Output("export-dashboard-to-image", "targetSelector"),
    Input("export-pdf", "nClicks"),
    prevent_initial_call=True,
)
def export_dashboard_to_image(n_clicks):
    """触发仪表盘目标容器导出为图片数据动作"""

    # 额外设置导出按钮相关提示信息
    set_props("export-pdf", {"tooltip": "导出中,请稍候", "icon": fac.AntdIcon(icon="antd-loading")})

    # 对应仪表盘容器id的选择器
    return "#dashboard-container"


@app.callback(Input("export-dashboard-to-image", "screenshotResult"))
def export_dashboard_image_to_pdf(screen_shot_result):
    """将最近一次生成的仪表盘内容图片数据导出为pdf文件"""

    # 提取已导出图片有效部分数据
    base64_data = screen_shot_result["dataUrl"].split(",")[1]

    # 解码base64字符串
    image_data = base64.b64decode(base64_data)

    # 将图片数据转换为PIL图像对象
    image = Image.open(io.BytesIO(image_data))

    # 构造pdf文档
    pdf = FPDF(unit="pt", format=[image.width, image.height])
    pdf.add_page()

    # 写出临时图片文件
    temp_file_name = ".{}.png".format(uuid.uuid4())
    image.save(temp_file_name)
    pdf.image(temp_file_name, x=0, y=0, w=image.width, h=image.height)

    # 创建临时pdf所需io流
    temp_pdf_io = io.BytesIO(pdf.output())

    # 清理临时图片文件
    os.remove(temp_file_name)

    # 返回下载目标结果
    set_props("global-download", {"data": dcc.send_bytes(temp_pdf_io.getvalue(), "仪表盘导出结果.pdf")})

    # 还原导出按钮提示信息
    set_props("export-pdf", {"tooltip": "导出仪表盘为pdf", "icon": fac.AntdIcon(icon="antd-cloud-download")}, )


if __name__ == "__main__":
    app.run(debug=True)

 演示效果

 导出后的文件

具备实时数据更新的仪表盘

import dash
import random
from datetime import datetime
import feffery_antd_charts as fact
import feffery_antd_components as fac
import feffery_utils_components as fuc
from dash import html, dcc, set_props, Patch
from feffery_dash_utils.style_utils import style
from dash.dependencies import Input, Output, State
from feffery_dash_utils.template_utils.dashboard_components import (
    welcome_card,
    blank_card,
    index_card,
    simple_chart_card,
)

app = dash.Dash(__name__, update_title=None)


def layout():
    return html.Div(
        [
            # 消息提示输出目标
            fac.Fragment(id="message-target"),
            # 数据统一更新轮询
            dcc.Interval(
                id="update-data-interval",
                interval=3000,  # 示例,3秒更新一次
            ),
            # 仪表盘网格布局
            fac.AntdRow(
                [
                    # 欢迎卡片
                    fac.AntdCol(
                        welcome_card(
                            title="欢迎访问本应用,用户:张三",
                            description=fac.AntdText(
                                [
                                    "您有5个事项待处理,点击",
                                    html.A("此处", id="demo-link1"),
                                    "查看。",
                                ]
                            ),
                            avatar=fac.AntdAvatar(
                                src="/assets/demo-avatar.png",
                                mode="image",
                                size=72,
                                style=style(background="#1890ff"),
                            ),
                            extra=fac.AntdButton(
                                "更多信息", id="demo-link2", type="link"
                            ),
                        ),
                        span=24,
                    ),
                    # 展示数据更新时间
                    fac.AntdCol(
                        blank_card(
                            fac.AntdText(
                                [
                                    "数据最近更新时间:",
                                    fac.AntdText(
                                        datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
                                        id="update-datetime",
                                        type="secondary",
                                    ),
                                ]
                            )
                        ),
                        span=24,
                    ),
                    # 指标卡片示例
                    fac.AntdCol(
                        index_card(
                            index_name="当日销售额",
                            index_value=[
                                "¥ ",
                                html.Span(
                                    102389,
                                    id="today-sales",
                                ),
                            ],
                            index_description="这是当日销售额的指标描述示例内容",
                            footer_content="昨日销售额 ¥123456",
                        ),
                        span=6,
                    ),
                    fac.AntdCol(
                        index_card(
                            index_name="当日访问量",
                            index_value=html.Span(
                                fuc.FefferyCountUp(end=8846, separator=""),
                                id="today-visits",
                            ),
                            index_description="这是当日访问量的指标描述示例内容",
                            extra_content=fact.AntdTinyArea(
                                id="today-visits-chart",
                                data=[random.randint(20, 50) for _ in range(10)],
                                height=60,
                                smooth=True,
                            ),
                            footer_content="昨日访问量 6789",
                        ),
                        span=6,
                    ),
                    fac.AntdCol(
                        index_card(
                            index_name="当日支付笔数",
                            index_value=html.Span(
                                4678,
                                id="today-orders",
                            ),
                            index_description="这是当日支付笔数的指标描述示例内容",
                            extra_content=fact.AntdTinyColumn(
                                id="today-orders-chart",
                                data=[random.randint(50, 100) for _ in range(10)],
                                height=60,
                                color="#2389ff",
                                columnWidthRatio=0.75,
                            ),
                            footer_content="昨日支付笔数 5678",
                        ),
                        span=6,
                    ),
                    fac.AntdCol(
                        index_card(
                            index_name="当日活动转化率",
                            index_value=html.Span(
                                "78%",
                                id="today-conversion-rate",
                            ),
                            index_description="这是运营活动效果的指标描述示例内容",
                            extra_content=fac.AntdCenter(
                                fac.AntdProgress(
                                    id="today-conversion-rate-chart",
                                    percent=78,
                                    status="active",
                                    strokeColor={"from": "#128ee7", "to": "#6cc085"},
                                ),
                                style=style(height="100%"),
                            ),
                            footer_content="昨日活动转化率 75%",
                        ),
                        span=6,
                    ),
                    # 图表卡片示例
                    fac.AntdCol(
                        simple_chart_card(
                            title="销售额类别占比",
                            description="时间范围:今日",
                            chart=fact.AntdPie(
                                id="today-sales-class-chart",
                                data=[
                                    {
                                        "type": "家用电器",
                                        "value": 4544,
                                    },
                                    {
                                        "type": "食用酒水",
                                        "value": 3321,
                                    },
                                    {
                                        "type": "个护健康",
                                        "value": 3113,
                                    },
                                    {
                                        "type": "服饰箱包",
                                        "value": 2341,
                                    },
                                    {
                                        "type": "母婴产品",
                                        "value": 1231,
                                    },
                                    {
                                        "type": "其他",
                                        "value": 1231,
                                    },
                                ],
                                colorField="type",
                                angleField="value",
                                radius=0.8,
                                innerRadius=0.6,
                                label={"type": "spider"},
                            ),
                            height=450,
                        ),
                        span=12,
                    ),
                    fac.AntdCol(
                        simple_chart_card(
                            title="流量转化情况",
                            description="时间范围:今日",
                            chart=fact.AntdColumn(
                                id="today-conversion-chart",
                                data=[
                                    {
                                        "action": "浏览网站",
                                        "pv": 50000,
                                    },
                                    {
                                        "action": "放入购物车",
                                        "pv": 35000,
                                    },
                                    {
                                        "action": "生成订单",
                                        "pv": 25000,
                                    },
                                    {
                                        "action": "支付订单",
                                        "pv": 15000,
                                    },
                                    {
                                        "action": "完成交易",
                                        "pv": 8500,
                                    },
                                ],
                                xField="action",
                                yField="pv",
                                conversionTag={},
                                color="#2e8fff",
                            ),
                            height=450,
                        ),
                        span=12,
                    ),
                    # 空白卡片示例
                    fac.AntdCol(
                        blank_card(
                            fac.AntdCenter(
                                fac.AntdText(
                                    [
                                        fac.AntdText("玩转Dash", italic=True),
                                        "知识星球出品",
                                    ]
                                )
                            )
                        ),
                        span=24,
                    ),
                ],
                gutter=[18, 18],
            ),
        ],
        style=style(
            padding=50, background="#f5f5f5", minHeight="100vh", boxSizing="border-box"
        ),
    )


app.layout = layout


@app.callback([Input("demo-link1", "n_clicks"), Input("demo-link2", "nClicks")])
def link_click_demo(*args):
    """链接点击交互演示"""

    set_props(
        "message-target",
        {
            "children": fac.AntdMessage(
                content="你点击了链接 " + dash.ctx.triggered_id, type="info"
            )
        },
    )


@app.callback(
    [
        Output("update-datetime", "children"),
        Output("today-sales", "children"),
        Output("today-visits", "children"),
        Output("today-visits-chart", "data"),
        Output("today-orders", "children"),
        Output("today-orders-chart", "data"),
        Output("today-conversion-rate", "children"),
        Output("today-conversion-rate-chart", "percent"),
        Output("today-sales-class-chart", "data"),
        Output("today-conversion-chart", "data"),
    ],
    Input("update-data-interval", "n_intervals"),
    [
        State("today-sales", "children"),
        State("today-visits", "children"),
        State("today-orders", "children"),
        State("today-conversion-rate-chart", "percent"),
        State("today-sales-class-chart", "data"),
        State("today-conversion-chart", "data"),
    ],
    prevent_initial_call=True,
)
def update_dashboard_data(
        n_intervals,
        origin_today_sales,
        origin_today_visits,
        origin_today_orders,
        origin_today_conversion_rate,
        origin_today_sales_class_chart_data,
        origin_today_conversion_chart_data,
):
    """处理仪表盘中各目标的实时数据更新"""

    # 模拟最新实时数据的获取

    # 当日销售额
    next_today_sales = origin_today_sales + random.randint(50, 100)

    # 当日访问量
    today_visits_chunk = random.randint(20, 50)
    # 更新数字递增组件参数
    origin_today_visits["props"]["start"] = origin_today_visits["props"]["end"]
    origin_today_visits["props"]["end"] = (
            origin_today_visits["props"]["end"] + today_visits_chunk
    )
    next_today_visits = origin_today_visits

    # 当日访问量分时段图表数据
    today_visits_chart_data_patch = Patch()
    today_visits_chart_data_patch.append(today_visits_chunk)

    # 当日订单量
    today_orders_chunk = random.randint(50, 100)
    next_today_orders = origin_today_orders + today_orders_chunk

    # 当日订单量分时段图表数据
    today_orders_chart_data_patch = Patch()
    today_orders_chart_data_patch.append(today_orders_chunk)

    # 当日活动转化率
    next_today_conversion_rate = round(
        origin_today_conversion_rate + random.uniform(-1, 1), 1
    )
    # 修正模拟数据
    if next_today_conversion_rate > 100:
        next_today_conversion_rate = 100

    # 销售额类别占比
    for i in range(len(origin_today_sales_class_chart_data)):
        origin_today_sales_class_chart_data[i]["value"] += random.randint(5, 20)

    # 流量转化情况
    for i in range(len(origin_today_conversion_chart_data)):
        origin_today_conversion_chart_data[i]["pv"] += random.randint(10, 20)

    return [
        datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
        next_today_sales,
        next_today_visits,
        today_visits_chart_data_patch,
        next_today_orders,
        today_orders_chart_data_patch,
        f"{next_today_conversion_rate}%",
        next_today_conversion_rate,
        origin_today_sales_class_chart_data,
        origin_today_conversion_chart_data,
    ]


if __name__ == "__main__":
    app.run(debug=True)

效果演示

 动态效果, 每隔3s 会进行自动更新, 以定时器的方式去实现

 

posted @ 2025-05-19 18:23  羊驼之歌  阅读(70)  评论(0)    收藏  举报