儀表盤
由繫結到具名資料集的圖表元件構成的分析頁面 —— 帶有全域性過濾、自動重新整理,以及到底層記錄的下鑽。
儀表盤是一格格元件組成的網格;每個元件都繫結一個數據集。 資料集是 語義層:它擁有基礎物件、關聯、維度和度量。元件按名稱選擇這些內容,所以 "收入"在每個使用它的儀表盤和報表上含義都相同。
// 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 } },
],
}儀表盤屬性
| 屬性 | 型別 | 必需 | 說明 |
|---|---|---|---|
name | string | 是 | 機器名(snake_case) |
label | string | 是 | 顯示標籤 |
description | string | — | 儀表盤描述 |
widgets | DashboardWidget[] | 是 | 圖表和指標元件 |
refreshIntervalSeconds | number | — | 自動重新整理間隔,單位為秒 |
dateRange | object | — | 全域性日期範圍過濾 |
globalFilters | GlobalFilter[] | — | 互動式過濾控制元件 |
先有資料集
定義一次資料集;把每個元件都繫結到它上面:
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仍然是 用於渲染器特有附加項的自由逃生艙。
元件
| 屬性 | 型別 | 必需 | 說明 |
|---|---|---|---|
id | string | 是 | 唯一的元件 id(snake_case) |
dataset | string | 是 | 要繫結的資料集名稱 |
values | string[] | 是 | 度量名稱(至少一個) |
dimensions | string[] | — | 維度名稱 —— X 軸 / 分組 / 拆分 |
type | ChartType | — | 視覺化型別(預設 metric) |
title / description | string | — | 顯示標題和副標題 |
filter | FilterCondition | — | 展示範圍的過濾條件 |
layout | object | — | 網格位置(省略時自動排布) |
colorVariant | enum | — | KPI / 卡片的強調色 |
compareTo | enum | object | — | 同期對比的時間視窗 |
filterBindings | object | — | 按元件的全域性過濾對映(見下文) |
圖表型別
| 型別 | 最適合 |
|---|---|
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 描述它 —— "一個銷售概覽 儀表盤,包含按區域的收入和每月成交趨勢" —— 並在批准前審閱生成的資料集 和儀表盤後設資料。