Chart + TableGrid + PropertyGrid:实时数据可视化监控面板。
构建实时数据监控仪表盘:
• 折线图:Chart 显示 CPU/内存/网络实时曲线
• 数据表格:TableGrid 展示进程/服务列表
• 属性面板:PropertyGrid 显示选中项详情
• 饼图:磁盘/内存占比
• 自动刷新:定时器轮询数据源
| 模块 | XUI API |
|---|---|
折线图 | xuiChartCreate(LINE 模式) |
饼图 | xuiChartCreate(PIE 模式) |
数据网格 | xuiTableGridCreate(排序/筛选) |
属性 | xuiPropertyGridCreate(只读分类) |
布局 | DockPanel + ScrollView |
gcc -O2 -I. -o ch205.exe ch205_main.c src\xui_*.c build\xge.lib -lm -lws2_32 -liphlpapi -lgdi32 -luser32 -lshell32 -lopengl32 -lole32 -lwinmm -lavrt
.\ch205.exe
// 创建 CPU 使用率折线图
xui_chart_desc_t tChartDesc = { 0 };
tChartDesc.iType = XUI_CHART_SERIES_LINE;
tChartDesc.iMaxPoints = 60; // 60 秒窗口
xui_widget pChart;
xuiChartCreate(pCtx, &pChart, &tChartDesc);
// 定时器每秒更新
void OnTimer(void) {
float fCPU = GetCpuUsage();
float fMem = GetMemUsage();
/* 滚动窗口采样后整体提交序列数据 */
xuiChartSetSeriesData(pChart, 0, tCpuPts, iCount);
xuiChartSetSeriesData(pChart, 1, tMemPts, iCount);
// 更新表格当前行
/* TableGrid 数据经适配器更新(xuiTableGridSetAdapter) */
}
// 饼图:磁盘分区占比
xui_chart_desc_t tPieDesc = { 0 };
tPieDesc.iType = XUI_CHART_SERIES_PIE;
xui_widget pPie;
xuiChartCreate(pCtx, &pPie, &tPieDesc);
xuiChartAddSeries(pPie, XUI_CHART_SERIES_PIE, "C:", &iIdx);;
xuiChartAddSeries(pPie, XUI_CHART_SERIES_PIE, "D:", &iIdx);将以下代码保存为 ch205_main.c,编译后运行即可看到实时折线图监控面板效果:
#include "xge.h"
#include "xui.h"
static xui_context g_pCtx;
static xui_widget g_pChart;
static float g_fTimer = 0.0f;
static float g_fVal = 50.0f;
static int onFrame(void* pUser) {
(void)pUser;
float dt = xgeGetDelta();
xgeClear(0x1a1a2e);
/* 每秒添加一个数据点 */
g_fTimer += dt;
if (g_fTimer >= 1.0f) {
g_fTimer -= 1.0f;
g_fVal += (xgeGetDelta() * 1000.0f) - 8.0f;
if (g_fVal < 0) g_fVal = 0;
if (g_fVal > 100) g_fVal = 100;
xuiChartSetSeriesData(g_pChart, 0, tPts, iCount); /* 滚动窗口 */
}
xui_vec2_t pos;
xgeMouseGet(&pos.x, &pos.y);
xuiInputPointerMove(g_pCtx, pos.x, pos.y);
if (xgeMouseDown(XGE_MOUSE_LEFT))
xuiInputPointerDown(g_pCtx, pos.x, pos.y, 0);
else
xuiInputPointerUp(g_pCtx, pos.x, pos.y, 0);
xuiUpdate(g_pCtx, dt);
xuiLayout(g_pCtx);
xuiRender(g_pCtx, NULL, NULL, 0);
return XGE_OK;
}
int main(void) {
xge_desc_t d = {0};
d.iWidth = 800; d.iHeight = 500;
d.sTitle = "ch205 - System Monitor";
d.iFlags = XGE_INIT_VSYNC;
xgeInit(&d);
xuiCreate(&g_pCtx);
extern const xui_proxy_t tXgeProxy;
xui_proxy_t tXgeProxy = xuiProxyXge();
xuiSetProxy(g_pCtx, &tXgeProxy);
xuiSetViewportSize(g_pCtx, 800, 500);
xui_widget pRoot;
xuiPanelCreate(g_pCtx, &pRoot, NULL);
xuiWidgetSetRect(pRoot, (xui_rect_t){0, 0, 800, 500});
xui_chart_desc_t tCD = {0};
tCD.iType = XUI_CHART_SERIES_LINE;
tCD.iMaxPoints = 60;
xuiChartCreate(g_pCtx, &g_pChart, &tCD);
xuiWidgetSetRect(g_pChart, (xui_rect_t){40, 40, 720, 400});
xuiWidgetSetRect(g_pChart, (xui_rect_t){0, 0, 720, 400});
xgeRun(onFrame, NULL);
xuiDestroy(g_pCtx);
xgeUnit();
return 0;
}