|
|
|
|
@ -64,10 +64,57 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#include <QMessageBox>
|
|
|
|
|
#include <QResizeEvent>
|
|
|
|
|
#include <QTimer>
|
|
|
|
|
#include <QWidget>
|
|
|
|
|
|
|
|
|
|
namespace {
|
|
|
|
|
|
|
|
|
|
void includeMapPoint(const QPointF& oPoint,
|
|
|
|
|
bool& bHasBounds,
|
|
|
|
|
double& dMinX,
|
|
|
|
|
double& dMaxX,
|
|
|
|
|
double& dMinY,
|
|
|
|
|
double& dMaxY)
|
|
|
|
|
{
|
|
|
|
|
if(!qIsFinite(oPoint.x()) || !qIsFinite(oPoint.y())) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(!bHasBounds) {
|
|
|
|
|
dMinX = dMaxX = oPoint.x();
|
|
|
|
|
dMinY = dMaxY = oPoint.y();
|
|
|
|
|
bHasBounds = true;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
dMinX = qMin(dMinX, oPoint.x());
|
|
|
|
|
dMaxX = qMax(dMaxX, oPoint.x());
|
|
|
|
|
dMinY = qMin(dMinY, oPoint.y());
|
|
|
|
|
dMaxY = qMax(dMaxY, oPoint.y());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void includeMapPoints(const QVector<QPointF>& vecPoints,
|
|
|
|
|
bool& bHasBounds,
|
|
|
|
|
double& dMinX,
|
|
|
|
|
double& dMaxX,
|
|
|
|
|
double& dMinY,
|
|
|
|
|
double& dMaxY)
|
|
|
|
|
{
|
|
|
|
|
foreach(const QPointF& oPoint, vecPoints) {
|
|
|
|
|
includeMapPoint(oPoint, bHasBounds,
|
|
|
|
|
dMinX, dMaxX, dMinY, dMaxY);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
nmGuiPlot::nmGuiPlot(bool bUseBtns, QWidget *parent) :
|
|
|
|
|
iGuiPlot(bUseBtns, parent)
|
|
|
|
|
iGuiPlot(bUseBtns, parent),
|
|
|
|
|
m_pGraphicBinder(NULL),
|
|
|
|
|
m_pDataManager(nmDataAnalyzeManager::getCurrentInstance()),
|
|
|
|
|
m_bApplyingAxisRange(false),
|
|
|
|
|
m_bAxisInitializationPending(false)
|
|
|
|
|
{
|
|
|
|
|
m_bUseBtns = bUseBtns;
|
|
|
|
|
|
|
|
|
|
@ -86,8 +133,7 @@ nmGuiPlot::nmGuiPlot(bool bUseBtns, QWidget *parent) :
|
|
|
|
|
|
|
|
|
|
m_iRegionMarkCount = 0;
|
|
|
|
|
|
|
|
|
|
m_pGraphicBinder = new nmPlotGraphicBinder(
|
|
|
|
|
nmDataAnalyzeManager::getCurrentInstance(), this);
|
|
|
|
|
m_pGraphicBinder = new nmPlotGraphicBinder(m_pDataManager, this);
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@ -131,7 +177,6 @@ void nmGuiPlot::initChartView(QString sTitle, QSize szDefault)
|
|
|
|
|
m_pPlot = m_pPlotScene->m_pPlot;
|
|
|
|
|
m_pPlotView->setMargins(0, 0, 0, 0);
|
|
|
|
|
m_pPlotView->setZoomMode(ZxRenderView::eZoomFitWindow, true);
|
|
|
|
|
|
|
|
|
|
connectSignals();
|
|
|
|
|
|
|
|
|
|
initDefultGeoObj();
|
|
|
|
|
@ -179,68 +224,21 @@ void nmGuiPlot::cancelActiveTools()
|
|
|
|
|
|
|
|
|
|
void nmGuiPlot::initDefultGeoObj()
|
|
|
|
|
{
|
|
|
|
|
// 获取边界数据,来自数据中心
|
|
|
|
|
nmDataOutline* pOutlineData = nmDataAnalyzeManager::getCurrentInstance()->getOutlineData();
|
|
|
|
|
nmDataAnalyzeManager* pDataManager = dataManager();
|
|
|
|
|
if(pDataManager == nullptr) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
nmDataAxis* pAxisData = nmDataAnalyzeManager::getCurrentInstance()->getAxisData();
|
|
|
|
|
nmDataAxis* pAxisData = pDataManager->getAxisData();
|
|
|
|
|
|
|
|
|
|
if(pAxisData == nullptr) {
|
|
|
|
|
pAxisData = new nmDataAxis;
|
|
|
|
|
// 将 pAxisData 存入数据中心
|
|
|
|
|
nmDataAnalyzeManager::getCurrentInstance()->setAxisData(pAxisData);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 获取 X 最大值
|
|
|
|
|
nmDataAttribute xMaxAttr = pAxisData->getXMax();
|
|
|
|
|
double xMaxValue = xMaxAttr.getValue().toDouble();
|
|
|
|
|
m_pPlot->getMainAxisX()->setRangeMax(xMaxValue);
|
|
|
|
|
|
|
|
|
|
// 获取 Y 最大值
|
|
|
|
|
nmDataAttribute yMaxAttr = pAxisData->getYMax();
|
|
|
|
|
double yMaxValue = yMaxAttr.getValue().toDouble();
|
|
|
|
|
m_pPlot->getMainAxisY()->setRangeMax(yMaxValue);
|
|
|
|
|
|
|
|
|
|
// 获取 X 最小值
|
|
|
|
|
nmDataAttribute xMinAttr = pAxisData->getXMin();
|
|
|
|
|
double xMinValue = xMinAttr.getValue().toDouble();
|
|
|
|
|
m_pPlot->getMainAxisX()->setRangeMin(xMinValue);
|
|
|
|
|
|
|
|
|
|
// 获取 Y 最小值
|
|
|
|
|
nmDataAttribute yMinAttr = pAxisData->getYMin();
|
|
|
|
|
double yMinValue = yMinAttr.getValue().toDouble();
|
|
|
|
|
m_pPlot->getMainAxisY()->setRangeMin(yMinValue);
|
|
|
|
|
|
|
|
|
|
connect(m_pPlot->getMainAxisX(), SIGNAL(sigRangeChanged(double, double, bool, bool)),
|
|
|
|
|
this, SLOT(onRangeXChanged(double, double, bool, bool)));
|
|
|
|
|
|
|
|
|
|
connect(m_pPlot->getMainAxisY(), SIGNAL(sigRangeChanged(double, double, bool, bool)),
|
|
|
|
|
this, SLOT(onRangeYChanged(double, double, bool, bool)));
|
|
|
|
|
|
|
|
|
|
// 数据中心无边界数据,创建默认边界数据
|
|
|
|
|
if(pOutlineData == nullptr) {
|
|
|
|
|
pOutlineData = nmDataAnalyzeManager::getCurrentInstance()->createOutline();
|
|
|
|
|
|
|
|
|
|
// 设置默认边界名称
|
|
|
|
|
pOutlineData->setName("");
|
|
|
|
|
|
|
|
|
|
// 设置边界点
|
|
|
|
|
QVector<QPointF> vecPoints;
|
|
|
|
|
vecPoints << QPointF(-1000.00, 1000.00)
|
|
|
|
|
<< QPointF(1000.00, 1000.00)
|
|
|
|
|
<< QPointF(1000.00, -1000.00)
|
|
|
|
|
<< QPointF(-1000.00, -1000.00);
|
|
|
|
|
pOutlineData->setOutlinePoints(vecPoints);
|
|
|
|
|
|
|
|
|
|
// 设置边界类型
|
|
|
|
|
pOutlineData->setOutlineType(NM_Rect_Outline_Type);
|
|
|
|
|
|
|
|
|
|
// 设置流型列表(假设全部为0)
|
|
|
|
|
QVector<int> vecFlowTypes(vecPoints.size(), 0);
|
|
|
|
|
pOutlineData->setFlowTypeList(vecFlowTypes);
|
|
|
|
|
pDataManager->setAxisData(pAxisData);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 获取井数据,来自数据中心
|
|
|
|
|
QVector<nmDataWellBase*> vecWellDatas = nmDataAnalyzeManager::getCurrentInstance()->getWellDataList();
|
|
|
|
|
QVector<nmDataWellBase*> vecWellDatas = pDataManager->getWellDataList();
|
|
|
|
|
|
|
|
|
|
// 数据中心没有一口井数据,添加默认井数据
|
|
|
|
|
if(vecWellDatas.isEmpty()) {
|
|
|
|
|
@ -248,7 +246,7 @@ void nmGuiPlot::initDefultGeoObj()
|
|
|
|
|
ZxDataWell* pWellData = zxCurWell;
|
|
|
|
|
|
|
|
|
|
if(pWellData == nullptr) {
|
|
|
|
|
this->setPlotsByDataManger(nmDataAnalyzeManager::getCurrentInstance());
|
|
|
|
|
this->setPlotsByDataManger(pDataManager);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@ -258,8 +256,7 @@ void nmGuiPlot::initDefultGeoObj()
|
|
|
|
|
static_cast<NM_WELL_CATEGORY>(
|
|
|
|
|
pWellData->getWellTypeIndex());
|
|
|
|
|
if(!nmIsValidWellCategory(eWellCategory)) {
|
|
|
|
|
this->setPlotsByDataManger(
|
|
|
|
|
nmDataAnalyzeManager::getCurrentInstance());
|
|
|
|
|
this->setPlotsByDataManger(pDataManager);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@ -327,11 +324,11 @@ void nmGuiPlot::initDefultGeoObj()
|
|
|
|
|
|
|
|
|
|
if(ZxBaseUtil::isSameStr(wellClass, "VerticalWell")) {
|
|
|
|
|
// 初始化直井默认参数
|
|
|
|
|
nmDataWellBase* pWell = nmDataAnalyzeManager::getCurrentInstance()->createWell(NM_WELL_MODEL::Vertical_Well);
|
|
|
|
|
nmDataWellBase* pWell = pDataManager->createWell(NM_WELL_MODEL::Vertical_Well);
|
|
|
|
|
nmDataVerticalWell* m_VerticalWell = dynamic_cast<nmDataVerticalWell*>(pWell);
|
|
|
|
|
|
|
|
|
|
if(m_VerticalWell == nullptr) {
|
|
|
|
|
this->setPlotsByDataManger(nmDataAnalyzeManager::getCurrentInstance());
|
|
|
|
|
this->setPlotsByDataManger(pDataManager);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@ -353,7 +350,7 @@ void nmGuiPlot::initDefultGeoObj()
|
|
|
|
|
m_VerticalWell->setFlowPoints(vecPtsF);
|
|
|
|
|
|
|
|
|
|
// TODO: 计算井的历史双对数/半对数数据
|
|
|
|
|
nmDataAnalyzeManager::getCurrentInstance()->calculationLogData(m_VerticalWell, vvecHistoryPressureData, vvecHistoryLogData, vvecHistorySemiLogData);
|
|
|
|
|
pDataManager->calculationLogData(m_VerticalWell, vvecHistoryPressureData, vvecHistoryLogData, vvecHistorySemiLogData);
|
|
|
|
|
|
|
|
|
|
// 存储历史数据到井对象
|
|
|
|
|
m_VerticalWell->setHistoryPressure(vvecHistoryPressureData);
|
|
|
|
|
@ -361,15 +358,15 @@ void nmGuiPlot::initDefultGeoObj()
|
|
|
|
|
m_VerticalWell->setHistorySemiLog(vvecHistorySemiLogData);
|
|
|
|
|
|
|
|
|
|
// 设置为当前查看的井
|
|
|
|
|
nmDataAnalyzeManager::getCurrentInstance()->setCurWellData(m_VerticalWell);
|
|
|
|
|
pDataManager->setCurWellData(m_VerticalWell);
|
|
|
|
|
} else if(ZxBaseUtil::isSameStr(wellClass, "VerticalFracturedWell")) {
|
|
|
|
|
|
|
|
|
|
// 初始化垂直裂缝井默认参数
|
|
|
|
|
nmDataWellBase* pWell = nmDataAnalyzeManager::getCurrentInstance()->createWell(NM_WELL_MODEL::Vertical_Fractured_Well);
|
|
|
|
|
nmDataWellBase* pWell = pDataManager->createWell(NM_WELL_MODEL::Vertical_Fractured_Well);
|
|
|
|
|
nmDataVerticalFracturedWell* m_VFracturedWell = dynamic_cast<nmDataVerticalFracturedWell*>(pWell);
|
|
|
|
|
|
|
|
|
|
if(m_VFracturedWell == nullptr) {
|
|
|
|
|
this->setPlotsByDataManger(nmDataAnalyzeManager::getCurrentInstance());
|
|
|
|
|
this->setPlotsByDataManger(pDataManager);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@ -391,7 +388,7 @@ void nmGuiPlot::initDefultGeoObj()
|
|
|
|
|
m_VFracturedWell->setFlowPoints(vecPtsF);
|
|
|
|
|
|
|
|
|
|
// TODO: 计算井的历史双对数/半对数数据
|
|
|
|
|
nmDataAnalyzeManager::getCurrentInstance()->calculationLogData(m_VFracturedWell, vvecHistoryPressureData, vvecHistoryLogData, vvecHistorySemiLogData);
|
|
|
|
|
pDataManager->calculationLogData(m_VFracturedWell, vvecHistoryPressureData, vvecHistoryLogData, vvecHistorySemiLogData);
|
|
|
|
|
|
|
|
|
|
// 存储历史数据到井对象
|
|
|
|
|
m_VFracturedWell->setHistoryPressure(vvecHistoryPressureData);
|
|
|
|
|
@ -402,15 +399,15 @@ void nmGuiPlot::initDefultGeoObj()
|
|
|
|
|
m_VFracturedWell->setFracs();
|
|
|
|
|
|
|
|
|
|
// 设置为当前查看的井
|
|
|
|
|
nmDataAnalyzeManager::getCurrentInstance()->setCurWellData(m_VFracturedWell);
|
|
|
|
|
pDataManager->setCurWellData(m_VFracturedWell);
|
|
|
|
|
} else if(ZxBaseUtil::isSameStr(wellClass, "HorizontalMultiFracturedWell")) {
|
|
|
|
|
|
|
|
|
|
// 初始化多段压裂水平井默认参数
|
|
|
|
|
nmDataWellBase* pWell = nmDataAnalyzeManager::getCurrentInstance()->createWell(NM_WELL_MODEL::Horizontal_Fractured_Well);
|
|
|
|
|
nmDataWellBase* pWell = pDataManager->createWell(NM_WELL_MODEL::Horizontal_Fractured_Well);
|
|
|
|
|
nmDataHorizontalFracturedWell* m_HFracturedWell = dynamic_cast<nmDataHorizontalFracturedWell*>(pWell);
|
|
|
|
|
|
|
|
|
|
if(m_HFracturedWell == nullptr) {
|
|
|
|
|
this->setPlotsByDataManger(nmDataAnalyzeManager::getCurrentInstance());
|
|
|
|
|
this->setPlotsByDataManger(pDataManager);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@ -432,7 +429,7 @@ void nmGuiPlot::initDefultGeoObj()
|
|
|
|
|
m_HFracturedWell->setFlowPoints(vecPtsF);
|
|
|
|
|
|
|
|
|
|
// TODO: 计算井的历史双对数/半对数数据
|
|
|
|
|
nmDataAnalyzeManager::getCurrentInstance()->calculationLogData(m_HFracturedWell, vvecHistoryPressureData, vvecHistoryLogData, vvecHistorySemiLogData);
|
|
|
|
|
pDataManager->calculationLogData(m_HFracturedWell, vvecHistoryPressureData, vvecHistoryLogData, vvecHistorySemiLogData);
|
|
|
|
|
|
|
|
|
|
// 存储历史数据到井对象
|
|
|
|
|
m_HFracturedWell->setHistoryPressure(vvecHistoryPressureData);
|
|
|
|
|
@ -443,17 +440,21 @@ void nmGuiPlot::initDefultGeoObj()
|
|
|
|
|
m_HFracturedWell->setFracs();
|
|
|
|
|
|
|
|
|
|
// 设置为当前查看的井
|
|
|
|
|
nmDataAnalyzeManager::getCurrentInstance()->setCurWellData(m_HFracturedWell);
|
|
|
|
|
pDataManager->setCurWellData(m_HFracturedWell);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 重新获取添加后的井数据
|
|
|
|
|
nmDataAnalyzeManager::getCurrentInstance()->appendNmWellData(
|
|
|
|
|
nmDataAnalyzeManager::getCurrentInstance()->getCurWellData());
|
|
|
|
|
vecWellDatas = nmDataAnalyzeManager::getCurrentInstance()->getWellDataList();
|
|
|
|
|
pDataManager->appendNmWellData(pDataManager->getCurWellData());
|
|
|
|
|
vecWellDatas = pDataManager->getWellDataList();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 极端兼容入口没有预先建立边界时,也按当前井位置创建一次性默认边界。
|
|
|
|
|
if(pDataManager->getOutlineData() == nullptr) {
|
|
|
|
|
pDataManager->createDefaultOutlineFromWells();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 根据数据中心的数据渲染所有的图元,上面只是为了保证打开时有一口井和边界
|
|
|
|
|
this->setPlotsByDataManger(nmDataAnalyzeManager::getCurrentInstance());
|
|
|
|
|
this->setPlotsByDataManger(pDataManager);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void nmGuiPlot::initAxisFromData(nmDataAnalyzeManager* pDataManager)
|
|
|
|
|
@ -461,33 +462,39 @@ void nmGuiPlot::initAxisFromData(nmDataAnalyzeManager* pDataManager)
|
|
|
|
|
Q_ASSERT(nullptr != pDataManager);
|
|
|
|
|
// 0.坐标轴
|
|
|
|
|
// 0.1 获取坐标轴数据,来自数据中心
|
|
|
|
|
nmDataAxis* pAxisData = nmDataAnalyzeManager::getCurrentInstance()->getAxisData();
|
|
|
|
|
nmDataAxis* pAxisData = pDataManager->getAxisData();
|
|
|
|
|
Q_ASSERT(nullptr != pAxisData);
|
|
|
|
|
|
|
|
|
|
// 0.2 获取 X 最大值
|
|
|
|
|
nmDataAttribute xMaxAttr = pAxisData->getXMax();
|
|
|
|
|
double xMaxValue = xMaxAttr.getValue().toDouble();
|
|
|
|
|
m_pPlot->getMainAxisX()->setRangeMax(xMaxValue);
|
|
|
|
|
|
|
|
|
|
// 0.3 获取 Y 最大值
|
|
|
|
|
nmDataAttribute yMaxAttr = pAxisData->getYMax();
|
|
|
|
|
double yMaxValue = yMaxAttr.getValue().toDouble();
|
|
|
|
|
m_pPlot->getMainAxisY()->setRangeMax(yMaxValue);
|
|
|
|
|
|
|
|
|
|
// 0.4 获取 X 最小值
|
|
|
|
|
nmDataAttribute xMinAttr = pAxisData->getXMin();
|
|
|
|
|
double xMinValue = xMinAttr.getValue().toDouble();
|
|
|
|
|
m_pPlot->getMainAxisX()->setRangeMin(xMinValue);
|
|
|
|
|
|
|
|
|
|
// 0.5 获取 Y 最小值
|
|
|
|
|
nmDataAttribute yMinAttr = pAxisData->getYMin();
|
|
|
|
|
double yMinValue = yMinAttr.getValue().toDouble();
|
|
|
|
|
m_pPlot->getMainAxisY()->setRangeMin(yMinValue);
|
|
|
|
|
|
|
|
|
|
if(qIsFinite(xMinValue) && qIsFinite(xMaxValue) &&
|
|
|
|
|
qIsFinite(yMinValue) && qIsFinite(yMaxValue) &&
|
|
|
|
|
xMaxValue > xMinValue && yMaxValue > yMinValue) {
|
|
|
|
|
applyAxisRange(xMinValue, xMaxValue, yMinValue, yMaxValue);
|
|
|
|
|
} else {
|
|
|
|
|
pAxisData->setInitialViewFitted(false);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
connect(m_pPlot->getMainAxisX(), SIGNAL(sigRangeChanged(double, double, bool, bool)),
|
|
|
|
|
this, SLOT(onRangeXChanged(double, double, bool, bool)));
|
|
|
|
|
this, SLOT(onRangeXChanged(double, double, bool, bool)),
|
|
|
|
|
Qt::UniqueConnection);
|
|
|
|
|
connect(m_pPlot->getMainAxisY(), SIGNAL(sigRangeChanged(double, double, bool, bool)),
|
|
|
|
|
this, SLOT(onRangeYChanged(double, double, bool, bool)));
|
|
|
|
|
this, SLOT(onRangeYChanged(double, double, bool, bool)),
|
|
|
|
|
Qt::UniqueConnection);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void nmGuiPlot::initBoundaryObjFromData(nmDataAnalyzeManager* pDataManager)
|
|
|
|
|
@ -785,13 +792,17 @@ void nmGuiPlot::initRegionMarkObjsFromData(nmDataAnalyzeManager* pDataManager)
|
|
|
|
|
|
|
|
|
|
void nmGuiPlot::deleteAllPlotObjs()
|
|
|
|
|
{
|
|
|
|
|
QVector<nmObjBase*> vecObjs = this->getAllPlots();
|
|
|
|
|
if(m_pPlot == nullptr) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
foreach(nmObjBase* pObj, vecObjs) {
|
|
|
|
|
// 1、移除图元
|
|
|
|
|
m_pPlot->removeObjByName(pObj->getName());
|
|
|
|
|
// 2、清理数据
|
|
|
|
|
//pObj->removeData();
|
|
|
|
|
// 这里只清理显示对象,不能调用removeData()删除DataManager中的业务数据。
|
|
|
|
|
// 先解除全部绑定,再倒序删除图元,避免重名对象残留或Binder保存悬空指针。
|
|
|
|
|
if(m_pGraphicBinder != nullptr) {
|
|
|
|
|
m_pGraphicBinder->updateDataMgr(dataManager());
|
|
|
|
|
}
|
|
|
|
|
for(int nIndex = m_pPlot->getObjCount() - 1; nIndex >= 0; --nIndex) {
|
|
|
|
|
m_pPlot->removeObjByIndex(nIndex);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@ -1493,9 +1504,222 @@ void nmGuiPlot::deleteAllDFNPlots()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
nmDataAnalyzeManager* nmGuiPlot::dataManager() const
|
|
|
|
|
{
|
|
|
|
|
return m_pDataManager != nullptr
|
|
|
|
|
? m_pDataManager
|
|
|
|
|
: nmDataAnalyzeManager::getCurrentInstance();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool nmGuiPlot::calculateVisibleContentBounds(QRectF& oBounds) const
|
|
|
|
|
{
|
|
|
|
|
nmDataAnalyzeManager* pDataManager = dataManager();
|
|
|
|
|
if(pDataManager == nullptr) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool bHasBounds = false;
|
|
|
|
|
double dMinX = 0.0;
|
|
|
|
|
double dMaxX = 0.0;
|
|
|
|
|
double dMinY = 0.0;
|
|
|
|
|
double dMaxY = 0.0;
|
|
|
|
|
|
|
|
|
|
nmDataOutline* pOutlineData = pDataManager->getOutlineData();
|
|
|
|
|
if(pOutlineData != nullptr && pOutlineData->getPlotVisible()) {
|
|
|
|
|
if(pOutlineData->getOutlineType() == NM_Round_Outline_Type) {
|
|
|
|
|
const QPointF oCenter = pOutlineData->getCenter();
|
|
|
|
|
const double dRadius = qAbs(pOutlineData->getRadius());
|
|
|
|
|
includeMapPoint(QPointF(oCenter.x() - dRadius,
|
|
|
|
|
oCenter.y() - dRadius),
|
|
|
|
|
bHasBounds, dMinX, dMaxX, dMinY, dMaxY);
|
|
|
|
|
includeMapPoint(QPointF(oCenter.x() + dRadius,
|
|
|
|
|
oCenter.y() + dRadius),
|
|
|
|
|
bHasBounds, dMinX, dMaxX, dMinY, dMaxY);
|
|
|
|
|
} else {
|
|
|
|
|
includeMapPoints(pOutlineData->getOutlinePoints(),
|
|
|
|
|
bHasBounds, dMinX, dMaxX, dMinY, dMaxY);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const QVector<nmDataWellBase*> vecWells = pDataManager->getWellDataList();
|
|
|
|
|
foreach(nmDataWellBase* pWellData, vecWells) {
|
|
|
|
|
if(pWellData != nullptr && pWellData->getPlotVisible()) {
|
|
|
|
|
includeMapPoint(QPointF(
|
|
|
|
|
pWellData->getX().getValue().toDouble(),
|
|
|
|
|
pWellData->getY().getValue().toDouble()),
|
|
|
|
|
bHasBounds, dMinX, dMaxX, dMinY, dMaxY);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const QVector<nmDataFault*> vecFaults = pDataManager->getFaultDataList();
|
|
|
|
|
foreach(nmDataFault* pFaultData, vecFaults) {
|
|
|
|
|
if(pFaultData != nullptr && pFaultData->getPlotVisible()) {
|
|
|
|
|
includeMapPoints(pFaultData->getFaultPoints(),
|
|
|
|
|
bHasBounds, dMinX, dMaxX, dMinY, dMaxY);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const QVector<nmDataFracture*> vecFractures =
|
|
|
|
|
pDataManager->getFractureDataList();
|
|
|
|
|
foreach(nmDataFracture* pFractureData, vecFractures) {
|
|
|
|
|
if(pFractureData != nullptr && pFractureData->getPlotVisible()) {
|
|
|
|
|
includeMapPoints(pFractureData->getFracturePoints(),
|
|
|
|
|
bHasBounds, dMinX, dMaxX, dMinY, dMaxY);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const QVector<nmDataRegion*> vecRegions = pDataManager->getRegionDataList();
|
|
|
|
|
foreach(nmDataRegion* pRegionData, vecRegions) {
|
|
|
|
|
if(pRegionData != nullptr && pRegionData->getPlotVisible()) {
|
|
|
|
|
includeMapPoints(pRegionData->getVecPts(),
|
|
|
|
|
bHasBounds, dMinX, dMaxX, dMinY, dMaxY);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const QVector<nmDataRegionMark*> vecRegionMarks =
|
|
|
|
|
pDataManager->getRegionMarkDataList();
|
|
|
|
|
foreach(nmDataRegionMark* pRegionMarkData, vecRegionMarks) {
|
|
|
|
|
if(pRegionMarkData != nullptr && pRegionMarkData->getPlotVisible()) {
|
|
|
|
|
includeMapPoint(pRegionMarkData->getPtPos(),
|
|
|
|
|
bHasBounds, dMinX, dMaxX, dMinY, dMaxY);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(!bHasBounds) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
oBounds = QRectF(QPointF(dMinX, dMinY),
|
|
|
|
|
QPointF(dMaxX, dMaxY)).normalized();
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void nmGuiPlot::applyAxisRange(double dXMin, double dXMax,
|
|
|
|
|
double dYMin, double dYMax)
|
|
|
|
|
{
|
|
|
|
|
if(m_pPlot == nullptr ||
|
|
|
|
|
!qIsFinite(dXMin) || !qIsFinite(dXMax) ||
|
|
|
|
|
!qIsFinite(dYMin) || !qIsFinite(dYMax) ||
|
|
|
|
|
dXMax <= dXMin || dYMax <= dYMin) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const bool bOldApplying = m_bApplyingAxisRange;
|
|
|
|
|
m_bApplyingAxisRange = true;
|
|
|
|
|
m_pPlot->getMainAxisX()->setRangeMinMax(dXMin, dXMax, true, false);
|
|
|
|
|
m_pPlot->getMainAxisY()->setRangeMinMax(dYMin, dYMax, true, false);
|
|
|
|
|
|
|
|
|
|
nmDataAnalyzeManager* pDataManager = dataManager();
|
|
|
|
|
nmDataAxis* pAxisData = pDataManager != nullptr
|
|
|
|
|
? pDataManager->getAxisData() : nullptr;
|
|
|
|
|
if(pAxisData != nullptr) {
|
|
|
|
|
pAxisData->getXMin().setValue(dXMin);
|
|
|
|
|
pAxisData->getXMax().setValue(dXMax);
|
|
|
|
|
pAxisData->getYMin().setValue(dYMin);
|
|
|
|
|
pAxisData->getYMax().setValue(dYMax);
|
|
|
|
|
}
|
|
|
|
|
m_bApplyingAxisRange = bOldApplying;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool nmGuiPlot::fitInitialAxisToContent()
|
|
|
|
|
{
|
|
|
|
|
if(m_pPlot == nullptr) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QRectF oBounds;
|
|
|
|
|
if(!calculateVisibleContentBounds(oBounds)) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QRectF oPlotRect = m_pPlot->getInnerRectF();
|
|
|
|
|
if(oPlotRect.width() <= 0.0 || oPlotRect.height() <= 0.0) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
double dCenterX = (oBounds.left() + oBounds.right()) * 0.5;
|
|
|
|
|
double dCenterY = (oBounds.top() + oBounds.bottom()) * 0.5;
|
|
|
|
|
double dRangeX = oBounds.width();
|
|
|
|
|
double dRangeY = oBounds.height();
|
|
|
|
|
|
|
|
|
|
// 退化为点或直线时补足基础跨度,避免产生零范围坐标轴。
|
|
|
|
|
if(dRangeX <= 0.0) {
|
|
|
|
|
dRangeX = 1500.0;
|
|
|
|
|
}
|
|
|
|
|
if(dRangeY <= 0.0) {
|
|
|
|
|
dRangeY = 1500.0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 内容四周各增加最大边长的 5%,边界本身不因此发生变化。
|
|
|
|
|
const double dPadding = qMax(dRangeX, dRangeY) * 0.05;
|
|
|
|
|
dRangeX += dPadding * 2.0;
|
|
|
|
|
dRangeY += dPadding * 2.0;
|
|
|
|
|
|
|
|
|
|
const double dViewRatio = oPlotRect.width() / oPlotRect.height();
|
|
|
|
|
const double dContentRatio = dRangeX / dRangeY;
|
|
|
|
|
if(dContentRatio < dViewRatio) {
|
|
|
|
|
dRangeX = dRangeY * dViewRatio;
|
|
|
|
|
} else {
|
|
|
|
|
dRangeY = dRangeX / dViewRatio;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
applyAxisRange(dCenterX - dRangeX * 0.5,
|
|
|
|
|
dCenterX + dRangeX * 0.5,
|
|
|
|
|
dCenterY - dRangeY * 0.5,
|
|
|
|
|
dCenterY + dRangeY * 0.5);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void nmGuiPlot::scheduleInitialAxisView()
|
|
|
|
|
{
|
|
|
|
|
if(m_bAxisInitializationPending) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
m_bAxisInitializationPending = true;
|
|
|
|
|
QTimer::singleShot(0, this, SLOT(initializeAxisView()));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void nmGuiPlot::initializeAxisView()
|
|
|
|
|
{
|
|
|
|
|
m_bAxisInitializationPending = false;
|
|
|
|
|
nmDataAnalyzeManager* pDataManager = dataManager();
|
|
|
|
|
nmDataAxis* pAxisData = pDataManager != nullptr
|
|
|
|
|
? pDataManager->getAxisData() : nullptr;
|
|
|
|
|
if(pAxisData == nullptr || pAxisData->isInitialViewFitted()) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 只有真实绘图区和图元均准备好后才封闭初始化,失败时等待下一次显示尺寸变化。
|
|
|
|
|
if(fitInitialAxisToContent()) {
|
|
|
|
|
pAxisData->setInitialViewFitted(true);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void nmGuiPlot::resizeEvent(QResizeEvent* pEvent)
|
|
|
|
|
{
|
|
|
|
|
nmDataAnalyzeManager* pDataManager = dataManager();
|
|
|
|
|
nmDataAxis* pAxisData = pDataManager != nullptr
|
|
|
|
|
? pDataManager->getAxisData() : nullptr;
|
|
|
|
|
const bool bWaitingForInitialView =
|
|
|
|
|
pAxisData != nullptr && !pAxisData->isInitialViewFitted();
|
|
|
|
|
const bool bOldApplying = m_bApplyingAxisRange;
|
|
|
|
|
if(bWaitingForInitialView) {
|
|
|
|
|
// 布局阶段可能触发轴信号,不能把它误认为用户已经设置了范围。
|
|
|
|
|
m_bApplyingAxisRange = true;
|
|
|
|
|
}
|
|
|
|
|
iGuiPlot::resizeEvent(pEvent);
|
|
|
|
|
m_bApplyingAxisRange = bOldApplying;
|
|
|
|
|
if(bWaitingForInitialView) {
|
|
|
|
|
scheduleInitialAxisView();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void nmGuiPlot::onRangeXChanged(double dMin, double dMax, bool bRecalTicks, bool bAdjustRectZoomRatio)
|
|
|
|
|
{
|
|
|
|
|
nmDataAxis* pAxisData = nmDataAnalyzeManager::getCurrentInstance()->getAxisData();
|
|
|
|
|
nmDataAnalyzeManager* pDataManager = dataManager();
|
|
|
|
|
nmDataAxis* pAxisData = pDataManager != nullptr
|
|
|
|
|
? pDataManager->getAxisData() : nullptr;
|
|
|
|
|
|
|
|
|
|
if(pAxisData == nullptr) {
|
|
|
|
|
return;
|
|
|
|
|
@ -1506,11 +1730,18 @@ void nmGuiPlot::onRangeXChanged(double dMin, double dMax, bool bRecalTicks, bool
|
|
|
|
|
|
|
|
|
|
// 获取 X 最小值
|
|
|
|
|
pAxisData->getXMin().setValue(dMin);
|
|
|
|
|
|
|
|
|
|
if(!m_bApplyingAxisRange) {
|
|
|
|
|
// 任一用户轴操作都终止首次初始化,后续范围完全由用户控制。
|
|
|
|
|
pAxisData->setInitialViewFitted(true);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void nmGuiPlot::onRangeYChanged(double dMin, double dMax, bool bRecalTicks, bool bAdjustRectZoomRatio)
|
|
|
|
|
{
|
|
|
|
|
nmDataAxis* pAxisData = nmDataAnalyzeManager::getCurrentInstance()->getAxisData();
|
|
|
|
|
nmDataAnalyzeManager* pDataManager = dataManager();
|
|
|
|
|
nmDataAxis* pAxisData = pDataManager != nullptr
|
|
|
|
|
? pDataManager->getAxisData() : nullptr;
|
|
|
|
|
|
|
|
|
|
if(pAxisData == nullptr) {
|
|
|
|
|
return;
|
|
|
|
|
@ -1521,6 +1752,10 @@ void nmGuiPlot::onRangeYChanged(double dMin, double dMax, bool bRecalTicks, bool
|
|
|
|
|
|
|
|
|
|
// 获取 Y 最小值
|
|
|
|
|
pAxisData->getYMin().setValue(dMin);
|
|
|
|
|
|
|
|
|
|
if(!m_bApplyingAxisRange) {
|
|
|
|
|
pAxisData->setInitialViewFitted(true);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ============================== 可见性设置方法实现 ==============================
|
|
|
|
|
@ -1762,6 +1997,25 @@ void nmGuiPlot::finishMeasure()
|
|
|
|
|
|
|
|
|
|
bool nmGuiPlot::setPlotsByDataManger(nmDataAnalyzeManager* pDataManager)
|
|
|
|
|
{
|
|
|
|
|
if(pDataManager == nullptr || m_pPlot == nullptr) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 本函数按DataManager完整重建Map,重复调用也只能保留一套图元。
|
|
|
|
|
// 清理过程不删除业务数据,因此同一分析刷新和跨分析切换可使用同一路径。
|
|
|
|
|
deleteAllPlotObjs();
|
|
|
|
|
if(m_pGraphicBinder != nullptr) {
|
|
|
|
|
m_pGraphicBinder->updateDataMgr(pDataManager);
|
|
|
|
|
}
|
|
|
|
|
m_pDataManager = pDataManager;
|
|
|
|
|
nmDataAxis* pAxisData = pDataManager->getAxisData();
|
|
|
|
|
const bool bWaitingForInitialView =
|
|
|
|
|
pAxisData != nullptr && !pAxisData->isInitialViewFitted();
|
|
|
|
|
const bool bOldApplying = m_bApplyingAxisRange;
|
|
|
|
|
if(bWaitingForInitialView) {
|
|
|
|
|
// 图元创建过程可能发出轴范围信号,首次适配完成前统一按内部更新处理。
|
|
|
|
|
m_bApplyingAxisRange = true;
|
|
|
|
|
}
|
|
|
|
|
// 0.坐标轴
|
|
|
|
|
this->initAxisFromData(pDataManager);
|
|
|
|
|
// 1.边界
|
|
|
|
|
@ -1776,6 +2030,12 @@ bool nmGuiPlot::setPlotsByDataManger(nmDataAnalyzeManager* pDataManager)
|
|
|
|
|
this->initRegionObjsFromData(pDataManager);
|
|
|
|
|
// 6.区域标记
|
|
|
|
|
this->initRegionMarkObjsFromData(pDataManager);
|
|
|
|
|
m_bApplyingAxisRange = bOldApplying;
|
|
|
|
|
|
|
|
|
|
if(pAxisData != nullptr && !pAxisData->isInitialViewFitted()) {
|
|
|
|
|
// 等本轮布局和坐标轴内边距稳定后只初始化一次。
|
|
|
|
|
scheduleInitialAxisView();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|