Skip to content

Commit

Permalink
[FEATURE][diagrams] Add option to control pie diagram angular direction
Browse files Browse the repository at this point in the history
I.e. control whether the sections are rendered in a clockwise or
anticlockwise direction

Sponsored by SLYR
  • Loading branch information
nyalldawson committed Nov 21, 2019
1 parent 701ea05 commit baf3819
Show file tree
Hide file tree
Showing 21 changed files with 238 additions and 110 deletions.
24 changes: 24 additions & 0 deletions python/core/auto_generated/qgsdiagramrenderer.sip.in
Expand Up @@ -366,6 +366,12 @@ QgsDiagramLayerSettings stores settings which control how ALL diagrams within a
Right
};

enum Direction
{
Clockwise,
Counterclockwise,
};

QgsDiagramSettings();
%Docstring
Constructor for QgsDiagramSettings
Expand Down Expand Up @@ -486,6 +492,24 @@ Returns the map unit scale for the content spacing.

.. seealso:: :py:func:`spacingUnit`

.. versionadded:: 3.12
%End

Direction direction() const;
%Docstring
Returns the chart's angular direction.

.. seealso:: :py:func:`setDirection`

.. versionadded:: 3.12
%End

void setDirection( Direction direction );
%Docstring
Sets the chart's angular ``direction``.

.. seealso:: :py:func:`direction`

.. versionadded:: 3.12
%End

Expand Down
9 changes: 9 additions & 0 deletions src/app/qgsdiagramproperties.cpp
Expand Up @@ -192,6 +192,9 @@ QgsDiagramProperties::QgsDiagramProperties( QgsVectorLayer *layer, QWidget *pare
mAngleOffsetComboBox->addItem( tr( "Bottom" ), 90 );
mAngleOffsetComboBox->addItem( tr( "Left" ), 180 );

mAngleDirectionComboBox->addItem( tr( "Clockwise" ), QgsDiagramSettings::Clockwise );
mAngleDirectionComboBox->addItem( tr( "Counter-clockwise" ), QgsDiagramSettings::Counterclockwise );

QgsSettings settings;

// reset horiz stretch of left side of options splitter (set to 1 for previewing in Qt Designer)
Expand Down Expand Up @@ -320,6 +323,7 @@ QgsDiagramProperties::QgsDiagramProperties( QgsVectorLayer *layer, QWidget *pare
}

mAngleOffsetComboBox->setCurrentIndex( mAngleOffsetComboBox->findData( settingList.at( 0 ).rotationOffset ) );
mAngleDirectionComboBox->setCurrentIndex( mAngleDirectionComboBox->findData( settingList.at( 0 ).direction() ) );

mOrientationLeftButton->setProperty( "direction", QgsDiagramSettings::Left );
mOrientationRightButton->setProperty( "direction", QgsDiagramSettings::Right );
Expand Down Expand Up @@ -582,12 +586,16 @@ void QgsDiagramProperties::mDiagramTypeComboBox_currentIndexChanged( int index )
if ( DIAGRAM_NAME_PIE == mDiagramType )
{
mAngleOffsetComboBox->show();
mAngleDirectionComboBox->show();
mAngleDirectionLabel->show();
mAngleOffsetLabel->show();
mStartAngleDDBtn->show();
}
else
{
mAngleOffsetComboBox->hide();
mAngleDirectionComboBox->hide();
mAngleDirectionLabel->hide();
mAngleOffsetLabel->hide();
mStartAngleDDBtn->hide();
}
Expand Down Expand Up @@ -801,6 +809,7 @@ void QgsDiagramProperties::apply()

// Diagram angle offset (pie)
ds.rotationOffset = mAngleOffsetComboBox->currentData().toInt();
ds.setDirection( static_cast< QgsDiagramSettings::Direction>( mAngleDirectionComboBox->currentData().toInt() ) );

// Diagram orientation (histogram)
ds.diagramOrientation = static_cast<QgsDiagramSettings::DiagramOrientation>( mOrientationButtonGroup->checkedButton()->property( "direction" ).toInt() );
Expand Down
8 changes: 4 additions & 4 deletions src/core/diagram/qgspiediagram.cpp
Expand Up @@ -133,17 +133,17 @@ void QgsPieDiagram::renderDiagram( const QgsFeature &feature, QgsRenderContext &
{
if ( *valIt )
{
currentAngle = *valIt / valSum * 360 * 16;
currentAngle = ( *valIt / valSum * 360 * 16 ) * ( s.direction() == QgsDiagramSettings::Clockwise ? -1 : 1 );
mCategoryBrush.setColor( *colIt );
p->setBrush( mCategoryBrush );
// if only 1 value is > 0, draw a circle
if ( valCount == 1 )
{
p->drawEllipse( baseX, baseY, w, h );
p->drawEllipse( QRectF( baseX, baseY, w, h ) );
}
else
{
p->drawPie( baseX, baseY, w, h, totalAngle - s.rotationOffset * 16.0, currentAngle );
p->drawPie( QRectF( baseX, baseY, w, h ), totalAngle - s.rotationOffset * 16.0, currentAngle );
}
totalAngle += currentAngle;
}
Expand All @@ -154,6 +154,6 @@ void QgsPieDiagram::renderDiagram( const QgsFeature &feature, QgsRenderContext &
// draw empty circle if no values are defined at all
mCategoryBrush.setColor( Qt::transparent );
p->setBrush( mCategoryBrush );
p->drawEllipse( baseX, baseY, w, h );
p->drawEllipse( QRectF( baseX, baseY, w, h ) );
}
}
13 changes: 13 additions & 0 deletions src/core/qgsdiagramrenderer.cpp
Expand Up @@ -192,6 +192,8 @@ void QgsDiagramSettings::readXml( const QDomElement &elem )
penColor.setAlpha( penAlpha );
penWidth = elem.attribute( QStringLiteral( "penWidth" ) ).toDouble();

mDirection = static_cast< Direction >( elem.attribute( QStringLiteral( "direction" ), QStringLiteral( "1" ) ).toInt() );

maximumScale = elem.attribute( QStringLiteral( "minScaleDenominator" ), QStringLiteral( "-1" ) ).toDouble();
minimumScale = elem.attribute( QStringLiteral( "maxScaleDenominator" ), QStringLiteral( "-1" ) ).toDouble();
if ( elem.hasAttribute( QStringLiteral( "scaleBasedVisibility" ) ) )
Expand Down Expand Up @@ -334,6 +336,7 @@ void QgsDiagramSettings::writeXml( QDomElement &rendererElem, QDomDocument &doc
categoryElem.setAttribute( QStringLiteral( "spacing" ), QString::number( mSpacing ) );
categoryElem.setAttribute( QStringLiteral( "spacingUnit" ), QgsUnitTypes::encodeUnit( mSpacingUnit ) );
categoryElem.setAttribute( QStringLiteral( "spacingUnitScale" ), QgsSymbolLayerUtils::encodeMapUnitScale( mSpacingMapUnitScale ) );
categoryElem.setAttribute( QStringLiteral( "direction" ), QString::number( mDirection ) );

//diagram size unit type and scale
categoryElem.setAttribute( QStringLiteral( "sizeType" ), QgsUnitTypes::encodeUnit( sizeType ) );
Expand Down Expand Up @@ -753,6 +756,16 @@ QList< QgsLayerTreeModelLegendNode * > QgsDiagramSettings::legendItems( QgsLayer
return list;
}

QgsDiagramSettings::Direction QgsDiagramSettings::direction() const
{
return mDirection;
}

void QgsDiagramSettings::setDirection( Direction direction )
{
mDirection = direction;
}

QList< QgsLayerTreeModelLegendNode * > QgsDiagramRenderer::legendItems( QgsLayerTreeLayer * ) const
{
return QList< QgsLayerTreeModelLegendNode * >();
Expand Down
27 changes: 27 additions & 0 deletions src/core/qgsdiagramrenderer.h
Expand Up @@ -394,6 +394,16 @@ class CORE_EXPORT QgsDiagramSettings
Right
};

/**
* Angular directions.
* \since QGIS 3.12
*/
enum Direction
{
Clockwise, //!< Clockwise orientation
Counterclockwise, //!< Counter-clockwise orientation
};

//! Constructor for QgsDiagramSettings
QgsDiagramSettings() = default;

Expand Down Expand Up @@ -532,6 +542,22 @@ class CORE_EXPORT QgsDiagramSettings
*/
const QgsMapUnitScale &spacingMapUnitScale() const { return mSpacingMapUnitScale; }

/**
* Returns the chart's angular direction.
*
* \see setDirection()
* \since QGIS 3.12
*/
Direction direction() const;

/**
* Sets the chart's angular \a direction.
*
* \see direction()
* \since QGIS 3.12
*/
void setDirection( Direction direction );

//! Reads diagram settings from XML
void readXml( const QDomElement &elem );
//! Writes diagram settings to XML
Expand All @@ -549,6 +575,7 @@ class CORE_EXPORT QgsDiagramSettings
double mSpacing = 0;
QgsUnitTypes::RenderUnit mSpacingUnit;
QgsMapUnitScale mSpacingMapUnitScale;
Direction mDirection = Counterclockwise;

};

Expand Down

0 comments on commit baf3819

Please sign in to comment.