Skip to content

Commit

Permalink
[FEATURE][diagrams] New diagram type "stacked bars"
Browse files Browse the repository at this point in the history
Stacks bars of varying colors for each attribute on top of each other
vertically or horizontally.

Sponsored by SLYR
  • Loading branch information
nyalldawson committed Nov 24, 2019
1 parent ec9e598 commit 204bd47
Show file tree
Hide file tree
Showing 21 changed files with 535 additions and 36 deletions.
23 changes: 12 additions & 11 deletions images/images.qrc
Expand Up @@ -88,12 +88,12 @@
<file>themes/default/algorithms/mAlgorithmCollect.svg</file>
<file>themes/default/algorithms/mAlgorithmConvexHull.svg</file>
<file>themes/default/algorithms/mAlgorithmCreateGrid.svg</file>
<file>themes/default/algorithms/mAlgorithmFuzzifyLinear.svg</file>
<file>themes/default/algorithms/mAlgorithmFuzzifyPower.svg</file>
<file>themes/default/algorithms/mAlgorithmFuzzifyLarge.svg</file>
<file>themes/default/algorithms/mAlgorithmFuzzifySmall.svg</file>
<file>themes/default/algorithms/mAlgorithmFuzzifyGaussian.svg</file>
<file>themes/default/algorithms/mAlgorithmFuzzifyNear.svg</file>
<file>themes/default/algorithms/mAlgorithmFuzzifyLinear.svg</file>
<file>themes/default/algorithms/mAlgorithmFuzzifyPower.svg</file>
<file>themes/default/algorithms/mAlgorithmFuzzifyLarge.svg</file>
<file>themes/default/algorithms/mAlgorithmFuzzifySmall.svg</file>
<file>themes/default/algorithms/mAlgorithmFuzzifyGaussian.svg</file>
<file>themes/default/algorithms/mAlgorithmFuzzifyNear.svg</file>
<file>themes/default/algorithms/mAlgorithmDelaunay.svg</file>
<file>themes/default/algorithms/mAlgorithmDifference.svg</file>
<file>themes/default/algorithms/mAlgorithmDissolve.svg</file>
Expand Down Expand Up @@ -427,7 +427,7 @@
<file>themes/default/mActionZoomToLayer.svg</file>
<file>themes/default/mActionZoomToSelected.svg</file>
<file>themes/default/mActionFilterTableFields.svg</file>
<file>themes/default/mActionFirst.svg</file>
<file>themes/default/mActionFirst.svg</file>
<file>themes/default/mIconAtlas.svg</file>
<file>themes/default/mIconAutoPlacementSettings.svg</file>
<file>themes/default/mIconCertificate.svg</file>
Expand Down Expand Up @@ -626,16 +626,16 @@
<file>themes/default/user.svg</file>
<file>themes/default/mIconAuxiliaryStorage.svg</file>
<file>themes/default/relation.svg</file>
<file>themes/default/mActionLast.svg</file>
<file>themes/default/mActionLast.svg</file>
<file>themes/default/mActionLink.svg</file>
<file>themes/default/mActionUnlink.svg</file>
<file>themes/default/mActionZoomToArea.svg</file>
<file>themes/default/mActionMapIdentification.svg</file>
<file>themes/default/mActionHighlightFeature.svg</file>
<file>themes/default/mActionScaleHighlightFeature.svg</file>
<file>themes/default/mActionPanHighlightFeature.svg</file>
<file>themes/default/mActionPrevious.svg</file>
<file>themes/default/mActionPlay.svg</file>
<file>themes/default/mActionPrevious.svg</file>
<file>themes/default/mActionPlay.svg</file>
<file>themes/default/cadtools/construction.svg</file>
<file>themes/default/cadtools/delta.svg</file>
<file>themes/default/cadtools/floater.svg</file>
Expand Down Expand Up @@ -698,7 +698,7 @@
<file>themes/default/search.svg</file>
<file>themes/default/mActionNew3DMap.svg</file>
<file>themes/default/mActionNewMap.svg</file>
<file>themes/default/mActionNext.svg</file>
<file>themes/default/mActionNext.svg</file>
<file>themes/default/mActionMapSettings.svg</file>
<file>themes/default/mActionLockExtent.svg</file>
<file>themes/default/mGeoPackage.svg</file>
Expand Down Expand Up @@ -797,6 +797,7 @@
<file>themes/default/mActionShowUnplacedLabel.svg</file>
<file>themes/default/mActionHandleStoreFilterExpressionChecked.svg</file>
<file>themes/default/mActionHandleStoreFilterExpressionUnchecked.svg</file>
<file>themes/default/stacked-bar.svg</file>
</qresource>
<qresource prefix="/images/tips">
<file alias="symbol_levels.png">qgis_tips/symbol_levels.png</file>
Expand Down
1 change: 1 addition & 0 deletions images/themes/default/stacked-bar.svg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
13 changes: 13 additions & 0 deletions python/core/auto_generated/diagram/qgsdiagram.sip.in
Expand Up @@ -20,6 +20,19 @@ Base class for all diagram types*
%End
public:

%ConvertToSubClassCode
if ( sipCpp->diagramName() == QStringLiteral( "Pie" ) )
sipType = sipType_QgsPieDiagram;
else if ( sipCpp->diagramName() == QStringLiteral( "Histogram" ) )
sipType = sipType_QgsHistogramDiagram;
else if ( sipCpp->diagramName() == QStringLiteral( "Text" ) )
sipType = sipType_QgsTextDiagram;
else if ( sipCpp->diagramName() == QStringLiteral( "Stacked" ) )
sipType = sipType_QgsStackedBarDiagram;
else
sipType = NULL;
%End

virtual ~QgsDiagram();

virtual QgsDiagram *clone() const = 0 /Factory/;
Expand Down
53 changes: 53 additions & 0 deletions python/core/auto_generated/diagram/qgsstackedbardiagram.sip.in
@@ -0,0 +1,53 @@
/************************************************************************
* This file has been generated automatically from *
* *
* src/core/diagram/qgsstackedbardiagram.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
************************************************************************/






class QgsStackedBarDiagram: QgsDiagram
{
%Docstring

A stacked bar chart diagram.

.. versionadded:: 3.12
%End

%TypeHeaderCode
#include "qgsstackedbardiagram.h"
%End
public:
QgsStackedBarDiagram();

virtual QgsStackedBarDiagram *clone() const /Factory/;


virtual void renderDiagram( const QgsFeature &feature, QgsRenderContext &c, const QgsDiagramSettings &s, QPointF position );


virtual QSizeF diagramSize( const QgsAttributes &attributes, const QgsRenderContext &c, const QgsDiagramSettings &s );

virtual QSizeF diagramSize( const QgsFeature &feature, const QgsRenderContext &c, const QgsDiagramSettings &s, const QgsDiagramInterpolationSettings &is );

virtual double legendSize( double value, const QgsDiagramSettings &s, const QgsDiagramInterpolationSettings &is ) const;

virtual QString diagramName() const;


};


/************************************************************************
* This file has been generated automatically from *
* *
* src/core/diagram/qgsstackedbardiagram.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
************************************************************************/
1 change: 1 addition & 0 deletions python/core/core_auto.sip
Expand Up @@ -252,6 +252,7 @@
%Include auto_generated/diagram/qgsdiagram.sip
%Include auto_generated/diagram/qgshistogramdiagram.sip
%Include auto_generated/diagram/qgspiediagram.sip
%Include auto_generated/diagram/qgsstackedbardiagram.sip
%Include auto_generated/diagram/qgstextdiagram.sip
%Include auto_generated/dxf/qgsdxfexport.sip
%Include auto_generated/effects/qgsblureffect.sip
Expand Down
34 changes: 21 additions & 13 deletions src/app/qgsdiagramproperties.cpp
Expand Up @@ -18,6 +18,7 @@
#include "diagram/qgshistogramdiagram.h"
#include "diagram/qgspiediagram.h"
#include "diagram/qgstextdiagram.h"
#include "diagram/qgsstackedbardiagram.h"

#include "qgsproject.h"
#include "qgsapplication.h"
Expand Down Expand Up @@ -92,13 +93,15 @@ QgsDiagramProperties::QgsDiagramProperties( QgsVectorLayer *layer, QWidget *pare

mDiagramTypeComboBox->blockSignals( true );
QPixmap pix = QgsApplication::getThemePixmap( QStringLiteral( "diagramNone" ) );
mDiagramTypeComboBox->addItem( pix, tr( "No diagrams" ), "None" );
mDiagramTypeComboBox->addItem( pix, tr( "No Diagrams" ), "None" );
pix = QgsApplication::getThemePixmap( QStringLiteral( "pie-chart" ) );
mDiagramTypeComboBox->addItem( pix, tr( "Pie chart" ), DIAGRAM_NAME_PIE );
mDiagramTypeComboBox->addItem( pix, tr( "Pie Chart" ), DIAGRAM_NAME_PIE );
pix = QgsApplication::getThemePixmap( QStringLiteral( "text" ) );
mDiagramTypeComboBox->addItem( pix, tr( "Text diagram" ), DIAGRAM_NAME_TEXT );
mDiagramTypeComboBox->addItem( pix, tr( "Text Diagram" ), DIAGRAM_NAME_TEXT );
pix = QgsApplication::getThemePixmap( QStringLiteral( "histogram" ) );
mDiagramTypeComboBox->addItem( pix, tr( "Histogram" ), DIAGRAM_NAME_HISTOGRAM );
pix = QgsApplication::getThemePixmap( QStringLiteral( "stacked-bar" ) );
mDiagramTypeComboBox->addItem( pix, tr( "Stacked Bars" ), DIAGRAM_NAME_STACKED );
mDiagramTypeComboBox->blockSignals( false );

mAxisLineStyleButton->setSymbolType( QgsSymbol::Line );
Expand Down Expand Up @@ -549,7 +552,7 @@ void QgsDiagramProperties::mDiagramTypeComboBox_currentIndexChanged( int index )
mDiagramFontButton->hide();
}

if ( DIAGRAM_NAME_HISTOGRAM == mDiagramType )
if ( DIAGRAM_NAME_HISTOGRAM == mDiagramType || DIAGRAM_NAME_STACKED == mDiagramType )
{
mBarWidthLabel->show();
mBarWidthSpinBox->show();
Expand All @@ -558,9 +561,10 @@ void QgsDiagramProperties::mDiagramTypeComboBox_currentIndexChanged( int index )
mBarSpacingUnitComboBox->show();
mBarOptionsFrame->show();
mShowAxisGroupBox->show();
mAttributeBasedScalingRadio->setChecked( true );
mFixedSizeRadio->setEnabled( false );
mDiagramSizeSpinBox->setEnabled( false );
if ( DIAGRAM_NAME_HISTOGRAM == mDiagramType )
mAttributeBasedScalingRadio->setChecked( true );
mFixedSizeRadio->setEnabled( DIAGRAM_NAME_STACKED == mDiagramType );
mDiagramSizeSpinBox->setEnabled( DIAGRAM_NAME_STACKED == mDiagramType );
mLinearlyScalingLabel->setText( tr( "Bar length: Scale linearly, so that the following value matches the specified bar length:" ) );
mSizeLabel->setText( tr( "Bar length" ) );
mFrameIncreaseSize->setVisible( false );
Expand Down Expand Up @@ -748,7 +752,7 @@ void QgsDiagramProperties::apply()
int index = mDiagramTypeComboBox->currentIndex();
bool diagramsEnabled = ( index != 0 );

QgsDiagram *diagram = nullptr;
std::unique_ptr< QgsDiagram > diagram;

if ( diagramsEnabled && 0 == mDiagramAttributesTreeWidget->topLevelItemCount() )
{
Expand All @@ -760,15 +764,19 @@ void QgsDiagramProperties::apply()

if ( mDiagramType == DIAGRAM_NAME_TEXT )
{
diagram = new QgsTextDiagram();
diagram = qgis::make_unique< QgsTextDiagram >();
}
else if ( mDiagramType == DIAGRAM_NAME_PIE )
{
diagram = new QgsPieDiagram();
diagram = qgis::make_unique< QgsPieDiagram >();
}
else if ( mDiagramType == DIAGRAM_NAME_STACKED )
{
diagram = qgis::make_unique< QgsStackedBarDiagram >();
}
else // if ( diagramType == DIAGRAM_NAME_HISTOGRAM )
{
diagram = new QgsHistogramDiagram();
diagram = qgis::make_unique< QgsHistogramDiagram >();
}

QgsDiagramSettings ds;
Expand Down Expand Up @@ -799,7 +807,7 @@ void QgsDiagramProperties::apply()
ds.lineSizeUnit = mDiagramLineUnitComboBox->unit();
ds.lineSizeScale = mDiagramLineUnitComboBox->getMapUnitScale();
ds.labelPlacementMethod = static_cast<QgsDiagramSettings::LabelPlacementMethod>( mLabelPlacementComboBox->currentData().toInt() );
ds.scaleByArea = mScaleDependencyComboBox->currentData().toBool();
ds.scaleByArea = ( mDiagramType == DIAGRAM_NAME_STACKED ) ? false : mScaleDependencyComboBox->currentData().toBool();

if ( mIncreaseSmallDiagramsCheck->isChecked() )
{
Expand Down Expand Up @@ -865,7 +873,7 @@ void QgsDiagramProperties::apply()

renderer = dr;
}
renderer->setDiagram( diagram );
renderer->setDiagram( diagram.release() );
renderer->setAttributeLegend( mCheckBoxAttributeLegend->isChecked() );
mLayer->setDiagramRenderer( renderer );

Expand Down
2 changes: 2 additions & 0 deletions src/core/CMakeLists.txt
Expand Up @@ -76,6 +76,7 @@ SET(QGIS_CORE_SRCS
diagram/qgsdiagram.cpp
diagram/qgshistogramdiagram.cpp
diagram/qgspiediagram.cpp
diagram/qgsstackedbardiagram.cpp
diagram/qgstextdiagram.cpp

effects/qgsblureffect.cpp
Expand Down Expand Up @@ -944,6 +945,7 @@ SET(QGIS_CORE_HDRS
diagram/qgsdiagram.h
diagram/qgshistogramdiagram.h
diagram/qgspiediagram.h
diagram/qgsstackedbardiagram.h
diagram/qgstextdiagram.h

dxf/qgsdxfexport.h
Expand Down
15 changes: 15 additions & 0 deletions src/core/diagram/qgsdiagram.h
Expand Up @@ -39,6 +39,21 @@ class CORE_EXPORT QgsDiagram
{
public:

#ifdef SIP_RUN
SIP_CONVERT_TO_SUBCLASS_CODE
if ( sipCpp->diagramName() == QStringLiteral( "Pie" ) )
sipType = sipType_QgsPieDiagram;
else if ( sipCpp->diagramName() == QStringLiteral( "Histogram" ) )
sipType = sipType_QgsHistogramDiagram;
else if ( sipCpp->diagramName() == QStringLiteral( "Text" ) )
sipType = sipType_QgsTextDiagram;
else if ( sipCpp->diagramName() == QStringLiteral( "Stacked" ) )
sipType = sipType_QgsStackedBarDiagram;
else
sipType = NULL;
SIP_END
#endif

virtual ~QgsDiagram() { clearCache(); }

/**
Expand Down

0 comments on commit 204bd47

Please sign in to comment.