diff --git a/src/app/panels/chart/GridDataChartView.cpp b/src/app/panels/chart/GridDataChartView.cpp index c9847cc..78deba6 100644 --- a/src/app/panels/chart/GridDataChartView.cpp +++ b/src/app/panels/chart/GridDataChartView.cpp @@ -7,9 +7,18 @@ #include #include +#include +#include +#include +#include + #include "PanelHeader.hpp" #include "panels/AnomalyTablePanel.hpp" #include "panels/DescriptionPanel.hpp" +#include "panels/chart/ColorBarWidget.hpp" +#include "panels/chart/ColorMapService.hpp" +#include "panels/chart/ContourPlotItem.hpp" +#include "panels/chart/LivePanner.hpp" namespace geopro::app { @@ -85,16 +94,42 @@ GridDataChartView::GridDataChartView(QWidget* parent) : QWidget(parent) { lay->addWidget(toolbar); - // ---- 图表占位区(stretch) ---- - plotArea_ = new QWidget(this); - plotArea_->setObjectName(QStringLiteral("gridPlotArea")); - lay->addWidget(plotArea_, 1); + // ---- QwtPlot(仿 RawDataChartView,差异:x 轴在底部、不画过原点零线、网格线被填充覆盖故省)---- + plot_ = new QwtPlot(this); + plot_->setObjectName(QStringLiteral("gridPlotArea")); + plot_->enableAxis(QwtPlot::xBottom, true); + plot_->enableAxis(QwtPlot::xTop, false); + plot_->enableAxis(QwtPlot::yLeft, true); - // ---- 色阶占位(固定高 36px) ---- - auto* colorScaleBar = new QWidget(this); - colorScaleBar->setObjectName(QStringLiteral("gridColorScaleBar")); - colorScaleBar->setFixedHeight(36); - lay->addWidget(colorScaleBar); + // 白底浅色(对齐原版 web 图表)。 + plot_->setCanvasBackground(QBrush(Qt::white)); + plot_->setAutoFillBackground(true); + { + QPalette pal = plot_->palette(); + pal.setColor(QPalette::Window, Qt::white); + pal.setColor(QPalette::WindowText, QColor(90, 90, 90)); + pal.setColor(QPalette::Text, QColor(90, 90, 90)); + plot_->setPalette(pal); + } + + // 交互:LivePanner(左键实时平移,x 底轴 + y 左轴)+ Magnifier(滚轮缩放,反向使上滚=放大)。 + new LivePanner(plot_, QwtPlot::xBottom, QwtPlot::yLeft, this); + auto* magnifier = new QwtPlotMagnifier(plot_->canvas()); + magnifier->setWheelFactor(1.0 / 0.9); + + plot_->setMinimumSize(0, 0); + + // 锁定 x:y 真实比尺(参考轴 xBottom,Expanding)。 + rescaler_ = new QwtPlotRescaler(plot_->canvas(), QwtPlot::xBottom, QwtPlotRescaler::Expanding); + rescaler_->setAspectRatio(1.0); + rescaler_->setEnabled(true); + + lay->addWidget(plot_, 1); + + // ---- 独立色阶条(固定高 36px)---- + colorBar_ = new ColorBarWidget(this); + colorBar_->setObjectName(QStringLiteral("gridColorScaleBar")); + lay->addWidget(colorBar_); // ---- 底部双页签(异常列表 / 描述),固定高约 200px ---- anomalyTable_ = new AnomalyTablePanel(this); @@ -109,12 +144,67 @@ GridDataChartView::GridDataChartView(QWidget* parent) : QWidget(parent) { auto* bottomContainer = tabbedBottom.container; bottomContainer->setFixedHeight(200); lay->addWidget(bottomContainer); + + // ---- 工具条开关 → 重建/重绘 ---- + connect(chkShowAnom, &QCheckBox::toggled, this, [this](bool on) { + showAnomalies_ = on; + if (contourItem_) { contourItem_->setShowAnomalies(on); plot_->replot(); } + }); + connect(chkShowContourLabel, &QCheckBox::toggled, this, [this](bool on) { + showLabels_ = on; + if (contourItem_) { contourItem_->setShowLabels(on); plot_->replot(); } + }); } void GridDataChartView::setData(const geopro::controller::DatasetDetailController::ChartData& d) { data_ = d; - // 步骤1:只把 anomalies 喂给底部异常列表;图表区留空。 + // 开页:仅把 anomalies 喂给底部异常列表;图表区待网格数据懒加载后填充。 anomalyTable_->setAnomalies(d.anomalies, {}, {}); } +void GridDataChartView::setGridData(const geopro::core::Grid& grid, + const geopro::core::ColorScale& gridScale, + const std::vector& anoms) { + grid_ = grid; + gridScale_ = gridScale; + anoms_ = anoms; + hasGrid_ = true; + + // 重建色彩服务(旧 contourItem 已 detach/delete)。 + delete colorSvc_; + colorSvc_ = new ColorMapService(gridScale_); + + rebuildContour(); + + // 色阶条 + 底部异常表(懒加载结果含真实异常)。 + colorBar_->setColorScale(gridScale_); + anomalyTable_->setAnomalies(anoms_, {}, {}); +} + +void GridDataChartView::rebuildContour() { + if (!hasGrid_ || !colorSvc_) return; + + // 卸载旧项(QwtPlot 不拥有 item)。 + if (contourItem_) { + contourItem_->detach(); + delete contourItem_; + contourItem_ = nullptr; + } + + contourItem_ = new ContourPlotItem(); + contourItem_->setData(grid_, colorSvc_, anoms_, /*showLines*/ true, showLabels_); + contourItem_->setShowAnomalies(showAnomalies_); + contourItem_->attach(plot_); + + // 轴范围 = 数据范围(x=距离、y=深度/高程)。 + const QRectF bbox = contourItem_->boundingRect(); + if (!bbox.isNull()) { + plot_->setAxisScale(QwtPlot::xBottom, bbox.left(), bbox.right()); + plot_->setAxisScale(QwtPlot::yLeft, bbox.top(), bbox.bottom()); + } + plot_->updateAxes(); + if (rescaler_) rescaler_->rescale(); // 应用真实比尺 + plot_->replot(); +} + } // namespace geopro::app diff --git a/src/app/panels/chart/GridDataChartView.hpp b/src/app/panels/chart/GridDataChartView.hpp index 978b26f..75d9898 100644 --- a/src/app/panels/chart/GridDataChartView.hpp +++ b/src/app/panels/chart/GridDataChartView.hpp @@ -1,38 +1,65 @@ #pragma once +#include + #include + #include "DatasetDetailController.hpp" +#include "model/Anomaly.hpp" +#include "model/ColorScale.hpp" +#include "model/Field.hpp" class QSlider; class QLabel; +class QwtPlot; +class QwtPlotRescaler; namespace geopro::app { class AnomalyTablePanel; class DescriptionPanel; +class ColorBarWidget; +class ColorMapService; +class ContourPlotItem; -// 网格数据图表视图(步骤1骨架):工具条 + 图表占位 + 色阶占位 + 底部双页签(异常列表/描述)。 -// 图表渲染由后续步骤填入 plotArea()。 +// 网格数据图表视图:工具条 + QwtPlot(白底 + 真实比尺 + 实时平移/滚轮缩放,x 轴在底部) +// + 独立色阶条 + 底部双页签(异常列表/描述)。 +// 填充走 ContourPlotItem 栅格热力图 + 矢量等值线 + 标注 + 异常叠加。 class GridDataChartView : public QWidget { Q_OBJECT public: explicit GridDataChartView(QWidget* parent = nullptr); - // 步骤1:把 anomalies 喂给底部异常列表;图表区留空。 + // 开页时调用:仅喂底部异常列表(网格数据随网格页激活懒加载)。 void setData(const geopro::controller::DatasetDetailController::ChartData& d); - // 供后续步骤填充 Qwt 画布的占位区域。 - QWidget* plotArea() const { return plotArea_; } - - // 供后续步骤联动异常叠加。 - AnomalyTablePanel* anomalyTable() const { return anomalyTable_; } + // 网格数据到达(懒加载结果):建色彩服务 + ContourPlotItem,挂到 QwtPlot,更新色阶条/异常表。 + void setGridData(const geopro::core::Grid& grid, const geopro::core::ColorScale& gridScale, + const std::vector& anoms); private: + void rebuildContour(); // 按当前显隐开关重建并重绘 ContourPlotItem + geopro::controller::DatasetDetailController::ChartData data_; - QWidget* plotArea_; - AnomalyTablePanel* anomalyTable_; - DescriptionPanel* descriptionPanel_; - QSlider* simplifySlider_; - QLabel* simplifyValueLabel_; + + QwtPlot* plot_ = nullptr; + QwtPlotRescaler* rescaler_ = nullptr; + ColorBarWidget* colorBar_ = nullptr; + AnomalyTablePanel* anomalyTable_ = nullptr; + DescriptionPanel* descriptionPanel_ = nullptr; + QSlider* simplifySlider_ = nullptr; + QLabel* simplifyValueLabel_ = nullptr; + + // 渲染状态 + ColorMapService* colorSvc_ = nullptr; // heap,setGridData 重建 + ContourPlotItem* contourItem_ = nullptr; + geopro::core::Grid grid_{1, 1}; + geopro::core::ColorScale gridScale_; + std::vector anoms_; + bool hasGrid_ = false; + + // 工具条显隐开关 + bool showAnomalies_ = true; + bool showLabels_ = true; }; } // namespace geopro::app