[plots] Break Qgs2DPlot into a axis-less Qgs2DPlot and a X/Y axes Qgs2DXyPlot

This commit is contained in:
Mathieu Pellerin 2025-06-21 11:52:27 +07:00 committed by Nyall Dawson
parent 972f31b6e7
commit a453dd65b6
24 changed files with 348 additions and 157 deletions

View File

@ -14,11 +14,16 @@ try:
except (NameError, AttributeError):
pass
try:
Qgs2DPlot.__virtual_methods__ = ['renderContent']
Qgs2DPlot.__virtual_methods__ = ['render', 'renderContent', 'interiorPlotArea']
Qgs2DPlot.__overridden_methods__ = ['writeXml', 'readXml']
Qgs2DPlot.__group__ = ['plot']
except (NameError, AttributeError):
pass
try:
Qgs2DXyPlot.__overridden_methods__ = ['writeXml', 'readXml', 'render', 'interiorPlotArea']
Qgs2DXyPlot.__group__ = ['plot']
except (NameError, AttributeError):
pass
try:
QgsPlotAxis.__group__ = ['plot']
except (NameError, AttributeError):

View File

@ -50,7 +50,7 @@ The caller takes responsibility for deleting the returned object.
virtual bool containsAdvancedEffects() const;
Qgs2DPlot *plot();
Qgs2DXyPlot *plot();
%Docstring
Returns a reference to the elevation plot object, which can be used to
set plot appearance and properties.

View File

@ -234,10 +234,6 @@ class Qgs2DPlot : QgsPlot
%Docstring(signature="appended")
Base class for 2-dimensional plot/chart/graphs.
The base class is responsible for rendering the axis, grid lines and
chart area. Subclasses can implement the :py:func:`~renderContent`
method to render their actual plot content.
.. warning::
This class is not considered stable API, and may change in future!
@ -263,7 +259,7 @@ Constructor for Qgs2DPlot.
virtual bool readXml( const QDomElement &element, const QgsReadWriteContext &context );
void render( QgsRenderContext &context );
virtual void render( QgsRenderContext &context );
%Docstring
Renders the plot.
%End
@ -301,7 +297,73 @@ components which sit outside the plot area).
.. seealso:: :py:func:`size`
%End
QRectF interiorPlotArea( QgsRenderContext &context ) const;
virtual QRectF interiorPlotArea( QgsRenderContext &context ) const;
%Docstring
Returns the area of the plot which corresponds to the actual plot
content (excluding all titles and other components which sit outside the
plot area).
%End
const QgsMargins &margins() const;
%Docstring
Returns the margins of the plot area (in millimeters)
.. seealso:: :py:func:`setMargins`
%End
void setMargins( const QgsMargins &margins );
%Docstring
Sets the ``margins`` of the plot area (in millimeters)
.. seealso:: :py:func:`setMargins`
%End
private:
Qgs2DPlot( const Qgs2DPlot &other );
};
class Qgs2DXyPlot : Qgs2DPlot
{
%Docstring(signature="appended")
Base class for 2-dimensional plot/chart/graphs with an X and Y axes.
The base class is responsible for rendering the axis, grid lines and
chart area. Subclasses can implement the :py:func:`~renderContent`
method to render their actual plot content.
.. warning::
This class is not considered stable API, and may change in future!
.. versionadded:: 3.26
%End
%TypeHeaderCode
#include "qgsplot.h"
%End
public:
Qgs2DXyPlot();
%Docstring
Constructor for Qgs2DXyPlot.
%End
~Qgs2DXyPlot();
virtual bool writeXml( QDomElement &element, QDomDocument &document, const QgsReadWriteContext &context ) const;
virtual bool readXml( const QDomElement &element, const QgsReadWriteContext &context );
virtual void render( QgsRenderContext &context );
%Docstring
Renders the plot.
%End
virtual QRectF interiorPlotArea( QgsRenderContext &context ) const;
%Docstring
Returns the area of the plot which corresponds to the actual plot
content (excluding all titles and other components which sit outside the
@ -419,24 +481,10 @@ Sets the ``symbol`` used to render the border of the chart.
Ownership of ``symbol`` is transferred to the plot.
.. seealso:: :py:func:`chartBorderSymbol`
%End
const QgsMargins &margins() const;
%Docstring
Returns the margins of the plot area (in millimeters)
.. seealso:: :py:func:`setMargins`
%End
void setMargins( const QgsMargins &margins );
%Docstring
Sets the ``margins`` of the plot area (in millimeters)
.. seealso:: :py:func:`setMargins`
%End
private:
Qgs2DPlot( const Qgs2DPlot &other );
Qgs2DXyPlot( const Qgs2DXyPlot &other );
};
class QgsPlotDefaultSettings

View File

@ -189,7 +189,7 @@ Returns the elevation range currently visible in the plot.
%End
void render( QgsRenderContext &context, double width, double height, const Qgs2DPlot &plotSettings );
void render( QgsRenderContext &context, double width, double height, const Qgs2DXyPlot &plotSettings );
%Docstring
Renders a portion of the profile using the specified render ``context``.
%End

View File

@ -14,11 +14,16 @@ try:
except (NameError, AttributeError):
pass
try:
Qgs2DPlot.__virtual_methods__ = ['renderContent']
Qgs2DPlot.__virtual_methods__ = ['render', 'renderContent', 'interiorPlotArea']
Qgs2DPlot.__overridden_methods__ = ['writeXml', 'readXml']
Qgs2DPlot.__group__ = ['plot']
except (NameError, AttributeError):
pass
try:
Qgs2DXyPlot.__overridden_methods__ = ['writeXml', 'readXml', 'render', 'interiorPlotArea']
Qgs2DXyPlot.__group__ = ['plot']
except (NameError, AttributeError):
pass
try:
QgsPlotAxis.__group__ = ['plot']
except (NameError, AttributeError):

View File

@ -50,7 +50,7 @@ The caller takes responsibility for deleting the returned object.
virtual bool containsAdvancedEffects() const;
Qgs2DPlot *plot();
Qgs2DXyPlot *plot();
%Docstring
Returns a reference to the elevation plot object, which can be used to
set plot appearance and properties.

View File

@ -234,10 +234,6 @@ class Qgs2DPlot : QgsPlot
%Docstring(signature="appended")
Base class for 2-dimensional plot/chart/graphs.
The base class is responsible for rendering the axis, grid lines and
chart area. Subclasses can implement the :py:func:`~renderContent`
method to render their actual plot content.
.. warning::
This class is not considered stable API, and may change in future!
@ -263,7 +259,7 @@ Constructor for Qgs2DPlot.
virtual bool readXml( const QDomElement &element, const QgsReadWriteContext &context );
void render( QgsRenderContext &context );
virtual void render( QgsRenderContext &context );
%Docstring
Renders the plot.
%End
@ -301,7 +297,73 @@ components which sit outside the plot area).
.. seealso:: :py:func:`size`
%End
QRectF interiorPlotArea( QgsRenderContext &context ) const;
virtual QRectF interiorPlotArea( QgsRenderContext &context ) const;
%Docstring
Returns the area of the plot which corresponds to the actual plot
content (excluding all titles and other components which sit outside the
plot area).
%End
const QgsMargins &margins() const;
%Docstring
Returns the margins of the plot area (in millimeters)
.. seealso:: :py:func:`setMargins`
%End
void setMargins( const QgsMargins &margins );
%Docstring
Sets the ``margins`` of the plot area (in millimeters)
.. seealso:: :py:func:`setMargins`
%End
private:
Qgs2DPlot( const Qgs2DPlot &other );
};
class Qgs2DXyPlot : Qgs2DPlot
{
%Docstring(signature="appended")
Base class for 2-dimensional plot/chart/graphs with an X and Y axes.
The base class is responsible for rendering the axis, grid lines and
chart area. Subclasses can implement the :py:func:`~renderContent`
method to render their actual plot content.
.. warning::
This class is not considered stable API, and may change in future!
.. versionadded:: 3.26
%End
%TypeHeaderCode
#include "qgsplot.h"
%End
public:
Qgs2DXyPlot();
%Docstring
Constructor for Qgs2DXyPlot.
%End
~Qgs2DXyPlot();
virtual bool writeXml( QDomElement &element, QDomDocument &document, const QgsReadWriteContext &context ) const;
virtual bool readXml( const QDomElement &element, const QgsReadWriteContext &context );
virtual void render( QgsRenderContext &context );
%Docstring
Renders the plot.
%End
virtual QRectF interiorPlotArea( QgsRenderContext &context ) const;
%Docstring
Returns the area of the plot which corresponds to the actual plot
content (excluding all titles and other components which sit outside the
@ -419,24 +481,10 @@ Sets the ``symbol`` used to render the border of the chart.
Ownership of ``symbol`` is transferred to the plot.
.. seealso:: :py:func:`chartBorderSymbol`
%End
const QgsMargins &margins() const;
%Docstring
Returns the margins of the plot area (in millimeters)
.. seealso:: :py:func:`setMargins`
%End
void setMargins( const QgsMargins &margins );
%Docstring
Sets the ``margins`` of the plot area (in millimeters)
.. seealso:: :py:func:`setMargins`
%End
private:
Qgs2DPlot( const Qgs2DPlot &other );
Qgs2DXyPlot( const Qgs2DXyPlot &other );
};
class QgsPlotDefaultSettings

View File

@ -189,7 +189,7 @@ Returns the elevation range currently visible in the plot.
%End
void render( QgsRenderContext &context, double width, double height, const Qgs2DPlot &plotSettings );
void render( QgsRenderContext &context, double width, double height, const Qgs2DXyPlot &plotSettings );
%Docstring
Renders a portion of the profile using the specified render ``context``.
%End

View File

@ -31,7 +31,7 @@
///@cond PRIVATE
class QgsAlgorithmElevationProfilePlotItem : public Qgs2DPlot
class QgsAlgorithmElevationProfilePlotItem : public Qgs2DXyPlot
{
public:
explicit QgsAlgorithmElevationProfilePlotItem( int width, int height, int dpi )

View File

@ -25,7 +25,7 @@ QgsElevationProfileExportSettingsWidget::QgsElevationProfileExportSettingsWidget
setupUi( this );
}
void QgsElevationProfileExportSettingsWidget::setPlotSettings( const Qgs2DPlot &plot )
void QgsElevationProfileExportSettingsWidget::setPlotSettings( const Qgs2DXyPlot &plot )
{
mSpinMinDistance->setValue( plot.xMinimum() );
mSpinMinDistance->setClearValue( plot.xMinimum() );
@ -69,7 +69,7 @@ void QgsElevationProfileExportSettingsWidget::setPlotSettings( const Qgs2DPlot &
mSpinMajorIntervalY->setShowClearButton( true );
}
void QgsElevationProfileExportSettingsWidget::updatePlotSettings( Qgs2DPlot &plot )
void QgsElevationProfileExportSettingsWidget::updatePlotSettings( Qgs2DXyPlot &plot )
{
plot.setXMinimum( mSpinMinDistance->value() );
plot.setXMaximum( mSpinMaxDistance->value() );

View File

@ -21,7 +21,7 @@
#include <QWidget>
class Qgs2DPlot;
class Qgs2DXyPlot;
/**
* \brief Contains generic settings for exporting elevation profiles to drawings.
@ -35,12 +35,12 @@ class QgsElevationProfileExportSettingsWidget : public QWidget, private Ui::QgsE
/**
* Sets the initial plot settings to show in the widget.
*/
void setPlotSettings( const Qgs2DPlot &plot );
void setPlotSettings( const Qgs2DXyPlot &plot );
/**
* Updates plot settings based on the widget's state.
*/
void updatePlotSettings( Qgs2DPlot &plot );
void updatePlotSettings( Qgs2DXyPlot &plot );
};
#endif // QGSELEVATIONPROFILEEXPORTSETTINGSWIDGET_H

View File

@ -33,12 +33,12 @@ QgsElevationProfileImageExportDialog::QgsElevationProfileImageExportDialog( QWid
QgsGui::enableAutoGeometryRestore( this );
}
void QgsElevationProfileImageExportDialog::setPlotSettings( const Qgs2DPlot &plot )
void QgsElevationProfileImageExportDialog::setPlotSettings( const Qgs2DXyPlot &plot )
{
mProfileSettingsWidget->setPlotSettings( plot );
}
void QgsElevationProfileImageExportDialog::updatePlotSettings( Qgs2DPlot &plot )
void QgsElevationProfileImageExportDialog::updatePlotSettings( Qgs2DXyPlot &plot )
{
mProfileSettingsWidget->updatePlotSettings( plot );
}

View File

@ -22,7 +22,7 @@
#include <QDialog>
class Qgs2DPlot;
class Qgs2DXyPlot;
class QgsElevationProfileExportSettingsWidget;
/**
@ -37,12 +37,12 @@ class QgsElevationProfileImageExportDialog : public QDialog, private Ui::QgsElev
/**
* Sets the initial plot settings to show in the widget.
*/
void setPlotSettings( const Qgs2DPlot &plot );
void setPlotSettings( const Qgs2DXyPlot &plot );
/**
* Updates plot settings based on the widget's state.
*/
void updatePlotSettings( Qgs2DPlot &plot );
void updatePlotSettings( Qgs2DXyPlot &plot );
void setImageSize( const QSize &size );
QSize imageSize() const;

View File

@ -71,12 +71,12 @@ QgsElevationProfilePdfExportDialog::QgsElevationProfilePdfExportDialog( QWidget
mPageOrientationComboBox->setCurrentIndex( mPageOrientationComboBox->findData( QgsLayoutItemPage::Landscape ) );
}
void QgsElevationProfilePdfExportDialog::setPlotSettings( const Qgs2DPlot &plot )
void QgsElevationProfilePdfExportDialog::setPlotSettings( const Qgs2DXyPlot &plot )
{
mProfileSettingsWidget->setPlotSettings( plot );
}
void QgsElevationProfilePdfExportDialog::updatePlotSettings( Qgs2DPlot &plot )
void QgsElevationProfilePdfExportDialog::updatePlotSettings( Qgs2DXyPlot &plot )
{
mProfileSettingsWidget->updatePlotSettings( plot );
}

View File

@ -22,7 +22,7 @@
#include <QDialog>
class Qgs2DPlot;
class Qgs2DXyPlot;
class QgsElevationProfileExportSettingsWidget;
/**
@ -37,12 +37,12 @@ class QgsElevationProfilePdfExportDialog : public QDialog, private Ui::QgsElevat
/**
* Sets the initial plot settings to show in the widget.
*/
void setPlotSettings( const Qgs2DPlot &plot );
void setPlotSettings( const Qgs2DXyPlot &plot );
/**
* Updates plot settings based on the widget's state.
*/
void updatePlotSettings( Qgs2DPlot &plot );
void updatePlotSettings( Qgs2DXyPlot &plot );
QgsLayoutSize pageSizeMM() const;

View File

@ -842,7 +842,7 @@ void QgsElevationProfileWidget::exportAsPdf()
rc.setTextRenderFormat( Qgis::TextRenderFormat::AlwaysText );
rc.setPainterFlagsUsingContext( &p );
Qgs2DPlot plotSettings;
Qgs2DXyPlot plotSettings;
dialog.updatePlotSettings( plotSettings );
mCanvas->render( rc, rc.convertToPainterUnits( pageSizeMM.width(), Qgis::RenderUnit::Millimeters ), rc.convertToPainterUnits( pageSizeMM.height(), Qgis::RenderUnit::Millimeters ), plotSettings );
@ -892,7 +892,7 @@ void QgsElevationProfileWidget::exportAsImage()
rc.setFlag( Qgis::RenderContextFlag::HighQualityImageTransforms, true );
rc.setPainterFlagsUsingContext( &p );
Qgs2DPlot plotSettings;
Qgs2DXyPlot plotSettings;
dialog.updatePlotSettings( plotSettings );
mCanvas->render( rc, image.width(), image.height(), plotSettings );

View File

@ -41,7 +41,7 @@
#define CACHE_SIZE_LIMIT 5000
///@cond PRIVATE
class QgsLayoutItemElevationProfilePlot : public Qgs2DPlot
class QgsLayoutItemElevationProfilePlot : public Qgs2DXyPlot
{
public:
@ -467,12 +467,12 @@ bool QgsLayoutItemElevationProfile::containsAdvancedEffects() const
return mEvaluatedOpacity < 1.0;
}
Qgs2DPlot *QgsLayoutItemElevationProfile::plot()
Qgs2DXyPlot *QgsLayoutItemElevationProfile::plot()
{
return mPlot.get();
}
const Qgs2DPlot *QgsLayoutItemElevationProfile::plot() const
const Qgs2DXyPlot *QgsLayoutItemElevationProfile::plot() const
{
return mPlot.get();
}

View File

@ -22,7 +22,7 @@
#include "qgsmaplayerref.h"
class QgsLayoutItemElevationProfilePlot;
class Qgs2DPlot;
class Qgs2DXyPlot;
class QgsProfileRequest;
class QgsProfilePlotRenderer;
class QgsLineSymbol;
@ -63,13 +63,13 @@ class CORE_EXPORT QgsLayoutItemElevationProfile: public QgsLayoutItem
* Returns a reference to the elevation plot object, which can be used to
* set plot appearance and properties.
*/
Qgs2DPlot *plot();
Qgs2DXyPlot *plot();
/**
* Returns a reference to the elevation plot object, which can be used to
* set plot appearance and properties.
*/
const Qgs2DPlot *plot() const SIP_SKIP;
const Qgs2DXyPlot *plot() const SIP_SKIP;
/**
* Returns the list of map layers participating in the elevation profile.

View File

@ -169,15 +169,85 @@ void QgsPlotAxis::setTextFormat( const QgsTextFormat &format )
Qgs2DPlot::Qgs2DPlot()
: mMargins( 2, 2, 2, 2 )
{
// setup default style
mChartBackgroundSymbol.reset( QgsPlotDefaultSettings::chartBackgroundSymbol() );
mChartBorderSymbol.reset( QgsPlotDefaultSettings::chartBorderSymbol() );
}
bool Qgs2DPlot::writeXml( QDomElement &element, QDomDocument &document, const QgsReadWriteContext &context ) const
{
QgsPlot::writeXml( element, document, context );
element.setAttribute( QStringLiteral( "margins" ), mMargins.toString() );
return true;
}
bool Qgs2DPlot::readXml( const QDomElement &element, const QgsReadWriteContext &context )
{
QgsPlot::readXml( element, context );
mMargins = QgsMargins::fromString( element.attribute( QStringLiteral( "margins" ) ) );
return true;
}
void Qgs2DPlot::render( QgsRenderContext &context )
{
QgsExpressionContextScope *plotScope = new QgsExpressionContextScope( QStringLiteral( "plot" ) );
const QgsExpressionContextScopePopper scopePopper( context.expressionContext(), plotScope );
const QRectF plotArea = interiorPlotArea( context );
// give subclasses a chance to draw their content
renderContent( context, plotArea );
}
void Qgs2DPlot::renderContent( QgsRenderContext &, const QRectF & )
{
}
Qgs2DPlot::~Qgs2DPlot() = default;
QSizeF Qgs2DPlot::size() const
{
return mSize;
}
void Qgs2DPlot::setSize( QSizeF size )
{
mSize = size;
}
QRectF Qgs2DPlot::interiorPlotArea( QgsRenderContext & ) const
{
return QRectF( 0, 0, mSize.width(), mSize.height() );
}
const QgsMargins &Qgs2DPlot::margins() const
{
return mMargins;
}
void Qgs2DPlot::setMargins( const QgsMargins &margins )
{
mMargins = margins;
}
//
// Qgs2DPlot
//
Qgs2DXyPlot::Qgs2DXyPlot()
: Qgs2DPlot()
{
// setup default style
mChartBackgroundSymbol.reset( QgsPlotDefaultSettings::chartBackgroundSymbol() );
mChartBorderSymbol.reset( QgsPlotDefaultSettings::chartBorderSymbol() );
}
bool Qgs2DXyPlot::writeXml( QDomElement &element, QDomDocument &document, const QgsReadWriteContext &context ) const
{
Qgs2DPlot::writeXml( element, document, context );
element.setAttribute( QStringLiteral( "minX" ), qgsDoubleToString( mMinX ) );
element.setAttribute( QStringLiteral( "maxX" ), qgsDoubleToString( mMaxX ) );
element.setAttribute( QStringLiteral( "minY" ), qgsDoubleToString( mMinY ) );
@ -197,14 +267,12 @@ bool Qgs2DPlot::writeXml( QDomElement &element, QDomDocument &document, const Qg
borderElement.appendChild( QgsSymbolLayerUtils::saveSymbol( QString(), mChartBorderSymbol.get(), document, context ) );
element.appendChild( borderElement );
element.setAttribute( QStringLiteral( "margins" ), mMargins.toString() );
return true;
}
bool Qgs2DPlot::readXml( const QDomElement &element, const QgsReadWriteContext &context )
bool Qgs2DXyPlot::readXml( const QDomElement &element, const QgsReadWriteContext &context )
{
QgsPlot::readXml( element, context );
Qgs2DPlot::readXml( element, context );
mMinX = element.attribute( QStringLiteral( "minX" ) ).toDouble();
mMaxX = element.attribute( QStringLiteral( "maxX" ) ).toDouble();
@ -221,12 +289,10 @@ bool Qgs2DPlot::readXml( const QDomElement &element, const QgsReadWriteContext &
const QDomElement borderElement = element.firstChildElement( QStringLiteral( "borderSymbol" ) ).firstChildElement( QStringLiteral( "symbol" ) );
mChartBorderSymbol = QgsSymbolLayerUtils::loadSymbol< QgsFillSymbol >( borderElement, context );
mMargins = QgsMargins::fromString( element.attribute( QStringLiteral( "margins" ) ) );
return true;
}
void Qgs2DPlot::render( QgsRenderContext &context )
void Qgs2DXyPlot::render( QgsRenderContext &context )
{
QgsExpressionContextScope *plotScope = new QgsExpressionContextScope( QStringLiteral( "plot" ) );
const QgsExpressionContextScopePopper scopePopper( context.expressionContext(), plotScope );
@ -476,24 +542,9 @@ void Qgs2DPlot::render( QgsRenderContext &context )
mYAxis.gridMajorSymbol()->stopRender( context );
}
void Qgs2DPlot::renderContent( QgsRenderContext &, const QRectF & )
{
Qgs2DXyPlot::~Qgs2DXyPlot() = default;
}
Qgs2DPlot::~Qgs2DPlot() = default;
QSizeF Qgs2DPlot::size() const
{
return mSize;
}
void Qgs2DPlot::setSize( QSizeF size )
{
mSize = size;
}
QRectF Qgs2DPlot::interiorPlotArea( QgsRenderContext &context ) const
QRectF Qgs2DXyPlot::interiorPlotArea( QgsRenderContext &context ) const
{
QgsExpressionContextScope *plotScope = new QgsExpressionContextScope( QStringLiteral( "plot" ) );
const QgsExpressionContextScopePopper scopePopper( context.expressionContext(), plotScope );
@ -608,7 +659,7 @@ QRectF Qgs2DPlot::interiorPlotArea( QgsRenderContext &context ) const
return QRectF( leftMargin, topMargin, mSize.width() - rightMargin - leftMargin, mSize.height() - bottomMargin - topMargin );
}
void Qgs2DPlot::calculateOptimisedIntervals( QgsRenderContext &context )
void Qgs2DXyPlot::calculateOptimisedIntervals( QgsRenderContext &context )
{
if ( !mSize.isValid() )
return;
@ -743,36 +794,26 @@ void Qgs2DPlot::calculateOptimisedIntervals( QgsRenderContext &context )
}
}
QgsFillSymbol *Qgs2DPlot::chartBackgroundSymbol()
QgsFillSymbol *Qgs2DXyPlot::chartBackgroundSymbol()
{
return mChartBackgroundSymbol.get();
}
void Qgs2DPlot::setChartBackgroundSymbol( QgsFillSymbol *symbol )
void Qgs2DXyPlot::setChartBackgroundSymbol( QgsFillSymbol *symbol )
{
mChartBackgroundSymbol.reset( symbol );
}
QgsFillSymbol *Qgs2DPlot::chartBorderSymbol()
QgsFillSymbol *Qgs2DXyPlot::chartBorderSymbol()
{
return mChartBorderSymbol.get();
}
void Qgs2DPlot::setChartBorderSymbol( QgsFillSymbol *symbol )
void Qgs2DXyPlot::setChartBorderSymbol( QgsFillSymbol *symbol )
{
mChartBorderSymbol.reset( symbol );
}
const QgsMargins &Qgs2DPlot::margins() const
{
return mMargins;
}
void Qgs2DPlot::setMargins( const QgsMargins &margins )
{
mMargins = margins;
}
//
// QgsPlotDefaultSettings
//

View File

@ -261,9 +261,6 @@ class CORE_EXPORT QgsPlotAxis
/**
* \brief Base class for 2-dimensional plot/chart/graphs.
*
* The base class is responsible for rendering the axis, grid lines and chart area. Subclasses
* can implement the renderContent() method to render their actual plot content.
*
* \warning This class is not considered stable API, and may change in future!
*
* \ingroup core
@ -289,7 +286,7 @@ class CORE_EXPORT Qgs2DPlot : public QgsPlot
/**
* Renders the plot.
*/
void render( QgsRenderContext &context );
virtual void render( QgsRenderContext &context );
/**
* Renders the plot content.
@ -322,7 +319,72 @@ class CORE_EXPORT Qgs2DPlot : public QgsPlot
* Returns the area of the plot which corresponds to the actual plot content (excluding all titles and other components which sit
* outside the plot area).
*/
QRectF interiorPlotArea( QgsRenderContext &context ) const;
virtual QRectF interiorPlotArea( QgsRenderContext &context ) const;
/**
* Returns the margins of the plot area (in millimeters)
*
* \see setMargins()
*/
const QgsMargins &margins() const;
/**
* Sets the \a margins of the plot area (in millimeters)
*
* \see setMargins()
*/
void setMargins( const QgsMargins &margins );
private:
#ifdef SIP_RUN
Qgs2DPlot( const Qgs2DPlot &other );
#endif
QSizeF mSize;
QgsMargins mMargins;
friend class Qgs2DXyPlot;
};
/**
* \brief Base class for 2-dimensional plot/chart/graphs with an X and Y axes.
*
* The base class is responsible for rendering the axis, grid lines and chart area. Subclasses
* can implement the renderContent() method to render their actual plot content.
*
* \warning This class is not considered stable API, and may change in future!
*
* \ingroup core
* \since QGIS 3.26
*/
class CORE_EXPORT Qgs2DXyPlot : public Qgs2DPlot
{
public:
/**
* Constructor for Qgs2DXyPlot.
*/
Qgs2DXyPlot();
~Qgs2DXyPlot() override;
Qgs2DXyPlot( const Qgs2DXyPlot &other ) = delete;
Qgs2DXyPlot &operator=( const Qgs2DXyPlot &other ) = delete;
bool writeXml( QDomElement &element, QDomDocument &document, const QgsReadWriteContext &context ) const override;
bool readXml( const QDomElement &element, const QgsReadWriteContext &context ) override;
/**
* Renders the plot.
*/
void render( QgsRenderContext &context ) override;
/**
* Returns the area of the plot which corresponds to the actual plot content (excluding all titles and other components which sit
* outside the plot area).
*/
QRectF interiorPlotArea( QgsRenderContext &context ) const override;
/**
* Automatically sets the grid and label intervals to optimal values
@ -449,28 +511,12 @@ class CORE_EXPORT Qgs2DPlot : public QgsPlot
*/
void setChartBorderSymbol( QgsFillSymbol *symbol SIP_TRANSFER );
/**
* Returns the margins of the plot area (in millimeters)
*
* \see setMargins()
*/
const QgsMargins &margins() const;
/**
* Sets the \a margins of the plot area (in millimeters)
*
* \see setMargins()
*/
void setMargins( const QgsMargins &margins );
private:
#ifdef SIP_RUN
Qgs2DPlot( const Qgs2DPlot &other );
Qgs2DXyPlot( const Qgs2DXyPlot &other );
#endif
QSizeF mSize;
double mMinX = 0;
double mMinY = 0;
double mMaxX = 10;
@ -479,8 +525,6 @@ class CORE_EXPORT Qgs2DPlot : public QgsPlot
std::unique_ptr< QgsFillSymbol > mChartBackgroundSymbol;
std::unique_ptr< QgsFillSymbol > mChartBorderSymbol;
QgsMargins mMargins;
QgsPlotAxis mXAxis;
QgsPlotAxis mYAxis;
};

View File

@ -44,7 +44,7 @@
#include <QPalette>
///@cond PRIVATE
class QgsElevationProfilePlotItem : public Qgs2DPlot, public QgsPlotCanvasItem
class QgsElevationProfilePlotItem : public Qgs2DXyPlot, public QgsPlotCanvasItem
{
public:
QgsElevationProfilePlotItem( QgsElevationProfileCanvas *canvas )
@ -1382,13 +1382,13 @@ QgsDoubleRange QgsElevationProfileCanvas::visibleElevationRange() const
return QgsDoubleRange( mPlotItem->yMinimum(), mPlotItem->yMaximum() );
}
const Qgs2DPlot &QgsElevationProfileCanvas::plot() const
const Qgs2DXyPlot &QgsElevationProfileCanvas::plot() const
{
return *mPlotItem;
}
///@cond PRIVATE
class QgsElevationProfilePlot : public Qgs2DPlot
class QgsElevationProfilePlot : public Qgs2DXyPlot
{
public:
QgsElevationProfilePlot( QgsProfilePlotRenderer *renderer )
@ -1413,7 +1413,7 @@ class QgsElevationProfilePlot : public Qgs2DPlot
};
///@endcond PRIVATE
void QgsElevationProfileCanvas::render( QgsRenderContext &context, double width, double height, const Qgs2DPlot &plotSettings )
void QgsElevationProfileCanvas::render( QgsRenderContext &context, double width, double height, const Qgs2DXyPlot &plotSettings )
{
if ( !mCurrentJob )
return;

View File

@ -32,7 +32,7 @@ class QgsElevationProfileCrossHairsItem;
class QgsAbstractProfileResults;
class QgsProfilePlotRenderer;
class QgsCurve;
class Qgs2DPlot;
class Qgs2DXyPlot;
class QgsProfileSnapContext;
class QgsProfileIdentifyContext;
class QgsProfileIdentifyResults;
@ -192,12 +192,12 @@ class GUI_EXPORT QgsElevationProfileCanvas : public QgsPlotCanvas
*
* \note Not available in Python bindings
*/
const Qgs2DPlot &plot() const SIP_SKIP;
const Qgs2DXyPlot &plot() const SIP_SKIP;
/**
* Renders a portion of the profile using the specified render \a context.
*/
void render( QgsRenderContext &context, double width, double height, const Qgs2DPlot &plotSettings );
void render( QgsRenderContext &context, double width, double height, const Qgs2DXyPlot &plotSettings );
/**
* Identify results visible at the specified plot point.

View File

@ -38,7 +38,7 @@
///@cond PRIVATE
class QgsElevationProfilePlotItem : public Qgs2DPlot
class QgsElevationProfilePlotItem : public Qgs2DXyPlot
{
public:
explicit QgsElevationProfilePlotItem( QgsQuickElevationProfileCanvas *canvas )

View File

@ -14,7 +14,7 @@ from qgis.PyQt.QtCore import QDir, QSizeF, Qt
from qgis.PyQt.QtGui import QColor, QImage, QPainter
from qgis.PyQt.QtXml import QDomDocument
from qgis.core import (
Qgs2DPlot,
Qgs2DXyPlot,
QgsBasicNumericFormat,
QgsFillSymbol,
QgsFontUtils,
@ -40,7 +40,7 @@ class TestQgsPlot(QgisTestCase):
return "plot"
def testPlot(self):
plot = Qgs2DPlot()
plot = Qgs2DXyPlot()
plot.setSize(QSizeF(600, 500))
sym1 = QgsFillSymbol.createSimple({"color": "#fdbf6f", "outline_style": "no"})
@ -120,7 +120,7 @@ class TestQgsPlot(QgisTestCase):
self.assertAlmostEqual(plot_rect.bottom(), 465.55, delta=1)
def testPlotSuffixAll(self):
plot = Qgs2DPlot()
plot = Qgs2DXyPlot()
plot.setSize(QSizeF(600, 500))
sym1 = QgsFillSymbol.createSimple({"color": "#fdbf6f", "outline_style": "no"})
@ -207,7 +207,7 @@ class TestQgsPlot(QgisTestCase):
self.assertAlmostEqual(plot_rect.bottom(), 465.55, delta=1)
def testPlotSuffixFirst(self):
plot = Qgs2DPlot()
plot = Qgs2DXyPlot()
plot.setSize(QSizeF(600, 500))
sym1 = QgsFillSymbol.createSimple({"color": "#fdbf6f", "outline_style": "no"})
@ -294,7 +294,7 @@ class TestQgsPlot(QgisTestCase):
self.assertAlmostEqual(plot_rect.bottom(), 465.55, delta=1)
def testPlotSuffixLast(self):
plot = Qgs2DPlot()
plot = Qgs2DXyPlot()
plot.setSize(QSizeF(600, 500))
sym1 = QgsFillSymbol.createSimple({"color": "#fdbf6f", "outline_style": "no"})
@ -381,7 +381,7 @@ class TestQgsPlot(QgisTestCase):
self.assertAlmostEqual(plot_rect.bottom(), 465.55, delta=1)
def testPlotSuffixFirstAndLast(self):
plot = Qgs2DPlot()
plot = Qgs2DXyPlot()
plot.setSize(QSizeF(600, 500))
sym1 = QgsFillSymbol.createSimple({"color": "#fdbf6f", "outline_style": "no"})
@ -474,7 +474,7 @@ class TestQgsPlot(QgisTestCase):
self.assertAlmostEqual(plot_rect.bottom(), 465.55, delta=1)
def testPlotIntervals(self):
plot = Qgs2DPlot()
plot = Qgs2DXyPlot()
plot.setSize(QSizeF(600, 500))
sym1 = QgsFillSymbol.createSimple({"color": "#fdbf6f", "outline_style": "no"})
@ -546,7 +546,7 @@ class TestQgsPlot(QgisTestCase):
assert self.image_check("plot_2d_intervals", "plot_2d_intervals", im)
def testPlotDataDefinedProperties(self):
plot = Qgs2DPlot()
plot = Qgs2DXyPlot()
plot.setSize(QSizeF(600, 500))
sym1 = QgsFillSymbol.createSimple({"color": "#ffffff", "outline_style": "no"})
@ -651,7 +651,7 @@ class TestQgsPlot(QgisTestCase):
self.assertAlmostEqual(plot_rect.bottom(), 465.55, delta=1)
def testOptimiseIntervals(self):
plot = Qgs2DPlot()
plot = Qgs2DXyPlot()
plot.setSize(QSizeF(600, 500))
font = QgsFontUtils.getStandardTestFont("Bold", 16)
@ -732,7 +732,7 @@ class TestQgsPlot(QgisTestCase):
self.assertEqual(plot.xAxis().gridIntervalMajor(), 200000)
def test_read_write(self):
plot = Qgs2DPlot()
plot = Qgs2DXyPlot()
plot.setSize(QSizeF(600, 500))
sym1 = QgsFillSymbol.createSimple({"color": "#fdbf6f", "outline_style": "no"})
@ -812,7 +812,7 @@ class TestQgsPlot(QgisTestCase):
elem = doc.createElement("test")
plot.writeXml(elem, doc, QgsReadWriteContext())
res = Qgs2DPlot()
res = Qgs2DXyPlot()
self.assertTrue(res.readXml(elem, QgsReadWriteContext()))
self.assertEqual(res.xMinimum(), 3)