diff --git a/python/PyQt6/core/auto_generated/diagram/qgsstackeddiagram.sip.in b/python/PyQt6/core/auto_generated/diagram/qgsstackeddiagram.sip.in index fd4ba4c8401..1bd55e57d8e 100644 --- a/python/PyQt6/core/auto_generated/diagram/qgsstackeddiagram.sip.in +++ b/python/PyQt6/core/auto_generated/diagram/qgsstackeddiagram.sip.in @@ -46,9 +46,12 @@ Adds a subdiagram to the stacked diagram object along with its corresponding set or more to the top (if stacked diagram is vertical). %End - QList< QgsDiagram * > subDiagrams() const; + QList< QgsDiagram * > subDiagrams( const QgsDiagramSettings &s ) const; %Docstring Returns an ordered list with the subdiagrams of the stacked diagram object. +If the stacked diagram orientation is vertical, the list is returned backwards. + +:param s: stacked diagram settings %End QgsDiagramSettings *subDiagramSettings( const QgsDiagram *diagram ) const; diff --git a/python/core/auto_generated/diagram/qgsstackeddiagram.sip.in b/python/core/auto_generated/diagram/qgsstackeddiagram.sip.in index fd4ba4c8401..1bd55e57d8e 100644 --- a/python/core/auto_generated/diagram/qgsstackeddiagram.sip.in +++ b/python/core/auto_generated/diagram/qgsstackeddiagram.sip.in @@ -46,9 +46,12 @@ Adds a subdiagram to the stacked diagram object along with its corresponding set or more to the top (if stacked diagram is vertical). %End - QList< QgsDiagram * > subDiagrams() const; + QList< QgsDiagram * > subDiagrams( const QgsDiagramSettings &s ) const; %Docstring Returns an ordered list with the subdiagrams of the stacked diagram object. +If the stacked diagram orientation is vertical, the list is returned backwards. + +:param s: stacked diagram settings %End QgsDiagramSettings *subDiagramSettings( const QgsDiagram *diagram ) const; diff --git a/src/core/diagram/qgsstackeddiagram.cpp b/src/core/diagram/qgsstackeddiagram.cpp index d20c4b2e2b4..ef747fb8ecf 100644 --- a/src/core/diagram/qgsstackeddiagram.cpp +++ b/src/core/diagram/qgsstackeddiagram.cpp @@ -38,12 +38,26 @@ void QgsStackedDiagram::addSubDiagram( QgsDiagram *diagram, QgsDiagramSettings * mSubDiagrams.append( DiagramData{diagram, s} ); } -QList< QgsDiagram * > QgsStackedDiagram::subDiagrams() const +QList< QgsDiagram * > QgsStackedDiagram::subDiagrams( const QgsDiagramSettings &s ) const { QList< QgsDiagram * > diagrams; - for ( const auto &item : std::as_const( mSubDiagrams ) ) + + if ( s.stackedDiagramMode == QgsDiagramSettings::Horizontal ) { - diagrams.append( item.diagram ); + for ( const auto &item : std::as_const( mSubDiagrams ) ) + { + diagrams.append( item.diagram ); + } + } + else + { + // We'll draw vertical diagrams backwards, + // so we return the subdiagrams in reverse order + QList< DiagramData >::const_reverse_iterator iter = mSubDiagrams.rbegin(); + for ( ; iter != mSubDiagrams.rend(); ++iter ) + { + diagrams.append( iter->diagram ); + } } return diagrams; } @@ -71,7 +85,7 @@ void QgsStackedDiagram::subDiagramPosition( QPointF &newPos, const QgsRenderCont } else { - newPos += QPointF( 0, size.height() + spacing ); + newPos -= QPointF( 0, size.height() + spacing ); } } diff --git a/src/core/diagram/qgsstackeddiagram.h b/src/core/diagram/qgsstackeddiagram.h index d26181fcbee..7c80a29f099 100644 --- a/src/core/diagram/qgsstackeddiagram.h +++ b/src/core/diagram/qgsstackeddiagram.h @@ -62,8 +62,12 @@ class CORE_EXPORT QgsStackedDiagram : public QgsDiagram SIP_NODEFAULTCTORS */ void addSubDiagram( QgsDiagram *diagram, QgsDiagramSettings *s ); - //! Returns an ordered list with the subdiagrams of the stacked diagram object. - QList< QgsDiagram * > subDiagrams() const; + /** + * Returns an ordered list with the subdiagrams of the stacked diagram object. + * If the stacked diagram orientation is vertical, the list is returned backwards. + * \param s stacked diagram settings + */ + QList< QgsDiagram * > subDiagrams( const QgsDiagramSettings &s ) const; //! Returns the settings associated to the \a diagram. QgsDiagramSettings *subDiagramSettings( const QgsDiagram *diagram ) const; diff --git a/src/core/qgsdiagramrenderer.cpp b/src/core/qgsdiagramrenderer.cpp index 760068a9fb8..3673a911b59 100644 --- a/src/core/qgsdiagramrenderer.cpp +++ b/src/core/qgsdiagramrenderer.cpp @@ -507,7 +507,7 @@ void QgsDiagramRenderer::renderDiagram( const QgsFeature &feature, QgsRenderCont { // Iterate subdiagrams and render them individually QgsStackedDiagram *stackedDiagram = qgis::down_cast< QgsStackedDiagram *>( mDiagram.get() ); - QList< QgsDiagram * > subDiagrams = stackedDiagram->subDiagrams(); + QList< QgsDiagram * > subDiagrams = stackedDiagram->subDiagrams( s ); QPointF newPos = pos; // Each subdiagram will have its own newPos for ( const auto &subDiagram : std::as_const( subDiagrams ) ) diff --git a/tests/src/core/testqgsstackeddiagram.cpp b/tests/src/core/testqgsstackeddiagram.cpp index 28afa7af617..52d45cd550d 100644 --- a/tests/src/core/testqgsstackeddiagram.cpp +++ b/tests/src/core/testqgsstackeddiagram.cpp @@ -194,6 +194,84 @@ class TestQgsStackedDiagram : public QgsTest QGSVERIFYRENDERMAPSETTINGSCHECK( "stackedhistograms", "stackedhistograms", *mMapSettings, 200, 15 ); } + void testVerticallyStackedHistograms() + { + // Histogram 1 + QgsDiagramSettings ds1; + QColor col1 = Qt::blue; + QColor col2 = Qt::red; + QColor col3 = Qt::yellow; + QColor col4 = Qt::green; + col1.setAlphaF( 0.5 ); + col2.setAlphaF( 0.5 ); + col3.setAlphaF( 0.5 ); + col4.setAlphaF( 0.5 ); + ds1.categoryColors = QList() << col1 << col2 << col3 << col4; + ds1.categoryAttributes = QList() << QStringLiteral( "\"maennlich_ab_65\"" ) << QStringLiteral( "\"maennlich_18_64\"" ) << QStringLiteral( "\"maennlich_6_17\"" ) << QStringLiteral( "\"maennlich_unter_6\"" ); //#spellok + ds1.minimumScale = -1; + ds1.maximumScale = -1; + ds1.minimumSize = 0; + ds1.penColor = Qt::black; + ds1.penWidth = .5; + ds1.scaleByArea = true; + ds1.sizeType = Qgis::RenderUnit::Millimeters; + ds1.rotationOffset = 0; + ds1.diagramOrientation = QgsDiagramSettings::Up; + + // Histogram 2 + QgsDiagramSettings ds2; + col1 = Qt::blue; + col2 = Qt::red; + col3 = Qt::yellow; + col4 = Qt::green; + col1.setAlphaF( 0.5 ); + col2.setAlphaF( 0.5 ); + col3.setAlphaF( 0.5 ); + col4.setAlphaF( 0.5 ); + ds2.categoryColors = QList() << col1 << col2 << col3 << col4; + ds2.categoryAttributes = QList() << QStringLiteral( "\"weiblich_ab_65\"" ) << QStringLiteral( "\"weiblich_18_64\"" ) << QStringLiteral( "\"weiblich_6_17\"" ) << QStringLiteral( "\"weiblich_unter_6\"" ); //#spellok + ds2.minimumScale = -1; + ds2.maximumScale = -1; + ds2.minimumSize = 0; + ds2.penColor = Qt::black; + ds2.penWidth = .5; + ds2.scaleByArea = true; + ds2.sizeType = Qgis::RenderUnit::Millimeters; + ds2.rotationOffset = 0; + ds2.diagramOrientation = QgsDiagramSettings::Down; + + QgsDiagramSettings ds; + ds.stackedDiagramMode = QgsDiagramSettings::Vertical; + ds.categoryAttributes = ds1.categoryAttributes + ds2.categoryAttributes; + ds.setStackedDiagramSpacingUnit( Qgis::RenderUnit::Pixels ); + ds.setStackedDiagramSpacing( 0 ); + + QgsStackedDiagram *stackedDiagram = new QgsStackedDiagram(); + stackedDiagram->addSubDiagram( new QgsHistogramDiagram(), &ds1 ); + stackedDiagram->addSubDiagram( new QgsHistogramDiagram(), &ds2 ); + + QgsLinearlyInterpolatedDiagramRenderer *dr = new QgsLinearlyInterpolatedDiagramRenderer(); + dr->setLowerValue( 0.0 ); + dr->setLowerSize( QSizeF( 0.0, 0.0 ) ); + dr->setUpperValue( 15000 ); + dr->setUpperSize( QSizeF( 20, 20 ) ); + dr->setClassificationField( QStringLiteral( "max(\"maennlich_18_64\", \"maennlich_ab_65\", \"weiblich_unter_6\", \"weiblich_6_17\", \"weiblich_18_64\", \"weiblich_ab_65\")" ) ); //#spellok + dr->setDiagram( stackedDiagram ); + dr->setDiagramSettings( ds ); + mPointsLayer->setDiagramRenderer( dr ); + + QgsDiagramLayerSettings dls = QgsDiagramLayerSettings(); + dls.setPlacement( QgsDiagramLayerSettings::OverPoint ); + dls.setShowAllDiagrams( true ); + mPointsLayer->setDiagramLayerSettings( dls ); + + const QgsRectangle extent( 9.7, 53.5, 9.95, 53.6 ); + mMapSettings->setExtent( extent ); + mMapSettings->setFlag( Qgis::MapSettingsFlag::ForceVectorOutput ); + mMapSettings->setOutputDpi( 96 ); + QGSVERIFYRENDERMAPSETTINGSCHECK( "verticallystackedhistograms", "verticallystackedhistograms", *mMapSettings, 200, 15 ); + } + void testStackedHistogramsWithSpacing() { // Histogram 1 diff --git a/tests/testdata/control_images/stackeddiagrams/expected_stackedpies/expected_stackedpies.png b/tests/testdata/control_images/stackeddiagrams/expected_stackedpies/expected_stackedpies.png index 81734c2708e..3307b5d44f9 100644 Binary files a/tests/testdata/control_images/stackeddiagrams/expected_stackedpies/expected_stackedpies.png and b/tests/testdata/control_images/stackeddiagrams/expected_stackedpies/expected_stackedpies.png differ diff --git a/tests/testdata/control_images/stackeddiagrams/expected_verticallystackedhistograms/expected_verticallystackedhistograms.png b/tests/testdata/control_images/stackeddiagrams/expected_verticallystackedhistograms/expected_verticallystackedhistograms.png new file mode 100644 index 00000000000..8a220665115 Binary files /dev/null and b/tests/testdata/control_images/stackeddiagrams/expected_verticallystackedhistograms/expected_verticallystackedhistograms.png differ