145 lines
4.7 KiB
C++
145 lines
4.7 KiB
C++
#include "panels/chart/RawDataChartView.hpp"
|
||
#include "panels/chart/ColorBarWidget.hpp"
|
||
#include "panels/chart/ScatterPlotItem.hpp"
|
||
|
||
#include <QComboBox>
|
||
#include <QHBoxLayout>
|
||
#include <QLabel>
|
||
#include <QToolButton>
|
||
#include <QVBoxLayout>
|
||
|
||
#include <qwt_plot.h>
|
||
#include <qwt_plot_canvas.h>
|
||
#include <qwt_plot_panner.h>
|
||
#include <qwt_plot_magnifier.h>
|
||
#include <qwt_plot_marker.h>
|
||
|
||
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
|