iT邦幫忙

2024 iThome 鐵人賽

DAY 13
2

https://ithelp.ithome.com.tw/upload/images/20240927/20152073IMVKu7Yj44.png

前言

在前面的篇章中,我們從 Plugin 的初始化設置、時間範圍及變數設定到數據資料的取得,這一系列的資料收集方法即是為了視覺化的呈現,所以本章節會介紹圖表元件建置的方法,以及元件或實例提供的屬性設定方法。本章節會專注於屬性及功能的設置,以及實現的過程,而非各個圖表本身的功能細節,想詳細了解可以參考第五及第六章的介紹。視覺化的呈現是完成整個 Dashboard 的最後步驟,接下來就進入 Panel 的世界吧!

建置的方法

在第四章的介紹中有提到,一個 Panel 不是只有『圖』本身,還有包括圖表的標示、描述以及操作等等,因此 Grafana 提供的方法中也涵蓋了這所有的設定。而要在 Scenes 中設置 Panel 有兩種方法:以 VizPanel 實例的方式和 API 工具 PanelBuilders。

兩種方式皆可以達到相同的 Panel 呈現結果,VizPanel 是以建立一個實例 new VizPanel({}) 的方式並帶入各種屬性來實現;而 PanelBuilders 則是簡化了 VizPanel 的步驟所封裝的一個 API,PanelBuilders 最後也返回一個 VizPanel 來建立 Panel:

public build() {
  const panel = new VizPanel<TOptions, TFieldConfig>({
    ...this._state,
    options: this._panelOptionsBuilder.build(),
    fieldConfig: this._fieldConfigBuilder.build(),
  });

  return panel;
}

而兩者的差異在於 VizPanel 的屬性包含許多巢狀的設定值,在 PanelBuilders 則是將這些屬性扁平化,以 setXXXX 的方式接續著設定,最後進行 build() 創建一個 Panel,以下範例:

  • new VizPanel
const panel = new VizPanel({
  title: "My Panel Title",
  description: "This is a description of my panel.",
  fieldConfig: {
    defaults: {
      decimals: 2,
      unit: "ms",
    },
    overrides: [],
  },
  $data: myData,
});
  • PanelBuilders
const panelBuilder = PanelBuilders.timeseries()
  .setTitle("My Panel Title")
  .setDescription("This is a description of my panel.")
  .setUnit("ms") // 直接設置單位
  .setDecimals(2) // 直接設置小數位數
  .setData(myData);

由上述的範例可以觀察到兩種方式的差異,而這些 Panel 的設定有分為每種 Panel 都適用的標準屬性以及各個 Panel 專屬的屬性,例如 Bar chart 有著可以設定長條圖的寬度和其他樣式;Time Series 可以設置 legend 和 tooltip,但 Log 圖表就沒有此設定。所以會依據圖表的特型有不同地可設定屬性,而在 PanelBuilders 方法中設定這些屬性只需要調用 setOption 依屬性名稱進行設定:

PanelBuilders.timeseries()
  .setTitle("Basic panel")
  .setOption("legend", {
    displayMode: LegendDisplayMode.Hidden,
  })
  .setOption("tooltip", {
    mode: TooltipDisplayMode.Multi,
  })
  .build();

且 PanelBuilders 方法中也有 TypeScript 的提示,方便使用者在設定時了解該類型的 Panel 有什麼可以使用的屬性:

https://ithelp.ithome.com.tw/upload/images/20240927/20152073JtIWY1EBKp.png

標準屬性設定

VizPanel 和 PanelBuilders 方法皆需要設定一些基本的屬性,例如 Title、Description 等,但有些進階屬性可以調整更細節的功能,而設定的方法不同,接下來會列出一些較為特殊的屬性進行比較:

初始化

調用 VizPanel 和 PanelBuilders 兩個方法時皆需要設定使用哪一種 Panel,VizPanel 預設是使用 timeseries 類型,而其他的設定方法:

  • VizPanel:屬性中有個 pluginId,通常是引用 Plugin 所建立的 ID,也可以是通過 registerScenePanelPlugin 函數註冊 PanelPlugin 時所設定的思ID。
  • PanelBuilders:在調用 PanelBuilders 後的第一個參數必須接續想要設定 Panel 的類型,才能繼續設置其他的 set 屬性。
// VizPanel
new VizPanel({
  pluginId: 'timeseries',
}),

// PanelBuilders
PanelBuilders.piechart().build()

Header Actions

可以在 Panel 頂端設置各種操作功能,屬性接受的類型包括 ReactNode、SceneObject 和 SceneObject[],因此可以設置自由度很高的元件,樣式部分則是依序在右上角中排列:

https://ithelp.ithome.com.tw/upload/images/20240927/20152073InJxOsuTgg.png

// VizPanel
headerActions: [
  <Link key="link" href="https://grafana.com">
    Link
  </Link>,
],

// PanelBuilders
.setHeaderActions(
  <Link key="link" href="https://grafana.com">
    Link
  </Link>
)

Hover Hearder

為一個 Boolean 值的屬性,代表 Panel 的 Header 區塊會在 Hover 後浮動顯示出來,預設是 false 代表固定在頂端。而 VizPanel 和 PanelBuilders 的設置方法為一致。

https://ithelp.ithome.com.tw/upload/images/20240927/201520730eEcOJ5E9V.png

// PanelBuilders
setHoverHeader(true)

Links

在 Panel 選擇某一個數值時可以在 Tooltip 中設置連結,會顯示下圖中的連結樣式,這個屬性可以設定多個 url,並且可以透過 variable 作為動態的 url。

https://ithelp.ithome.com.tw/upload/images/20240927/20152073Rghl7Idyl3.png

// VizPanel
fieldConfig: {
  defaults: {
    links: [
      {
        title: 'Link 1',
        url: 'https://grafana.com',
      },
    ],
  },
  overrides: [],
},

// PanelBuilders
setLinks([
  {
    title: 'Link 1',
    url: 'https://grafana.com',
  },
])

Mappings

此屬性能自定義在圖表中顯示的數值,可以設定一些規則使原始資料轉換或映射。可支援的映射類型包括:value、range、regex 和 special:

  1. value:可以將以 string 呈現的值映射到不同的顯示文字或顏色,例如下圖中將值為 180 的數值顯示為『離線』並呈現紅色。
  2. range:設定數值範圍,以 from 和 to 的方式將某個範圍的數值設為特定顏色和文字,例如下圖0 ~ 50 的值皆以藍色顯示為『低』。
  3. regex:以正則表達式對應到文字和顏色,例如:一個值是 www.example.com,可以射置一個正則表達式值,使 Grafana 顯示「www」,並截斷域名。
  4. special:將特殊值如 Null、NaN(非數字)和布林值如 true 和 false 對應到需顯示的文字和顏色。
// VizPanel
fieldConfig: {
  defaults: {
    mappings: [
      {
        type: MappingType.RangeToText,
        options: {
          from: 0,
          to: 65,
          result: { text: '低', color: 'blue' },
        },
      },
    ],
  },
  overrides: [],
},

// PanelBuilders
.setMappings([
  {
    type: MappingType.RangeToText,
    options: {
      from: 0,
      to:65,
      result: { text: '低', color: 'blue' },
    },
  }
])

https://ithelp.ithome.com.tw/upload/images/20240927/20152073E0C02zvQ5h.png
https://ithelp.ithome.com.tw/upload/images/20240927/20152073lnTeOK6GrA.png

CustomFieldConfig

CustomFieldConfig 可以為特定欄位設置自定義的顯示內容和行為規則。可以包括單位、小數位數、最小/最大值等設置。VizPanel 是在 fieldConfig 的 defaults 的 custom 屬性設置;PanelBuilders 模式則是以 setCustomFieldConfig API 建置。可以設定的屬性為每一種 Panel 特有的 Field Config,例如:

  • timeseries:setCustomFieldConfig('axisLabel', 'Custom label')setCustomFieldConfig('thresholdsStyle', { mode: GraphThresholdsStyleMode.Area })
  • table:setCustomFieldConfig('cellOptions', { type: TableCellDisplayMode.Auto })

Thresholds

閾值用於重新定義數據資料的邊界點,通常用不同的顏色來表示不同的數據範圍。thresholds 的設定必須包含兩個屬性 - mode 和 steps,mode 可設為 absolute 和 percentage,absolute 為預設值可以在 steps 中設定指定數值,而若設定為 percentage 則 value 需設定 0 ~ 1 之間。

此設定通常會使用在 time series 的區域顯示、stat 圖表的背景及數值色、gauge、state time series 等可以顯示數值區間差別的圖表。而預設顯示的顏色是 green,數值超過 80 會顯示紅色。

💡NOTICE
某些類型的 Panel 需要設定 thresholds 的顯示類型(thresholdsStyle)才可以使這個屬性依據顏色顯示,例如:bar chart、candlestick、time series 以及 trend 圖表。

https://ithelp.ithome.com.tw/upload/images/20240927/20152073xCe56m71rj.png

// VizPanel
fieldConfig: {
  defaults: {
    thresholds: {
      mode: ThresholdsMode.Absolute,
      steps: [
        { value: -9, color: 'green' },
        { value: 0, color: 'blue' },
        { value: 9, color: 'red' },
      ],
    },
  },
  overrides: [],
},

// PanelBuilders
.setThresholds({
  mode: ThresholdsMode.Absolute,
  steps: [
    { value: -9, color: 'green' },
    { value: 0, color: 'blue' },
    { value: 9, color: 'red' },
  ],
})

Overrides

覆蓋特定字段或匹配特定條件的數據設置特殊規則,並覆蓋預設的設定。可以使用 matchermatchFieldsByXXXX 等 API 取得欲覆蓋的欄位,再使用 properties 屬性或在 PanelBuilders 中使用 overrideXXXX 的 API 進行值的修改。可修改的欄位包含所有的標準屬性及 Panel 的指定屬性。此方法可以讓使用者覆蓋多個屬性以及更精細的欄位設置。

💡NOTICE
PanelBuilders 的 macher API 包含:matchFieldsWithNamematchFieldsWithNameByRegexmatchFieldsByTypematchFieldsByQuerymatchFieldsByValuematchComparisonQuery

// VizPanel
fieldConfig: {
  defaults: {},
  overrides: [
    {
      matcher: {
        id: FieldMatcherID.byRegexp,
        options: '.*',
      },
      properties: [
        { id: 'filterable', value: false },
        
      ],
    },
  ],
},

// PanelBuilders
.setOverrides((b) =>
  b
    .matchFieldsWithNameByRegex('.*')
    .overrideFilterable(false)
    ])
)

Panel Menu

設定在 Panel 右上角的下拉選單中的選項。不論是 VizPanel 或 PanelBuilders 模式皆須以 new VizPanelMenu 的方式建立一個選單實例,VizPanel 是定義於 menu 屬性中,而 PanelBuilders 是定義在 setMenu 的 API 中。此功能也提供巢狀的選項設置,須以 subItem 的屬性定義:

https://ithelp.ithome.com.tw/upload/images/20240927/20152073EdUhjyqygW.png

new VizPanelMenu({
  items: [
    {
      text: 'Item 1',
      onClick: () => {
        alert('Item 1 clicked');
      },
    },
    {
      text: 'Item 2',
      onClick: () => {
        alert('Item 2 clicked');
      },
      subMenu: [
        {
          text: 'Sub Item 2.1',
          onClick: () => {
            alert('Sub Item 2.1 clicked');
          },
        },
      ],
    },
  ];
});

筆者語錄
Grafana Scenes 的 Panel 屬性實在是太多太複雜,不僅要設定 Panel 的操作功能還要兼顧圖表本身的圖例、顯示、文字數值等的設定。然而官方文件並沒有一一列出可以如何設定或是有什麼參數,如果是第一次接觸的工程師會非常困惑,需要翻閱每個 Panel 的屬性型別才可以進行設定。因此也推薦 PanelBuilders 的 API 設定方式,靠著 TypeScript 的提示降低開發的難度。也希望藉由這篇文章可以讓讀者在操作時更為順利。

參考資料

https://grafana.com/docs/grafana/latest/fundamentals/dashboards-overview/

https://grafana.com/docs/grafana/latest/panels-visualizations/


上一篇
靠 Grafana 吃飯的第十二天 - Grafana Scene 的 Variables 多重宇宙
系列文
論前端工程師如何靠 Grafana 吃飯:從 Grafana App 到前端可觀測性13
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言