build(qwt): 集成 Qwt 6.2 静态库(cmake/qwt.cmake 对接官方Qt6,绕开qmake/vcpkg) + 冒烟用例 + 返工方案文档
二维图表返工前置:QwtPlot 作科学图表框架。源码 external/qwt-src(gitignore)按 ENV_SETUP 拉取。
This commit is contained in:
parent
82b654176e
commit
b772b5a169
|
|
@ -63,6 +63,12 @@ FetchContent_Declare(qtkeychain
|
||||||
GIT_TAG v0.14.0)
|
GIT_TAG v0.14.0)
|
||||||
FetchContent_MakeAvailable(qtkeychain)
|
FetchContent_MakeAvailable(qtkeychain)
|
||||||
|
|
||||||
|
# Qwt 6.2(二维科学图表:数据集详情散点/等值线图)。见 cmake/qwt.cmake 说明。
|
||||||
|
# 源码 external/qwt-src 已 gitignore,需按 docs/ENV_SETUP 拉取。
|
||||||
|
if(EXISTS "${CMAKE_SOURCE_DIR}/external/qwt-src/src")
|
||||||
|
include("${CMAKE_SOURCE_DIR}/cmake/qwt.cmake")
|
||||||
|
endif()
|
||||||
|
|
||||||
add_subdirectory(src)
|
add_subdirectory(src)
|
||||||
|
|
||||||
enable_testing()
|
enable_testing()
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,29 @@
|
||||||
|
# 定义 qwt 静态库目标(Qwt 6.2 二维科学图表:数据集详情散点/等值线图)。
|
||||||
|
#
|
||||||
|
# 为何不用 Qwt 原生 qmake:本机 VS2026 预览版缺 vswhere,qmake 探测 cl 失败。
|
||||||
|
# 为何不用 vcpkg 的 qwt:其端口依赖 vcpkg-qtbase,会与官方 Qt 形成双 Qt 冲突(项目铁律:
|
||||||
|
# 依赖 Qt 的组件不走 vcpkg)。故此处用 CMake 直接编 Qwt 源码,对接官方 Qt6(同 VTK 思路)。
|
||||||
|
#
|
||||||
|
# 源码目录 external/qwt-src(已 gitignore,按 docs/ENV_SETUP 拉取):
|
||||||
|
# git clone --depth 1 https://github.com/opencor/qwt external/qwt-src # Qwt 6.2.0 镜像
|
||||||
|
# 由根 CMakeLists 在源码存在时 include 本文件。
|
||||||
|
|
||||||
|
set(QWT_SRC_DIR "${CMAKE_SOURCE_DIR}/external/qwt-src/src")
|
||||||
|
|
||||||
|
find_package(Qt6 REQUIRED COMPONENTS Widgets Concurrent PrintSupport Svg)
|
||||||
|
|
||||||
|
file(GLOB _qwt_sources CONFIGURE_DEPENDS "${QWT_SRC_DIR}/*.cpp")
|
||||||
|
file(GLOB _qwt_headers CONFIGURE_DEPENDS "${QWT_SRC_DIR}/*.h")
|
||||||
|
# 排除:OpenGL 画布 / SVG plot item / QwtPolar 部件(避免额外模块依赖与面积)。
|
||||||
|
# 保留 qwt_symbol.cpp(用 QSvgRenderer,故链 Qt6::Svg)与 qwt_point_polar.cpp(几何工具)。
|
||||||
|
list(FILTER _qwt_sources EXCLUDE REGEX "qwt_plot_glcanvas|qwt_plot_opengl_canvas|qwt_plot_svgitem|qwt_polar_")
|
||||||
|
list(FILTER _qwt_headers EXCLUDE REGEX "qwt_plot_glcanvas|qwt_plot_opengl_canvas|qwt_plot_svgitem|qwt_polar_")
|
||||||
|
|
||||||
|
add_library(qwt STATIC ${_qwt_sources} ${_qwt_headers})
|
||||||
|
set_target_properties(qwt PROPERTIES AUTOMOC ON)
|
||||||
|
target_include_directories(qwt PUBLIC "${QWT_SRC_DIR}")
|
||||||
|
target_link_libraries(qwt PUBLIC Qt6::Widgets Qt6::Concurrent Qt6::PrintSupport Qt6::Svg)
|
||||||
|
target_compile_features(qwt PUBLIC cxx_std_17)
|
||||||
|
if(MSVC)
|
||||||
|
target_compile_options(qwt PRIVATE /bigobj /EHsc /wd4244 /wd4267 /wd4305 /wd4456)
|
||||||
|
endif()
|
||||||
|
|
@ -0,0 +1,234 @@
|
||||||
|
# Geopro 3.0 桌面客户端 — 数据集详情「二维图表」返工技术方案
|
||||||
|
|
||||||
|
**版本 v1.0** · 适用范围:数据集详情页的「原数据(散点图)」与「网格数据(填充等值线图)」
|
||||||
|
**状态**:返工指令(推翻当前 QGraphicsView 实现,重做)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 0. 给开发(含 AI 编码)的硬约束 — 先读这一段
|
||||||
|
|
||||||
|
1. **不嵌入 QWebEngine,不引入 Chromium。** 整个客户端的技术路线是 Qt C++ 原生,核心动机包含离线/现场作业能力;把核心数据可视化做成依赖 web 渲染会破坏该前提,禁止。
|
||||||
|
2. **推翻当前的裸 `QGraphicsView` + VTK 渲染窗口方案。** 当前 9 个问题的根因是 2D 框架选错,不是"没嵌 web"。
|
||||||
|
3. **改用 `QwtPlot` 作为两类图的坐标系框架;等值线多边形用 VTK 算法(仅算法,不开 VTK 渲染窗口)。**
|
||||||
|
4. **验收标准 = 视觉等价 + 交互一致**,不是字节级像素 diff。原生渲染与 web 端 Plotly 在抗锯齿、字体、亚像素上天生有别,任何工具都无法字节级相同;目标是"用户看不出降级感"。
|
||||||
|
5. **不要自由发挥架构。** 本文档把分层、类、职责定死,照做;遇到本文档未覆盖的细节,先问,不要自行另起一套。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 1. 根因诊断(为什么会做崩)
|
||||||
|
|
||||||
|
当前实现把"图形 + 坐标轴 + 色阶图例"全部糊在一个 `QGraphicsView` 场景里一起做变换,导致系统性错误。裸 `QGraphicsView` 是通用图形框架,**不具备"科学图表"语义**——它不知道什么是固定坐标轴、什么是"仅数据区缩放"、什么是"图例不参与变换"。
|
||||||
|
|
||||||
|
把用户列的 9 个问题按根因归类:
|
||||||
|
|
||||||
|
| # | 问题 | 根因类别 | 由谁解决 |
|
||||||
|
|---|---|---|---|
|
||||||
|
| 1 | 色阶图随大图缩放、与横坐标重叠 | 框架(图例未独立) | QwtPlot 分层 |
|
||||||
|
| 3 | 拖动时坐标轴跟着动(应只动数据、轴值跟随) | 框架(无数据区/轴分离) | QwtPlot 内置交互 |
|
||||||
|
| 4 | 一拖动画面就花 | 框架(手写变换 + 重绘错误) | QwtPlot 内置交互 |
|
||||||
|
| 9 | 图比原版瘦(纵横比错) | 框架(无纵横比控制) | QwtPlot 纵横比锁定 |
|
||||||
|
| 2 | 配色与原版不一致(离散色带 vs 连续插值) | 实现细节(色阶映射) | QwtLinearColorMap |
|
||||||
|
| 5 | 等值线数字没显示 | 实现细节(缺标注) | 等值线 label |
|
||||||
|
| 6 | 原数据/网格数据切换样式被改错 | UI 布局(与图表无关) | 改回页签样式 |
|
||||||
|
| 7 | 显示异常/等值线开关跑到面板外 | UI 布局(与图表无关) | 归位工具条 |
|
||||||
|
| 8 | 下方缺「描述」页签 | UI 布局(与图表无关) | 补页签 |
|
||||||
|
|
||||||
|
**关键结论**:9 个问题没有一个需要"嵌 web"才能解决。第 1 类(#1/#3/#4/#9)换对框架即消失;第 2 类(#2/#5)是渲染细节;第 3 类(#6/#7/#8)是纯 UI,跟用什么画图无关。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2. 目标架构 — 三层分离
|
||||||
|
|
||||||
|
整个二维图表 widget 必须做成**三层分离**,这是治本:
|
||||||
|
|
||||||
|
```
|
||||||
|
┌─────────────────────────────────────────────┐
|
||||||
|
│ ChartPanel (QWidget) │
|
||||||
|
│ ┌───────────────────────────────────────┐ │
|
||||||
|
│ │ 工具条 ToolBar(网格/色阶配置/白化/...) │ │ ← 工具条层(属于面板,不属于绘图区)
|
||||||
|
│ ├───────────────────────────────────────┤ │
|
||||||
|
│ │ QwtPlot(数据区 + 固定坐标轴) │ │ ← 绘图层(QwtPlot 管坐标轴与交互)
|
||||||
|
│ │ • QwtPlotItem: 等值线多边形 / 散点 │ │
|
||||||
|
│ │ • QwtPlotMagnifier / Panner(交互) │ │
|
||||||
|
│ ├───────────────────────────────────────┤ │
|
||||||
|
│ │ ColorBarWidget(独立固定) │ │ ← 图例层(独立 widget,永不参与数据区变换)
|
||||||
|
│ └───────────────────────────────────────┘ │
|
||||||
|
└─────────────────────────────────────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
**铁律**:
|
||||||
|
- **坐标轴**由 QwtPlot 管理,**永远固定**(不随拖动移动其位置),拖动/缩放时只有**数据区内容**平移缩放,**轴上的刻度数值自动跟随重算**。这正是 QwtPlot 的默认行为,也正是原版的行为。
|
||||||
|
- **色阶条(ColorBar)是独立 widget**,放在绘图区下方,**绝不放进 QwtPlot 的数据坐标系**,因此永远不会随图缩放、不会和横坐标重叠(直接消灭 #1)。
|
||||||
|
- **工具条属于面板**,不属于绘图区(修正 #7)。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 3. 框架与依赖
|
||||||
|
|
||||||
|
| 用途 | 选用 | 协议 | 说明 |
|
||||||
|
|---|---|---|---|
|
||||||
|
| 2D 图表坐标系框架 | **QwtPlot(Qwt 6.2+)** | QWT License(LGPL + 例外,商用免费) | 坐标轴、缩放、平移、刻度跟随、图例、色阶映射全内置 |
|
||||||
|
| 等值线多边形算法 | **vtkBandedPolyDataContourFilter** | BSD(商用免费) | 仅当算法用,**不开 VTK 渲染窗口** |
|
||||||
|
| 等值线(线)算法 | vtkContourFilter / vtkFlyingEdges2D | BSD | 生成等值线及其标注位置 |
|
||||||
|
| 连续色阶映射 | **QwtLinearColorMap** | QWT License | 对齐原版 Plotly 的连续插值色阶 |
|
||||||
|
|
||||||
|
> 协议全部商用友好,零授权费。QWT 与 VTK 都不触发开源传染。
|
||||||
|
|
||||||
|
> **VTK 的双重角色**(务必理解,否则又会做重):在 3D 视图 / 地图视图里 VTK 是**渲染器**(开渲染窗口);在本页这种纯二维详情图里,VTK **退化为算法库**(只用它的 filter 算多边形,取出顶点交给 QwtPlot 画)。本页**不允许**出现 QVTKOpenGLWidget / 渲染窗口。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 4. 逐项解法(对应 9 个问题)
|
||||||
|
|
||||||
|
### 4.1 色阶条独立固定(治 #1)
|
||||||
|
|
||||||
|
- 新建 `ColorBarWidget : public QWidget`,自绘一条水平色带 + 刻度数值 + 单位。
|
||||||
|
- 它在布局上位于 QwtPlot **下方**,是**兄弟 widget**,不是 QwtPlot 的内部 item。
|
||||||
|
- 它的色阶**与绘图区用同一个色阶对象**(见 §6 色阶服务),保证图与图例配色一致。
|
||||||
|
- 因为它不在数据坐标系内,**永远不随拖动/缩放移动,不会与横坐标轴重叠**。
|
||||||
|
- 刻度数值与原版对齐:用与数据相同的分级断点(原版色阶断点形如 17.105 / 25.937 / ...,等比/对数分布,见 §6)。
|
||||||
|
|
||||||
|
### 4.2 仅数据区缩放、坐标轴固定、轴值跟随(治 #3)
|
||||||
|
|
||||||
|
- 用 QwtPlot,坐标轴(`QwtPlot::xBottom` / `yLeft`)由 QwtPlot 框架绘制,位置固定。
|
||||||
|
- 缩放/平移用 QwtPlot 内置:
|
||||||
|
- `QwtPlotMagnifier`(滚轮缩放数据区)
|
||||||
|
- `QwtPlotPanner`(拖动平移数据区)
|
||||||
|
- 需要框选缩放可加 `QwtPlotZoomer`
|
||||||
|
- 这些组件只改变**坐标轴的数值范围(scaleDiv)**,QwtPlot 自动重算刻度并重绘——**轴不动、轴上的数字跟着变**,与原版完全一致。
|
||||||
|
- **原数据 = 四象限坐标系**(数据含正负,x/y 轴交叉于原点区域);**网格数据 = 单象限**(数据全正,原点在左下)。在 QwtPlot 里就是设置不同的轴范围与原点位置,不需要两套框架。
|
||||||
|
|
||||||
|
### 4.3 拖动不再花屏(治 #4)
|
||||||
|
|
||||||
|
- 当前"花屏"是手写 `QGraphicsView` 变换 + 重绘时机错误导致。改用 QwtPlot 后,重绘由 QwtPlot 的 replot 机制统一管理,不会出现脏区残留。
|
||||||
|
- 大数据量等值线多边形若导致拖动卡顿:对 `QwtPlotItem` 开启 `QwtPlotItem::RenderAntialiased` 视情况关闭、并启用绘制缓存;必要时对多边形做 LOD 简化(与原版"简化容差"滑块一致,见 §7)。
|
||||||
|
|
||||||
|
### 4.4 纵横比 / 宽度修正(治 #9)
|
||||||
|
|
||||||
|
- 原版图是"宽扁"的剖面图(x 范围远大于 y)。当前实现"偏瘦"是因为没有锁定数据纵横比、或 widget 尺寸策略错误。
|
||||||
|
- 解法:根据数据的 x/y 跨度设定数据区的纵横比;若要求等比例(1 个数据单位 x = 1 个数据单位 y 的像素),自定义布局在 replot 时按数据范围调整 canvas 的宽高比,或固定 y 轴范围、x 轴自适应填充。
|
||||||
|
- 先对齐原版的"宽扁"观感即可,不必强制物理等比,除非业务要求等比例尺。
|
||||||
|
|
||||||
|
### 4.5 连续插值色阶,对齐 Plotly 配色(治 #2)
|
||||||
|
|
||||||
|
- 原版散点/等值线用的是**连续插值色阶**(Plotly 的 colorscale),当前实现用了**离散色带**,所以配色不同。
|
||||||
|
- 用 `QwtLinearColorMap`,设置与原版相同的**控制点颜色 + 位置**,开启连续插值(`QwtLinearColorMap` 默认 `ScaledColors` 连续模式,不要用 `FixedColors`)。
|
||||||
|
- 控制点取自原版色阶(紫蓝→蓝→青→绿→黄→橙→红→深红的彩虹序列)。**必须从原版抓取实际色值**(见 §6 第 4 步),不要凭记忆配色。
|
||||||
|
- 色阶分布是**对数/等比**的(断点 17.105, 25.937, 34.382... 比值递增),映射时对数据取 log 再线性映射,否则颜色分布会与原版不同。
|
||||||
|
|
||||||
|
### 4.6 等值线数值标注(治 #5)
|
||||||
|
|
||||||
|
- 等值线(contour line)由 `vtkContourFilter` 在各分级阈值生成线,取出线的折点。
|
||||||
|
- 在 QwtPlot 中用自定义 `QwtPlotItem` 绘制这些线,并在线的合适位置绘制数值标签(label):沿线取中点或曲率较小处,绘制旋转贴合线方向的文本(原版标签是贴着等值线方向旋转的)。
|
||||||
|
- 受工具条「显示等值线标注」复选框控制开关。
|
||||||
|
- 「显示等值线提示信息」控制 hover 时的 tooltip(鼠标移到等值线上显示数值),与原版一致。
|
||||||
|
|
||||||
|
### 4.7 页签切换样式归位(治 #6)
|
||||||
|
|
||||||
|
- 「原数据 / 网格数据」切换**不是两个按钮**,而是与「数据集面板的 数据/文件」「右栏的 异常/对象属性」**同一种下划线页签样式**(之前已专门调过样式,复用那套 QSS/组件,不要重写成 QPushButton)。
|
||||||
|
- 直接复用既有的下划线 Tab 组件类,保证全客户端切换样式统一。
|
||||||
|
|
||||||
|
### 4.8 工具条归位到网格数据面板内(治 #7)
|
||||||
|
|
||||||
|
- 「显示异常 / 显示等值线标注 / 显示等值线提示信息 / 简化容差滑块 / 网格 / 色阶配置 / 白化 / 滤波处理 / 异常标注 / 自动标注 / 另存为」这些**属于网格数据视图的工具条**,必须在网格数据面板**内部**的工具条上,不能浮到外层。
|
||||||
|
- 「原数据」页签的工具条是另一套(网格 / 色阶配置 / 当前图形下拉 / 另存为),各自归属各自页签。
|
||||||
|
|
||||||
|
### 4.9 下方补「描述」页签(治 #8)
|
||||||
|
|
||||||
|
- 图下方区域是一个含两个页签的容器:**「异常列表」+「描述」**,当前只做了异常列表表格,缺「描述」。
|
||||||
|
- 补上「描述」页签(富文本/纯文本说明区),与原版结构一致。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 5. 组件清单与职责(定死,不要改结构)
|
||||||
|
|
||||||
|
| 类 | 基类 | 职责 |
|
||||||
|
|---|---|---|
|
||||||
|
| `DatasetDetailPanel` | QWidget | 数据集详情页根容器:顶部下划线页签(原数据/网格数据)+ 内容区 + 下方(异常列表/描述)|
|
||||||
|
| `RawDataChartView` | QWidget | 「原数据」散点图:工具条 + QwtPlot(四象限)+ ColorBar |
|
||||||
|
| `GridDataChartView` | QWidget | 「网格数据」等值线图:工具条 + QwtPlot(单象限)+ ColorBar |
|
||||||
|
| `ContourPlotItem` | QwtPlotItem | 自定义:绘制 VTK 算出的分层填充多边形 + 等值线 + 标注 |
|
||||||
|
| `ScatterPlotItem` | QwtPlotItem / QwtPlotSpectroCurve | 散点,按值连续着色 |
|
||||||
|
| `ColorBarWidget` | QWidget | 独立色阶条(固定,不入数据坐标系)|
|
||||||
|
| `ColorMapService` | (单例/服务) | 全局色阶:断点、颜色、命名保存、对数映射;图与图例同源 |
|
||||||
|
| `ContourEngine` | (封装 VTK) | 输入网格数据 → 输出分层多边形 + 等值线折点(封装 vtkBandedPolyDataContourFilter / vtkContourFilter)|
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 6. 色阶服务(对齐原版的关键)
|
||||||
|
|
||||||
|
色阶是"配色一致"的命门,单独抽成服务,**图、图例、3D 视图共用同一份**(呼应视觉设计规范 §8):
|
||||||
|
|
||||||
|
1. **断点(分级阈值)**:采用原版的对数/等比分布。原版断点示例:`17.105, 25.937, 34.382, 35.972, 42.555, 49.051, 56.312, 68.950, 83.029, 98.454, 110.570, 129.660, 158.270, 204.160, 260.820, 321.710, 1335.500`(不同数据集断点不同,应由数据的 min/max + 分级规则动态生成,规则与原版一致)。
|
||||||
|
2. **颜色控制点**:彩虹序列(深蓝 → 蓝 → 亮蓝 → 青 → 浅绿 → 绿 → 黄绿 → 黄 → 土黄 → 橙 → 黄 → 红 → 深红 → 紫红 → 紫 → 深紫黑)。
|
||||||
|
3. **映射方式**:连续插值(`QwtLinearColorMap` ScaledColors)+ 对数标度(数据先 log,再线性映射到 [0,1])。
|
||||||
|
4. **必须从原版抓真实色值**:打开原版页面 `http://tenant.geomative.cn/#/projectSpace/datasetMange/datasetInfo?id=...&ddCode=dd_inversion_data`,用浏览器开发者工具检查 Plotly 的 `colorscale` 配置,或对色阶条截图取色(每个色块取中心像素 RGB)。**严禁凭记忆配色** —— 这是 #2 反复出错的根源。
|
||||||
|
5. **命名保存**:色阶可命名、保存、切换,调整后图与图例实时刷新(业务规约要求)。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 7. 工具条功能对照(两个页签各一套)
|
||||||
|
|
||||||
|
**原数据页签工具条**:网格 | 色阶配置 | 当前图形(下拉:散点图/...)| 另存为
|
||||||
|
|
||||||
|
**网格数据页签工具条**:网格 | 色阶配置 | 白化 | 滤波处理 | ☑显示异常 | ☑显示等值线标注 | ☐显示等值线提示信息 | 简化容差(滑块,0–1)| 异常标注 | 自动标注 | 另存为
|
||||||
|
|
||||||
|
- 「简化容差」滑块:控制等值线多边形的简化程度(值越大,多边形越简化、越平滑),对应 VTK 侧对多边形做 `vtkDecimatePolylineFilter` 或道格拉斯-普克简化的容差参数。
|
||||||
|
- 「白化」「滤波处理」是对网格数据的预处理操作,作用于 ContourEngine 的输入。
|
||||||
|
- 「自动标注」弹出对话框(见 §8)。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 8. 自动标注对话框(复用同一图表组件)
|
||||||
|
|
||||||
|
- 「自动标注」弹出的对话框里那张图,**必须与主页面网格数据图完全一致**——做法是**复用同一个 `GridDataChartView` / `ContourPlotItem` 类的另一个实例**,传入同一份数据 + 同一个 ColorMapService,**不要另写一套渲染**(否则又会出现两张图不一致)。
|
||||||
|
- 对话框结构:左侧「异常判定规则」(阈值模式 数值/百分位、最小点数、异常类型)+ 右侧统计信息(最大/最小/均值/中位数)+ 图(同主图)+ 自动标注结果列表 + 底部(取消/执行自动标注/确认保存)。
|
||||||
|
- 因为是普通 QWidget(QwtPlot 而非 VTK 窗口),嵌进对话框无任何 OpenGL 上下文问题,开关对话框不会闪烁/泄漏。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 9. 实施顺序(建议分步验收,避免再次大返工)
|
||||||
|
|
||||||
|
> 每一步做完就和原版对照截图验收,通过再进入下一步。不要一次性全做完再看。
|
||||||
|
|
||||||
|
1. **搭三层骨架**:DatasetDetailPanel + 两个页签(下划线样式)+ 下方(异常列表/描述)。先不画图,验证 UI 结构对齐(治 #6/#7/#8)。
|
||||||
|
2. **QwtPlot 接入 + 交互**:空 QwtPlot,配好固定坐标轴 + Magnifier/Panner,验证"拖动只动数据、轴值跟随、不花屏、纵横比对"(治 #3/#4/#9)。
|
||||||
|
3. **ColorBar 独立**:加 ColorBarWidget 固定在下方,验证缩放时色阶条不动、不与轴重叠(治 #1)。
|
||||||
|
4. **色阶服务 + 抓原版色值**:实现 ColorMapService,从原版抓真实色值与断点,连续对数映射(治 #2 的基础)。
|
||||||
|
5. **散点图**:原数据页用 ScatterPlotItem 连续着色,对照原版配色(治 #2)。
|
||||||
|
6. **等值线图**:ContourEngine(VTK 算多边形)+ ContourPlotItem 绘制填充 + 等值线 + 标注(治 #2/#5)。
|
||||||
|
7. **工具条联动**:显示异常/等值线/提示、简化容差滑块、白化、滤波接通。
|
||||||
|
8. **自动标注对话框**:复用图表组件 + 规则面板 + 统计 + 结果。
|
||||||
|
9. **整体对照验收**:原数据、网格数据分别与原版并排截图,核对配色/布局/交互/标注/纵横比。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 10. 验收标准(写清楚,避免预期错位)
|
||||||
|
|
||||||
|
**通过标准 = 视觉等价 + 交互一致**:
|
||||||
|
|
||||||
|
- [ ] 配色与原版视觉一致(同一色阶、连续插值、对数分布)
|
||||||
|
- [ ] 坐标轴固定,拖动/缩放只动数据区,轴刻度值跟随
|
||||||
|
- [ ] 色阶条固定在轴下方,不随图缩放,不与坐标轴重叠
|
||||||
|
- [ ] 等值线数值标注显示,贴合线方向
|
||||||
|
- [ ] 原数据=四象限、网格数据=单象限,缩放/移动行为分别与原版一致
|
||||||
|
- [ ] 纵横比/宽扁观感与原版一致
|
||||||
|
- [ ] 拖动流畅、无花屏
|
||||||
|
- [ ] 页签切换为下划线样式(与数据/文件、异常/属性一致)
|
||||||
|
- [ ] 工具条开关位于各自页签面板内
|
||||||
|
- [ ] 下方含「异常列表 + 描述」两个页签
|
||||||
|
- [ ] 自动标注对话框内图与主图完全一致
|
||||||
|
|
||||||
|
**不作为通过标准**(明确排除,避免无意义返工):
|
||||||
|
|
||||||
|
- ✗ 与 web 端逐像素 diff 相同(抗锯齿/字体/亚像素天生有别,任何原生方案都无法做到,非缺陷)。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 11. 一句话方向
|
||||||
|
|
||||||
|
> 不嵌 Chromium。推翻 QGraphicsView,用 **QwtPlot(坐标系/交互/图例)+ VTK 算法(等值线多边形)+ 连续对数色阶(对齐原版)**,三层分离(绘图区 / 固定坐标轴 / 独立色阶条),UI 三处(页签样式/工具条归位/描述页)按原版恢复。验收按"视觉等价 + 交互一致",非字节级。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
*本方案针对当前返工,钉死架构与分层,禁止在图表渲染框架上再自由发挥。未覆盖的细节先确认再实现。*
|
||||||
|
|
@ -80,6 +80,12 @@ target_sources(geopro_tests PRIVATE render/test_terrain.cpp)
|
||||||
target_link_libraries(geopro_tests PRIVATE geopro_render ${VTK_LIBRARIES})
|
target_link_libraries(geopro_tests PRIVATE geopro_render ${VTK_LIBRARIES})
|
||||||
vtk_module_autoinit(TARGETS geopro_tests MODULES ${VTK_LIBRARIES})
|
vtk_module_autoinit(TARGETS geopro_tests MODULES ${VTK_LIBRARIES})
|
||||||
|
|
||||||
|
# Qwt 集成冒烟(仅当 qwt 目标存在,即 external/qwt-src 已拉取)。
|
||||||
|
if(TARGET qwt)
|
||||||
|
target_sources(geopro_tests PRIVATE render/test_qwt_smoke.cpp)
|
||||||
|
target_link_libraries(geopro_tests PRIVATE qwt)
|
||||||
|
endif()
|
||||||
|
|
||||||
target_include_directories(geopro_tests PRIVATE ${CMAKE_SOURCE_DIR}/src/app)
|
target_include_directories(geopro_tests PRIVATE ${CMAKE_SOURCE_DIR}/src/app)
|
||||||
target_sources(geopro_tests PRIVATE app/test_chart_strategy_registry.cpp)
|
target_sources(geopro_tests PRIVATE app/test_chart_strategy_registry.cpp)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,10 @@
|
||||||
|
#include <gtest/gtest.h>
|
||||||
|
|
||||||
|
#include <qwt_text.h>
|
||||||
|
|
||||||
|
// 冒烟:验证项目能编译 Qwt 头文件并链接 Qwt 静态库(QwtText 为值类型,无需 QApplication)。
|
||||||
|
// 保障 Qwt 集成(cmake/qwt.cmake + 官方 Qt6)持续可用,不回归。
|
||||||
|
TEST(QwtSmoke, LinksAgainstQwt) {
|
||||||
|
QwtText t(QStringLiteral("hello"));
|
||||||
|
EXPECT_EQ(t.text(), QStringLiteral("hello"));
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue