Commit f9af7b3b by 五更

release: v0.1.11

parents
# argus-board-react
基于 React 的可嵌入监控仪表盘 Web Component。
## 快速开始
构建产物包含三个文件:
| 文件 | 说明 |
|------|------|
| `dist/argus-board.js` | IIFE 格式,直接用 `<script>` 引入 |
| `dist/argus-board.es.js` | ES Module 格式,用于 `import` |
| `dist/style.css` | 样式文件,两种方式都需要引入 |
### IIFE(`<script>` 标签)
```html
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="dist/style.css" />
</head>
<body>
<argus-board style="width:100%;height:100vh;display:block;"></argus-board>
<script src="dist/argus-board.js"></script>
</body>
</html>
```
### ES Module(`import`)
```js
import 'dist/style.css';
import 'dist/argus-board.es.js';
// 注册完成后即可使用 <argus-board> 标签
document.body.innerHTML = '<argus-board style="width:100%;height:100vh;display:block;"></argus-board>';
```
或在 Vue / React 等框架中:
```js
// main.js / main.ts
import 'dist/style.css';
import 'dist/argus-board.es.js';
```
```html
<!-- 任意组件模板中 -->
<argus-board style="width:100%;height:600px;display:block;"></argus-board>
```
---
## 配置方式
`<argus-board>` 支持两种配置方式,可混合使用:
- **HTML Attribute**:适合简单标量值(布尔、枚举、短字符串),可在 HTML 中静态声明
- **JS Property**:适合大型 JSON 数据(仪表盘配置、预设列表、数据源列表),直接赋值给元素属性,避免 HTML 膨胀
**优先级:JS Property > HTML Attribute**
---
## 配置属性(HTML Attributes)
适合简单标量值,属性变化时组件自动重新渲染。
### 基础配置
| 属性 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| `hide-header` | `"true" \| "false"` | `"false"` | 是否隐藏顶部工具栏 |
| `can-edit` | `"true" \| "false"` | `"true"` | 是否允许进入编辑模式 |
| `theme` | `"dark" \| "light"` | — | 主题,不传时使用用户上次选择 |
| `lang` | `"zh" \| "en"` | `"zh"` | 界面语言 |
### 初始状态
| 属性 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| `locked` | `"true" \| "false"` | — | 初始是否锁定(查看模式)。`true` = 查看,`false` = 编辑,不传时使用上次状态 |
| `editing-panel` | `string` | — | 初始打开编辑器的面板 ID,仅挂载时生效一次 |
### 仪表盘数据
| 属性 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| `initial-config` | `string`(JSON) | — | 初始加载的仪表盘 JSON 字符串,传入时替换默认面板,仅挂载时生效一次。格式见下方说明 |
| `render-default-dashboard` | `"true" \| "false"` | `"true"` | 没有 `initial-config` 时是否渲染内置默认示例面板。设为 `"false"` 时显示空白画布 |
| `presets` | `string`(JSON 数组) | — | 预设列表,用户可从下拉菜单加载。格式见下方说明 |
**`initial-config` 格式:**
```json
{
"title": "我的仪表盘",
"panels": { ... },
"layouts": [ ... ],
"variables": [ ... ]
}
```
> 可通过页面右上角"导出"按钮获取当前仪表盘的 JSON,直接作为 `initial-config` 的值传入。
**`presets` 格式:**
```json
[
{ "label": "网络设备面板", "config": "{...仪表盘JSON字符串...}" },
{ "label": "服务器监控", "config": "{...仪表盘JSON字符串...}" }
]
```
> 下拉菜单中始终包含内置"默认模板"选项,用户自定义预设追加在其后。
### 数据源
| 属性 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| `datasource-config` | `string`(JSON 数组) | — | 数据源配置列表,格式见下方说明 |
**`datasource-config` 格式:**
```json
[
{
"type": "zabbix",
"uid": "zabbix-prod",
"url": "https://zabbix.example.com",
"token": "your-api-token",
"name": "生产 Zabbix",
"default": true
},
{
"type": "argus",
"uid": "argus-main",
"url": "https://argus.example.com",
"token": "your-api-token",
"name": "Argus 主集群"
}
]
```
- `type`:数据源类型,支持 `"zabbix"` / `"argus"`
- `uid`:唯一标识,用于面板绑定;不填时自动用数组下标作为 uid
- `default`:标记为默认数据源,新建查询时优先选中
---
## JS Property API
大型 JSON 数据推荐通过 JS 属性赋值,不写入 HTML attribute,避免 DOM 膨胀。
| 属性 | 类型 | 对应 attribute |
|------|------|----------------|
| `element.initialConfig` | `DashboardConfig \| string \| undefined` | `initial-config` |
| `element.presets` | `PresetConfig[] \| undefined` | `presets` |
| `element.datasourceConfig` | `DataSourceConfig[] \| null` | `datasource-config` |
赋值后组件立即重新渲染,JS Property 优先级高于同名 attribute。
`initialConfig` 接受对象或 JSON 字符串,传对象时内部自动 `JSON.stringify`
```js
const board = document.querySelector('argus-board');
// 直接传对象,无需手动 JSON.stringify
board.initialConfig = {
title: '我的仪表盘',
panels: { ... },
layouts: [ ... ],
};
// 也可以传 JSON 字符串(如从接口直接拿到的响应体)
const res = await fetch('/api/dashboard/1');
board.initialConfig = await res.text();
// 设置数据源(无需 JSON.stringify)
board.datasourceConfig = [
{ type: 'zabbix', uid: 'z1', url: 'https://zabbix.example.com', token: 'xxx', name: 'Zabbix', default: true }
];
// 设置预设列表
board.presets = [
{ label: '网络设备面板', config: networkDashboardJson },
{ label: '服务器监控', config: serverDashboardJson },
];
```
---
## 事件
### `save`
用户点击"保存"按钮时触发,携带当前仪表盘的完整 JSON。
```js
const board = document.querySelector('argus-board');
board.addEventListener('save', (e) => {
const json = e.detail.json; // 仪表盘 JSON 字符串
// 持久化到后端...
});
```
事件属性:`bubbles: true, composed: true`,可穿透 Shadow DOM 冒泡。
---
## 完整示例
### 空白画布(不渲染默认面板)
```html
<argus-board
render-default-dashboard="false"
locked="true">
</argus-board>
```
### 加载已保存的仪表盘
```html
<argus-board
id="board"
locked="true"
render-default-dashboard="false">
</argus-board>
<script>
fetch('/api/dashboard/1').then(r => r.text()).then(json => {
document.getElementById('board').setAttribute('initial-config', json);
});
</script>
```
### 带数据源 + 保存回调
```html
<argus-board
id="board"
theme="dark"
locked="true"
datasource-config='[{"type":"zabbix","uid":"z1","url":"https://zabbix.example.com","token":"xxx","name":"Zabbix","default":true}]'>
</argus-board>
<script>
document.getElementById('board').addEventListener('save', async (e) => {
await fetch('/api/dashboard/save', {
method: 'POST',
body: e.detail.json,
headers: { 'Content-Type': 'application/json' }
});
});
</script>
```
### 带预设的嵌入场景
```html
<argus-board
render-default-dashboard="false"
presets='[{"label":"网络设备","config":"{...}"},{"label":"服务器","config":"{...}"}]'>
</argus-board>
```
---
## 查询选项配置(Query Options)
每个面板支持 `queryOptions` 字段,对应 Query Editor 工具栏下方的 "Query options" 折叠区域:
| 字段 | 类型 | 说明 |
|------|------|------|
| `queryOptions.maxDataPoints` | `number` | 覆盖面板默认 maxDataPoints(默认值:1000)。影响降采样步长 |
| `queryOptions.minIntervalMs` | `number` | 查询最小间隔(ms),0 = 不限制 |
| `queryOptions.relativeTime` | `string` | 相对时间覆盖,如 `"1h"``"30m"`,将查询窗口向前偏移 |
| `queryOptions.timeShift` | `string` | 时间偏移,如 `"1h"`,将 from/to 整体平移 |
`queryOptions.minIntervalMs` 输入框支持 `s / m / h / ms` 后缀(例如 `"30s"` = 30000ms)。
`Interval` 行为只读,显示当前计算值:`ceil((to - from) * 1000 / maxDataPoints)`
---
## 表格面板配置(Table Panel)
表格面板支持以下 `PanelConfig` 字段:
| 字段 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| `tableShowHeader` | `boolean` | `true` | 是否显示列标题 |
| `tableCellHeight` | `'small' \| 'medium' \| 'large'` | `'medium'` | 行高 |
| `tableFrozenColumns` | `number` | `0` | 左侧冻结列数 |
| `tableColumnFilter` | `boolean` | `false` | 启用列过滤器 |
| `tableWrapText` | `boolean` | `false` | 文本换行 |
| `tableEnablePagination` | `boolean` | `false` | 启用分页 |
| `tablePageSize` | `number` | `20` | 每页行数(`tableEnablePagination``true` 时生效) |
| `tableFooterEnabled` | `boolean` | `false` | 显示底部统计行 |
| `tableFooterReducers` | `string[]` | `[]` | 底部聚合函数,取第一个值作为统计方式,支持所有 Grafana ReducerID |
| `tableFooterFields` | `string[]` | `undefined` | 参与底部计算的字段名;空/未设置 = 所有数值字段 |
| `tableMinColumnWidth` | `number` | `100` | 列最小宽度 |
| `tableColumnOverrides` | `Record<string, TableColumnOverride>` | `{}` | 按列名覆盖显示配置 |
### `tableFooterReducers` 支持的值
| 分组 | 值 |
|------|----|
| Standard | `lastNotNull`, `last`, `firstNotNull`, `first`, `min`, `max`, `mean`, `sum`, `count`, `range` |
| Extended | `median`, `stdDev`, `variance`, `delta`, `diff`, `diffperc`, `step`, `logmin`, `countAll`, `changeCount`, `distinctCount` |
| Boolean | `allIsZero`, `allIsNull` |
| Percentile | `p1``p99` |
### `TableColumnOverride` 字段
| 字段 | 类型 | 说明 |
|------|------|------|
| `hidden` | `boolean` | 隐藏该列 |
| `label` | `string` | 覆盖列标题显示名 |
| `width` | `number` | 固定列宽(px) |
| `alignment` | `'auto' \| 'left' \| 'center' \| 'right'` | 列对齐方式 |
| `displayMode` | `TableCellDisplayMode` | 单元格显示模式 |
| `wrapText` | `boolean` | 该列文本换行 |
| `valueRegex` | `{ pattern: string; replace: string }` | 正则替换单元格值 |
**`displayMode` 支持的值:** `auto`, `colored-text`, `colored-background`, `gauge`, `data-links`, `json-view`, `pill`
```json
{
"type": "table",
"title": "API 请求日志",
"tableFooterEnabled": true,
"tableFooterReducers": ["mean"],
"tableColumnOverrides": {
"latency": { "displayMode": "gauge", "label": "延迟 (ms)" },
"status": { "alignment": "center" },
"endpoint": { "width": 200 }
}
}
```
---
## 变量配置弹窗
在编辑模式下(`isEditing === true`),`VariableBar` 右侧会显示 ⚙ 设置图标。点击后弹出变量配置弹窗,支持:
- 查看、新增、编辑、删除所有仪表盘变量
- 支持类型:`custom``query``textbox``datasource``constant`
- 所有修改在点击"保存"后统一提交,取消则丢弃草稿
### VariableConfig 新增字段
| 字段 | 类型 | 说明 |
|------|------|------|
| `description` | `string?` | 变量描述 |
| `showOnDashboard` | `'label-and-value' \| 'value' \| 'nothing'` | 显示模式,`nothing` 时自动设置 `hide: true` |
| `customOptions` | `Array<{text, value}>?` | custom 类型选项(替代 customValues 字符串) |
| `dsType` | `string?` | datasource 类型的数据源类型 |
| `constantValue` | `string?` | constant 类型的常量值 |
---
## 开发
```bash
npm install
npm run dev # 开发模式
npm run build # 构建 Web Component
npm run lint # 代码检查
```
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
{
"name": "argus-board",
"version": "0.1.11",
"type": "module",
"main": "./dist/argus-board.js",
"module": "./dist/argus-board.es.js",
"exports": {
".": {
"import": "./dist/argus-board.es.js",
"default": "./dist/argus-board.js"
},
"./dist/style.css": "./dist/style.css"
},
"files": [
"dist/",
"lib/",
"README.md",
"LICENSE"
],
"dependencies": {
"@ant-design/icons": "^5.2.6",
"@grafana/data": "^11.2.3",
"@visx/gradient": "^3.12.0",
"@visx/group": "^3.12.0",
"@visx/shape": "^3.12.0",
"allotment": "1.20.5",
"antd": "^5.11.0",
"classnames": "^2.5.1",
"dayjs": "^1.11.10",
"lodash-es": "^4.17.21",
"lucide-react": "^1.14.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-grid-layout": "^1.3.4",
"react-virtuoso": "^4.18.6",
"tinycolor2": "^1.6.0",
"uplot": "1.6.31",
"uuid": "^14.0.0",
"zustand": "^5.0.11"
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment