#include "panels/chart/RawDataChartView.hpp" #include "panels/chart/ColorBarWidget.hpp" #include "panels/chart/ScatterPlotItem.hpp" #include #include #include #include #include #include #include #include #include #include namespace geopro::app { RawDataChartView::RawDataChartView(QWidget* parent) : QWidget(parent) { auto* lay = new QVBoxLayout(this); lay->setContentsMargins(0, 0, 0, 0); lay->setSpacing(0); // ---- 工具条 ---- auto* toolbar = new QWidget(this); auto* tbLay = new QHBoxLayout(toolbar); tbLay->setContentsMargins(4, 4, 4, 4); tbLay->setSpacing(4); auto* btnGrid = new QToolButton(toolbar); btnGrid->setText(QStringLiteral("网格")); auto* btnColorScale = new QToolButton(toolbar); btnColorScale->setText(QStringLiteral("色阶配置")); auto* lblCurrentChart = new QLabel(QStringLiteral("当前图形:"), toolbar); chartTypeCombo_ = new QComboBox(toolbar); chartTypeCombo_->addItem(QStringLiteral("散点图")); auto* btnSaveAs = new QToolButton(toolbar); btnSaveAs->setText(QStringLiteral("另存为")); tbLay->addWidget(btnGrid); tbLay->addWidget(btnColorScale); tbLay->addWidget(lblCurrentChart); tbLay->addWidget(chartTypeCombo_); tbLay->addWidget(btnSaveAs); tbLay->addStretch(); lay->addWidget(toolbar); // ---- QwtPlot(stretch 填满剩余空间)---- plot_ = new QwtPlot(this); plot_->setObjectName(QStringLiteral("rawPlotArea")); // x 轴顶部,关闭底部 x 轴 plot_->enableAxis(QwtPlot::xTop, true); plot_->enableAxis(QwtPlot::xBottom, false); plot_->enableAxis(QwtPlot::yLeft, true); // 白底浅色(对齐原版 web 图表,与 App 暗色主题独立):画布白、轴文字深灰。 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); } // 过原点零线(对齐原版 zeroline:x=0 竖线 + y=0 横线 → "四象限"观感)。 auto* zeroX = new QwtPlotMarker(); zeroX->setLineStyle(QwtPlotMarker::VLine); zeroX->setXValue(0.0); zeroX->setLinePen(QColor(180, 180, 180), 1.0); zeroX->setXAxis(QwtPlot::xTop); zeroX->attach(plot_); auto* zeroY = new QwtPlotMarker(); zeroY->setLineStyle(QwtPlotMarker::HLine); zeroY->setYValue(0.0); zeroY->setLinePen(QColor(180, 180, 180), 1.0); zeroY->attach(plot_); // 交互:Panner(左键拖动平移)+ Magnifier(滚轮缩放) auto* panner = new QwtPlotPanner(plot_->canvas()); panner->setMouseButton(Qt::LeftButton); auto* magnifier = new QwtPlotMagnifier(plot_->canvas()); // 反转滚轮方向:Qwt 默认 wheelFactor=0.9 → 上滚缩小;取倒数使「上滚=放大」(常规习惯)。 magnifier->setWheelFactor(1.0 / 0.9); // 允许随停靠面板自由收缩(不强制最小宽度→不出横向滚动条,对齐原版响应式填充)。 plot_->setMinimumSize(0, 0); lay->addWidget(plot_, 1); // ---- 独立色阶条(固定高 36px,QwtPlot 的兄弟 widget)---- colorBar_ = new ColorBarWidget(this); colorBar_->setObjectName(QStringLiteral("rawColorScaleBar")); lay->addWidget(colorBar_); } QWidget* RawDataChartView::plotArea() const { return plot_; } void RawDataChartView::setData( const geopro::controller::DatasetDetailController::ChartData& d) { data_ = d; if (d.scatterScale.empty()) return; // 重建 ColorMapService(旧的 scatterItem 已被 QwtPlot detach/delete) delete colorSvc_; colorSvc_ = new ColorMapService(d.scatterScale); // 卸载旧散点项 if (scatterItem_) { scatterItem_->detach(); // QwtPlot 不拥有 item,需要我们释放 delete scatterItem_; scatterItem_ = nullptr; } // 新建散点项并挂到 plot scatterItem_ = new ScatterPlotItem(); scatterItem_->setData(d.scatter, colorSvc_); scatterItem_->attach(plot_); // 按数据包围盒设置轴范围 QRectF bbox = scatterItem_->boundingRect(); if (!bbox.isEmpty()) { plot_->setAxisScale(QwtPlot::xTop, bbox.left(), bbox.right()); plot_->setAxisScale(QwtPlot::yLeft, bbox.top(), bbox.bottom()); } plot_->replot(); // 更新色阶条 colorBar_->setColorScale(d.scatterScale); } } // namespace geopro::app