diff --git a/ApplicationCode/ProjectDataModel/Rim3dOverlayInfoConfig.cpp b/ApplicationCode/ProjectDataModel/Rim3dOverlayInfoConfig.cpp index a60b8e5f2e..b7e32797b7 100644 --- a/ApplicationCode/ProjectDataModel/Rim3dOverlayInfoConfig.cpp +++ b/ApplicationCode/ProjectDataModel/Rim3dOverlayInfoConfig.cpp @@ -632,9 +632,14 @@ QString Rim3dOverlayInfoConfig::resultInfoText(const HistogramData& histData, Ri if (isResultsInfoRelevant) { QString propName = eclipseView->cellResult()->resultVariableUiShortName(); + QString diffResString = eclipseView->cellResult()->diffResultUiName(); if (!contourMap->contourMapProjection()->isColumnResult()) { - infoText += QString("Cell Property: %1 ").arg(propName); + infoText += QString("Cell Property: %1
").arg(propName); + } + if (!diffResString.isEmpty()) + { + infoText += QString("%1
").arg(diffResString); } infoText += QString("
Statistics: Current Time Step and Visible Cells"); infoText += QString("" @@ -656,13 +661,18 @@ QString Rim3dOverlayInfoConfig::resultInfoText(const HistogramData& histData, Ri if (isResultsInfoRelevant) { QString propName = eclipseView->cellResult()->resultVariableUiShortName(); + QString diffResString = eclipseView->cellResult()->diffResultUiName(); QString timeRangeText = m_statisticsTimeRange().uiText(); if (eclipseView->cellResult()->isFlowDiagOrInjectionFlooding()) { timeRangeText = caf::AppEnum::uiText(CURRENT_TIMESTEP); } - infoText += QString("Cell Property: %1 ").arg(propName); + infoText += QString("Cell Property: %1
").arg(propName); + if (!diffResString.isEmpty()) + { + infoText += QString("%1
").arg(diffResString); + } infoText += QString("
Statistics: ") + timeRangeText + " and " + m_statisticsCellRange().uiText(); infoText += QString("
" "" @@ -734,9 +744,9 @@ QString Rim3dOverlayInfoConfig::resultInfoText(const HistogramData& histData, Ri if (isResultsInfoRelevant) { QString resultPos; - QString fieldName = geoMechView->cellResultResultDefinition()->resultFieldUiName(); - QString compName = geoMechView->cellResultResultDefinition()->resultComponentUiName(); - + QString fieldName = geoMechView->cellResultResultDefinition()->resultFieldUiName(); + QString compName = geoMechView->cellResultResultDefinition()->resultComponentUiName(); + QString diffResString = geoMechView->cellResultResultDefinition()->diffResultUiName(); switch (geoMechView->cellResultResultDefinition()->resultPositionType()) { case RIG_NODAL: @@ -759,13 +769,17 @@ QString Rim3dOverlayInfoConfig::resultInfoText(const HistogramData& histData, Ri } if (compName == "") { - infoText += QString("Cell result: %1, %2").arg(resultPos).arg(fieldName); + infoText += QString("Cell result: %1, %2
").arg(resultPos).arg(fieldName); } else { - infoText += QString("Cell result: %1, %2, %3").arg(resultPos).arg(fieldName).arg(compName); + infoText += QString("Cell result: %1, %2, %3
").arg(resultPos).arg(fieldName).arg(compName); + } + + if (!diffResString.isEmpty()) + { + infoText += QString("%1
").arg(diffResString); } - infoText += QString("
Statistics: ") + m_statisticsTimeRange().uiText() + " and " + m_statisticsCellRange().uiText(); infoText += QString("
Min P90 Mean P10 Max Sum
" "" diff --git a/ApplicationCode/ProjectDataModel/RimEclipseResultDefinition.cpp b/ApplicationCode/ProjectDataModel/RimEclipseResultDefinition.cpp index 9d8d50e2ae..7cff00c374 100644 --- a/ApplicationCode/ProjectDataModel/RimEclipseResultDefinition.cpp +++ b/ApplicationCode/ProjectDataModel/RimEclipseResultDefinition.cpp @@ -73,7 +73,7 @@ CAF_PDM_SOURCE_INIT(RimEclipseResultDefinition, "ResultDefinition"); /// //-------------------------------------------------------------------------------------------------- RimEclipseResultDefinition::RimEclipseResultDefinition() - : m_showUiForDerivedDifferenceResults(false) + : m_diffResultOptionsEnabled(false) { CAF_PDM_InitObject("Result Definition", "", "", ""); @@ -91,10 +91,8 @@ RimEclipseResultDefinition::RimEclipseResultDefinition() CAF_PDM_InitField( &m_timeLapseBaseTimestep, "TimeLapseBaseTimeStep", RigEclipseResultAddress::NO_TIME_LAPSE, "Base Time Step", "", "", ""); - m_timeLapseBaseTimestep.uiCapability()->setUiHidden(true); CAF_PDM_InitFieldNoDefault(&m_differenceCase, "DifferenceCase", "Difference Case", "", "", ""); - m_differenceCase.uiCapability()->setUiHidden(true); // One single tracer list has been split into injectors and producers. // The old list is defined as injectors and we'll have to move any producers in old projects. @@ -126,18 +124,6 @@ RimEclipseResultDefinition::RimEclipseResultDefinition() m_resultVariableUiField.xmlCapability()->disableIO(); m_resultVariableUiField.uiCapability()->setUiEditorTypeName(caf::PdmUiListEditor::uiEditorTypeName()); - CAF_PDM_InitField(&m_timeLapseBaseTimestepUiField, - "TimeLapseBaseTimeStepUI", - RigEclipseResultAddress::NO_TIME_LAPSE, - "Base Time Step", - "", - "", - ""); - m_timeLapseBaseTimestepUiField.xmlCapability()->disableIO(); - - CAF_PDM_InitFieldNoDefault(&m_differenceCaseUiField, "MDifferenceCase", "Difference Case", "", "", ""); - m_differenceCaseUiField.xmlCapability()->disableIO(); - CAF_PDM_InitFieldNoDefault(&m_flowSolutionUiField, "MFlowDiagSolution", "Solution", "", "", ""); m_flowSolutionUiField.xmlCapability()->disableIO(); m_flowSolutionUiField.uiCapability()->setUiHidden(true); // For now since there are only one to choose from @@ -252,8 +238,6 @@ void RimEclipseResultDefinition::fieldChangedByUi(const caf::PdmFieldHandle* cha m_porosityModel = m_porosityModelUiField; m_resultType = m_resultTypeUiField; m_resultVariable = m_resultVariableUiField; - m_timeLapseBaseTimestep = m_timeLapseBaseTimestepUiField; - m_differenceCase = m_differenceCaseUiField(); if (m_resultTypeUiField() == RiaDefines::FLOW_DIAGNOSTICS) { @@ -268,9 +252,10 @@ void RimEclipseResultDefinition::fieldChangedByUi(const caf::PdmFieldHandle* cha loadDataAndUpdate(); } - if (&m_timeLapseBaseTimestepUiField == changedField || &m_differenceCaseUiField == changedField) + if (&m_timeLapseBaseTimestep == changedField || + &m_differenceCase == changedField) { - m_resultVariableUiField = ""; + loadDataAndUpdate(); } if (&m_flowTracerSelectionMode == changedField) @@ -627,7 +612,7 @@ QList RimEclipseResultDefinition::calculateValueOptions( { options = calcOptionsForVariableUiFieldStandard(); } - else if (fieldNeedingOptions == &m_timeLapseBaseTimestepUiField) + else if (fieldNeedingOptions == &m_timeLapseBaseTimestep) { std::vector stepDates; const RigCaseCellResultsData* gridCellResults = this->currentGridCellResults(); @@ -641,12 +626,12 @@ QList RimEclipseResultDefinition::calculateValueOptions( for (size_t stepIdx = 0; stepIdx < stepDates.size(); ++stepIdx) { QString displayString = stepDates[stepIdx].toString(RimTools::dateFormatString()); - displayString += " (" + QString::number(stepIdx) + ")"; + displayString += QString(" (#%1)").arg(stepIdx); options.push_back(caf::PdmOptionItemInfo(displayString, static_cast(stepIdx))); } } - else if (fieldNeedingOptions == &m_differenceCaseUiField) + else if (fieldNeedingOptions == &m_differenceCase) { options.push_back(caf::PdmOptionItemInfo("None", nullptr)); @@ -665,7 +650,7 @@ QList RimEclipseResultDefinition::calculateValueOptions( if (otherCase->eclipseCaseData() && otherCase->eclipseCaseData()->mainGrid()) { options.push_back( - caf::PdmOptionItemInfo(otherCase->caseUserDescription(), otherCase, false, otherCase->uiIcon())); + caf::PdmOptionItemInfo(QString("%1 (#%2)").arg(otherCase->caseUserDescription()).arg(otherCase->caseId()), otherCase, false, otherCase->uiIcon())); } } } @@ -695,7 +680,7 @@ RigEclipseResultAddress RimEclipseResultDefinition::eclipseResultAddress() const timelapseTimeStep = m_timeLapseBaseTimestep(); } - if (isCaseDifferenceResult()) + if (isCaseDiffResult()) { diffCaseId = m_differenceCase->caseId(); } @@ -814,16 +799,6 @@ QString RimEclipseResultDefinition::resultVariableUiName() const return flowDiagResUiText(false, 32); } - if (isTimeDiffResult() && resultType() == RiaDefines::DYNAMIC_NATIVE) - { - return timeDiffResultName(m_resultVariable(), m_timeLapseBaseTimestep()); - } - - if (isCaseDifferenceResult()) - { - return caseDiffResultName(m_resultVariable(), m_differenceCase()->caseId()); - } - return m_resultVariable(); } @@ -837,19 +812,74 @@ QString RimEclipseResultDefinition::resultVariableUiShortName() const return flowDiagResUiText(true, 24); } - if (isTimeDiffResult() && resultType() == RiaDefines::DYNAMIC_NATIVE) - { - return timeDiffResultName(m_resultVariable(), m_timeLapseBaseTimestep()); - } - - if (isCaseDifferenceResult()) - { - return caseDiffResultName(m_resultVariable(), m_differenceCase()->caseId()); - } - return m_resultVariable(); } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RimEclipseResultDefinition::diffResultUiName() const +{ + QStringList diffResult; + if (isTimeDiffResult()) + { + std::vector stepDates; + const RigCaseCellResultsData* gridCellResults = this->currentGridCellResults(); + if (gridCellResults) + { + stepDates = gridCellResults->timeStepDates(); + diffResult += QString("Base Time Step: %1").arg(stepDates[m_timeLapseBaseTimestep()].toString(RimTools::dateFormatString())); + } + } + if (isCaseDiffResult()) + { + diffResult += QString("Base Case: %1").arg(m_differenceCase()->caseUserDescription()); + } + return diffResult.join("
\n"); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RimEclipseResultDefinition::diffResultUiShortName() const +{ + QStringList diffResult; + if (isTimeDiffResult() || isCaseDiffResult()) + { + diffResult += QString("Diff. Options:"); + } + if (isTimeDiffResult()) + { + diffResult += QString("Base Time: #%1").arg(m_timeLapseBaseTimestep()); + } + if (isCaseDiffResult()) + { + diffResult += QString("Base Case: #%1").arg(m_differenceCase()->caseId()); + } + return diffResult.join("\n"); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RimEclipseResultDefinition::diffResultUiShortNameHTML() const +{ + QStringList diffResult; + if (isTimeDiffResult() || isCaseDiffResult()) + { + diffResult += QString("Diff. Options:"); + } + if (isTimeDiffResult()) + { + diffResult += QString("Base Time: #%1").arg(m_timeLapseBaseTimestep()); + } + if (isCaseDiffResult()) + { + diffResult += QString("Base Case: #%1").arg(m_differenceCase()->caseId()); + } + return diffResult.join("\n
"); +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -878,7 +908,7 @@ void RimEclipseResultDefinition::loadResult() RigCaseCellResultsData* gridCellResults = this->currentGridCellResults(); if (gridCellResults) { - if (isTimeDiffResult() || isCaseDifferenceResult()) + if (isTimeDiffResult() || isCaseDiffResult()) { gridCellResults->createResultEntry(this->eclipseResultAddress(), false); } @@ -979,8 +1009,6 @@ void RimEclipseResultDefinition::initAfterRead() m_porosityModelUiField = m_porosityModel; m_resultTypeUiField = m_resultType; m_resultVariableUiField = m_resultVariable; - m_timeLapseBaseTimestepUiField = m_timeLapseBaseTimestep; - m_differenceCaseUiField = m_differenceCase(); m_flowSolutionUiField = m_flowSolution(); m_selectedInjectorTracersUiField = m_selectedInjectorTracers; @@ -1106,9 +1134,9 @@ void RimEclipseResultDefinition::updateUiFieldsFromActiveResult() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RimEclipseResultDefinition::enableUiForDerivedDifferenceResults() +void RimEclipseResultDefinition::setDiffResultOptionsEnabled(bool enabled) { - m_showUiForDerivedDifferenceResults = true; + m_diffResultOptionsEnabled = true; } //-------------------------------------------------------------------------------------------------- @@ -1217,25 +1245,30 @@ void RimEclipseResultDefinition::defineUiOrdering(QString uiConfigName, caf::Pdm uiOrdering.add(&m_resultVariableUiField); } - if (m_showUiForDerivedDifferenceResults) + if (enableDiffResultOptions()) { // NOTE // - // It is possible to use the case/time diff results in property filter, fault result, etc + // It is possible to enable the use of case/time diff results in property filter, fault result, etc // but to limit the number of UI items, the time/case diff is only available as part of "Cell Result" - if (m_resultTypeUiField() == RiaDefines::DYNAMIC_NATIVE || m_resultTypeUiField() == RiaDefines::STATIC_NATIVE || - m_resultTypeUiField() == RiaDefines::GENERATED) + caf::PdmUiGroup* differenceGroup = uiOrdering.addNewGroup("Difference Options"); + differenceGroup->setUiReadOnly(!(isTimeDiffResultAvailable() || isCaseDiffResultAvailable())); + + m_timeLapseBaseTimestep.uiCapability()->setUiReadOnly(!isTimeDiffResultAvailable()); + m_differenceCase.uiCapability()->setUiReadOnly(!isCaseDiffResultAvailable()); + + if (isTimeDiffResultAvailable()) + differenceGroup->add(&m_timeLapseBaseTimestep); + if (isCaseDiffResultAvailable()) + differenceGroup->add(&m_differenceCase); + + QString resultPropertyLabel = "Result Property"; + if (isTimeDiffResult() || isCaseDiffResult()) { - caf::PdmUiGroup* differenceGroup = uiOrdering.addNewGroup("Difference Options"); - - if (m_resultTypeUiField() == RiaDefines::DYNAMIC_NATIVE) - { - differenceGroup->add(&m_timeLapseBaseTimestepUiField); - } - - differenceGroup->add(&m_differenceCaseUiField); + resultPropertyLabel += QString("
\n
\n%1").arg(diffResultUiShortNameHTML()); } + m_resultVariableUiField.uiCapability()->setUiName(resultPropertyLabel); } uiOrdering.skipRemainingFields(true); @@ -1385,41 +1418,6 @@ QString RimEclipseResultDefinition::flowDiagResUiText(bool shortLabel, int maxTr return uiText; } -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -QString RimEclipseResultDefinition::timeDiffResultName(const QString& resultName, int timeStepIndex) -{ - return resultName + "_dt_" + QString::number(timeStepIndex); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -QString RimEclipseResultDefinition::caseDiffResultName(const QString& resultName, int caseId) -{ - return resultName + " (diff case - " + QString::number(caseId) + ")"; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -QString RimEclipseResultDefinition::convertToTimeOrCaseDiffUiVarName(const QString& resultName) -{ - if (m_timeLapseBaseTimestepUiField() >= 0 && - (m_resultTypeUiField() == RiaDefines::DYNAMIC_NATIVE || m_resultTypeUiField() == RiaDefines::GENERATED)) - { - return timeDiffResultName(resultName, m_timeLapseBaseTimestepUiField()); - } - - if (m_differenceCaseUiField()) - { - return caseDiffResultName(resultName, m_differenceCaseUiField()->caseId()); - } - - return resultName; -} - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -1440,7 +1438,6 @@ QList RimEclipseResultDefinition::calcOptionsForVariable { if (s == RiaDefines::completionTypeResultName()) { - if (m_timeLapseBaseTimestepUiField() >= 0) continue; if (results->timeStepDates().empty()) continue; } @@ -1460,7 +1457,7 @@ QList RimEclipseResultDefinition::calcOptionsForVariable // Cell Center result names foreach (QString s, cellCenterResultNames) { - optionList.push_back(caf::PdmOptionItemInfo(convertToTimeOrCaseDiffUiVarName(s), s)); + optionList.push_back(caf::PdmOptionItemInfo(s, s)); } // Ternary Result @@ -1472,8 +1469,7 @@ QList RimEclipseResultDefinition::calcOptionsForVariable else if (cellCenterResultNames.contains("SWAT")) hasAtLeastOneTernaryComponent = true; - if ((m_timeLapseBaseTimestepUiField() < 0) && m_resultTypeUiField == RiaDefines::DYNAMIC_NATIVE && - hasAtLeastOneTernaryComponent) + if (m_resultTypeUiField == RiaDefines::DYNAMIC_NATIVE && hasAtLeastOneTernaryComponent) { optionList.push_front( caf::PdmOptionItemInfo(RiaDefines::ternarySaturationResultName(), RiaDefines::ternarySaturationResultName())); @@ -1492,11 +1488,11 @@ QList RimEclipseResultDefinition::calcOptionsForVariable { if (showDerivedResultsFirstInList) { - optionList.push_front(caf::PdmOptionItemInfo(convertToTimeOrCaseDiffUiVarName(s), s)); + optionList.push_front(caf::PdmOptionItemInfo(s, s)); } else { - optionList.push_back(caf::PdmOptionItemInfo(convertToTimeOrCaseDiffUiVarName(s), s)); + optionList.push_back(caf::PdmOptionItemInfo(s, s)); } } @@ -1911,15 +1907,45 @@ void RimEclipseResultDefinition::syncProducerToInjectorSelection() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -bool RimEclipseResultDefinition::isTimeDiffResult() const +bool RimEclipseResultDefinition::enableDiffResultOptions() const { - return m_timeLapseBaseTimestep() >= 0; + return m_diffResultOptionsEnabled; + } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -bool RimEclipseResultDefinition::isCaseDifferenceResult() const +bool RimEclipseResultDefinition::isTimeDiffResultAvailable() const { - return m_differenceCase() != nullptr; + return enableDiffResultOptions() && + m_resultType() == RiaDefines::DYNAMIC_NATIVE && + !isTernarySaturationSelected(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimEclipseResultDefinition::isTimeDiffResult() const +{ + return isTimeDiffResultAvailable() && m_timeLapseBaseTimestep() >= 0; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimEclipseResultDefinition::isCaseDiffResultAvailable() const +{ + return enableDiffResultOptions() && !isTernarySaturationSelected() && + (m_resultType() == RiaDefines::DYNAMIC_NATIVE || + m_resultType() == RiaDefines::STATIC_NATIVE || + m_resultType() == RiaDefines::GENERATED); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimEclipseResultDefinition::isCaseDiffResult() const +{ + return isCaseDiffResultAvailable() && m_differenceCase() != nullptr; } diff --git a/ApplicationCode/ProjectDataModel/RimEclipseResultDefinition.h b/ApplicationCode/ProjectDataModel/RimEclipseResultDefinition.h index d4a6952f1d..f9a83fa715 100644 --- a/ApplicationCode/ProjectDataModel/RimEclipseResultDefinition.h +++ b/ApplicationCode/ProjectDataModel/RimEclipseResultDefinition.h @@ -93,6 +93,10 @@ public: QString resultVariableUiName() const; QString resultVariableUiShortName() const; + QString diffResultUiName() const; + QString diffResultUiShortName() const; + QString diffResultUiShortNameHTML() const; + void loadResult(); RigEclipseResultAddress eclipseResultAddress() const; bool hasStaticResult() const; @@ -116,7 +120,7 @@ public: void updateUiFieldsFromActiveResult(); - void enableUiForDerivedDifferenceResults(); + void setDiffResultOptionsEnabled(bool enabled); protected: virtual void updateLegendCategorySettings() {}; @@ -150,9 +154,6 @@ protected: caf::PdmField< caf::AppEnum< RiaDefines::ResultCatType > > m_resultTypeUiField; caf::PdmField< caf::AppEnum< RiaDefines::PorosityModelType > > m_porosityModelUiField; caf::PdmField m_resultVariableUiField; - caf::PdmField m_timeLapseBaseTimestepUiField; - - caf::PdmPtrField m_differenceCaseUiField; caf::PdmField< caf::AppEnum< FlowTracerSelectionType > > m_flowTracerSelectionMode; caf::PdmPtrField m_flowSolutionUiField; @@ -182,10 +183,6 @@ private: QString flowDiagResUiText(bool shortLabel, int maxTracerStringLength = std::numeric_limits::max()) const; - static QString timeDiffResultName(const QString& resultName, int timeStepIndex); - static QString caseDiffResultName(const QString& resultName, int caseId); - - QString convertToTimeOrCaseDiffUiVarName(const QString& resultName); QList calcOptionsForVariableUiFieldStandard(); QList calcOptionsForSelectedTracerField(bool injector); @@ -207,9 +204,13 @@ private: void syncInjectorToProducerSelection(); void syncProducerToInjectorSelection(); + bool enableDiffResultOptions() const; + bool isTimeDiffResultAvailable() const; bool isTimeDiffResult() const; - bool isCaseDifferenceResult() const; + bool isCaseDiffResultAvailable() const; + bool isCaseDiffResult() const; - bool m_showUiForDerivedDifferenceResults; +private: + bool m_diffResultOptionsEnabled; }; diff --git a/ApplicationCode/ProjectDataModel/RimEclipseView.cpp b/ApplicationCode/ProjectDataModel/RimEclipseView.cpp index 785454ad71..cd520daade 100644 --- a/ApplicationCode/ProjectDataModel/RimEclipseView.cpp +++ b/ApplicationCode/ProjectDataModel/RimEclipseView.cpp @@ -121,7 +121,7 @@ RimEclipseView::RimEclipseView() CAF_PDM_InitFieldNoDefault(&m_cellResult, "GridCellResult", "Cell Result", ":/CellResult.png", "", ""); m_cellResult = new RimEclipseCellColors(); m_cellResult.uiCapability()->setUiHidden(true); - m_cellResult->enableUiForDerivedDifferenceResults(); + m_cellResult->setDiffResultOptionsEnabled(true); CAF_PDM_InitFieldNoDefault(&m_cellEdgeResult, "GridCellEdgeResult", "Cell Edge Result", ":/EdgeResult_1.png", "", ""); m_cellEdgeResult = new RimCellEdgeColors(); @@ -1204,7 +1204,13 @@ void RimEclipseView::updateMinMaxValuesAndAddLegendToView(QString legendLabel, if (resultColors->hasResult() && resultColors->legendConfig()->showLegend()) { - resultColors->legendConfig()->setTitle(legendLabel + resultColors->resultVariableUiName()); + QString title = legendLabel + resultColors->resultVariableUiName(); + if (!resultColors->diffResultUiShortName().isEmpty()) + { + title += QString("\n%1").arg(resultColors->diffResultUiShortName()); + } + + resultColors->legendConfig()->setTitle(title); m_viewer->addColorLegendToBottomLeftCorner(resultColors->legendConfig()->titledOverlayFrame()); } diff --git a/ApplicationCode/ProjectDataModel/RimGeoMechPropertyFilter.cpp b/ApplicationCode/ProjectDataModel/RimGeoMechPropertyFilter.cpp index f15f5c1438..5b67a624c7 100644 --- a/ApplicationCode/ProjectDataModel/RimGeoMechPropertyFilter.cpp +++ b/ApplicationCode/ProjectDataModel/RimGeoMechPropertyFilter.cpp @@ -177,8 +177,7 @@ void RimGeoMechPropertyFilter::updateReadOnlyStateOfAllFields() // Include fields declared in RimResultDefinition objFields.push_back(&(resultDefinition->m_resultPositionTypeUiField)); objFields.push_back(&(resultDefinition->m_resultVariableUiField)); - objFields.push_back(&(resultDefinition->m_isTimeLapseResultUiField)); - objFields.push_back(&(resultDefinition->m_timeLapseBaseTimestepUiField)); + objFields.push_back(&(resultDefinition->m_timeLapseBaseTimestep)); for (size_t i = 0; i < objFields.size(); i++) { diff --git a/ApplicationCode/ProjectDataModel/RimGeoMechResultDefinition.cpp b/ApplicationCode/ProjectDataModel/RimGeoMechResultDefinition.cpp index a90c1d050b..2c315980ce 100644 --- a/ApplicationCode/ProjectDataModel/RimGeoMechResultDefinition.cpp +++ b/ApplicationCode/ProjectDataModel/RimGeoMechResultDefinition.cpp @@ -1,6 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2018- Equinor ASA +// Copyright (C) 2015-2018 Statoil ASA // Copyright (C) 2015- Ceetron Solutions AS // // ResInsight is free software: you can redistribute it and/or modify @@ -76,11 +77,7 @@ RimGeoMechResultDefinition::RimGeoMechResultDefinition(void) CAF_PDM_InitField(&m_resultComponentName, "ResultComponentName", QString(""), "Component", "", "", ""); m_resultComponentName.uiCapability()->setUiHidden(true); - CAF_PDM_InitField(&m_isTimeLapseResult, "IsTimeLapseResult", false, "TimeLapseResult", "", "", ""); - m_isTimeLapseResult.uiCapability()->setUiHidden(true); - - CAF_PDM_InitField(&m_timeLapseBaseTimestep, "TimeLapseBaseTimeStep", 0, "Base Time Step", "", "", ""); - m_timeLapseBaseTimestep.uiCapability()->setUiHidden(true); + CAF_PDM_InitField(&m_timeLapseBaseTimestep, "TimeLapseBaseTimeStep", (int) RigFemResultAddress::NO_TIME_LAPSE, "Base Time Step", "", "", ""); CAF_PDM_InitField(&m_compactionRefLayer, "CompactionRefLayer", 0, "Compaction Ref Layer", "", "", ""); m_compactionRefLayer.uiCapability()->setUiHidden(true); @@ -91,18 +88,17 @@ RimGeoMechResultDefinition::RimGeoMechResultDefinition(void) CAF_PDM_InitField(&m_resultVariableUiField, "ResultVariableUI", QString(""), "Value", "", "", ""); m_resultVariableUiField.xmlCapability()->disableIO(); - CAF_PDM_InitField(&m_isTimeLapseResultUiField, "IsTimeLapseResultUI", false, "Enable Relative Result", "", "Use the difference with respect to a specific time step as the result variable to plot", ""); - m_isTimeLapseResultUiField.xmlCapability()->disableIO(); - - CAF_PDM_InitField(&m_timeLapseBaseTimestepUiField, "TimeLapseBaseTimeStepUI", 0, "Base Time Step", "", "", ""); - m_timeLapseBaseTimestepUiField.xmlCapability()->disableIO(); - m_resultVariableUiField.uiCapability()->setUiEditorTypeName(caf::PdmUiListEditor::uiEditorTypeName()); m_resultVariableUiField.uiCapability()->setUiLabelPosition(caf::PdmUiItemInfo::TOP); CAF_PDM_InitField(&m_compactionRefLayerUiField, "CompactionRefLayerUi", (int)RigFemResultAddress::NO_COMPACTION, "Compaction Ref Layer", "", "The compaction is calculated with reference to this layer. Default layer is the topmost layer with POR", ""); m_compactionRefLayerUiField.xmlCapability()->disableIO(); + // OBSOLETE FIELDS + CAF_PDM_InitField(&m_isTimeLapseResult_OBSOLETE, "IsTimeLapseResult", true, "TimeLapseResult", "", "", ""); + m_isTimeLapseResult_OBSOLETE.xmlCapability()->setIOWritable(false); + m_isTimeLapseResult_OBSOLETE.uiCapability()->setUiHidden(true); + m_isChangedByField = false; m_addWellPathDerivedResults = false; } @@ -123,12 +119,17 @@ void RimGeoMechResultDefinition::defineUiOrdering(QString uiConfigName, caf::Pdm uiOrdering.add(&m_resultPositionTypeUiField); uiOrdering.add(&m_resultVariableUiField); + QString valueLabel = "Value"; + if (m_timeLapseBaseTimestep != RigFemResultAddress::NO_TIME_LAPSE) + { + valueLabel += QString(" (%1)").arg(diffResultUiName()); + } + m_resultVariableUiField.uiCapability()->setUiName(valueLabel); + if ( m_resultPositionTypeUiField() != RIG_FORMATION_NAMES ) { - caf::PdmUiGroup * timeLapseGr = uiOrdering.addNewGroup("Relative Result Options"); - timeLapseGr->add(&m_isTimeLapseResultUiField); - if ( m_isTimeLapseResultUiField() ) - timeLapseGr->add(&m_timeLapseBaseTimestepUiField); + caf::PdmUiGroup * timeLapseGr = uiOrdering.addNewGroup("Difference Options"); + timeLapseGr->add(&m_timeLapseBaseTimestep); } if (m_resultPositionTypeUiField() == RIG_NODAL) @@ -184,21 +185,15 @@ QList RimGeoMechResultDefinition::calculateValueOptions( QStringList uiVarNames; QStringList varNames; - bool isNeedingTimeLapseStrings = m_isTimeLapseResultUiField() && (m_resultPositionTypeUiField() != RIG_FORMATION_NAMES); - getUiAndResultVariableStringList(&uiVarNames, &varNames, fieldCompNames, isNeedingTimeLapseStrings, m_timeLapseBaseTimestepUiField); + getUiAndResultVariableStringList(&uiVarNames, &varNames, fieldCompNames); for (int oIdx = 0; oIdx < uiVarNames.size(); ++oIdx) { options.push_back(caf::PdmOptionItemInfo(uiVarNames[oIdx], varNames[oIdx])); } } - else if (&m_isTimeLapseResultUiField == fieldNeedingOptions) - { - //options.push_back(caf::PdmOptionItemInfo("Absolute", false)); - //options.push_back(caf::PdmOptionItemInfo("Time Lapse", true)); - } - else if (&m_timeLapseBaseTimestepUiField == fieldNeedingOptions) + else if (&m_timeLapseBaseTimestep == fieldNeedingOptions) { std::vector stepNames; if(m_geomCase->geoMechData()) @@ -206,9 +201,10 @@ QList RimGeoMechResultDefinition::calculateValueOptions( stepNames = m_geomCase->geoMechData()->femPartResults()->filteredStepNames(); } + options.push_back(caf::PdmOptionItemInfo(QString("Disabled"), (int)RigFemResultAddress::NO_TIME_LAPSE)); for (size_t stepIdx = 0; stepIdx < stepNames.size(); ++stepIdx) { - options.push_back(caf::PdmOptionItemInfo(QString::fromStdString(stepNames[stepIdx]), static_cast(stepIdx))); + options.push_back(caf::PdmOptionItemInfo(QString("%1 (#%2)").arg(QString::fromStdString(stepNames[stepIdx])).arg(stepIdx), static_cast(stepIdx))); } } else if (&m_compactionRefLayerUiField == fieldNeedingOptions) @@ -246,45 +242,27 @@ void RimGeoMechResultDefinition::fieldChangedByUi(const caf::PdmFieldHandle* cha if (&m_resultPositionTypeUiField == changedField) { - if (m_resultPositionTypeUiField() == RIG_WELLPATH_DERIVED) + if (m_resultPositionTypeUiField() == RIG_WELLPATH_DERIVED || m_resultPositionType() == RIG_FORMATION_NAMES) { - m_isTimeLapseResultUiField = false; - m_isTimeLapseResultUiField.uiCapability()->setUiReadOnly(true); - m_timeLapseBaseTimestepUiField.uiCapability()->setUiReadOnly(true); + m_timeLapseBaseTimestep = RigFemResultAddress::NO_TIME_LAPSE; + m_timeLapseBaseTimestep.uiCapability()->setUiReadOnly(true); } else - { - m_isTimeLapseResultUiField.uiCapability()->setUiReadOnly(false); - m_timeLapseBaseTimestepUiField.uiCapability()->setUiReadOnly(false); - } - } - - if (&m_isTimeLapseResultUiField == changedField) - { - m_isTimeLapseResult = m_isTimeLapseResultUiField; - if (m_isTimeLapseResult()) - { - if (m_timeLapseBaseTimestep() == RigFemResultAddress::NO_TIME_LAPSE) - { - m_timeLapseBaseTimestep = 0; - m_timeLapseBaseTimestepUiField = 0; - } + { + m_timeLapseBaseTimestep.uiCapability()->setUiReadOnly(false); } } if( &m_resultPositionTypeUiField == changedField - || &m_isTimeLapseResultUiField == changedField - || &m_timeLapseBaseTimestepUiField == changedField) + || &m_timeLapseBaseTimestep == changedField) { std::map > fieldCompNames = getResultMetaDataForUIFieldSetting(); QStringList uiVarNames; QStringList varNames; - bool isNeedingTimeLapseStrings = m_isTimeLapseResultUiField() && (m_resultPositionTypeUiField() != RIG_FORMATION_NAMES); - getUiAndResultVariableStringList(&uiVarNames, &varNames, fieldCompNames, isNeedingTimeLapseStrings, m_timeLapseBaseTimestepUiField); + + getUiAndResultVariableStringList(&uiVarNames, &varNames, fieldCompNames); if (m_resultPositionTypeUiField() == m_resultPositionType() - && m_isTimeLapseResultUiField() == m_isTimeLapseResult() - && m_timeLapseBaseTimestepUiField() == m_timeLapseBaseTimestep() && varNames.contains(composeFieldCompString(m_resultFieldName(), m_resultComponentName()))) { m_resultVariableUiField = composeFieldCompString(m_resultFieldName(), m_resultComponentName()); @@ -305,7 +283,7 @@ void RimGeoMechResultDefinition::fieldChangedByUi(const caf::PdmFieldHandle* cha this->firstAncestorOrThisOfType(rim3dWellLogCurve); - if (&m_resultVariableUiField == changedField || &m_compactionRefLayerUiField == changedField) + if (&m_resultVariableUiField == changedField || &m_compactionRefLayerUiField == changedField || &m_timeLapseBaseTimestep == changedField) { QStringList fieldComponentNames = m_resultVariableUiField().split(QRegExp("\\s+")); if (fieldComponentNames.size() > 0) @@ -316,8 +294,6 @@ void RimGeoMechResultDefinition::fieldChangedByUi(const caf::PdmFieldHandle* cha // Complete string of selected formation is stored in m_resultFieldName m_resultFieldName = m_resultVariableUiField(); m_resultComponentName = ""; - m_isTimeLapseResult = false; - m_timeLapseBaseTimestep = 0; } else { @@ -331,8 +307,6 @@ void RimGeoMechResultDefinition::fieldChangedByUi(const caf::PdmFieldHandle* cha m_resultComponentName = ""; } - m_isTimeLapseResult = m_isTimeLapseResultUiField(); - m_timeLapseBaseTimestep = m_timeLapseBaseTimestepUiField(); m_compactionRefLayer = m_compactionRefLayerUiField(); } @@ -416,9 +390,7 @@ std::map > RimGeoMechResultDefinition::get //-------------------------------------------------------------------------------------------------- void RimGeoMechResultDefinition::getUiAndResultVariableStringList(QStringList* uiNames, QStringList* variableNames, - const std::map >& fieldCompNames, - bool isTimeLapseResultList, - int baseFrameIdx) + const std::map >& fieldCompNames) { CVF_ASSERT(uiNames && variableNames); @@ -429,7 +401,7 @@ void RimGeoMechResultDefinition::getUiAndResultVariableStringList(QStringList* u if (resultFieldName == "E" || resultFieldName == "S" || resultFieldName == "POR") continue; // We will not show the native POR, Stress and Strain - QString resultFieldUiName = convertToUiResultFieldName(resultFieldName, isTimeLapseResultList, baseFrameIdx); + QString resultFieldUiName = convertToUiResultFieldName(resultFieldName); uiNames->push_back(resultFieldUiName); variableNames->push_back(resultFieldName); @@ -438,7 +410,7 @@ void RimGeoMechResultDefinition::getUiAndResultVariableStringList(QStringList* u for (compIt = fieldIt->second.begin(); compIt != fieldIt->second.end(); ++compIt) { QString resultCompName = QString::fromStdString(*compIt); - uiNames->push_back(" " + convertToUIComponentName(resultCompName, isTimeLapseResultList, baseFrameIdx)); + uiNames->push_back(resultCompName); variableNames->push_back(composeFieldCompString(resultFieldName, resultCompName)); } } @@ -461,13 +433,17 @@ QString RimGeoMechResultDefinition::composeFieldCompString(const QString& result //-------------------------------------------------------------------------------------------------- void RimGeoMechResultDefinition::initAfterRead() { + if (!m_isTimeLapseResult_OBSOLETE()) + { + m_timeLapseBaseTimestep = RigFemResultAddress::NO_TIME_LAPSE; + } + m_resultPositionTypeUiField = m_resultPositionType; - m_resultVariableUiField = composeFieldCompString(m_resultFieldName(), m_resultComponentName()); - m_isTimeLapseResultUiField = m_isTimeLapseResult; - m_timeLapseBaseTimestepUiField = m_timeLapseBaseTimestep; - m_isTimeLapseResultUiField.uiCapability()->setUiReadOnly(resultPositionType() == RIG_WELLPATH_DERIVED); - m_timeLapseBaseTimestepUiField.uiCapability()->setUiReadOnly(resultPositionType() == RIG_WELLPATH_DERIVED); + m_resultVariableUiField = composeFieldCompString(m_resultFieldName(), m_resultComponentName()); m_compactionRefLayerUiField = m_compactionRefLayer; + + m_timeLapseBaseTimestep.uiCapability()->setUiReadOnly(resultPositionType() == RIG_WELLPATH_DERIVED); + } @@ -509,7 +485,7 @@ RigFemResultAddress RimGeoMechResultDefinition::resultAddress() const return RigFemResultAddress(resultPositionType(), resultFieldName().toStdString(), resultComponentName().toStdString(), - m_isTimeLapseResult() ? m_timeLapseBaseTimestep() : RigFemResultAddress::NO_TIME_LAPSE, + m_timeLapseBaseTimestep(), resultFieldName().toStdString() == RigFemPartResultsCollection::FIELD_NAME_COMPACTION ? m_compactionRefLayer() : RigFemResultAddress::NO_COMPACTION); } @@ -545,6 +521,40 @@ QString RimGeoMechResultDefinition::resultComponentName() const return m_resultComponentName(); } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RimGeoMechResultDefinition::diffResultUiName() const +{ + QString diffResultString; + if (m_timeLapseBaseTimestep != RigFemResultAddress::NO_TIME_LAPSE) + { + if (m_geomCase->geoMechData()) + { + std::vector stepNames = m_geomCase->geoMechData()->femPartResults()->filteredStepNames(); + QString timeStepString = QString::fromStdString(stepNames[m_timeLapseBaseTimestep()]); + diffResultString += QString("Base Time Step: %1").arg(timeStepString); + } + } + return diffResultString; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RimGeoMechResultDefinition::diffResultUiShortName() const +{ + QString diffResultString; + if (m_timeLapseBaseTimestep != RigFemResultAddress::NO_TIME_LAPSE) + { + if (m_geomCase->geoMechData()) + { + diffResultString += QString("Base Time: #%1").arg(m_timeLapseBaseTimestep()); + } + } + return diffResultString; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -576,7 +586,7 @@ bool RimGeoMechResultDefinition::hasResult() //-------------------------------------------------------------------------------------------------- QString RimGeoMechResultDefinition::resultFieldUiName() { - return convertToUiResultFieldName(m_resultFieldName(), m_isTimeLapseResult, m_timeLapseBaseTimestep); + return convertToUiResultFieldName(m_resultFieldName()); } //-------------------------------------------------------------------------------------------------- @@ -584,15 +594,13 @@ QString RimGeoMechResultDefinition::resultFieldUiName() //-------------------------------------------------------------------------------------------------- QString RimGeoMechResultDefinition::resultComponentUiName() { - return convertToUIComponentName(m_resultComponentName(), m_isTimeLapseResult, m_timeLapseBaseTimestep); + return m_resultComponentName(); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -QString RimGeoMechResultDefinition::convertToUiResultFieldName(QString resultFieldName, - bool isTimeLapseResultList, - int baseFrameIdx) +QString RimGeoMechResultDefinition::convertToUiResultFieldName(QString resultFieldName) { QString newName (resultFieldName); @@ -603,23 +611,9 @@ QString RimGeoMechResultDefinition::convertToUiResultFieldName(QString resultFie if (resultFieldName == "MODULUS") newName = "Young's Modulus"; if (resultFieldName == "RATIO") newName = "Poisson's Ratio"; - if (isTimeLapseResultList) newName += "_D" + QString::number(baseFrameIdx); - return newName; } -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -QString RimGeoMechResultDefinition::convertToUIComponentName(QString resultComponentName, - bool isTimeLapseResultList, - int baseFrameIdx) -{ - if(isTimeLapseResultList) resultComponentName += "_D" + QString::number(baseFrameIdx); - - return resultComponentName; -} - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -628,18 +622,10 @@ void RimGeoMechResultDefinition::setResultAddress( const RigFemResultAddress& re m_resultPositionType = resultAddress.resultPosType; m_resultFieldName = QString::fromStdString(resultAddress.fieldName); m_resultComponentName = QString::fromStdString(resultAddress.componentName); + m_timeLapseBaseTimestep = resultAddress.timeLapseBaseFrameIdx; + m_compactionRefLayer = resultAddress.refKLayerIndex; + m_resultPositionTypeUiField = m_resultPositionType; - m_resultVariableUiField = composeFieldCompString(m_resultFieldName(), m_resultComponentName()); - - m_isTimeLapseResult = resultAddress.isTimeLapse(); - m_isTimeLapseResultUiField = m_isTimeLapseResult; - - if (m_isTimeLapseResult) - { - m_timeLapseBaseTimestep = resultAddress.timeLapseBaseFrameIdx; - } - m_timeLapseBaseTimestepUiField = m_timeLapseBaseTimestep; - - m_compactionRefLayer = resultAddress.refKLayerIndex; + m_resultVariableUiField = composeFieldCompString(m_resultFieldName(), m_resultComponentName()); m_compactionRefLayerUiField = m_compactionRefLayer; } diff --git a/ApplicationCode/ProjectDataModel/RimGeoMechResultDefinition.h b/ApplicationCode/ProjectDataModel/RimGeoMechResultDefinition.h index ad4f4004bc..419c50329f 100644 --- a/ApplicationCode/ProjectDataModel/RimGeoMechResultDefinition.h +++ b/ApplicationCode/ProjectDataModel/RimGeoMechResultDefinition.h @@ -1,6 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2018- Equinor ASA +// Copyright (C) 2015-2018 Statoil ASA // Copyright (C) 2015- Ceetron Solutions AS // // ResInsight is free software: you can redistribute it and/or modify @@ -43,28 +44,30 @@ public: RimGeoMechResultDefinition(void); ~RimGeoMechResultDefinition(void) override; - void setGeoMechCase(RimGeoMechCase* geomCase); + void setGeoMechCase(RimGeoMechCase* geomCase); - RigGeoMechCaseData* ownerCaseData(); - bool hasResult(); - void loadResult(); - void setAddWellPathDerivedResults(bool addWellPathDerivedResults); + RigGeoMechCaseData* ownerCaseData(); + bool hasResult(); + void loadResult(); + void setAddWellPathDerivedResults(bool addWellPathDerivedResults); - RigFemResultAddress resultAddress() const; + RigFemResultAddress resultAddress() const; std::vector observedResults() const override; - RigFemResultPosEnum resultPositionType() const; - QString resultFieldName() const; - QString resultComponentName() const; - void setResultAddress(const RigFemResultAddress& resultAddress); + RigFemResultPosEnum resultPositionType() const; + QString resultFieldName() const; + QString resultComponentName() const; + QString diffResultUiName() const; + QString diffResultUiShortName() const; + void setResultAddress(const RigFemResultAddress& resultAddress); - QString resultFieldUiName(); - QString resultComponentUiName(); + QString resultFieldUiName(); + QString resultComponentUiName(); - bool hasCategoryResult() { return m_resultPositionType() == RIG_FORMATION_NAMES; } + bool hasCategoryResult() { return m_resultPositionType() == RIG_FORMATION_NAMES; } protected: - virtual void updateLegendCategorySettings() {}; + virtual void updateLegendCategorySettings() {}; void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; private: @@ -83,41 +86,33 @@ private: std::map > getResultMetaDataForUIFieldSetting(); static void getUiAndResultVariableStringList(QStringList* uiNames, QStringList* variableNames, - const std::map >& fieldCompNames, - bool isTimeLapseResultList, - int baseFrameIdx); + const std::map >& fieldCompNames); static QString composeFieldCompString(const QString& resultFieldName, const QString& resultComponentName); - static QString convertToUiResultFieldName(QString resultFieldName, - bool isTimeLapseResultList, - int baseFrameIdx); - static QString convertToUIComponentName(QString resultComponentName, - bool isTimeLapseResultList, - int baseFrameIdx); + static QString convertToUiResultFieldName(QString resultFieldName); // Data Fields caf::PdmField > m_resultPositionType; caf::PdmField m_resultFieldName; caf::PdmField m_resultComponentName; - caf::PdmField m_isTimeLapseResult; caf::PdmField m_timeLapseBaseTimestep; caf::PdmField m_compactionRefLayer; // UI Fields only - friend class RimGeoMechPropertyFilter; // Property filter needs the ui fields friend class RimWellLogExtractionCurve; // Curve needs the ui fields friend class RimGeoMechCellColors; // Needs the ui fields caf::PdmField > m_resultPositionTypeUiField; caf::PdmField m_resultVariableUiField; - caf::PdmField m_isTimeLapseResultUiField; - caf::PdmField m_timeLapseBaseTimestepUiField; caf::PdmField m_compactionRefLayerUiField; caf::PdmPointer m_geomCase; + // Obsolete Data Fields + caf::PdmField m_isTimeLapseResult_OBSOLETE; + bool m_isChangedByField; bool m_addWellPathDerivedResults; }; diff --git a/ApplicationCode/ProjectDataModel/RimGeoMechView.cpp b/ApplicationCode/ProjectDataModel/RimGeoMechView.cpp index 23601e4463..abccbc2345 100644 --- a/ApplicationCode/ProjectDataModel/RimGeoMechView.cpp +++ b/ApplicationCode/ProjectDataModel/RimGeoMechView.cpp @@ -554,6 +554,11 @@ void RimGeoMechView::updateLegendTextAndRanges(RimRegularLegendConfig* legendCon legendTitle += " [GPa]"; } + if (!cellResult->diffResultUiShortName().isEmpty()) + { + legendTitle += QString("\nTime Diff:\n%1").arg(cellResult->diffResultUiShortName()); + } + legendConfig->setTitle(legendTitle); }
Min P90 Mean P10 Max Sum