在先前的文章中我們接觸過了許多 Dashboard 或是 Panel 上的 control 元件,包括 Variables 的下拉選單、TimeRange 的選單、AdHocFiltersVariable 的多重篩選器等等。除此之外,Grafana 也提供了許多 control 元件讓使用者可以進行更多操作,例如更多功能的時間操作、Input 元件、Button 元件等等,本章節將繼續為介紹有哪些元件可以增加 Dashboard 的互動性。
在 Dashboard 中顯示的所有屬性都會在 SceneAppPage 或 EmbeddedScene 的 controls 屬性中設置,所以在介紹元件本身之前,我們需要了解 controls 的運作機制。其實 controls 的處理非常簡單,把在陣列中收集的 controller 做 map 列出,而每個 controller 都是 Scene Object,所以直接調用其中 Component 屬性,即可將元件渲染而出。
{controls && (
<div className={styles.controls}>
{controls.map((control) => (
<control.Component key={control.state.key} model={control} />
))}
</div>
)}
這是一個在 Grafana Scenes 中提供的時間比較功能,在許多使用場景中會需要比較兩個時間區間的趨勢圖,可以識別季節性模式、週期性變化或長期趨勢,讓開發者更容易發現異常或偏差,可用於效能監控和問題診斷。
使用 SceneTimeCompare 可以不需要再進行額外的設定或手動資料請求,即可在圖表中顯示另一條時間範圍的資料線圖。在 controls 中加入 new SceneTimeCompare({})
後會顯示一個混合元件在操作區塊(Dashboard 的右上角),可自行選擇是否顯示時間比較的曲線,勾選後可以再選擇需選擇的區間,預設的區間有:
SceneTimeCompare 在 Grafana Scenes 中實現時間範圍比較時,比較時間範圍的數據請求是通過 SceneTimeCompare 的內部機制處理的,該機制將請求參數集中在 getExtraQueries
方法中。這與 SceneQueryRunner 的數據請求流程很有關聯。在第十一章節〖從 Grafana Scenes 請求資料〗中對 SceneQueryRunner 的介紹時,有提及 data 是使用 runWithTimeRange
的內部函數做一系列請求處理,在這個過程中,首先執行 primary request 取得原始資料,然後 runWithTimeRange
會檢查是否存在需要額外請求的實例,如果有,會從該實例的 getExtraQueries
方法中獲取額外的請求參數,並發起一個 secondary request,最後將回傳的資料實現在圖表中。
可以在 Panel 的 setOverrides API 對比較的資料圖層進行樣式的修改,使用 matchComparisonQuery
並以請求資源的 refId 為參數取得欄位,再進行各式的修改,例如顏色或 legend 的顯示名稱:
body: PanelBuilders.timeseries()
.setTitle('Humidity over time')
.setUnit('humidity')
.setOverrides((b) =>
b
.matchComparisonQuery('Humidity')
.overrideColor({
mode: FieldColorModeId.Fixed,
fixedColor: 'red',
})
.overrideDisplayName(`${roomName} Comparison`)
)
.build(),
SceneControlsSpacer 的主要功能是在控制元件之間創建空白空間。可以被插入到一系列控制元件中,達到視覺上的分隔。SceneControlsSpacer 本身是一個 flex 為 1 的 <div/>
標籤,因此可以撐開 flex box 中剩餘的空間:
<div style="flex:1"></div>
SceneControlsSpacer 通常不需要任何特殊的設置,只需要放在希望出現空白的位置即可。它會根據周圍的元件自動調整。以下是與其他 Scene 元件一起使用時的一些範例:
未使用 SceneControlsSpacer 時:所有元件以 flex-start
排序
controls: [
new VariableValueSelectors({}),
customObject,
new SceneTimePicker({}),
new SceneRefreshPicker({}),
],
使用一個 SceneControlsSpacer 時:
controls: [
new VariableValueSelectors({}),
new SceneControlsSpacer(),
customObject,
new SceneTimePicker({}),
new SceneRefreshPicker({}),
],
使用多個 SceneControlsSpacer 時:
controls: [
new VariableValueSelectors({}),
new SceneControlsSpacer(),
customObject,
new SceneTimePicker({}),
new SceneControlsSpacer(),
new SceneRefreshPicker({}),
],
SceneRefreshPicker 提供了一個用於設置數據資料刷新間隔的下拉選單。這個元件通常用於控制 Panel 或 Dashboard 的自動刷新功能。
SceneRefreshPicker 的主要功能包括:
以下範例為設置下拉選單包含 '5s', '1m', '1h' 的選項:
controls: [
new SceneRefreshPicker({
intervals: ['5s', '1m', '1h'],
}),
],
SceneRefreshPicker 除了提供 intervals 屬性讓我們能夠自定義選單選項,也提供了以下的屬性,讓元件及功能更多樣化:
refresh:可以設定一個時間間隔值,若有設值時,是作為頁面載入後的預設刷新間隔時間,若在下拉選單選擇其他選項,則會同時更新 refresh,並作為請求依據。
withText:為 boolean 值,代表是否顯示 Refresh 字樣。下圖為未顯示時的圖示:
primary:為 boolean 值,可以改變按鈕的主題色。
autoEnabled:預設為 true,若設為 false 則預設選單不會有 auto 選項。
autoValue:表示自動刷新計算出的間隔值。當選擇 auto 時,這個值會根據當前的時間範圍和其他因素計算得出,並用於設置自動刷新的頻率。而算出的值不論是否啟用 withText,皆會顯示在Refresh 字樣的位置:
SceneToolbarButton 是一個可用於 Grafana Scenes 中的按鈕元件。它提供了包含 icon(按鈕圖標)和 onClick(點擊事件)的屬性,可以自定義點擊後的行為。例如轉跳頁面,或是額外調用 Scenes 的功能進行操作。
controls: [
new SceneToolbarButton({
icon: 'document-info',
onClick: () => {
console.log('Hello World');
},
}),
],
SceneToolbarInput 是一個輸入框元件,包含 value(輸入框的值)、label(輸入框的標籤)和 onChange 三個狀態,如果 label 未設置時,則為上圖的一個空輸入框。
下述範例中即為藉由 input 的 onChange 進行 queryRunner 的動態請求:
controls: [
new SceneToolbarInput({
value: '2',
label: 'Series count',
onChange: (newValue) => {
queryRunner.setState({
queries: [
{
...queryRunner.state.queries[0],
seriesCount: newValue,
},
],
});
queryRunner.runQueries();
},
}),
],
筆者語錄
在這一章節中,我們探討了多種可用於 Grafana Scenes 的控制元件,從時間比較功能到刷新設定、空白分隔元件,以及按鈕和輸入框等。這些元件不僅提升了 Dashboard 的互動性,還提供了靈活的設定屬性,讓開發者可以根據實際需求進行調整和優化。尤其 SceneToolbarButton 和 SceneToolbarInput 雖然看似沒有什麼額外的功能,但藉由 Scenes 的一些操作 API 或 hooks,能動態地讓 Dashboard 的操作有很多變化。