構建介面

儀表盤

由繫結到具名資料集的圖表元件構成的分析頁面 —— 帶有全域性過濾、自動重新整理,以及到底層記錄的下鑽。

儀表盤是一格格元件組成的網格;每個元件都繫結一個數據集。 資料集是 語義層:它擁有基礎物件、關聯、維度和度量。元件按名稱選擇這些內容,所以 "收入"在每個使用它的儀表盤和報表上含義都相同。

// One dashboard, bound to the `sales` dataset defined below.
const salesDashboard = {
  name: 'sales_overview',
  label: 'Sales Overview',
  description: 'Key sales metrics and pipeline analysis',
  refreshIntervalSeconds: 300,            // auto-refresh every 5 minutes

  dateRange: {
    field: 'close_date',
    defaultRange: 'this_quarter',
    allowCustomRange: true,
  },

  widgets: [
    { id: 'total_revenue',     title: 'Total Revenue',     type: 'metric',
      dataset: 'sales', values: ['revenue'],
      layout: { x: 0, y: 0, w: 3, h: 2 } },
    { id: 'revenue_by_region', title: 'Revenue by Region', type: 'bar',
      dataset: 'sales', dimensions: ['region'], values: ['revenue'],
      layout: { x: 3, y: 0, w: 6, h: 4 } },
    { id: 'deals_by_month',    title: 'Deals by Month',    type: 'pie',
      dataset: 'sales', dimensions: ['close_month'], values: ['deal_count'],
      layout: { x: 9, y: 0, w: 3, h: 4 } },
  ],
}

儀表盤屬性

屬性型別必需說明
namestring是機器名(snake_case)
labelstring是顯示標籤
descriptionstring—儀表盤描述
widgetsDashboardWidget[]是圖表和指標元件
refreshIntervalSecondsnumber—自動重新整理間隔,單位為秒
dateRangeobject—全域性日期範圍過濾
globalFiltersGlobalFilter[]—互動式過濾控制元件

先有資料集

定義一次資料集;把每個元件都繫結到它上面:

import { defineDataset } from '@objectstack/spec/ui'

export const salesDataset = defineDataset({
  name: 'sales',
  label: 'Sales',
  object: 'opportunity',
  include: ['account'],
  dimensions: [
    { name: 'region',      field: 'account.region', type: 'string' },
    { name: 'close_month', field: 'close_date',     type: 'date', dateGranularity: 'month' },
  ],
  measures: [
    { name: 'revenue',    field: 'amount', aggregate: 'sum' },
    { name: 'deal_count', aggregate: 'count' },
  ],
})

聚合方式定義在資料集的度量上(aggregate),而不是在元件上:count、 sum、avg、min、max、count_distinct、array_agg、string_agg。 元件的 dimensions 和 values 必須引用它所繫結的資料集上宣告的名稱。

在執行時,資料集查詢經由分析服務執行,並自動對基礎物件和關聯物件應用 呼叫者的行級安全範圍 —— 儀表盤永遠不會向用戶展示其 許可權不允許看到的記錄。

從 16.0 起,元件的 schema 是嚴格的:一個未宣告的頂層鍵 —— 拼寫錯誤、 憑空編造的鍵,或已移除的內聯查詢鍵(object + categoryField + valueField + aggregate,透視表的 rowField / columnField)—— 都是 會點名出錯鍵的解析錯誤,並指向資料集的形態,而不再被悄悄剝離成一個 什麼也不渲染的元件。定義一個數據集並把元件繫結到它;options 仍然是 用於渲染器特有附加項的自由逃生艙。

元件

屬性型別必需說明
idstring是唯一的元件 id(snake_case)
datasetstring是要繫結的資料集名稱
valuesstring[]是度量名稱(至少一個)
dimensionsstring[]—維度名稱 —— X 軸 / 分組 / 拆分
typeChartType—視覺化型別(預設 metric)
title / descriptionstring—顯示標題和副標題
filterFilterCondition—展示範圍的過濾條件
layoutobject—網格位置(省略時自動排布)
colorVariantenum—KPI / 卡片的強調色
compareToenum | object—同期對比的時間視窗
filterBindingsobject—按元件的全域性過濾對映(見下文)

圖表型別

型別最適合
metric (預設)單個數字的 KPI —— 收入、數量、百分比
bar / horizontal-bar / column類別比較
line隨時間的趨勢
pie / donut分佈
area隨時間的總量
scatter相關性
radar多維比較
funnel轉化階段
gauge / solid-gauge / bullet / kpi目標完成進度
treemap / sankey層級佔比 / 流向
table明細記錄 —— 可下鑽
pivot交叉彙總 —— 可下鑽

佈局

元件放在一個 12 列的網格上:

// Keys of a dashboard widget; its other keys are omitted.
layout: {
  x: 0,    // column position (0-11)
  y: 0,    // row position
  w: 6,    // width in columns (1-12)
  h: 4,    // height in rows
}

下鑽

table 和 pivot 元件可下鑽:點選一個聚合行或單元格,會開啟一個側邊 抽屜,列出該分組背後的底層記錄。資料集保留了原始的分組鍵,所以抽屜的 過濾條件精確匹配那些記錄 —— 不需要從標籤去猜 id。點選抽屜中的任意一行 即可開啟該記錄的詳情:完整的分組 → 記錄列表 → 記錄鏈路。

抽屜還提供一個 "Open in list →" 出口,把這次快速檢視升級為該物件的 完整列表頁(排序、批次選擇、匯出、可分享的 URL),範圍仍由同一個下鑽 過濾條件限定。

圖表元件的下鑽方式相同:點選一根柱子、一個點或一塊扇區,抽屜就會列出該 分桶中的記錄 —— 對日期維度,精確限定為該分桶的日期範圍。只要資料集暴露了 基礎物件、且元件至少按一個維度分組,下鑽就是自動的 —— 不需要按元件配置。 metric 卡片只顯示聚合值。報表的下鑽方式也一樣。

全域性日期範圍和過濾條件

全域性時間過濾作用於所有元件:

// Keys of a dashboard; its other keys are omitted.
dateRange: { field: 'created_at', defaultRange: 'this_month', allowCustomRange: true }

預設範圍:today、yesterday、this_week、last_week、this_month、 last_month、this_quarter、last_quarter、this_year、last_year、 last_7_days、last_30_days、last_90_days、custom。

互動式全域性過濾的工作方式相同:

// Keys of a dashboard; its other keys are omitted.
globalFilters: [
  { name: 'region', field: 'region', label: 'Region',    type: 'select' },
  { field: 'owner',                  label: 'Sales Rep', type: 'lookup' },
]

每個過濾條件的 name(預設為 field)是它穩定的身份 —— 元件在 filterBindings 中引用的就是這個鍵,它也是在元件表示式中可以通過 page.<name> 讀取的儀表盤級變數。名稱 dateRange 保留給內建的日期範圍。

按元件的過濾繫結

預設情況下,一個過濾條件會作用於每個元件上它自己的 field。當某個元件 把這個概念存放在另一個欄位下 —— 或者應該忽略某個過濾條件 —— 時,宣告 filterBindings:

// Keys of a dashboard; each widget's dataset, values and title are omitted (`/* … */`).
widgets: [
  // Default binding: dateRange → created_at, region → region.
  { id: 'invoices_by_status', /* … */ },
  // This widget's fields differ — map each filter explicitly.
  { id: 'accounts_signed',
    filterBindings: { dateRange: 'signed_at', region: 'sales_region' }, /* … */ },
  // Opt out of a filter with `false`.
  { id: 'total_invoices', filterBindings: { region: false }, /* … */ },
]

優先順序:顯式的 filterBindings 條目(字串覆蓋或 false 退出)→ 過濾 條件舊有的 targetWidgets 允許列表 → 過濾條件自己的 field。

把儀表盤呈現出來

在一個應用中新增一個 dashboard 導航入口:

// One navigation item of an app.
{ id: 'nav_analytics', type: 'dashboard', label: 'Analytics',
  dashboardName: 'sales_overview', icon: 'bar-chart' }

或者向 AI Builder 描述它 —— "一個銷售概覽 儀表盤,包含按區域的收入和每月成交趨勢" —— 並在批准前審閱生成的資料集 和儀表盤後設資料。

下一步

頁面為什麼
報表基於同一批資料集的分組報表和交叉報表
應用把儀表盤放進導航
檢視基於同一批資料集的內嵌 chart 列表檢視
頁面元件網格不夠用時的自由佈局
資料模型你的資料集所聚合的物件
許可權儀表盤繼承的行級安全