feat(nmNum): 调整结果入口与阈值显示

- 移除 Results 按钮和 Valid runs 提示。
- 右键控制图内阈值显示,随拖动和重置更新。
- 删除阈值悬停提示,保留散点参数提示。
feature/Sensitivity-20261012
lvjunjie 1 week ago
parent 111f496579
commit a1356f5555

@ -73,7 +73,6 @@ signals:
void sigGenerateClicked(); // 点击生成按钮时发出的信号
// 敏感性批量任务交给所属主窗口,复用普通求解进度框。
void sigSensitivityTaskReady(nmWxSensitive* dialog, nmCalculationDllPebiSolverTask* task);
void sigSensitiveResultsRequested();
void sigIncludeWells(); // 包含其他井后刷新参数栏的信号
/** @brief 用户切换结果井时发送快照中的稳定井 UUID。 */
void sigResultWellChanged(const QString& sWellInstanceId);

@ -25,6 +25,7 @@ class SensitivityDistributionPlot;
class SensitivityResultsModel;
class iGuiPlot;
class QMenu;
class QAction;
class NM_SUB_WXS_EXPORT nmWxSensitivityHistogramOptions : public iDlgBase
{
@ -54,6 +55,7 @@ private slots:
void updateThreshold();
void resetThreshold();
void adjustContextMenu(QMenu* menu);
void updateLegend();
private:
QSharedPointer<nmDataSensitive::BatchResult> m_results;
double m_baseError;
@ -62,6 +64,7 @@ private:
QComboBox* m_parameter;
double m_threshold;
QLabel* m_legend;
QAction* m_resultsInPlot;
iGuiPlot* m_plot;
QVector<QPointF> m_points;
QVector<int> m_runRows;
@ -98,7 +101,6 @@ public:
signals:
void sigSensitivityTaskReady(nmWxSensitive* dialog, nmCalculationDllPebiSolverTask* task);
void sigSensitivityCancelRequested();
void sigSensitiveResultsRequested();
public slots:
void reject() override;
@ -118,7 +120,6 @@ protected:
void onPreviewClicked();
void onPreviewScrollAction(int action);
void onSensitivityFinished();
void onResultsClicked();
void onResultsChanged();
void onModelResultChanged();
@ -149,7 +150,6 @@ private:
QPushButton *generateButton;
QPushButton *cancelButton;
QPushButton *previewButton;
QPushButton *resultsButton;
// 各个变量页面的控件列表
QList<QComboBox*> m_modeCombos;

@ -2013,7 +2013,7 @@ void nmSubWndMain::onShowSensitiveResults()
curve->setVisible(!hidden.contains(curve->getName()));
plot->setReadOnly(true);
plot->freshAxisScales(true, false);
// 关闭后仍可通过 Results 恢复;只有新建或恢复窗口时才重新调整内部布局。
// 只有新建或恢复窗口时才重新调整内部布局。
QMdiSubWindow* subWindow = nullptr;
for(QWidget* parent = plot->parentWidget(); parent && !subWindow; parent = parent->parentWidget())
subWindow = qobject_cast<QMdiSubWindow*>(parent);
@ -2206,9 +2206,6 @@ void nmSubWndMain::updateSensitiveHistogramPlot()
settings->setObjectName("nmHistogramOptionsButton");
options->addWidget(scatter);
options->addWidget(settings);
QLabel* count = new QLabel(page);
count->setObjectName("nmHistogramCount");
options->addWidget(count);
options->addStretch();
layout->addLayout(options);
iGuiPlot* plot = new iGuiPlot(true, page);
@ -2239,8 +2236,6 @@ void nmSubWndMain::updateSensitiveHistogramPlot()
if(run.m_bSucceeded && !run.m_bCancelled && qIsFinite(run.m_dPressureRmse) && run.m_dPressureRmse >= 0.0)
errors.append(run.m_dPressureRmse);
}
window->findChild<QLabel*>("nmHistogramCount")->setText(errors.isEmpty()
? tr("No valid goodness-of-fit results") : tr("Valid runs: %1").arg(errors.size()));
double minimum = 0.0, maximum = 1.0;
if(!errors.isEmpty()) {
minimum = maximum = errors.first();

@ -483,8 +483,6 @@ void nmSubWndUtils::setupNumericalDockWidgets(nmDataAnalyzeManager* pDataManager
pSubWndMain, SLOT(onGenerateButtonClicked()));
connect(pAnalWx, SIGNAL(sigSensitivityTaskReady(nmWxSensitive*,nmCalculationDllPebiSolverTask*)),
pSubWndMain, SLOT(onSensitivityTaskReady(nmWxSensitive*,nmCalculationDllPebiSolverTask*)));
connect(pAnalWx, SIGNAL(sigSensitiveResultsRequested()),
pSubWndMain, SLOT(onShowSensitiveResults()));
connect(pAnalWx, SIGNAL(sigResultWellChanged(QString)),
pSubWndMain, SLOT(onWellSelected(QString)));

@ -1464,7 +1464,6 @@ void nmWxNumericalDesign::onSensitiveClicked()
// 按数值生成按钮的现有路径,将任务请求转发给所属主窗口。
connect(dlg, SIGNAL(sigSensitivityTaskReady(nmWxSensitive*,nmCalculationDllPebiSolverTask*)),
this, SIGNAL(sigSensitivityTaskReady(nmWxSensitive*,nmCalculationDllPebiSolverTask*)));
connect(dlg, SIGNAL(sigSensitiveResultsRequested()), this, SIGNAL(sigSensitiveResultsRequested()));
dlg->show();
}

@ -37,6 +37,7 @@
#include "tCurvePlotView.h"
#include "iCurveDesc.h"
#include <QMenu>
#include <QAction>
#include <QHelpEvent>
#include <QToolTip>
#include <QTableWidget>
@ -516,11 +517,12 @@ nmWxSensitivityScatter::nmWxSensitivityScatter(
layout->addWidget(m_plot);
// 两项固定图例不使用框架的分组标题,覆盖在绘图区左上角。
m_legend = new QLabel(m_plot->m_pPlotView->viewport());
m_legend->setText("<table cellspacing='2'><tr><td>&#9633;</td><td>" + tr("sensitivity data")
+ "</td></tr><tr><td style='color:blue'>&#9632;</td><td>" + tr("reference") + "</td></tr></table>");
m_legend->setStyleSheet("QLabel { background: white; color: black; border: 1px solid #cccccc; }");
m_legend->setAttribute(Qt::WA_TransparentForMouseEvents);
m_legend->adjustSize();
m_resultsInPlot = new QAction(tr("Results in plot"), this);
m_resultsInPlot->setCheckable(true);
connect(m_resultsInPlot, SIGNAL(toggled(bool)), this, SLOT(updateLegend()));
updateLegend();
m_plot->m_pPlotView->viewport()->installEventFilter(this);
connect(m_parameter, SIGNAL(currentIndexChanged(int)), this, SLOT(updateParameter()));
connect(m_plot->m_pPlotView, SIGNAL(sigAdjustContextMenu(QMenu*)), this, SLOT(adjustContextMenu(QMenu*)));
@ -608,22 +610,13 @@ void nmWxSensitivityScatter::updateParameter()
void nmWxSensitivityScatter::updateThreshold()
{
// 阈值以下的点填黑,范围使用这些采样点的参数值,不包含蓝色基准点。
// 阈值以下的点填黑,并同步图例中的阈值显示。
if(m_parameter->currentIndex() < 0) return;
updateLegend();
QVector<QPointF> accepted;
double lower = 0.0, upper = 0.0;
for(int i = 0; i < m_points.size(); ++i) if(m_points[i].y() < m_threshold) {
if(accepted.isEmpty()) lower = upper = m_points[i].x();
lower = qMin(lower, m_points[i].x());
upper = qMax(upper, m_points[i].x());
accepted.append(m_points[i]);
}
const int index = m_parameter->itemData(m_parameter->currentIndex()).toInt();
const nmDataSensitive::VariableSampling& variable = m_results->m_variables[index];
m_plot->setToolTip(tr("Threshold: %1 MPa\n").arg(m_threshold, 0, 'g', 6)
+ tr("Below threshold: %1 / %2; %3 range: %4").arg(accepted.size()).arg(m_points.size())
.arg(variable.m_varName).arg(accepted.isEmpty() ? tr("N/A")
: QString::number(lower, 'g', 6) + " - " + QString::number(upper, 'g', 6) + " " + variable.m_modelValue.getUnit()));
if(m_threshold > m_plot->getAxisOf(1)->getRangeMax()) {
VecDouble ticks;
const double top = m_threshold * 1.1;
@ -670,9 +663,21 @@ void nmWxSensitivityScatter::resetThreshold()
void nmWxSensitivityScatter::adjustContextMenu(QMenu* menu)
{
// 复用绘图右键菜单,保留框架的缩放、复制与导出入口。
menu->addAction(m_resultsInPlot);
menu->addAction(tr("Reset line"), this, SLOT(resetThreshold()));
}
void nmWxSensitivityScatter::updateLegend()
{
// 勾选后在原有两项图例下追加阈值,拖线和重置时实时更新。
QString text = "<table cellspacing='2'><tr><td>&#9633;</td><td>" + tr("sensitivity data")
+ "</td></tr><tr><td style='color:blue'>&#9632;</td><td>" + tr("reference") + "</td></tr></table>";
if(m_resultsInPlot->isChecked())
text += "<div>" + tr("Threshold: %1 MPa").arg(m_threshold, 0, 'g', 6) + "</div>";
m_legend->setText(text);
m_legend->adjustSize();
}
bool nmWxSensitivityScatter::eventFilter(QObject* object, QEvent* event)
{
if(object != m_plot->m_pPlotView->viewport()) return iDlgBase::eventFilter(object, event);
@ -707,7 +712,8 @@ bool nmWxSensitivityScatter::eventFilter(QObject* object, QEvent* event)
.arg(run.m_dPressureRmse, 0, 'g', 6), view->viewport());
return true;
}
QToolTip::showText(help->globalPos(), m_plot->toolTip(), view->viewport());
QToolTip::hideText();
event->ignore();
return true;
}
return iDlgBase::eventFilter(object, event);
@ -1173,7 +1179,7 @@ nmWxSensitive::nmWxSensitive(QWidget *parent, nmDataAnalyzeManager* manager)
loadDataToUI();
m_loading = false;
onTreeItemChanged(nullptr, 0);
// 已有批次可直接重新打开,结果发布后同步入口与列表。
// 结果发布或清除后,同步本窗口持有的批次数据。
if(m_pDataManager) {
connect(m_pDataManager, SIGNAL(sigSensitiveResultsChanged()), this, SLOT(onResultsChanged()));
connect(m_pDataManager, SIGNAL(sigPebiResultSnapshotChanged()), this, SLOT(onModelResultChanged()));
@ -1694,11 +1700,9 @@ void nmWxSensitive::setupUI()
bottomLayout->addWidget(previewButton);
bottomLayout->addStretch();
resultsButton = new QPushButton(tr("Results"), this);
generateButton = new QPushButton(tr("Generate"), this);
cancelButton = new QPushButton(tr("Cancel"), this);
bottomLayout->addWidget(resultsButton);
bottomLayout->addWidget(generateButton);
bottomLayout->addWidget(cancelButton);
@ -1714,7 +1718,6 @@ void nmWxSensitive::createConnections()
connect(cancelButton, SIGNAL(clicked()),
this, SLOT(onCancelClicked()));
connect(previewButton, SIGNAL(clicked()), this, SLOT(onPreviewClicked()));
connect(resultsButton, SIGNAL(clicked()), this, SLOT(onResultsClicked()));
connect(calculationTypeCombo, SIGNAL(currentIndexChanged(int)),
this, SLOT(onCalculationTypeChanged(int)));
@ -2408,22 +2411,12 @@ void nmWxSensitive::onSensitivityFinished()
QMessageBox::warning(ownerWindow, tr("Sensitivity"), message);
}
void nmWxSensitive::onResultsClicked()
{
// Results 只打开或恢复结果图,曲线显示由各图自己的 Show 控制。
onResultsChanged();
if(!resultsButton->isEnabled()) return;
emit sigSensitiveResultsRequested();
hide();
}
void nmWxSensitive::onResultsChanged()
{
// 新模型清除旧批次后同步禁用结果入口。
// 同步当前批次,新模型清除旧结果时也清除本地引用。
QSharedPointer<nmDataSensitive::BatchResult> results;
if(m_pDataManager && m_pDataManager->getSensitiveData())
results = m_pDataManager->getSensitiveData()->getResults();
resultsButton->setEnabled(!results.isNull());
m_sensitiveData.setResults(results);
}

Loading…
Cancel
Save