You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
nmWTAI-Platform/Src/nmNum/nmSubWxs/nmWellPressureFlowPage.cpp

773 lines
24 KiB
C++

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#include "nmWellPressureFlowPage.h"
#include "iUnitGroup.h"
#include "iUnitHelper.h"
#include "iUnitItem.h"
#include "nmDataWellBase.h"
#include "nmWxPressFlowChartWidget.h"
#include "ZxBaseUtil.h"
#include "ZxTableHeaderViewUnit.h"
#include <QAbstractItemView>
#include <QHeaderView>
#include <QLabel>
#include <QList>
#include <QPalette>
#include <QSplitter>
#include <QStackedWidget>
#include <QStringList>
#include <QTableWidget>
#include <QTableWidgetItem>
#include <QVBoxLayout>
namespace
{
QString preferredTimeUnit()
{
return QLatin1String("h");
}
QString preferredFlowUnit()
{
return QString::fromUtf8("m\xC2\xB3/d");
}
iUnitGroup* resolveUnitGroup(const QStringList& listCandidates,
QString& sResolvedUnit)
{
for (int nIndex = 0; nIndex < listCandidates.size(); ++nIndex)
{
const QString& sCandidate = listCandidates[nIndex];
iUnitGroup* pUnitGroup =
iUnitHelper::getUnitGroupByUnit(sCandidate);
if (pUnitGroup == nullptr)
{
continue;
}
int nUnitIndex = pUnitGroup->indexOf(sCandidate);
QStringList listUnitNames = pUnitGroup->getAllUnitNames();
if (nUnitIndex < 0 || nUnitIndex >= listUnitNames.size())
{
continue;
}
sResolvedUnit = listUnitNames[nUnitIndex];
return pUnitGroup;
}
sResolvedUnit = listCandidates.isEmpty()
? QString() : listCandidates.first();
return nullptr;
}
QLabel* createEmptyLabel(const QString& sText, QWidget* pParent)
{
QLabel* pLabel = new QLabel(sText, pParent);
pLabel->setAlignment(Qt::AlignCenter);
QPalette oPalette = pLabel->palette();
oPalette.setColor(QPalette::WindowText,
pParent->palette().color(QPalette::Mid));
pLabel->setPalette(oPalette);
return pLabel;
}
QString displayValueText(double dValue, int nDigit)
{
if (nDigit <= 0)
{
return QString::number(dValue, 'f', 0);
}
return ZxBaseUtil::getValidStr(dValue, nDigit);
}
}
nmWellPressureFlowPage::nmWellPressureFlowPage(QWidget* pParent)
: QWidget(pParent),
m_pWell(nullptr),
m_pContentStack(nullptr),
m_pHorizontalSplitter(nullptr),
m_pChartSplitter(nullptr),
m_pPressureChartStack(nullptr),
m_pFlowChartStack(nullptr),
m_pFlowTableStack(nullptr),
m_pPressureChart(nullptr),
m_pFlowChart(nullptr),
m_pFlowTable(nullptr),
m_pFlowHeader(nullptr),
m_pTimeUnitGroup(nullptr),
m_pFlowUnitGroup(nullptr),
m_sTimeBaseUnit(preferredTimeUnit()),
m_sFlowBaseUnit(preferredFlowUnit()),
m_sTimeUnit(preferredTimeUnit()),
m_sFlowUnit(preferredFlowUnit()),
m_nTimeDigit(6),
m_nFlowDigit(6),
m_nSelectedFlowSegment(-1)
{
createUi();
initializeUnitSupport();
resetDataViews();
}
void nmWellPressureFlowPage::setWell(nmDataWellBase* pWell)
{
if (m_pWell == pWell)
{
return;
}
m_pWell = pWell;
resetDataViews();
}
void nmWellPressureFlowPage::refreshData()
{
if (m_pWell == nullptr)
{
resetDataViews();
return;
}
// 第一步:井数据只复制到页面基准副本,后续显示换算不会回写井对象。
QVector<QPointF> vecRawPressurePoints =
m_pWell->getPressurePoints();
QVector<QPointF> vecRawFlowPoints = m_pWell->getFlowPoints();
// 第二步:单位服务可能晚于页面构造完成,再刷新一次可用单位组。
initializeUnitSupport();
m_vecRawPressurePoints = vecRawPressurePoints;
m_vecRawFlowPoints = vecRawFlowPoints;
QVector<QPointF> vecTableFlowPoints;
int nTimeDigit = m_nTimeDigit;
int nFlowDigit = m_nFlowDigit;
if (!buildFlowTableData(m_sTimeUnit,
m_sFlowUnit,
vecTableFlowPoints,
nTimeDigit,
nFlowDigit))
{
// 当前显示单位不可用时回退基准单位,禁止继续展示旧井快照。
m_sTimeUnit = m_sTimeBaseUnit;
m_sFlowUnit = m_sFlowBaseUnit;
if (!buildFlowTableData(m_sTimeUnit,
m_sFlowUnit,
vecTableFlowPoints,
nTimeDigit,
nFlowDigit))
{
resetDataViews();
updateUnitHeader();
return;
}
}
// 第三步:换算与精度读取全部成功后再提交,曲线始终读取原始数据。
m_vecTableFlowPoints = vecTableFlowPoints;
m_nTimeDigit = nTimeDigit;
m_nFlowDigit = nFlowDigit;
updateUnitHeader();
updateViews();
}
void nmWellPressureFlowPage::clearData()
{
m_pWell = nullptr;
resetDataViews();
}
void nmWellPressureFlowPage::slotUnitChanged(
int nColumn,
const iUnitItem* pSourceUnit,
const iUnitItem* pDestinationUnit)
{
Q_UNUSED(pSourceUnit);
if (pDestinationUnit == nullptr ||
(nColumn != 0 && nColumn != 1))
{
updateUnitHeader();
return;
}
QString sTimeUnit = m_sTimeUnit;
QString sFlowUnit = m_sFlowUnit;
if (nColumn == 0)
{
if (m_pTimeUnitGroup == nullptr)
{
updateUnitHeader();
return;
}
sTimeUnit = pDestinationUnit->m_sName;
}
else
{
if (m_pFlowUnitGroup == nullptr)
{
updateUnitHeader();
return;
}
sFlowUnit = pDestinationUnit->m_sName;
}
// 每次都从基准副本换算,禁止使用当前显示值继续换算。
QVector<QPointF> vecTableFlowPoints;
int nTimeDigit = m_nTimeDigit;
int nFlowDigit = m_nFlowDigit;
if (!buildFlowTableData(sTimeUnit,
sFlowUnit,
vecTableFlowPoints,
nTimeDigit,
nFlowDigit))
{
updateUnitHeader();
return;
}
m_sTimeUnit = sTimeUnit;
m_sFlowUnit = sFlowUnit;
m_vecTableFlowPoints = vecTableFlowPoints;
m_nTimeDigit = nTimeDigit;
m_nFlowDigit = nFlowDigit;
updateUnitHeader();
updateFlowTable();
}
void nmWellPressureFlowPage::slotFlowRowChanged(
int nCurrentRow,
int nCurrentColumn,
int nPreviousRow,
int nPreviousColumn)
{
Q_UNUSED(nCurrentColumn);
Q_UNUSED(nPreviousRow);
Q_UNUSED(nPreviousColumn);
applyFlowSegmentSelection(nCurrentRow);
}
void nmWellPressureFlowPage::slotFlowChartPointClicked(double dTimePoint)
{
// 曲线保持基准单位,点击时间先换算为表格当前单位再定位行。
double dTableTimePoint = 0.0;
if (!convertValue(m_pTimeUnitGroup,
m_sTimeBaseUnit,
m_sTimeUnit,
dTimePoint,
dTableTimePoint))
{
applyFlowSegmentSelection(-1);
return;
}
applyFlowSegmentSelection(
findFlowSegmentByTableTime(dTableTimePoint));
}
void nmWellPressureFlowPage::createUi()
{
QVBoxLayout* pMainLayout = new QVBoxLayout(this);
pMainLayout->setContentsMargins(8, 6, 8, 8);
pMainLayout->setSpacing(0);
m_pContentStack = new QStackedWidget(this);
m_pHorizontalSplitter = new QSplitter(
Qt::Horizontal, m_pContentStack);
m_pHorizontalSplitter->setChildrenCollapsible(false);
// 左侧上下两图共享时间范围,但各自保留独立空状态。
m_pChartSplitter = new QSplitter(
Qt::Vertical, m_pHorizontalSplitter);
m_pChartSplitter->setChildrenCollapsible(false);
m_pPressureChartStack = new QStackedWidget(m_pChartSplitter);
m_pPressureChart = new nmWxPressFlowChartWidget(
m_pPressureChartStack);
m_pPressureChart->setReadOnly(true);
m_pPressureChart->setTimeSelectionEnabled(false);
m_pPressureChart->setAxisLabels(tr("Time"), tr("Pressure"));
m_pPressureChart->setAxisUnits(
m_sTimeBaseUnit, tr("MPa"));
m_pPressureChart->setLineColor(QColor(50, 200, 50));
m_pPressureChart->setChartType(CHART_TYPE_LINE);
m_pPressureChartStack->addWidget(m_pPressureChart);
m_pPressureChartStack->addWidget(createEmptyLabel(
tr("No pressure data"), m_pPressureChartStack));
m_pFlowChartStack = new QStackedWidget(m_pChartSplitter);
m_pFlowChart = new nmWxPressFlowChartWidget(m_pFlowChartStack);
m_pFlowChart->setReadOnly(true);
m_pFlowChart->setTimeSelectionEnabled(true);
m_pFlowChart->setAxisLabels(tr("Time"), tr("Flow"));
m_pFlowChart->setAxisUnits(m_sTimeBaseUnit, m_sFlowBaseUnit);
m_pFlowChart->setLineColor(QColor(255, 0, 0));
m_pFlowChart->setChartType(CHART_TYPE_STEP);
m_pFlowChartStack->addWidget(m_pFlowChart);
m_pFlowChartStack->addWidget(createEmptyLabel(
tr("No flow data"), m_pFlowChartStack));
m_pChartSplitter->addWidget(m_pPressureChartStack);
m_pChartSplitter->addWidget(m_pFlowChartStack);
m_pChartSplitter->setStretchFactor(0, 1);
m_pChartSplitter->setStretchFactor(1, 1);
// 右侧仅显示原始流量段对应的时间和流量,不提供任何编辑入口。
m_pFlowTableStack = new QStackedWidget(m_pHorizontalSplitter);
m_pFlowTable = new QTableWidget(m_pFlowTableStack);
m_pFlowTable->setColumnCount(2);
m_pFlowTable->setEditTriggers(QAbstractItemView::NoEditTriggers);
m_pFlowTable->setSelectionBehavior(QAbstractItemView::SelectRows);
m_pFlowTable->setSelectionMode(QAbstractItemView::SingleSelection);
m_pFlowTable->setSortingEnabled(false);
m_pFlowTable->setDragEnabled(false);
m_pFlowTable->setAcceptDrops(false);
m_pFlowTable->setDropIndicatorShown(false);
m_pFlowTable->setAlternatingRowColors(true);
m_pFlowTable->setStyleSheet(
"QTableWidget {"
" background-color: palette(base);"
" alternate-background-color: rgb(232, 232, 232);"
" gridline-color: palette(midlight);"
" border: 1px solid palette(mid);"
"}"
"QHeaderView {"
" background-color: palette(button);"
" color: palette(button-text);"
"}"
"QHeaderView::section {"
" background-color: palette(button);"
" color: palette(button-text);"
" border: none;"
" border-right: 1px solid palette(mid);"
" border-bottom: 1px solid palette(mid);"
"}"
"QTableCornerButton::section {"
" background-color: palette(base);"
" border: none;"
" border-right: 1px solid palette(mid);"
" border-bottom: 1px solid palette(mid);"
"}");
m_pFlowHeader = new ZxTableHeaderViewUnit(m_pFlowTable);
m_pFlowTable->setHorizontalHeader(m_pFlowHeader);
m_pFlowTable->horizontalHeader()->setMovable(false);
m_pFlowTable->horizontalHeader()->setResizeMode(QHeaderView::Stretch);
m_pFlowTable->verticalHeader()->setMovable(false);
m_pFlowTable->verticalHeader()->setDefaultAlignment(Qt::AlignCenter);
m_pFlowTable->verticalHeader()->setMinimumWidth(18);
m_pFlowTableStack->addWidget(m_pFlowTable);
m_pFlowTableStack->addWidget(createEmptyLabel(
tr("No flow data"), m_pFlowTableStack));
m_pHorizontalSplitter->addWidget(m_pChartSplitter);
m_pHorizontalSplitter->addWidget(m_pFlowTableStack);
m_pHorizontalSplitter->setStretchFactor(0, 7);
m_pHorizontalSplitter->setStretchFactor(1, 3);
QList<int> listHorizontalSizes;
listHorizontalSizes << 700 << 300;
m_pHorizontalSplitter->setSizes(listHorizontalSizes);
m_pContentStack->addWidget(m_pHorizontalSplitter);
m_pContentStack->addWidget(createEmptyLabel(
tr("No pressure or flow data"), m_pContentStack));
pMainLayout->addWidget(m_pContentStack, 1);
connect(m_pFlowHeader,
SIGNAL(sigCbxValueChanged(int,const iUnitItem*,const iUnitItem*)),
this,
SLOT(slotUnitChanged(int,const iUnitItem*,const iUnitItem*)));
connect(m_pFlowTable,
SIGNAL(currentCellChanged(int,int,int,int)),
this,
SLOT(slotFlowRowChanged(int,int,int,int)));
connect(m_pFlowChart,
SIGNAL(chartPointClicked(double)),
this,
SLOT(slotFlowChartPointClicked(double)));
}
void nmWellPressureFlowPage::initializeUnitSupport()
{
QStringList listTimeCandidates;
listTimeCandidates << preferredTimeUnit() << QLatin1String("hr");
QStringList listFlowCandidates;
listFlowCandidates << preferredFlowUnit()
<< QLatin1String("m^3/d")
<< QLatin1String("m^3/D");
// 优先使用当前单位包的h、m³/d旧英文单位包自动兼容hr、m^3/d。
m_pTimeUnitGroup = resolveUnitGroup(
listTimeCandidates, m_sTimeBaseUnit);
m_pFlowUnitGroup = resolveUnitGroup(
listFlowCandidates, m_sFlowBaseUnit);
// 单位组缺失或当前单位不再存在时回退基准单位,入口由框架表头禁用。
if (m_pTimeUnitGroup == nullptr ||
m_pTimeUnitGroup->indexOf(m_sTimeUnit) < 0)
{
m_sTimeUnit = m_sTimeBaseUnit;
}
if (m_pFlowUnitGroup == nullptr ||
m_pFlowUnitGroup->indexOf(m_sFlowUnit) < 0)
{
m_sFlowUnit = m_sFlowBaseUnit;
}
updateUnitHeader();
}
void nmWellPressureFlowPage::updateUnitHeader()
{
if (m_pFlowHeader == nullptr)
{
return;
}
QStringList listTitles;
listTitles << tr("Time") << tr("Flow");
QStringList listUnits;
listUnits << m_sTimeUnit << m_sFlowUnit;
m_pFlowHeader->setHeaderData(listTitles, listUnits);
}
bool nmWellPressureFlowPage::buildFlowTableData(
const QString& sTimeUnit,
const QString& sFlowUnit,
QVector<QPointF>& vecFlowPoints,
int& nTimeDigit,
int& nFlowDigit) const
{
vecFlowPoints = m_vecRawFlowPoints;
// 空数据也必须验证目标单位,避免表头切换后留下不可用单位状态。
double dConvertedZero = 0.0;
if (!convertValue(m_pTimeUnitGroup,
m_sTimeBaseUnit,
sTimeUnit,
0.0,
dConvertedZero,
&nTimeDigit) ||
!convertValue(m_pFlowUnitGroup,
m_sFlowBaseUnit,
sFlowUnit,
0.0,
dConvertedZero,
&nFlowDigit))
{
return false;
}
// 表格每次从原始副本换算,禁止使用当前显示值继续换算。
for (int nIndex = 0; nIndex < vecFlowPoints.size(); ++nIndex)
{
double dDuration = 0.0;
double dFlow = 0.0;
if (!convertValue(m_pTimeUnitGroup,
m_sTimeBaseUnit,
sTimeUnit,
m_vecRawFlowPoints[nIndex].x(),
dDuration) ||
!convertValue(m_pFlowUnitGroup,
m_sFlowBaseUnit,
sFlowUnit,
m_vecRawFlowPoints[nIndex].y(),
dFlow))
{
return false;
}
vecFlowPoints[nIndex] = QPointF(dDuration, dFlow);
}
return true;
}
bool nmWellPressureFlowPage::convertValue(
iUnitGroup* pUnitGroup,
const QString& sBaseUnit,
const QString& sDestinationUnit,
double dSourceValue,
double& dDestinationValue,
int* pDestinationDigit) const
{
int nDigit = 6;
if (pUnitGroup != nullptr)
{
iUnitItem* pUnitItem =
pUnitGroup->getUnitItem(sDestinationUnit);
if (pUnitItem != nullptr && pUnitItem->m_nDigit >= 0)
{
nDigit = pUnitItem->m_nDigit;
}
}
if (sDestinationUnit == sBaseUnit)
{
dDestinationValue = dSourceValue;
if (pDestinationDigit != nullptr)
{
*pDestinationDigit = nDigit;
}
return true;
}
if (pUnitGroup == nullptr ||
pUnitGroup->indexOf(sBaseUnit) < 0 ||
pUnitGroup->indexOf(sDestinationUnit) < 0)
{
return false;
}
int nFallbackDigit = nDigit;
bool bConverted = pUnitGroup->convert(sBaseUnit,
dSourceValue,
sDestinationUnit,
dDestinationValue,
nDigit);
if (bConverted && pDestinationDigit != nullptr)
{
*pDestinationDigit = nDigit >= 0
? nDigit : nFallbackDigit;
}
return bConverted;
}
void nmWellPressureFlowPage::updateViews()
{
QVector<QPointF> vecFlowChartPoints = createFlowChartPoints();
m_pPressureChart->setAxisUnits(
m_sTimeBaseUnit, tr("MPa"));
m_pFlowChart->setAxisUnits(m_sTimeBaseUnit, m_sFlowBaseUnit);
m_pPressureChart->setData(m_vecRawPressurePoints);
m_pFlowChart->setData(vecFlowChartPoints);
updateXAxisRange(vecFlowChartPoints);
updateFlowTable();
bool bPressureEmpty = m_vecRawPressurePoints.isEmpty();
bool bFlowEmpty = m_vecRawFlowPoints.isEmpty();
m_pPressureChartStack->setCurrentIndex(bPressureEmpty ? 1 : 0);
m_pFlowChartStack->setCurrentIndex(bFlowEmpty ? 1 : 0);
m_pFlowTableStack->setCurrentIndex(bFlowEmpty ? 1 : 0);
m_pContentStack->setCurrentIndex(
bPressureEmpty && bFlowEmpty ? 1 : 0);
updateSelectedFlowSegment();
}
QVector<QPointF> nmWellPressureFlowPage::createFlowChartPoints() const
{
QVector<QPointF> vecChartPoints;
double dTotalTime = 0.0;
for (int nIndex = 0;
nIndex < m_vecRawFlowPoints.size();
++nIndex)
{
const QPointF& oSegment = m_vecRawFlowPoints[nIndex];
if (nIndex == 0)
{
vecChartPoints.append(QPointF(0.0, oSegment.y()));
}
dTotalTime += oSegment.x();
vecChartPoints.append(QPointF(dTotalTime, oSegment.y()));
if (nIndex < m_vecRawFlowPoints.size() - 1 &&
qAbs(m_vecRawFlowPoints[nIndex + 1].y() -
oSegment.y()) > 1e-6)
{
vecChartPoints.append(QPointF(
dTotalTime,
m_vecRawFlowPoints[nIndex + 1].y()));
}
}
return vecChartPoints;
}
void nmWellPressureFlowPage::updateFlowTable()
{
bool bSignalsWereBlocked = m_pFlowTable->blockSignals(true);
m_pFlowTable->clearContents();
m_pFlowTable->setRowCount(m_vecTableFlowPoints.size());
// 纵向表头显示Qt默认的1N序号内部仍使用零基流量点索引。
for (int nIndex = 0;
nIndex < m_vecTableFlowPoints.size();
++nIndex)
{
QTableWidgetItem* pTimeItem = new QTableWidgetItem(
displayValueText(m_vecTableFlowPoints[nIndex].x(),
m_nTimeDigit));
pTimeItem->setTextAlignment(Qt::AlignCenter);
m_pFlowTable->setItem(nIndex, 0, pTimeItem);
QTableWidgetItem* pFlowItem = new QTableWidgetItem(
displayValueText(m_vecTableFlowPoints[nIndex].y(),
m_nFlowDigit));
pFlowItem->setTextAlignment(Qt::AlignCenter);
m_pFlowTable->setItem(nIndex, 1, pFlowItem);
}
if (m_nSelectedFlowSegment >= 0 &&
m_nSelectedFlowSegment < m_pFlowTable->rowCount())
{
m_pFlowTable->setCurrentCell(m_nSelectedFlowSegment, 0);
m_pFlowTable->selectRow(m_nSelectedFlowSegment);
}
else
{
m_nSelectedFlowSegment = -1;
m_pFlowTable->setCurrentCell(-1, -1);
m_pFlowTable->clearSelection();
}
m_pFlowTable->blockSignals(bSignalsWereBlocked);
}
void nmWellPressureFlowPage::updateXAxisRange(
const QVector<QPointF>& vecFlowChartPoints)
{
bool bHasRange = false;
double dMinimum = 0.0;
double dMaximum = 0.0;
for (int nIndex = 0;
nIndex < m_vecRawPressurePoints.size();
++nIndex)
{
double dTime = m_vecRawPressurePoints[nIndex].x();
dMinimum = bHasRange ? qMin(dMinimum, dTime) : dTime;
dMaximum = bHasRange ? qMax(dMaximum, dTime) : dTime;
bHasRange = true;
}
for (int nIndex = 0; nIndex < vecFlowChartPoints.size(); ++nIndex)
{
double dTime = vecFlowChartPoints[nIndex].x();
dMinimum = bHasRange ? qMin(dMinimum, dTime) : dTime;
dMaximum = bHasRange ? qMax(dMaximum, dTime) : dTime;
bHasRange = true;
}
if (bHasRange)
{
m_pPressureChart->setXAxisRange(dMinimum, dMaximum);
m_pFlowChart->setXAxisRange(dMinimum, dMaximum);
}
else
{
m_pPressureChart->clearXAxisRange();
m_pFlowChart->clearXAxisRange();
}
}
void nmWellPressureFlowPage::updateSelectedFlowSegment()
{
if (m_nSelectedFlowSegment < 0 ||
m_nSelectedFlowSegment >= m_vecRawFlowPoints.size())
{
m_pPressureChart->clearHighlightedTimeRange();
m_pFlowChart->clearHighlightedTimeRange();
return;
}
// 流量点X值是持续时间段区间必须从第0段开始逐段累加。
double dStartTime = 0.0;
for (int nIndex = 0;
nIndex < m_nSelectedFlowSegment;
++nIndex)
{
dStartTime += m_vecRawFlowPoints[nIndex].x();
}
double dEndTime = dStartTime +
m_vecRawFlowPoints[m_nSelectedFlowSegment].x();
m_pPressureChart->setHighlightedTimeRange(
dStartTime, dEndTime);
m_pFlowChart->setHighlightedTimeRange(dStartTime, dEndTime);
}
void nmWellPressureFlowPage::applyFlowSegmentSelection(int nSegmentIndex)
{
if (nSegmentIndex < 0 ||
nSegmentIndex >= m_vecRawFlowPoints.size() ||
nSegmentIndex >= m_pFlowTable->rowCount())
{
nSegmentIndex = -1;
}
m_nSelectedFlowSegment = nSegmentIndex;
bool bSignalsWereBlocked = m_pFlowTable->blockSignals(true);
if (m_nSelectedFlowSegment >= 0)
{
m_pFlowTable->setCurrentCell(m_nSelectedFlowSegment, 0);
m_pFlowTable->selectRow(m_nSelectedFlowSegment);
QTableWidgetItem* pItem = m_pFlowTable->item(
m_nSelectedFlowSegment, 0);
if (pItem != nullptr)
{
m_pFlowTable->scrollToItem(
pItem, QAbstractItemView::EnsureVisible);
}
}
else
{
m_pFlowTable->setCurrentCell(-1, -1);
m_pFlowTable->clearSelection();
}
m_pFlowTable->blockSignals(bSignalsWereBlocked);
updateSelectedFlowSegment();
}
int nmWellPressureFlowPage::findFlowSegmentByTableTime(
double dTimePoint) const
{
double dTotalTime = 0.0;
for (int nIndex = 0;
nIndex < m_vecTableFlowPoints.size();
++nIndex)
{
dTotalTime += qMax(0.0, m_vecTableFlowPoints[nIndex].x());
}
const double dTolerance = qMax(1.0, qAbs(dTotalTime)) * 1e-9;
if (dTimePoint < 0.0 ||
dTimePoint > dTotalTime + dTolerance)
{
return -1;
}
// 零时长点不占区间;分界点继续查找后一有效段。
double dStartTime = 0.0;
int nLastValidSegment = -1;
for (int nIndex = 0;
nIndex < m_vecTableFlowPoints.size();
++nIndex)
{
double dDuration = m_vecTableFlowPoints[nIndex].x();
if (dDuration <= dTolerance)
{
continue;
}
nLastValidSegment = nIndex;
double dEndTime = dStartTime + dDuration;
if (dTimePoint < dEndTime - dTolerance)
{
return nIndex;
}
dStartTime = dEndTime;
}
// 最终结束点没有后一段,归入最后一个有效流量段。
if (nLastValidSegment >= 0 &&
qAbs(dTimePoint - dTotalTime) <= dTolerance)
{
return nLastValidSegment;
}
return -1;
}
void nmWellPressureFlowPage::resetDataViews()
{
m_vecRawPressurePoints.clear();
m_vecRawFlowPoints.clear();
m_vecTableFlowPoints.clear();
m_nSelectedFlowSegment = -1;
updateViews();
}