创建仪表板Skill creating-dashboards

这个技能用于创建综合性的仪表板和数据分析界面,结合数据可视化、KPI卡片、实时更新和交互式布局。适用于商业智能仪表板、监控系统、执行报告等场景,支持多数据展示、过滤、指标和可视化协同工作。关键词:仪表板、数据分析、数据可视化、KPI、实时更新、商业智能。

商业智能 0 次安装 0 次浏览 更新于 3/23/2026

名称: 创建仪表板 描述: 创建综合性仪表板和数据分析界面,结合数据可视化、KPI卡片、实时更新和交互式布局。使用此技能构建商业智能仪表板、监控系统、执行报告或任何需要多数据展示、过滤、指标和可视化协同工作的界面。

创建仪表板

目的

此技能能够创建复杂的仪表板界面,通过协调的小部件(如KPI卡片、图表、表格和过滤器)聚合和展示数据。仪表板作为数据驱动决策的集中指挥中心,将其他技能(数据可视化、表格、设计令牌)的多个组件类型结合成统一的分析体验,具有实时更新、响应式布局和交互式过滤功能。

使用时机

在以下情况激活此技能:

  • 构建商业智能或分析仪表板
  • 创建执行报告界面
  • 实施实时监控系统
  • 设计带指标和趋势的KPI显示
  • 开发可定制的小部件布局
  • 协调跨多数据展示的过滤器
  • 构建响应式数据密集型界面
  • 实施拖放式仪表板编辑器
  • 创建基于模板的分析系统
  • 设计多租户SaaS仪表板

核心仪表板元素

KPI卡片解剖

┌────────────────────────────┐
│ 收入(本月)               │ ← 带时间段的标签
│                            │
│  $1,245,832               │ ← 大数字(主要指标)
│  ↑ 15.3% 对比上月         │ ← 带比较的趋势指示器
│  ▂▃▅▆▇█(迷你图表)       │ ← 迷你可视化
└────────────────────────────┘

小部件容器结构

  • 带小部件名称和操作的标题栏
  • 加载状态(骨架或旋转器)
  • 带重试选项的错误边界
  • 可调整布局的调整手柄
  • 设置菜单(导出、配置、刷新)

仪表板布局类型

固定布局:设计者定义的放置,跨用户一致 可定制网格:用户拖放、可调整大小的小部件、保存布局 基于模板:预构建模式、行业特定起点

全局仪表板控制

  • 日期范围选择器(影响所有小部件)
  • 过滤器面板(跨小部件协调)
  • 刷新控制(手动/自动刷新)
  • 导出操作(PDF、图像、数据)
  • 主题切换器(浅色/深色/自定义)

实施方法

1. 选择仪表板架构

用于快速分析仪表板 → 使用 Tremor 预构建的KPI卡片、图表和表格,代码最少:

npm install @tremor/react

用于可定制仪表板 → 使用 react-grid-layout 拖放、可调整大小的小部件、用户定义布局:

npm install react-grid-layout

2. 设置全局状态管理

实现过滤器上下文以进行跨小部件协调:

// 用于共享过滤器的仪表板上下文
const DashboardContext = createContext({
  filters: { dateRange: null, categories: [] },
  setFilters: () => {},
  refreshInterval: 30000
});

// 用提供者包裹仪表板
<DashboardContext.Provider value={dashboardState}>
  <FilterPanel />
  <WidgetGrid />
</DashboardContext.Provider>

3. 实施数据获取策略

并行加载:同时获取所有小部件数据 懒加载:先加载可见小部件,其他在滚动时加载 缓存更新:从缓存提供服务,同时获取新数据

4. 配置实时更新

服务器发送事件(推荐用于仪表板)

const eventSource = new EventSource('/api/dashboard/stream');
eventSource.onmessage = (event) => {
  const update = JSON.parse(event.data);
  updateWidget(update.widgetId, update.data);
};

5. 应用响应式设计

定义不同屏幕尺寸的断点:

  • 桌面 (>1200px):多列网格
  • 平板 (768-1200px):2列布局
  • 移动 (<768px):单列堆叠

使用 Tremor 快速开始

基本KPI仪表板

import { Card, Grid, Metric, Text, BadgeDelta, AreaChart } from '@tremor/react';

function QuickDashboard({ data }) {
  return (
    <Grid numItems={1} numItemsSm={2} numItemsLg={4} className="gap-4">
      {/* KPI 卡片 */}
      <Card>
        <Text>总收入</Text>
        <Metric>$45,231.89</Metric>
        <BadgeDelta deltaType="increase">+12.5%</BadgeDelta>
      </Card>

      <Card>
        <Text>活跃用户</Text>
        <Metric>1,234</Metric>
        <BadgeDelta deltaType="decrease">-2.3%</BadgeDelta>
      </Card>

      {/* 图表小部件 */}
      <Card className="lg:col-span-2">
        <Text>收入趋势</Text>
        <AreaChart
          data={data.revenue}
          index="date"
          categories={["revenue"]}
          valueFormatter={(value) => `$${value.toLocaleString()}`}
        />
      </Card>
    </Grid>
  );
}

完整实现见 examples/tremor-dashboard.tsx

可定制仪表板实施

拖放网格布局

import { Responsive, WidthProvider } from 'react-grid-layout';
import 'react-grid-layout/css/styles.css';

const ResponsiveGridLayout = WidthProvider(Responsive);

function CustomizableDashboard() {
  const [layouts, setLayouts] = useState(getStoredLayouts());

  return (
    <ResponsiveGridLayout
      layouts={layouts}
      breakpoints={{ lg: 1200, md: 996, sm: 768 }}
      cols={{ lg: 12, md: 10, sm: 6 }}
      rowHeight={60}
      onLayoutChange={(layout, layouts) => {
        setLayouts(layouts);
        localStorage.setItem('dashboardLayout', JSON.stringify(layouts));
      }}
      draggableHandle=".widget-header"
    >
      <div key="kpi1">
        <KPIWidget data={kpiData} />
      </div>
      <div key="chart1">
        <ChartWidget data={chartData} />
      </div>
      <div key="table1">
        <TableWidget data={tableData} />
      </div>
    </ResponsiveGridLayout>
  );
}

完整示例和小部件目录见 examples/customizable-dashboard.tsx

实时数据模式

服务器发送事件(推荐)

最佳用于从服务器到仪表板的单向更新:

function useSSEUpdates(endpoint) {
  useEffect(() => {
    const eventSource = new EventSource(endpoint);

    eventSource.onmessage = (event) => {
      const update = JSON.parse(event.data);
      // 更新特定小部件或所有小部件
      dispatch({ type: 'UPDATE_WIDGET', payload: update });
    };

    return () => eventSource.close();
  }, [endpoint]);
}

WebSocket(用于双向)

当仪表板需要向服务器发送命令时使用:

const ws = new WebSocket('ws://localhost:3000/dashboard');
ws.onmessage = (event) => {
  const data = JSON.parse(event.data);
  updateDashboard(data);
};
// 发送过滤器更改到服务器
ws.send(JSON.stringify({ type: 'FILTER_CHANGE', filters }));

智能轮询回退

用于不支持WebSocket/SSE的环境:

function useSmartPolling(fetchData, interval = 30000) {
  const [isPaused, setIsPaused] = useState(false);

  useEffect(() => {
    if (isPaused || document.hidden) return;

    const timer = setInterval(fetchData, interval);
    return () => clearInterval(timer);
  }, [isPaused, interval]);

  // 标签页不活跃时暂停
  useEffect(() => {
    const handleVisibilityChange = () => {
      setIsPaused(document.hidden);
    };
    document.addEventListener('visibilitychange', handleVisibilityChange);
    return () => document.removeEventListener('visibilitychange', handleVisibilityChange);
  }, []);
}

详细模式包括错误处理和重连,见 references/real-time-updates.md

性能优化

懒加载策略

function DashboardGrid({ widgets }) {
  const [visibleWidgets, setVisibleWidgets] = useState(new Set());

  return widgets.map(widget => (
    <LazyLoad
      key={widget.id}
      height={widget.height}
      offset={100}
      once
      placeholder={<WidgetSkeleton />}
    >
      <Widget {...widget} />
    </LazyLoad>
  ));
}

并行数据获取

// 同时获取所有小部件数据
const loadDashboard = async () => {
  const [kpis, charts, tables] = await Promise.all([
    fetchKPIs(),
    fetchChartData(),
    fetchTableData()
  ]);

  return { kpis, charts, tables };
};

小部件级缓存

function CachedWidget({ id, fetcher, ttl = 60000 }) {
  const cache = useRef({ data: null, timestamp: 0 });

  const getData = async () => {
    const now = Date.now();
    if (cache.current.data && now - cache.current.timestamp < ttl) {
      return cache.current.data;
    }

    const fresh = await fetcher();
    cache.current = { data: fresh, timestamp: now };
    return fresh;
  };

  // 获取新数据时使用缓存数据
  return <Widget data={cache.current.data} onRefresh={getData} />;
}

分析和优化仪表板性能,运行:

python scripts/optimize-dashboard-performance.py --analyze dashboard-config.json

跨技能集成

使用数据可视化组件

参考 data-viz 技能以获取图表小部件:

// 使用 data-viz 技能的图表
import { createChart } from '../data-viz/chart-factory';

const revenueChart = createChart('area', {
  data: revenueData,
  xAxis: 'date',
  yAxis: 'revenue',
  theme: dashboardTheme
});

集成数据表

参考 tables 技能以获取数据网格:

// 使用 tables 技能的高级表格
import { DataGrid } from '../tables/data-grid';

<DataGrid
  data={transactions}
  columns={columnDefs}
  pagination={true}
  sorting={true}
  filtering={true}
/>

应用设计令牌

使用 design-tokens 技能以获取一致主题:

// 来自 design-tokens 技能的仪表板特定令牌
const dashboardTokens = {
  '--dashboard-bg': 'var(--color-bg-secondary)',
  '--widget-bg': 'var(--color-white)',
  '--widget-shadow': 'var(--shadow-lg)',
  '--kpi-value-size': 'var(--font-size-4xl)',
  '--kpi-trend-positive': 'var(--color-success)',
  '--kpi-trend-negative': 'var(--color-error)'
};

过滤器输入组件

可选使用 forms 技能以获取过滤器控制:

// 来自 forms 技能的高级过滤器输入
import { DateRangePicker, MultiSelect } from '../forms/inputs';

<FilterPanel>
  <DateRangePicker onChange={handleDateChange} />
  <MultiSelect options={categories} onChange={handleCategoryFilter} />
</FilterPanel>

库选择指南

选择 Tremor 当:

  • 需要快速构建仪表板
  • 想要预样式化、专业的组件
  • 在项目中使用 Tailwind CSS
  • 构建标准分析界面
  • 有限的自定义需求

选择 react-grid-layout 当:

  • 用户需要自定义布局
  • 需要拖放功能
  • 不同用户需要不同视图
  • 构建仪表板构建工具
  • 最大灵活性是优先事项

结合两者当:

  • 使用 Tremor 获取小部件内容(KPI、图表)
  • 使用 react-grid-layout 进行布局管理
  • 获得两者最佳

捆绑资源

脚本(无令牌执行)

  • scripts/generate-dashboard-layout.py - 生成响应式网格配置
  • scripts/calculate-kpi-metrics.py - 计算趋势、比较、迷你图表
  • scripts/validate-widget-config.py - 验证小部件和过滤器配置
  • scripts/optimize-dashboard-performance.py - 分析和优化性能
  • scripts/export-dashboard.py - 导出仪表板到各种格式

直接运行脚本,无需加载到上下文:

python scripts/calculate-kpi-metrics.py --data metrics.json --period monthly

参考(详细模式)

  • references/kpi-card-patterns.md - KPI卡片设计模式和变体
  • references/layout-strategies.md - 网格系统和响应式方法
  • references/real-time-updates.md - WebSocket、SSE和轮询实施
  • references/filter-coordination.md - 跨小部件过滤器同步
  • references/performance-optimization.md - 高级优化技术
  • references/library-guide.md - 详细的Tremor和react-grid-layout指南

示例(完整实施)

  • examples/sales-dashboard.tsx - 完整销售分析仪表板
  • examples/monitoring-dashboard.tsx - 带警报的实时监控
  • examples/executive-dashboard.tsx - 精美的执行报告
  • examples/customizable-dashboard.tsx - 带持久性的拖放
  • examples/tremor-dashboard.tsx - 快速Tremor实施
  • examples/filter-context.tsx - 全局过滤器协调

资产(模板和配置)

  • assets/dashboard-templates.json - 预构建仪表板布局
  • assets/widget-library.json - 小部件目录和配置
  • assets/grid-layouts.json - 响应式网格配置
  • assets/kpi-formats.json - 数字格式化规则
  • assets/theme-tokens.json - 仪表板特定设计令牌

仪表板创建工作流

  1. 定义需求:固定或可定制?实时还是静态?
  2. 选择库:Tremor用于快速,react-grid-layout用于灵活
  3. 设置结构:全局状态、过滤器上下文、布局系统
  4. 构建小部件:KPI卡片、图表(数据可视化技能)、表格(表格技能)
  5. 实施数据流:获取策略、缓存、更新
  6. 添加交互性:过滤器、下钻、导出
  7. 优化性能:懒加载、并行获取、缓存
  8. 应用主题:使用设计令牌以保持样式一致
  9. 测试响应式:桌面、平板、移动断点
  10. 部署和监控:跟踪性能、用户参与度

特定模式和详细实施,探索上述引用的捆绑资源。