刻度计算引擎 - QwtScaleEngine
QwtScaleEngine 是坐标轴刻度的计算引擎,负责根据数据范围自动计算合理的刻度位置和标签。不同类型的刻度引擎支持不同的刻度策略。
主要功能特性
特性
- ✅ 自动刻度计算:根据数据范围自动计算主刻度和次刻度
- ✅ 多种刻度类型:支持线性、对数、日期等多种刻度引擎
- ✅ 刻度优化:自动选择美观的刻度间隔(如10、5、2等)
- ✅ 边界处理:支持包含/排除边界的刻度计算
基本概念
刻度引擎类型
| 引擎类 |
说明 |
QwtLinearScaleEngine |
线性刻度引擎(默认) |
QwtLogScaleEngine |
对数刻度引擎 |
QwtDateScaleEngine |
日期/时间刻度引擎 |
刻度划分结构
QwtScaleDiv 表示刻度划分结果:
| QwtScaleDiv包含:
- Interval: 数据范围 [min, max]
- MajorTicks: 主刻度位置列表
- MinorTicks: 次刻度位置列表
- MediumTicks: 中等刻度位置列表
|
使用方法
1. 线性刻度引擎(默认)
1
2
3
4
5
6
7
8
9
10
11
12 | #include <QwtPlot>
QwtPlot* plot = new QwtPlot();
// 默认使用线性刻度引擎
plot->setAxisAutoScale(QwtAxis::XBottom);
// 设置主刻度数量上限
plot->setAxisMaxMajor(QwtAxis::XBottom, 10); // 最多10个主刻度
// 设置次刻度数量上限
plot->setAxisMaxMinor(QwtAxis::XBottom, 5); // 每个主刻度区间最多5个次刻度
|
2. 对数刻度引擎
用于大范围数据或指数关系数据:
| #include <QwtLogScaleEngine>
// 设置对数刻度引擎
plot->setAxisScaleEngine(QwtAxis::YLeft, new QwtLogScaleEngine());
// 设置对数刻度范围
plot->setAxisScale(QwtAxis::YLeft, 0.001, 1000); // 跨越6个数量级
// 对数刻度特性:
// - 主刻度位于10^n位置(1, 10, 100, 1000...)
// - 次刻度位于中间位置(2, 3, 4, 5, 6, 7, 8, 9)
|
3. 日期刻度引擎
用于时间序列数据:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 | #include <QwtDateScaleEngine>
#include <QwtDateScaleDraw>
// 设置日期刻度引擎
plot->setAxisScaleEngine(QwtAxis::XBottom, new QwtDateScaleEngine());
// 设置日期刻度绘制
QwtDateScaleDraw* dateDraw = new QwtDateScaleDraw();
dateDraw->setDateFormat(QwtDateScaleDraw::Month, QString("yyyy-MM")); // 月份格式
dateDraw->setDateFormat(QwtDateScaleDraw::Day, QString("MM-dd")); // 日期格式
plot->setAxisScaleDraw(QwtAxis::XBottom, dateDraw);
// 设置时间范围
QDateTime start = QDateTime::fromString("2024-01-01", "yyyy-MM-dd");
QDateTime end = QDateTime::fromString("2024-12-31", "yyyy-MM-dd");
plot->setAxisScale(QwtAxis::XBottom,
QwtDate::toDouble(start),
QwtDate::toDouble(end));
|
4. 自定义刻度划分
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 | #include <QwtScaleDiv>
// 手动创建刻度划分
QwtScaleDiv scaleDiv;
scaleDiv.setInterval(0, 100); // 设置范围
// 设置主刻度
QList<double> majorTicks;
majorTicks << 0 << 20 << 40 << 60 << 80 << 100;
scaleDiv.setTicks(QwtScaleDiv::MajorTick, majorTicks);
// 设置次刻度
QList<double> minorTicks;
for (int i = 0; i <= 100; i += 4) {
if (!majorTicks.contains(i))
minorTicks << i;
}
scaleDiv.setTicks(QwtScaleDiv::MinorTick, minorTicks);
// 应用刻度划分
plot->setAxisScaleDiv(QwtAxis::XBottom, scaleDiv);
|
5. 刻度引擎属性
| // 获取刻度引擎
QwtScaleEngine* engine = plot->axisScaleEngine(QwtAxis::XBottom);
// 设置引擎属性
engine->setAttribute(QwtScaleEngine::IncludeReference, true); // 包含参考值
engine->setAttribute(QwtScaleEngine::Symmetric, false); // 不对称范围
engine->setAttribute(QwtScaleEngine::Floating, false); // 不浮动端点
// 设置边距
engine->setMargins(0.05); // 5%边距
|
6. 计算刻度划分
1
2
3
4
5
6
7
8
9
10
11
12 | #include <QwtScaleEngine>
// 手动使用引擎计算刻度
QwtLinearScaleEngine engine;
QwtScaleDiv scaleDiv = engine.divideScale(
0, 100, // 数据范围
10, 5, // 最大主刻度数,最大次刻度数
0, 100 // 参考范围(可选)
);
// 应用结果
plot->setAxisScaleDiv(QwtAxis::XBottom, scaleDiv);
|
刻度引擎属性说明
| 属性 |
说明 |
IncludeReference |
强制包含参考值作为刻度 |
Symmetric |
强制范围对称 |
Floating |
端点不强制落在刻度上 |
Inverted |
反转刻度方向 |
日期格式级别
QwtDateScaleDraw 支持不同时间级别的格式:
| 级别 |
枚举值 |
说明 |
Millisecond |
毫秒级 |
"hh:mm:ss.zzz" |
Second |
秒级 |
"hh:mm:ss" |
Minute |
分钟级 |
"hh:mm" |
Hour |
小时级 |
"hh:mm" |
Day |
日级 |
"MM-dd" |
Week |
周级 |
"MM-dd" |
Month |
月级 |
"yyyy-MM" |
Year |
年级 |
"yyyy" |
核心方法总结
| 方法 |
说明 |
setAxisScaleEngine() |
设置刻度引擎 |
setAxisAutoScale() |
启用自动刻度 |
setAxisMaxMajor() |
设置主刻度上限 |
setAxisMaxMinor() |
设置次刻度上限 |
axisScaleEngine() |
获取刻度引擎 |
axisScaleDiv() |
获取刻度划分 |
刻度优化建议
- 线性数据使用线性引擎(默认)
- 大范围数据(跨越多个数量级)使用对数引擎
- 时间序列数据使用日期引擎
- 特殊需求可手动设置刻度划分
相关示例
- 刻度引擎演示:
playground/scaleengine