本头文件包含三层曲线控件:STTChart(手工送点)、STTRealTrend(实时变量趋势)和 STTHistoryTrend(采样数据库历史趋势)。三者均在 stt 命名空间。
STTChart* chart = new STTChart(getRuntime(), this, "chart");
chart->setMainArg(10, 20, 460, 220, 1, 120, 4, 6,
14, "", 0x202020, 0);
chart->setYAxis(6, 3, 6, 2, true, "", 0, 100);
chart->setXAxis(6, 3, 7, 2, true,
"0\n10\n20\n30\n40\n50\n60");
LvChartSeries* temp = chart->addSeries(0xe53935, 0);
chart->setAllValue(temp, 0);
chart->setNextValue(temp, 23.5f);
chart->refresh();
charttype:0 不绘制、1 折线、2 柱状、3 散点。pt_cnt 是每个 series 的点数。hdiv/vdiv 是内部水平/垂直分隔线数,不含两侧边线。
setXAxis(...):下 X 轴。setX2Axis(...):上 X 轴。setYAxis(..., min, max):左 Y 轴并设范围。setY2Axis(..., min, max):右 Y 轴并设范围。setRange(axis,min,max):axis=0 左 Y,1 右 Y。setAxisTick(axis,...):通用轴刻度;轴编号 0 左 Y、1 下 X、2 右 Y、3 上 X。getTickParam(axis,paramtype):查询主/次刻度长度、数量、标签开关或额外绘制尺寸。setTickStyle(width,color):统一刻度线样式。标签字符串用 \n 分隔,数量应与主刻度数一致。Y 轴 min 必须小于 max;范围变化后调用 refresh()。
chart->setPos(10, 20)->setSize(460, 220);
chart->setWidth(460)->setHeight(220)->center();
chart->setType(1)
->setPointCount(120)
->setUpdateMode(0)
->setDivLineCount(4, 6)
->setZoomX(1.0f)
->setZoomY(1.0f);
setUpdateMode(0) 是 shift,新增点使曲线移动;其他 LVGL 模式按底层枚举解释。getType()、getPointCount()、getDivLineCountH()、getDivLineCountV()、getZoomX()、getZoomY() 返回当前值。setHidden 同时处理 chart 复合容器;优先用该重载,不要只隐藏内部 image。enableDrag() 开启拖拽。改变点数会重新分配 series 数据。外部数组模式下先解除/重新设置外部数组,避免长度不匹配。
setMainStyle(...) 设置控件背景、边框、阴影和四边留白。setChartBgStyle(...) 设置绘图区背景/边框、折线宽、点大小和分隔虚线。setFadeArea(true) 启用折线下渐变,getFadeArea() 查询。
chart->setMainStyle(0, 0xffffff, 0xffffff, 0,
1, 0xb0b0b0, 0, 0,
42, 20, 16, 28);
chart->setChartBgStyle(0, 0xffffff, 0xf7f7f7, 1,
1, 0xd0d0d0, 2, 4,
1, 0xd8d8d8, 4, 4);
LvChartSeries* left = chart->addSeries(0xff0000, 0);
LvChartSeries* right = chart->setAddSeries(1, 0x0066cc, nullptr, 0, 1000);
chart->setSeriesColor(left, 0x00aa00);
chart->hideSeries(right, true);
chart->setSeriesMinMax(right, 0, 1000);
chart->setAllSeriesMinMax(0, 100);
int count = chart->getSeriesCount();
LvChartSeries* first = chart->getSeries(0);
for (LvChartSeries* s = chart->getSeriesNext(nullptr);
s != nullptr; s = chart->getSeriesNext(s)) {
// 遍历
}
chart->removeSeries(right);
addSeries(color,axis) 中 axis=0/1 对应主/次 Y 轴。setAddSeries 可在创建时装载 vector<float> 并设置该 series 的真实量程。getSeries(idx) 越界时应按空指针处理。
calShowValue/calRealValue 在 series 自身 min/max 与所用 Y 轴范围间换算;getSeriesMin()/getSeriesMax() 查询 series 量程。分母量程不能为 0。
chart->setNextValue(left, 12.3f);
chart->setPrevValue(left, 11.8f);
chart->setValueById(left, 10, 15);
// 散点图
chart->setNextValue2(left, 100, 23);
chart->setPrevValue2(left, 90, 22);
chart->setValueById2(left, 5, 50, 18);
int* ys = chart->getYArray(left);
int* xs = chart->getXArray(left);
chart->setXStartPoint(left, 4);
int start = chart->getXStartPoint(left);
LvPoint p;
chart->getPointPosById(left, 5, &p);
setAllValue(series,value) 设置全部 Y;FLOAT_MAX 语义为不绘制。setNextValue2 等 XY 接口仅对散点图有意义。fixFirstSeriesLine(series) 用第二点覆盖第一点,处理高密度数据首点竖线。refresh()。外部数组:
static int ybuf[120];
static int xbuf[120];
chart->setExtYArray(left, ybuf);
chart->setExtXArray(left, xbuf);
setExtYArray/setExtXArray 只是让 LVGL 指向数组,不复制数据。数组长度必须等于 point count,并且寿命覆盖 series;调整点数前先规划好缓冲区。
chart->enableCusror(true); // API 名称确实拼作 Cusror
chart->setCursorStyle(0xffff0000, 2, 5, "时间");
chart->setCursorTable(cursorTable);
LvChartCursor* cursor = chart->getCursor();
chart->setCursorPoint(cursor, left, 10);
LvPoint pos;
chart->getCursorPoint(cursor, &pos);
低层接口还有 addCursor(color,dir)、setCursorPos(cursor,&pos)。dir 是方向位掩码:左 1、右 2、上 4、下 8。setCursorPoint(..., INT32_MAX) 隐藏光标。
getPressedPoint() 返回当前按下点,getLastPressedPoint() 返回最后一次点选。setCursorTable 会解绑并隐藏传入表格,点击曲线后用于显示各 series 数据;表格必须比 chart 活得久。isEnableCursor、getCursorTable 查询当前配置。
STTRealTrend* trend = new STTRealTrend(getRuntime(), this, "realtime");
trend->setMainArg(10, 20, 460, 220, 1, 300, 4, 6);
trend->setDataSource(
"PLC.Temp;PLC.Pressure",
R"({"xu":5,"xs":60,"xsu":0,"m":0})");
trend->setFractionLen(0, 1, 2);
trend->setXLabelMode(0);
trend->setFactorAndOffset("PLC.Temp", 1.0, 0.0);
trend->startCollect();
配置字段:xu X 标签格式(0 SS、1 MM、2 HH、3 MM:SS、4 HH:MM、5 HH:MM:SS);xs 时间跨度,0 时取 xsv 变量,其他有效值至少 30;xsu 单位 0 秒/1 分/2 小时;y1n/y1m/y2n/y2m 是轴上下限变量;m=0 绝对时间,m=1 相对变量并使用 mv。
startCollect、pauseCollect、resumeCollect、stopCollect 返回状态转换是否成功。setXLabelMode(0) 标签左移,1 位置不动但时间变化;getXLabelMode 查询。setFactorAndOffset 只改变本控件的实时值:结果为 value*factor+offset。
STTHistoryTrend* history = new STTHistoryTrend(getRuntime(), this, "history");
history->setMainArg(10, 20, 460, 220, 1, 600, 4, 6);
history->setDataSource("1", "20261020", false,
"PLC.Temp;PLC.Pressure",
R"({"xu":5,"xs":3600,"xsu":0})");
history->setRefreshPeriod(2);
history->navLast();
getSampleDB() 返回采样数据库连接,属于框架,不要关闭或 delete。isrt=true 使用实时模式;false 浏览历史。
导航接口:navFirst()、navNext()、navBack()、navLast();带 delayms 的 navFirst(int)/navLast(int) 延时导航。navTo(...) 可指定起点或终点,带 msspan 重载指定单次时间跨度。moveNext/moveBack 以当前跨度除以垂直分段数移动。
日期和跟随:
history->bindHistoryDate(vm->get("UI.HistoryDate"));
history->setHistoryDate(20261020);
int ymd = history->getHistoryDate();
history->setFollowLatest(true);
bool following = history->isFollowingLatest();
翻页或定位历史会自动关闭跟随。setRefreshPeriod(s) 必须在 stopCollect() 后使用;它只控制显示刷新,不停止后台采样。
历史采集的 pauseCollect/resumeCollect/stopCollect 主要控制显示定时器,后台采样任务仍可继续。setFixTime(1/2/3) 把时间固定到日/时/分边界;其他值无效。setDownSamplingType(0/1/2) 对应近值、插值、LTTB。
浏览模式:
history->browseModeEnter(2000, 2);
history->browseModeZoomIn();
history->browseModeZoomOut();
history->browseModeToPrev();
history->browseModeToNext();
history->browseModeExit();
dataSize 最大 65536,nPeriod=2 表示每 2 条取 1 条。浏览模式仅适合周期采样。历史 setFactorAndOffset 会影响对应采样变量,影响范围大于单个实时曲线,修改前确认系统约定。
enableCusror 是头文件中的实际拼写,不要改写为 enableCursor。stopCollect();不要从后台线程直接调用绘图接口。refreshDraw()、refine() 及各 onXxxChanged/onTimerCb 是派生类内部刷新入口;业务代码不要绕过 start、导航和数据源接口直接调用。