Remove QT_CHARTS dependency.

This commit is contained in:
Kristian Bendiksen
2025-07-30 13:39:02 +02:00
parent fa3f43456e
commit ade8e1d7e6
25 changed files with 3 additions and 3154 deletions
@@ -232,9 +232,6 @@ RiaPreferences::RiaPreferences()
CAF_PDM_InitField( &m_writeEchoInGrdeclFiles, "writeEchoInGrdeclFiles", false, "Write NOECHO and ECHO in GRDECL files" );
caf::PdmUiNativeCheckBoxEditor::configureFieldForEditor( &m_writeEchoInGrdeclFiles );
CAF_PDM_InitField( &m_useQtChartsPlotByDefault, "useQtChartsPlotByDefault", false, "Use QtChart as Default Plot Type" );
caf::PdmUiNativeCheckBoxEditor::configureFieldForEditor( &m_useQtChartsPlotByDefault );
CAF_PDM_InitFieldNoDefault( &m_gridCalculationExpressionFolder, "gridCalculationExpressionFolder", "Grid Calculation Expression Folder" );
CAF_PDM_InitFieldNoDefault( &m_summaryCalculationExpressionFolder,
"summaryCalculationExpressionFolder",
@@ -461,9 +458,6 @@ void RiaPreferences::defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering&
pageSetup->add( &m_pageTopMargin );
pageSetup->appendToRow( &m_pageBottomMargin );
generalGrp->add( &m_useQtChartsPlotByDefault );
m_useQtChartsPlotByDefault.uiCapability()->setUiHidden( true );
QString unitLabel = " [mm]";
if ( QPageSize( m_pageSize() ).definitionUnits() == QPageSize::Inch )
{
@@ -836,14 +830,6 @@ bool RiaPreferences::openExportedPdfInViewer() const
return m_openExportedPdfInViewer;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RiaPreferences::useQtChartsAsDefaultPlotType() const
{
return m_useQtChartsPlotByDefault;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@@ -86,7 +86,6 @@ public:
QString lastUsedPlotTemplateAbsolutePath() const;
void setLastUsedPlotTemplatePath( const QString& templatePath );
bool openExportedPdfInViewer() const;
bool useQtChartsAsDefaultPlotType() const;
bool writeEchoInGrdeclFiles() const;
RiaDefines::ThemeEnum guiTheme() const;
@@ -198,7 +197,6 @@ private:
caf::PdmField<QString> m_plotTemplateFolders;
caf::PdmField<int> m_maxPlotTemplateFoldersDepth;
caf::PdmField<caf::FilePath> m_lastUsedPlotTemplate;
caf::PdmField<bool> m_useQtChartsPlotByDefault;
caf::PdmField<caf::FilePath> m_gridCalculationExpressionFolder;
caf::PdmField<caf::FilePath> m_summaryCalculationExpressionFolder;
@@ -22,15 +22,6 @@
#include "cafPdmUiFilePathEditor.h"
#include "cafPdmUiTextEditor.h"
template <>
void caf::AppEnum<RiaRegressionTest::PlotEngine>::setUp()
{
addItem( RiaRegressionTest::PlotEngine::USE_QWT, "USE_QWT", "Use Qwt" );
addItem( RiaRegressionTest::PlotEngine::USER_QTCHARTS, "USER_QTCHARTS", "Use QtCharts" );
addItem( RiaRegressionTest::PlotEngine::NONE, "NONE", "None" );
setDefault( RiaRegressionTest::PlotEngine::NONE );
}
CAF_PDM_SOURCE_INIT( RiaRegressionTest, "RiaRegressionTest" );
//--------------------------------------------------------------------------------------------------
@@ -84,8 +75,6 @@ RiaRegressionTest::RiaRegressionTest()
CAF_PDM_InitField( &invalidateExternalFilePaths, "invalidateExternalFilePaths", false, "Invalidate External File Paths" );
CAF_PDM_InitField( &activateObjectsInPropertyEditor, "activateObjectsInPropertyEditor", false, "Activate Objects In Property Editor" );
CAF_PDM_InitFieldNoDefault( &overridePlotEngine, "forcePlotEngine", "Force Plot Engine" );
CAF_PDM_InitField( &exportSnapshots3dViews, "exportSnapshots3dViews", true, "Export Snapshots 3D Views" );
CAF_PDM_InitField( &exportSnapshotsPlots, "exportSnapshotsPlots", true, "Export Snapshots Plots" );
}
@@ -26,14 +26,6 @@ class RiaRegressionTest : public caf::PdmObject
{
CAF_PDM_HEADER_INIT;
public:
enum class PlotEngine
{
USE_QWT,
USER_QTCHARTS,
NONE
};
public:
RiaRegressionTest();
~RiaRegressionTest() override;
@@ -57,8 +49,6 @@ public:
caf::PdmField<bool> exportSnapshots3dViews;
caf::PdmField<bool> exportSnapshotsPlots;
caf::PdmField<caf::AppEnum<PlotEngine>> overridePlotEngine;
protected:
void defineEditorAttribute( const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute ) override;
};
@@ -772,14 +772,6 @@ bool RiaRegressionTestRunner::useOpenMPForGeometryCreation() const
return m_regressionTestSettings.useOpenMPForGeometryCreation;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiaRegressionTest::PlotEngine RiaRegressionTestRunner::overridePlotEngine() const
{
return m_regressionTestSettings.overridePlotEngine();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@@ -43,8 +43,6 @@ public:
bool isRunningRegressionTests() const;
bool useOpenMPForGeometryCreation() const;
RiaRegressionTest::PlotEngine overridePlotEngine() const;
static void updateRegressionTest( const QString& testRootPath );
static void setDefaultSnapshotSizeFor3dViews();
-2
View File
@@ -32,7 +32,6 @@ find_package(
PrintSupport
Svg
Sql
OPTIONAL_COMPONENTS Charts
)
set(QT_LIBRARIES
Qt6::Core
@@ -46,7 +45,6 @@ set(QT_LIBRARIES
Qt6::PrintSupport
Qt6::Svg
Qt6::Sql
Qt6::Charts
)
qt_standard_project_setup()
@@ -68,10 +68,6 @@
#include "RiuQwtPlotWidget.h"
#include "RiuSummaryQwtPlot.h"
#ifdef USE_QTCHARTS
#include "RiuSummaryQtChartsPlot.h"
#endif
#include "cvfColor3.h"
#include "cafPdmFieldScriptingCapability.h"
@@ -130,11 +126,7 @@ RimSummaryPlot::RimSummaryPlot()
CAF_PDM_InitScriptableField( &m_useAutoPlotTitle, "IsUsingAutoName", true, "Auto Title" );
CAF_PDM_InitScriptableField( &m_description, "PlotDescription", QString( "Summary Plot" ), "Name" );
CAF_PDM_InitScriptableField( &m_normalizeCurveYValues, "normalizeCurveYValues", false, "Normalize all curves" );
#ifdef USE_QTCHARTS
bool useQtChart = RiaPreferences::current()->useQtChartsAsDefaultPlotType();
CAF_PDM_InitScriptableField( &m_useQtChartsPlot, "useQtChartsPlot", useQtChart, "Use Qt Charts" );
m_useQtChartsPlot.uiCapability()->setUiHidden( true );
#endif
CAF_PDM_InitFieldNoDefault( &m_summaryCurveCollection, "SummaryCurveCollection", "" );
m_summaryCurveCollection = new RimSummaryCurveCollection;
m_summaryCurveCollection->curvesChanged.connect( this, &RimSummaryPlot::onCurveCollectionChanged );
@@ -1602,29 +1594,6 @@ void RimSummaryPlot::fieldChangedByUi( const caf::PdmFieldHandle* changedField,
if ( changedField == &m_showPlotLegends ) updateLegend();
#ifdef USE_QTCHARTS
if ( changedField == &m_useQtChartsPlot )
{
// Hide window
setShowWindow( false );
// Detach and destroy plot curves
for ( auto c : summaryCurves() )
{
c->detach( true );
}
for ( auto& curveSet : ensembleCurveSetCollection()->curveSets() )
{
curveSet->deletePlotCurves();
}
// Destroy viewer
removeMdiWindowFromMdiArea();
deletePlotCurvesAndPlotWidget();
}
#endif
if ( changedField == &m_normalizeCurveYValues )
{
loadDataAndUpdate();
@@ -2604,9 +2573,6 @@ void RimSummaryPlot::defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering&
}
caf::PdmUiGroup* mainOptions = uiOrdering.addNewGroup( "General Plot Options" );
#ifdef USE_QTCHARTS
mainOptions->add( &m_useQtChartsPlot );
#endif
if ( isMdiWindow() )
{
mainOptions->add( &m_showPlotTitle );
@@ -2640,34 +2606,7 @@ RiuPlotWidget* RimSummaryPlot::doCreatePlotViewWidget( QWidget* mainWindowParent
{
if ( !plotWidget() )
{
#ifdef USE_QTCHARTS
bool useQtCharts = m_useQtChartsPlot;
auto regTestRunner = RiaRegressionTestRunner::instance();
if ( regTestRunner->isRunningRegressionTests() )
{
if ( regTestRunner->overridePlotEngine() == RiaRegressionTest::PlotEngine::USE_QWT )
useQtCharts = false;
else if ( regTestRunner->overridePlotEngine() == RiaRegressionTest::PlotEngine::USER_QTCHARTS )
useQtCharts = true;
}
// Disable all use of QtCharts for now. If a plot was created using QtCharts during the period this flag was
// active, the use of QtCharts was stored in the project file or template file. Set flag to false to force use
// of Qwt
useQtCharts = false;
if ( useQtCharts )
{
m_summaryPlot = std::make_unique<RiuSummaryQtChartsPlot>( this, mainWindowParent );
}
else
{
m_summaryPlot = std::make_unique<RiuSummaryQwtPlot>( this, mainWindowParent );
}
#else
m_summaryPlot = std::make_unique<RiuSummaryQwtPlot>( this, mainWindowParent );
#endif
QObject::connect( plotWidget(), SIGNAL( curveOrderNeedsUpdate() ), this, SLOT( onUpdateCurveOrder() ) );
@@ -318,9 +318,6 @@ private:
static RiuPlotAxis plotAxisForTime();
private:
#ifdef USE_QTCHARTS
caf::PdmField<bool> m_useQtChartsPlot;
#endif
caf::PdmField<bool> m_normalizeCurveYValues;
caf::PdmField<bool> m_useAutoPlotTitle;
@@ -31,7 +31,6 @@
#include "RimSummaryEnsemble.h"
#include "Tools/RimPlotAxisTools.h"
#include "RiuQtChartsPlotWidget.h"
#include "RiuQwtPlotWidget.h"
#include "RiuSummaryQuantityNameInfoProvider.h"
#include "RiuSummaryQwtPlot.h"
@@ -85,27 +84,6 @@ void RimSummaryPlotAxisFormatter::applyAxisPropertiesToPlot( RiuPlotWidget* plot
RimPlotAxisTools::applyAxisScaleDraw( plotWidget, axis, m_axisProperties );
#ifdef USE_QTCHARTS
auto qtChartsPlotWidget = dynamic_cast<RiuQtChartsPlotWidget*>( plotWidget );
if ( qtChartsPlotWidget )
{
auto mapToRiaNumberFormatType = []( RimPlotAxisProperties::NumberFormatType formatType )
{
if ( formatType == RimPlotAxisProperties::NumberFormatType::NUMBER_FORMAT_DECIMAL )
return RiaNumberFormat::NumberFormatType::FIXED;
if ( formatType == RimPlotAxisProperties::NumberFormatType::NUMBER_FORMAT_SCIENTIFIC )
return RiaNumberFormat::NumberFormatType::SCIENTIFIC;
return RiaNumberFormat::NumberFormatType::AUTO;
};
auto formatType = mapToRiaNumberFormatType( m_axisProperties->numberFormat() );
QString format = RiaNumberFormat::sprintfFormat( formatType, m_axisProperties->decimalCount() );
qtChartsPlotWidget->setAxisFormat( axis, format );
}
#endif
{
if ( m_axisProperties->isLogarithmicScaleEnabled() )
{
@@ -229,31 +229,5 @@ set(SOURCE_GROUP_SOURCE_FILES
${CMAKE_CURRENT_LIST_DIR}/RiuCellSelectionTool.cpp
)
if(RESINSIGHT_USE_QT_CHARTS)
list(
APPEND
CODE_HEADER_FILES
${CMAKE_CURRENT_LIST_DIR}/RiuQtChartView.h
${CMAKE_CURRENT_LIST_DIR}/RiuQtChartsPlotCurve.h
${CMAKE_CURRENT_LIST_DIR}/RiuQtChartsPlotWidget.h
${CMAKE_CURRENT_LIST_DIR}/RiuQtChartsPlotTools.h
${CMAKE_CURRENT_LIST_DIR}/RiuQtChartsPlotCurveSymbol.h
${CMAKE_CURRENT_LIST_DIR}/RiuQtChartsToolTip.h
${CMAKE_CURRENT_LIST_DIR}/RiuSummaryQtChartsPlot.h
)
list(
APPEND
CODE_SOURCE_FILES
${CMAKE_CURRENT_LIST_DIR}/RiuQtChartView.cpp
${CMAKE_CURRENT_LIST_DIR}/RiuQtChartsPlotCurve.cpp
${CMAKE_CURRENT_LIST_DIR}/RiuQtChartsPlotWidget.cpp
${CMAKE_CURRENT_LIST_DIR}/RiuQtChartsPlotTools.cpp
${CMAKE_CURRENT_LIST_DIR}/RiuQtChartsPlotCurveSymbol.cpp
${CMAKE_CURRENT_LIST_DIR}/RiuQtChartsToolTip.cpp
${CMAKE_CURRENT_LIST_DIR}/RiuSummaryQtChartsPlot.cpp
)
endif()
list(APPEND CODE_HEADER_FILES ${SOURCE_GROUP_HEADER_FILES})
list(APPEND CODE_SOURCE_FILES ${SOURCE_GROUP_SOURCE_FILES})
@@ -40,9 +40,6 @@
#include "RiuQwtPlotLegend.h"
#include "RiuQwtPlotTools.h"
#include "RiuQwtPlotWidget.h"
#ifdef USE_QTCHARTS
#include "RiuQtChartsPlotWidget.h"
#endif
#include "cafCmdFeatureMenuBuilder.h"
#include "cafSelectionManager.h"
@@ -201,15 +198,6 @@ void RiuMultiPlotPage::insertPlot( RiuPlotWidget* plotWidget, size_t index )
SLOT( updateLegend( const QVariant&, const QList<QwtLegendData>& ) ) );
qwtPlotWidget->connect( legend, SIGNAL( clicked( const QVariant&, int ) ), SLOT( onLegendClicked( const QVariant&, int ) ) );
}
else
{
#ifdef USE_QTCHARTS
auto qtchartPlotWidget = dynamic_cast<RiuQtChartsPlotWidget*>( plotWidget );
legend->connect( qtchartPlotWidget,
SIGNAL( legendDataChanged( const QList<QwtLegendData>& ) ),
SLOT( updateLegend( const QList<QwtLegendData>& ) ) );
#endif
}
QObject::connect( legend, SIGNAL( legendUpdated() ), this, SLOT( onLegendUpdated() ) );
@@ -1,107 +0,0 @@
////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2020- Equinor ASA
//
// ResInsight is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.
//
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#include "RiuQtChartView.h"
#include "RimPlotWindow.h"
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiuQtChartView::RiuQtChartView( RimPlotWindow* plotWindow, QWidget* parent )
: QChartView( parent )
, m_plotWindow( plotWindow )
{
setMouseTracking( true );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiuQtChartView::~RiuQtChartView()
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimViewWindow* RiuQtChartView::ownerViewWindow() const
{
return m_plotWindow;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuQtChartView::mousePressEvent( QMouseEvent* event )
{
if ( event->button() == Qt::MiddleButton )
{
m_isPanning = true;
m_panStartPosition = event->pos();
setCursor( Qt::ClosedHandCursor );
event->accept();
}
else
{
QChartView::mousePressEvent( event );
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuQtChartView::mouseReleaseEvent( QMouseEvent* event )
{
if ( event->button() == Qt::MiddleButton )
{
m_isPanning = false;
setCursor( Qt::ArrowCursor );
event->accept();
}
else
{
if ( event->button() == Qt::RightButton )
{
// Skip QtCharts::QChartView::mouseReleaseEvent() to avoid zoom on right mouse button
// NOLINTNEXTLINE: Suppress clang-tidy for the next line
return QGraphicsView::mouseReleaseEvent( event );
}
QChartView::mouseReleaseEvent( event );
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuQtChartView::mouseMoveEvent( QMouseEvent* event )
{
if ( event->buttons() & Qt::MiddleButton && m_isPanning )
{
QPoint newPosition = event->pos();
QPointF delta = mapToScene( newPosition ) - mapToScene( m_panStartPosition );
chart()->scroll( -delta.x(), delta.y() );
m_panStartPosition = newPosition;
event->accept();
}
else
{
QChartView::mouseMoveEvent( event );
}
}
@@ -1,50 +0,0 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2020- Equinor ASA
//
// ResInsight is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.
//
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#pragma once
#include "RiuInterfaceToViewWindow.h"
#include "cafPdmPointer.h"
#include <QtCharts/QChartView>
class RimPlotWindow;
//==================================================================================================
//
//==================================================================================================
class RiuQtChartView : public QChartView, public RiuInterfaceToViewWindow
{
public:
RiuQtChartView( RimPlotWindow* plotWindow, QWidget* parent = nullptr );
~RiuQtChartView() override;
RimViewWindow* ownerViewWindow() const override;
protected:
void mouseReleaseEvent( QMouseEvent* event ) override;
void mousePressEvent( QMouseEvent* event ) override;
void mouseMoveEvent( QMouseEvent* event ) override;
private:
caf::PdmPointer<RimPlotWindow> m_plotWindow;
bool m_isPanning;
QPoint m_panStartPosition;
};
@@ -1,637 +0,0 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2021- Equinor ASA
//
// ResInsight is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.
//
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#include "RiuQtChartsPlotCurve.h"
#include "RiaPlotDefines.h"
#include "RiuQtChartsPlotCurveSymbol.h"
#include "RiuQtChartsPlotWidget.h"
#include "cvfBoundingBox.h"
#include <QLegend>
#include <QLegendMarker>
#include <QtCharts/QChart>
#include <QtCharts/QChartView>
#include <QtCharts/QDateTimeAxis>
#include <QtCharts/QLineSeries>
#include <QtCharts/QValueAxis>
#include <limits>
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiuQtChartsPlotCurve::RiuQtChartsPlotCurve( RimPlotCurve* ownerRimCurve, const QString& title )
: RiuPlotCurve( ownerRimCurve, title )
{
m_plotWidget = nullptr;
m_lineSeries = new QLineSeries();
m_lineSeries->setName( title );
m_areaSeries = new QAreaSeries();
m_areaSeries->setName( title );
m_scatterSeries = new QScatterSeries();
m_scatterSeries->setName( title );
m_axisX = RiuPlotAxis::defaultBottom();
m_axisY = RiuPlotAxis::defaultLeft();
m_isVisibleInLegend = false;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiuQtChartsPlotCurve::~RiuQtChartsPlotCurve()
{
if ( m_plotWidget && m_plotWidget->qtChart() )
{
m_plotWidget->detach( this );
auto* line = lineSeries();
if ( line )
{
m_plotWidget->qtChart()->removeSeries( line );
// removeSeries() releases chart ownership of the data, delete data to avoid memory leak
delete line;
}
auto* area = areaSeries();
if ( area )
{
m_plotWidget->qtChart()->removeSeries( area );
// removeSeries() releases chart ownership of the data, delete data to avoid memory leak
delete area;
}
auto* scatter = scatterSeries();
if ( scatter )
{
m_plotWidget->qtChart()->removeSeries( scatter );
// removeSeries() releases chart ownership of the data, delete data to avoid memory leak
delete scatter;
}
}
// Delete if it is still owned by by plot curve
delete m_lineSeries;
m_lineSeries = nullptr;
delete m_areaSeries;
m_areaSeries = nullptr;
delete m_scatterSeries;
m_scatterSeries = nullptr;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuQtChartsPlotCurve::setTitle( const QString& title )
{
if ( !isQtChartObjectsPresent() ) return;
lineSeries()->setName( title );
areaSeries()->setName( title );
scatterSeries()->setName( title );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuQtChartsPlotCurve::setAppearance( RiuQwtPlotCurveDefines::LineStyleEnum lineStyle,
RiuQwtPlotCurveDefines::CurveInterpolationEnum interpolationType,
int requestedCurveThickness,
const QColor& curveColor,
const QBrush& fillBrush /* = QBrush( Qt::NoBrush )*/ )
{
if ( !isQtChartObjectsPresent() ) return;
Qt::PenStyle penStyle = RiuQwtPlotCurveDefines::convertToPenStyle( lineStyle );
QPen curvePen( curveColor );
curvePen.setWidth( requestedCurveThickness );
curvePen.setStyle( penStyle );
lineSeries()->setPen( curvePen );
lineSeries()->setBrush( fillBrush );
areaSeries()->setPen( curvePen );
areaSeries()->setBrush( fillBrush );
if ( fillBrush.style() == Qt::NoBrush )
{
lineSeries()->show();
areaSeries()->hide();
setVisibleInLegend( m_isVisibleInLegend );
}
else
{
lineSeries()->hide();
areaSeries()->show();
setVisibleInLegend( m_isVisibleInLegend );
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuQtChartsPlotCurve::setBrush( const QBrush& brush )
{
if ( !isQtChartObjectsPresent() ) return;
lineSeries()->setBrush( brush );
areaSeries()->setBrush( brush );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuQtChartsPlotCurve::setColor( const QColor& color )
{
QPen curvePen = lineSeries()->pen();
curvePen.setColor( color );
lineSeries()->setPen( curvePen );
curvePen = areaSeries()->pen();
curvePen.setColor( color );
areaSeries()->setPen( curvePen );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuQtChartsPlotCurve::attachToPlot( RiuPlotWidget* plotWidget )
{
m_plotWidget = dynamic_cast<RiuQtChartsPlotWidget*>( plotWidget );
CAF_ASSERT( m_plotWidget );
if ( m_plotWidget->getLineSeries( this ) && m_plotWidget->getScatterSeries( this ) )
{
m_plotWidget->qtChart()->legend()->setMarkerShape( QLegend::MarkerShape::MarkerShapeFromSeries );
setVisibleInLegend( true );
lineSeries()->show();
}
else
{
if ( !m_lineSeries ) m_lineSeries = new QLineSeries();
if ( !m_areaSeries ) m_areaSeries = new QAreaSeries();
if ( !m_scatterSeries ) m_scatterSeries = new QScatterSeries();
m_plotWidget->attach( this, m_lineSeries, m_areaSeries, m_scatterSeries, m_axisX, m_axisY );
// Plot widget takes ownership.
m_lineSeries = nullptr;
m_areaSeries = nullptr;
m_scatterSeries = nullptr;
}
if ( scatterSeries() )
{
if ( m_symbol )
{
scatterSeries()->show();
auto qtChartsSymbol = dynamic_cast<RiuQtChartsPlotCurveSymbol*>( m_symbol.get() );
CAF_ASSERT( qtChartsSymbol );
qtChartsSymbol->applyToScatterSeries( scatterSeries() );
}
else
{
scatterSeries()->hide();
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuQtChartsPlotCurve::detach()
{
QLineSeries* line = lineSeries();
if ( line )
{
line->hide();
}
QAreaSeries* area = areaSeries();
if ( area )
{
area->hide();
}
if ( scatterSeries() )
{
scatterSeries()->hide();
}
if ( m_plotWidget )
{
m_plotWidget->detach( this );
setVisibleInLegend( false );
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuQtChartsPlotCurve::showInPlot()
{
// show();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuQtChartsPlotCurve::setSamplesInPlot( const std::vector<double>& xValues, const std::vector<double>& yValues )
{
if ( !isQtChartObjectsPresent() ) return;
CAF_ASSERT( xValues.size() == yValues.size() );
QVector<QPointF> values( static_cast<int>( xValues.size() ) );
for ( int i = 0; i < static_cast<int>( xValues.size() ); i++ )
{
values[i] = QPointF( xValues[i], yValues[i] );
}
QLineSeries* line = lineSeries();
line->replace( values );
QLineSeries* upper = new QLineSeries;
upper->replace( values );
areaSeries()->setUpperSeries( upper );
updateScatterSeries();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuQtChartsPlotCurve::updateScatterSeries()
{
if ( !scatterSeries() ) return;
double minX = std::numeric_limits<double>::max();
double maxX = -std::numeric_limits<double>::max();
QVector<QPointF> points;
if ( lineSeries() )
{
points = lineSeries()->pointsVector();
bool foundAxis = false;
auto axes = lineSeries()->attachedAxes();
for ( auto axis : axes )
{
if ( axis->orientation() == Qt::Orientation::Horizontal )
{
QValueAxis* valueAxis = dynamic_cast<QValueAxis*>( axis );
QDateTimeAxis* dateTimeAxis = dynamic_cast<QDateTimeAxis*>( axis );
if ( valueAxis )
{
minX = valueAxis->min();
maxX = valueAxis->max();
foundAxis = true;
}
else if ( dateTimeAxis )
{
minX = dateTimeAxis->min().toMSecsSinceEpoch();
maxX = dateTimeAxis->max().toMSecsSinceEpoch();
foundAxis = true;
}
}
}
if ( !foundAxis )
{
for ( auto p : points )
{
minX = std::min( minX, p.x() );
maxX = std::max( maxX, p.x() );
}
}
}
QVector<QPointF> scatterValues;
if ( !points.empty() )
{
double range = maxX - minX;
double displaySize = 1400;
if ( m_plotWidget && m_plotWidget->qtChart() )
{
// Use the max size since plot area can be small before the widget is shown
displaySize = std::max( displaySize, m_plotWidget->qtChart()->plotArea().width() );
}
double rangePerPixel = range / displaySize;
double skipDistance = rangePerPixel * m_symbolSkipPixelDistance;
// Always have symbol on first point
scatterValues << points[0];
int lastDrawnIndex = 0;
for ( int i = 1; i < static_cast<int>( points.size() ); i++ )
{
// Skip points until skip distance is reached
double diff = points[i].x() - points[lastDrawnIndex].x();
// Always add last point.
bool isLastPoint = i == points.size() - 1;
if ( diff > skipDistance || isLastPoint )
{
scatterValues << points[i];
lastDrawnIndex = i;
}
}
}
scatterSeries()->replace( scatterValues );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RiuQtChartsPlotCurve::isQtChartObjectsPresent() const
{
return lineSeries() != nullptr;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuQtChartsPlotCurve::setZ( int z )
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuQtChartsPlotCurve::clearErrorBars()
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuQtChartsPlotCurve::updateErrorBarsAppearance( bool showErrorBars, const QColor& curveColor )
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuQtChartsPlotCurve::setXAxis( RiuPlotAxis axis )
{
m_axisX = axis;
if ( m_plotWidget )
{
m_plotWidget->setXAxis( axis, lineSeries(), this );
m_plotWidget->setXAxis( axis, areaSeries(), this );
m_plotWidget->setXAxis( axis, scatterSeries(), this );
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuQtChartsPlotCurve::setYAxis( RiuPlotAxis axis )
{
m_axisY = axis;
if ( m_plotWidget )
{
m_plotWidget->setYAxis( axis, lineSeries(), this );
m_plotWidget->setYAxis( axis, areaSeries(), this );
m_plotWidget->setYAxis( axis, scatterSeries(), this );
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
int RiuQtChartsPlotCurve::numSamples() const
{
if ( !lineSeries() ) return 0;
return lineSeries()->count();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::pair<double, double> RiuQtChartsPlotCurve::sample( int index ) const
{
CAF_ASSERT( index >= 0 && index <= numSamples() );
auto p = lineSeries()->at( index );
return std::make_pair( p.x(), p.y() );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::pair<double, double> RiuQtChartsPlotCurve::xDataRange() const
{
cvf::BoundingBox bb = computeBoundingBox();
return std::make_pair( bb.min().x(), bb.max().x() );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::pair<double, double> RiuQtChartsPlotCurve::yDataRange() const
{
cvf::BoundingBox bb = computeBoundingBox();
return std::make_pair( bb.min().y(), bb.max().y() );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
cvf::BoundingBox RiuQtChartsPlotCurve::computeBoundingBox() const
{
auto points = lineSeries()->pointsVector();
cvf::BoundingBox bb;
for ( auto p : points )
bb.add( cvf::Vec3d( p.x(), p.y(), 0.0 ) );
return bb;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuQtChartsPlotCurve::setVisibleInLegend( bool isVisibleInLegend )
{
if ( !m_plotWidget ) return;
CAF_ASSERT( m_plotWidget->qtChart() );
CAF_ASSERT( m_plotWidget->qtChart()->legend() );
// The markers can be set visible independent to the visibility state of the containing legend. Use the
// visibility state of the legend to override the visibility flag
if ( !m_plotWidget->qtChart()->legend()->isAttachedToChart() ) isVisibleInLegend = false;
if ( !m_plotWidget->qtChart()->legend()->isVisible() ) isVisibleInLegend = false;
bool showScatterMarker = isVisibleInLegend && m_symbol;
bool showLineMarker = isVisibleInLegend && !m_symbol;
auto setLegendVisibility = [this]( auto series, bool isVisible )
{
if ( series )
{
auto markers = m_plotWidget->qtChart()->legend()->markers( series );
if ( !markers.isEmpty() ) markers[0]->setVisible( isVisible );
}
};
m_isVisibleInLegend = showLineMarker || showScatterMarker;
setLegendVisibility( lineSeries(), showLineMarker );
setLegendVisibility( areaSeries(), false );
setLegendVisibility( scatterSeries(), showScatterMarker );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QLineSeries* RiuQtChartsPlotCurve::lineSeries() const
{
if ( m_lineSeries ) return m_lineSeries;
if ( m_plotWidget ) return dynamic_cast<QLineSeries*>( m_plotWidget->getLineSeries( this ) );
return nullptr;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QScatterSeries* RiuQtChartsPlotCurve::scatterSeries() const
{
if ( m_scatterSeries ) return m_scatterSeries;
if ( m_plotWidget ) return dynamic_cast<QScatterSeries*>( m_plotWidget->getScatterSeries( this ) );
return nullptr;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QAreaSeries* RiuQtChartsPlotCurve::areaSeries() const
{
if ( m_areaSeries ) return m_areaSeries;
if ( m_plotWidget ) return dynamic_cast<QAreaSeries*>( m_plotWidget->getAreaSeries( this ) );
return nullptr;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuQtChartsPlotCurve::setSymbol( RiuPlotCurveSymbol* symbol )
{
if ( symbol )
{
auto qtChartsSymbol = dynamic_cast<RiuQtChartsPlotCurveSymbol*>( symbol );
CAF_ASSERT( qtChartsSymbol );
m_symbol.reset( symbol );
if ( scatterSeries() )
{
qtChartsSymbol->applyToScatterSeries( scatterSeries() );
updateScatterSeries();
updateLineAndAreaSeries();
}
}
else
{
m_symbol.reset();
if ( scatterSeries() ) scatterSeries()->hide();
updateLineAndAreaSeries();
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuQtChartsPlotCurve::updateLineAndAreaSeries()
{
bool isFilled = areaSeries() && areaSeries()->brush().style() != Qt::NoBrush;
bool isLine = lineSeries() && lineSeries()->pen().style() != Qt::PenStyle::NoPen;
if ( areaSeries() ) areaSeries()->setVisible( isFilled );
if ( lineSeries() ) lineSeries()->setVisible( isLine );
setVisibleInLegend( m_isVisibleInLegend );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiuPlotCurveSymbol* RiuQtChartsPlotCurve::createSymbol( RiuPlotCurveSymbol::PointSymbolEnum symbol ) const
{
return new RiuQtChartsPlotCurveSymbol( symbol );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuQtChartsPlotCurve::setCurveFittingTolerance( double tolerance )
{
// Not supported
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuQtChartsPlotCurve::setLegendIconSize( const QSize& iconSize )
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QSize RiuQtChartsPlotCurve::legendIconSize() const
{
// Default from Qwt
return QSize( 8, 8 );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QPixmap RiuQtChartsPlotCurve::legendIcon( const QSizeF& iconSize ) const
{
return QPixmap();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuQtChartsPlotCurve::axisRangeChanged()
{
updateScatterSeries();
}
@@ -1,113 +0,0 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2021- Equinor ASA
//
// ResInsight is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.
//
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#pragma once
#include "RiuPlotCurve.h"
#include "RiuQwtPlotCurveDefines.h"
#include "cvfBoundingBox.h"
#include <QAreaSeries>
#include <QLineSeries>
#include <QScatterSeries>
class RiuQtChartsPlotWidget;
class RiuPlotCurveSymbol;
class QLineSeries;
class QScatterSeries;
class QAreaSeries;
//==================================================================================================
//
//==================================================================================================
class RiuQtChartsPlotCurve : public QObject, public RiuPlotCurve
{
Q_OBJECT
public:
explicit RiuQtChartsPlotCurve( RimPlotCurve* ownerRimCurve, const QString& title = QString() );
~RiuQtChartsPlotCurve() override;
void setTitle( const QString& title ) override;
void setAppearance( RiuQwtPlotCurveDefines::LineStyleEnum lineStyle,
RiuQwtPlotCurveDefines::CurveInterpolationEnum interpolationType,
int curveThickness,
const QColor& curveColor,
const QBrush& fillBrush = QBrush( Qt::NoBrush ) ) override;
void setBrush( const QBrush& brush ) override;
void setColor( const QColor& color ) override;
void setLegendIconSize( const QSize& iconSize ) override;
QSize legendIconSize() const override;
QPixmap legendIcon( const QSizeF& size ) const override;
void attachToPlot( RiuPlotWidget* plotWidget ) override;
void showInPlot() override;
void setZ( int z ) override;
void updateErrorBarsAppearance( bool showErrorBars, const QColor& curveColor ) override;
void clearErrorBars() override;
int numSamples() const override;
std::pair<double, double> sample( int index ) const override;
std::pair<double, double> xDataRange() const override;
std::pair<double, double> yDataRange() const override;
void detach() override;
void setXAxis( RiuPlotAxis axis ) override;
void setYAxis( RiuPlotAxis axis ) override;
void setVisibleInLegend( bool isVisibleInLegend ) override;
void setSymbol( RiuPlotCurveSymbol* symbol ) override;
void updateLineAndAreaSeries();
RiuPlotCurveSymbol* createSymbol( RiuPlotCurveSymbol::PointSymbolEnum symbol ) const override;
void setCurveFittingTolerance( double tolerance ) override;
void updateScatterSeries();
public slots:
void axisRangeChanged();
private:
void setSamplesInPlot( const std::vector<double>&, const std::vector<double>& ) override;
bool isQtChartObjectsPresent() const;
QLineSeries* lineSeries() const;
QScatterSeries* scatterSeries() const;
QAreaSeries* areaSeries() const;
cvf::BoundingBox computeBoundingBox() const;
private:
QLineSeries* m_lineSeries;
QScatterSeries* m_scatterSeries;
QAreaSeries* m_areaSeries;
std::shared_ptr<RiuPlotCurveSymbol> m_symbol;
QPointer<RiuQtChartsPlotWidget> m_plotWidget;
RiuPlotAxis m_axisX;
RiuPlotAxis m_axisY;
bool m_isVisibleInLegend;
};
@@ -1,115 +0,0 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2015- Equinor ASA
// Copyright (C) 2015- Ceetron Solutions AS
//
// ResInsight is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.
//
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#include "RiuQtChartsPlotCurveSymbol.h"
#include "RiaColorTools.h"
#include "RiaFontCache.h"
#include "RiaLogging.h"
#include "RiuPlotCurveSymbol.h"
#include "RiuPlotCurveSymbolImageCreator.h"
#include "cvfAssert.h"
#include <QPainter>
#include <QPainterPath>
#include <QScatterSeries>
#include <cmath>
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiuQtChartsPlotCurveSymbol::RiuQtChartsPlotCurveSymbol( PointSymbolEnum riuStyle, const QString& label, LabelPosition labelPosition, int labelFontSize )
: RiuPlotCurveSymbol( riuStyle, label, labelPosition, labelFontSize )
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuQtChartsPlotCurveSymbol::setSize( int width, int height )
{
m_size = std::min( width, height );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuQtChartsPlotCurveSymbol::setColor( const QColor& color )
{
m_color = color;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuQtChartsPlotCurveSymbol::setPen( const QPen& pen )
{
m_pen = pen;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuQtChartsPlotCurveSymbol::setPixmap( const QPixmap& pixmap )
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuQtChartsPlotCurveSymbol::applyToScatterSeries( QScatterSeries* series ) const
{
if ( m_style == PointSymbolEnum::SYMBOL_NONE )
{
series->hide();
return;
}
series->show();
QImage image = RiuPlotCurveSymbolImageCreator::createSymbolImage( m_style, QSize( m_size, m_size ), m_pen, m_color );
if ( !image.isNull() )
{
setImageBrush( series, image );
}
series->setMarkerSize( m_size );
series->setColor( m_color );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuQtChartsPlotCurveSymbol::setImageBrush( QScatterSeries* series, const QImage& image ) const
{
series->setMarkerShape( QScatterSeries::MarkerShapeRectangle );
series->setBrush( image );
series->setPen( QColor( Qt::transparent ) );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QRect RiuQtChartsPlotCurveSymbol::boundingRect() const
{
return QRect( 0, 0, m_size, m_size );
}
@@ -1,67 +0,0 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2015- Equinor ASA
// Copyright (C) 2015- Ceetron Solutions AS
//
// ResInsight is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.
//
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#pragma once
#include "RiuPlotCurveSymbol.h"
#include <QColor>
#include <QImage>
#include <QPen>
#include <QString>
class QPainter;
class QPointF;
class QRect;
class QScatterSeries;
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
class RiuQtChartsPlotCurveSymbol : public RiuPlotCurveSymbol
{
public:
RiuQtChartsPlotCurveSymbol( RiuPlotCurveSymbol::PointSymbolEnum riuStyle,
const QString& label = QString(),
LabelPosition labelPosition = RiuPlotCurveSymbol::LabelAboveSymbol,
int labelFontSize = 8 );
void renderSymbolLabel( QPainter* painter, const QPointF& position, const QString& label ) const;
void setSize( int width, int height ) override;
void setColor( const QColor& color ) override;
void setPen( const QPen& pen ) override;
void setPixmap( const QPixmap& pixmap ) override;
QRect boundingRect() const override;
void applyToScatterSeries( QScatterSeries* series ) const;
QImage image() const;
private:
void setImageBrush( QScatterSeries* series, const QImage& image ) const;
QColor m_color;
QPen m_pen;
int m_size;
};
@@ -1,105 +0,0 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2021- Equinor ASA
//
// ResInsight is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.
//
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#include "RiuQtChartsPlotTools.h"
#include "RiaApplication.h"
#include "RiaPlotDefines.h"
#include "RiaPreferences.h"
#include "RiaQDateTimeTools.h"
#include "RiuGuiTheme.h"
#include "RiuQtChartsPlotWidget.h"
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuQtChartsPlotTools::setCommonPlotBehaviour( RiuQtChartsPlotWidget* plot )
{
// Plot background and frame look
QPalette newPalette( plot->palette() );
newPalette.setColor( QPalette::Window, Qt::white );
plot->setPalette( newPalette );
plot->setAutoFillBackground( true );
// Axis number font
int axisFontSize =
caf::FontTools::absolutePointSize( RiaPreferences::current()->defaultPlotFontSize(), caf::FontTools::RelativeSize::Medium );
// Axis title font
int titleFontSize =
caf::FontTools::absolutePointSize( RiaPreferences::current()->defaultPlotFontSize(), caf::FontTools::RelativeSize::Medium );
bool titleBold = false;
plot->setAxesFontsAndAlignment( titleFontSize, axisFontSize, titleBold, Qt::AlignRight );
// Store the pointer address as an object name. This way
// each plot can be identified uniquely for CSS-stylesheets
QString objectName = QString( "%1" ).arg( reinterpret_cast<uint64_t>( plot ) );
plot->setObjectName( objectName );
QString canvasName = QString( "%1" ).arg( reinterpret_cast<uint64_t>( plot->getParentForOverlay() ) );
plot->getParentForOverlay()->setObjectName( canvasName );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuQtChartsPlotTools::setDefaultAxes( RiuQtChartsPlotWidget* plot )
{
plot->enableAxis( RiuPlotAxis::defaultBottom(), true );
plot->enableAxis( RiuPlotAxis::defaultLeft(), true );
plot->enableAxis( RiuPlotAxis::defaultTop(), false );
plot->enableAxis( RiuPlotAxis::defaultRight(), false );
plot->setAxisMaxMinor( RiuPlotAxis::defaultBottom(), 2 );
plot->setAxisMaxMinor( RiuPlotAxis::defaultLeft(), 0 );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuQtChartsPlotTools::enableDateBasedBottomXAxis( RiuQtChartsPlotWidget* plot,
const QString& dateFormat,
const QString& timeFormat,
RiaDefines::DateFormatComponents dateComponents,
RiaDefines::TimeFormatComponents timeComponents )
{
QString format = dateTimeFormatForInterval( dateFormat, timeFormat, dateComponents, timeComponents );
plot->setAxisFormat( RiuPlotAxis::defaultBottom(), format );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RiuQtChartsPlotTools::dateTimeFormatForInterval( const QString& dateFormat,
const QString& timeFormat,
RiaDefines::DateFormatComponents dateComponents,
RiaDefines::TimeFormatComponents timeComponents )
{
if ( dateComponents != RiaDefines::DateFormatComponents::DATE_FORMAT_UNSPECIFIED &&
timeComponents != RiaDefines::TimeFormatComponents::TIME_FORMAT_UNSPECIFIED )
{
return RiaQDateTimeTools::timeFormatString( timeFormat, timeComponents ) + "\n" +
RiaQDateTimeTools::dateFormatString( dateFormat, dateComponents );
}
// Default:
return RiaQDateTimeTools::timeFormatString( timeFormat, RiaDefines::TimeFormatComponents::TIME_FORMAT_NONE ) + "\n" +
RiaQDateTimeTools::dateFormatString( dateFormat, RiaDefines::DateFormatComponents::DATE_FORMAT_YEAR_MONTH_DAY );
}
@@ -1,40 +0,0 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2021- Equinor ASA
//
// ResInsight is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.
//
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#pragma once
#include "RiaDateTimeDefines.h"
class RiuQtChartsPlotWidget;
class RiuQtChartsPlotTools
{
public:
static void setCommonPlotBehaviour( RiuQtChartsPlotWidget* plot );
static void setDefaultAxes( RiuQtChartsPlotWidget* plot );
static void enableDateBasedBottomXAxis(
RiuQtChartsPlotWidget* plot,
const QString& dateFormat,
const QString& timeFormat,
RiaDefines::DateFormatComponents dateComponents = RiaDefines::DateFormatComponents::DATE_FORMAT_UNSPECIFIED,
RiaDefines::TimeFormatComponents timeComponents = RiaDefines::TimeFormatComponents::TIME_FORMAT_UNSPECIFIED );
static QString dateTimeFormatForInterval( const QString& dateFormat,
const QString& timeFormat,
RiaDefines::DateFormatComponents dateComponents,
RiaDefines::TimeFormatComponents timeComponents );
};
File diff suppressed because it is too large Load Diff
@@ -1,248 +0,0 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2015- Statoil ASA
// Copyright (C) 2015- Ceetron Solutions AS
//
// ResInsight is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.
//
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#pragma once
#include "RiaDateTimeDefines.h"
#include "RiaDefines.h"
#include "RiaPlotDefines.h"
#include "RiuPlotWidget.h"
#include "cafPdmObject.h"
#include "cafPdmPointer.h"
#include "qwt_legend_data.h"
#include <QPointer>
#include <set>
class RiaPlotWindowRedrawScheduler;
class RimPlot;
class RiuPlotCurve;
class RiuQtChartsPlotCurve;
class RiuQtChartsToolTip;
class RiuPlotCurveSymbol;
class RiuPlotCurveInfoTextProvider;
class QEvent;
class QLabel;
class QPainter;
class QPaintDevice;
class QWheelEvent;
class RiuQwtDateScaleWrapper;
class QValueAxis;
class QChart;
class QAbstractSeries;
class QAbstractAxis;
class QChartView;
class QCategoryAxis;
//==================================================================================================
//
//
//
//==================================================================================================
class RiuQtChartsPlotWidget : public RiuPlotWidget
{
Q_OBJECT
public:
RiuQtChartsPlotWidget( RimPlot* plotDefinition, QWidget* parent = nullptr, RiuPlotCurveInfoTextProvider* plotCurveNameProvider = nullptr );
~RiuQtChartsPlotWidget() override;
int axisTitleFontSize( RiuPlotAxis axis ) const override;
int axisValueFontSize( RiuPlotAxis axis ) const override;
void setAxisFontsAndAlignment( RiuPlotAxis,
int titleFontSize,
int valueFontSize,
bool titleBold = false,
int alignment = (int)Qt::AlignCenter ) override;
void setAxesFontsAndAlignment( int titleFontSize, int valueFontSize, bool titleBold = false, int alignment = (int)Qt::AlignCenter ) override;
void enableAxisNumberLabels( RiuPlotAxis axis, bool isEnabled ) override;
void enableAxis( RiuPlotAxis axis, bool isEnabled ) override;
bool axisEnabled( RiuPlotAxis axis ) const override;
void setAxisScale( RiuPlotAxis axis, double min, double max ) override;
void setAxisAutoScale( RiuPlotAxis axis, bool enable ) override;
void setAxisMaxMinor( RiuPlotAxis axis, int maxMinor ) override;
void setAxisMaxMajor( RiuPlotAxis axis, int maxMajor ) override;
RiuPlotWidget::AxisScaleType axisScaleType( RiuPlotAxis axis ) const override;
void setAxisScaleType( RiuPlotAxis axis, RiuPlotWidget::AxisScaleType axisScaleType ) override;
void setAxisTitleText( RiuPlotAxis axis, const QString& title ) override;
void setAxisTitleEnabled( RiuPlotAxis axis, bool enable ) override;
void setAxisFormat( RiuPlotAxis axis, const QString& format );
void pruneAxes( const std::set<RiuPlotAxis>& usedAxis ) override;
void moveAxis( RiuPlotAxis oldAxis, RiuPlotAxis newAxis ) override;
RiuPlotAxis createNextPlotAxis( RiaDefines::PlotAxis axis ) override;
bool isMultiAxisSupported() const override;
void setPlotTitle( const QString& plotTitle ) override;
const QString& plotTitle() const;
void setPlotTitleEnabled( bool enabled ) override;
bool plotTitleEnabled() const override;
void setPlotTitleFontSize( int titleFontSize ) override;
void setLegendFontSize( int fontSize ) override;
void insertLegend( RiuPlotWidget::Legend ) override;
void clearLegend() override;
std::pair<double, double> axisRange( RiuPlotAxis axis ) const override;
void setAxisRange( RiuPlotAxis axis, double min, double max ) override;
void setAxisInverted( RiuPlotAxis axis, bool isInverted ) override;
void setAxisLabelsAndTicksEnabled( RiuPlotAxis axis, bool enableLabels, bool enableTicks ) override;
void enableGridLines( RiuPlotAxis axis, bool majorGridLines, bool minorGridLines ) override;
void setMajorTicksList( RiuPlotAxis axis, const QList<double>& majorTicks, double minValue, double maxValue ) override;
void setMajorAndMinorTickIntervals( RiuPlotAxis axis, double majorTickInterval, double minorTickInterval, double minValue, double maxValue ) override;
void setMajorAndMinorTickIntervalsAndRange( RiuPlotAxis axis,
double majorTickInterval,
double minorTickInterval,
double minTickValue,
double maxTickValue,
double rangeMin,
double rangeMax ) override;
void setAutoTickIntervalCounts( RiuPlotAxis axis, int maxMajorTickIntervalCount, int maxMinorTickIntervalCount ) override;
double majorTickInterval( RiuPlotAxis axis ) const override;
double minorTickInterval( RiuPlotAxis axis ) const override;
void detachItems( RiuPlotWidget::PlotItemType plotItemType ) override;
int axisExtent( RiuPlotAxis axis ) const override;
void ensureAxisIsCreated( RiuPlotAxis axis ) override;
QPoint dragStartPosition() const;
void scheduleReplot();
void updateLayout() override;
void renderTo( QPainter* painter, const QRect& targetRect, double scaling ) override;
void renderTo( QPaintDevice* painter, const QRect& targetRect ) override;
int overlayMargins() const;
RimViewWindow* ownerViewWindow() const override;
void updateLegend() override;
void updateAxes() override;
RiuPlotCurve* createPlotCurve( RimPlotCurve* ownerRimCurve, const QString& title ) override;
QChart* qtChart();
void attach( RiuPlotCurve* plotCurve,
QAbstractSeries* lineSeries,
QAbstractSeries* areaSeries,
QAbstractSeries* scatterSeries,
RiuPlotAxis xAxis,
RiuPlotAxis yAxis );
void detach( RiuPlotCurve* plotCurve );
QAbstractSeries* getLineSeries( const RiuPlotCurve* plotCurve ) const;
QAbstractSeries* getAreaSeries( const RiuPlotCurve* plotCurve ) const;
QAbstractSeries* getScatterSeries( const RiuPlotCurve* plotCurve ) const;
void setXAxis( RiuPlotAxis axis, QAbstractSeries* series, RiuQtChartsPlotCurve* plotCurve );
void setYAxis( RiuPlotAxis axis, QAbstractSeries* series, RiuQtChartsPlotCurve* plotCurve );
const QColor& backgroundColor() const override;
QWidget* getParentForOverlay() const override;
std::pair<RiuPlotCurve*, int> findClosestCurve( const QPoint& pos, double& distanceToClick ) const override;
void updateZoomDependentCurveProperties() override;
void setFormatStrings( const QString& dateFormat,
const QString& timeFormat,
RiaDefines::DateFormatComponents dateComponents,
RiaDefines::TimeFormatComponents timeComponents );
protected:
void attachSeriesToAxis( RiuPlotAxis axis, QAbstractSeries* series, RiuQtChartsPlotCurve* plotCurve );
void resizeEvent( QResizeEvent* event ) override;
void keyPressEvent( QKeyEvent* event ) override;
void wheelEvent( QWheelEvent* event ) override;
bool eventFilter( QObject* watched, QEvent* event ) override;
void applyPlotTitleToPlot();
void applyAxisTitleToPlot( RiuPlotAxis axis );
QSize sizeHint() const override;
QSize minimumSizeHint() const override;
virtual bool isZoomerActive() const;
virtual void endZoomOperations();
void rescaleAxis( RiuPlotAxis axis );
QAbstractAxis* plotAxis( RiuPlotAxis axis ) const;
Qt::Orientation orientation( RiaDefines::PlotAxis axis ) const;
void dragEnterEvent( QDragEnterEvent* event ) override;
void dropEvent( QDropEvent* event ) override;
signals:
void plotZoomed();
void legendDataChanged( const QList<QwtLegendData>& data );
private slots:
void axisRangeChanged();
void tooltip( const QPointF& point, bool state );
private:
void addAxis( RiuPlotAxis plotAxis, bool isEnabled, bool isAutoScale );
void deleteAxis( RiuPlotAxis plotAxis );
static Qt::Alignment mapPlotAxisToQtAlignment( RiaDefines::PlotAxis axis );
static int defaultMinimumWidth();
void replot() override;
QCategoryAxis* categoryAxis();
QString createNameFromSeries( QAbstractSeries* series ) const;
private:
QPointer<QChartView> m_viewer;
std::map<RiuPlotAxis, QAbstractAxis*> m_axes;
std::map<RiuPlotAxis, bool> m_axesEnabled;
std::map<RiuPlotAxis, bool> m_axesAutoScale;
std::map<RiuPlotCurve*, QAbstractSeries*> m_lineSeriesMap;
std::map<RiuPlotCurve*, QAbstractSeries*> m_areaSeriesMap;
std::map<RiuPlotCurve*, QAbstractSeries*> m_scatterSeriesMap;
RiuQwtDateScaleWrapper* m_dateScaleWrapper;
RiuQtChartsToolTip* m_toolTip;
RiuPlotCurveInfoTextProvider* m_plotCurveNameProvider;
};
@@ -1,110 +0,0 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2022- Equinor ASA
//
// ResInsight is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.
//
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#include "RiuQtChartsToolTip.h"
#include <QtCharts/QChart>
#include <QtGui/QFontMetrics>
#include <QtGui/QMouseEvent>
#include <QtGui/QPainter>
#include <QtWidgets/QGraphicsSceneMouseEvent>
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiuQtChartsToolTip::RiuQtChartsToolTip( QChart* chart, QAbstractSeries* series )
: QGraphicsItem( chart )
, m_chart( chart )
, m_series( series )
, m_radius( 10 )
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QRectF RiuQtChartsToolTip::boundingRect() const
{
QPointF anchor = mapFromParent( m_chart->mapToPosition( m_anchor, m_series ) );
QRectF rect = m_rect.united( m_textRect );
rect.setLeft( std::min( rect.left(), anchor.x() ) );
rect.setRight( std::max( rect.right(), anchor.x() ) );
rect.setTop( std::min( rect.top(), anchor.y() ) );
rect.setBottom( std::max( rect.bottom(), anchor.y() ) );
return rect;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuQtChartsToolTip::paint( QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget )
{
Q_UNUSED( option )
Q_UNUSED( widget )
QPainterPath path;
QPointF anchor = mapFromParent( m_chart->mapToPosition( m_anchor, m_series ) );
path.addEllipse( anchor, m_radius, m_radius );
path = path.simplified();
painter->setPen( QPen( Qt::black ) );
painter->drawPath( path );
painter->drawText( m_textRect, m_text );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuQtChartsToolTip::setSeries( QAbstractSeries* series )
{
m_series = series;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuQtChartsToolTip::setText( const QString& text )
{
m_text = text;
QFontMetrics metrics( m_font );
m_textRect = metrics.boundingRect( QRect( 0, 0, 150, 150 ), Qt::AlignLeft, m_text );
m_textRect.translate( m_radius, 0 );
prepareGeometryChange();
m_rect.setRect( -m_radius, -m_radius, m_radius, m_radius );
m_rect.moveCenter( QPoint( m_radius, m_radius ) );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuQtChartsToolTip::setAnchor( QPointF point )
{
m_anchor = point;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuQtChartsToolTip::updateGeometry()
{
prepareGeometryChange();
setPos( m_chart->mapToPosition( m_anchor, m_series ) );
}
@@ -1,48 +0,0 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2022- Equinor ASA
//
// ResInsight is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.
//
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#pragma once
#include <QtCharts/QChart>
#include <QtCharts/QChartGlobal>
#include <QtGui/QFont>
#include <QtWidgets/QGraphicsItem>
class RiuQtChartsToolTip : public QGraphicsItem
{
public:
RiuQtChartsToolTip( QChart* parent, QAbstractSeries* series );
void setSeries( QAbstractSeries* series );
void setText( const QString& text );
void setAnchor( QPointF point );
void updateGeometry();
QRectF boundingRect() const override;
void paint( QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget ) override;
private:
QString m_text;
QRectF m_textRect;
QRectF m_rect;
QPointF m_anchor;
QFont m_font;
int m_radius;
QChart* m_chart;
QAbstractSeries* m_series;
};
+2 -16
View File
@@ -570,17 +570,9 @@ endif()
find_package(
Qt6
COMPONENTS
REQUIRED
Core
Gui
OpenGL
Network
Widgets
Charts
)
set(QT_LIBRARIES Qt6::Core Qt6::Gui Qt6::OpenGL Qt6::Network Qt6::Widgets
Qt6::Charts
REQUIRED Core Gui OpenGL Network Widgets
)
set(QT_LIBRARIES Qt6::Core Qt6::Gui Qt6::OpenGL Qt6::Network Qt6::Widgets)
qt_standard_project_setup()
# Disable use of foreach
@@ -589,12 +581,6 @@ add_definitions(-DQT_NO_FOREACH)
# Open GL
find_package(OpenGL)
# ##############################################################################
# QtCharts
# ##############################################################################
set(RESINSIGHT_USE_QT_CHARTS ON)
add_definitions(-DUSE_QTCHARTS)
# ##############################################################################
# Qwt
# ##############################################################################