Skip to content

Commit

Permalink
Port diagrams to use properties
Browse files Browse the repository at this point in the history
  • Loading branch information
nyalldawson committed Jan 23, 2017
1 parent f1c1589 commit 43a3286
Show file tree
Hide file tree
Showing 4 changed files with 99 additions and 4 deletions.
24 changes: 23 additions & 1 deletion python/core/qgsdiagramrenderer.sip
Expand Up @@ -34,6 +34,18 @@ class QgsDiagramLayerSettings
};
typedef QFlags<QgsDiagramLayerSettings::LinePlacementFlag> LinePlacementFlags;

/** Data definable properties.
* @note added in QGIS 2.16
*/
enum Properties
{
Size, /*!< Overall diagram size*/
BackgroundColor, /*!< Diagram background color*/
OutlineColor, /*!< Outline color */
OutlineWidth, /*!< Outline width */
Opacity, /*!< Diagram opacity */
};

QgsDiagramLayerSettings();

//! Copy constructor
Expand Down Expand Up @@ -191,6 +203,16 @@ class QgsDiagramLayerSettings
//TODO QGIS 3.0 - remove need for fields parameter
QSet< QString > referencedFields( const QgsExpressionContext& context = QgsExpressionContext(), const QgsFields& fields = QgsFields() ) const;

/** Returns a reference to the diagram's property collection, used for data defined overrides.
* @note added in QGIS 2.16
*/
QgsPropertyCollection& properties();

/** Returns a reference to the diagram's property collection, used for data defined overrides.
* @note added in QGIS 2.16
*/
//const QgsPropertyCollection& properties() const;

};

/** \ingroup core
Expand Down Expand Up @@ -332,7 +354,7 @@ class QgsDiagramRenderer
*/
virtual QSet< QString > referencedFields( const QgsExpressionContext& context = QgsExpressionContext() ) const;

void renderDiagram( const QgsFeature& feature, QgsRenderContext& c, QPointF pos );
void renderDiagram( const QgsFeature& feature, QgsRenderContext& c, QPointF pos, const QgsPropertyCollection& properties = QgsPropertyCollection() );

void setDiagram( QgsDiagram* d /Transfer/ );
QgsDiagram* diagram() const;
Expand Down
42 changes: 41 additions & 1 deletion src/core/qgsdiagramrenderer.cpp
Expand Up @@ -31,6 +31,7 @@ QgsDiagramLayerSettings::QgsDiagramLayerSettings()
, showColumn( -1 )
, mRenderer( nullptr )
{
init();
}

QgsDiagramLayerSettings::QgsDiagramLayerSettings( const QgsDiagramLayerSettings& rh )
Expand All @@ -46,7 +47,9 @@ QgsDiagramLayerSettings::QgsDiagramLayerSettings( const QgsDiagramLayerSettings&
, mDistance( rh.mDistance )
, mRenderer( rh.mRenderer ? rh.mRenderer->clone() : nullptr )
, mShowAll( rh.mShowAll )
, mProperties( rh.mProperties )
{
init();
}

QgsDiagramLayerSettings&QgsDiagramLayerSettings::operator=( const QgsDiagramLayerSettings & rh )
Expand All @@ -63,6 +66,7 @@ QgsDiagramLayerSettings&QgsDiagramLayerSettings::operator=( const QgsDiagramLaye
yPosColumn = rh.yPosColumn;
showColumn = rh.showColumn;
mShowAll = rh.mShowAll;
mProperties = rh.mProperties;
return *this;
}

Expand All @@ -89,6 +93,16 @@ void QgsDiagramLayerSettings::readXml( const QDomElement& elem, const QgsVectorL
{
Q_UNUSED( layer )

QDomNodeList propertyElems = elem.elementsByTagName( "properties" );
if ( !propertyElems.isEmpty() )
{
( void )mProperties.readXML( propertyElems.at( 0 ).toElement(), elem.ownerDocument(), sPropertyNameMap );
}
else
{
mProperties.clear();
}

mPlacement = static_cast< Placement >( elem.attribute( QStringLiteral( "placement" ) ).toInt() );
mPlacementFlags = static_cast< LinePlacementFlag >( elem.attribute( QStringLiteral( "linePlacementFlags" ) ).toInt() );
mPriority = elem.attribute( QStringLiteral( "priority" ) ).toInt();
Expand All @@ -106,6 +120,9 @@ void QgsDiagramLayerSettings::writeXml( QDomElement& layerElem, QDomDocument& do
Q_UNUSED( layer )

QDomElement diagramLayerElem = doc.createElement( QStringLiteral( "DiagramLayerSettings" ) );
QDomElement propertiesElem = doc.createElement( "properties" );
( void )mProperties.writeXML( propertiesElem, doc, sPropertyNameMap );
diagramLayerElem.appendChild( propertiesElem );
diagramLayerElem.setAttribute( QStringLiteral( "placement" ), mPlacement );
diagramLayerElem.setAttribute( QStringLiteral( "linePlacementFlags" ), mPlacementFlags );
diagramLayerElem.setAttribute( QStringLiteral( "priority" ), mPriority );
Expand All @@ -119,12 +136,27 @@ void QgsDiagramLayerSettings::writeXml( QDomElement& layerElem, QDomDocument& do
layerElem.appendChild( diagramLayerElem );
}

void QgsDiagramLayerSettings::init()
{
if ( sPropertyNameMap.isEmpty() )
{
sPropertyNameMap.insert( Size, "diagramSize" );
sPropertyNameMap.insert( BackgroundColor, "backgroundColor" );
sPropertyNameMap.insert( OutlineColor, "outlineColor" );
sPropertyNameMap.insert( OutlineWidth, "outlineWidth" );
sPropertyNameMap.insert( Opacity, "opacity" );
}
}

QSet<QString> QgsDiagramLayerSettings::referencedFields( const QgsExpressionContext &context, const QgsFields& fieldsParameter ) const
{
QSet< QString > referenced;
if ( mRenderer )
referenced = mRenderer->referencedFields( context );

//add the ones needed for data defined settings
referenced.unite( mProperties.referencedFields( context ) );

//and the ones needed for data defined diagram positions
if ( xPosColumn >= 0 && xPosColumn < fieldsParameter.count() )
referenced << fieldsParameter.at( xPosColumn ).name();
Expand Down Expand Up @@ -397,7 +429,7 @@ QgsDiagramRenderer &QgsDiagramRenderer::operator=( const QgsDiagramRenderer & ot
return *this;
}

void QgsDiagramRenderer::renderDiagram( const QgsFeature& feature, QgsRenderContext& c, QPointF pos ) const
void QgsDiagramRenderer::renderDiagram( const QgsFeature& feature, QgsRenderContext& c, QPointF pos, const QgsPropertyCollection &properties ) const
{
if ( !mDiagram )
{
Expand All @@ -410,6 +442,14 @@ void QgsDiagramRenderer::renderDiagram( const QgsFeature& feature, QgsRenderCont
return;
}

if ( properties.hasActiveProperties() )
{
s.transparency = properties.valueAsInt( QgsDiagramLayerSettings::Opacity, c.expressionContext(), s.transparency );
s.backgroundColor = properties.valueAsColor( QgsDiagramLayerSettings::BackgroundColor, c.expressionContext(), s.backgroundColor );
s.penColor = properties.valueAsColor( QgsDiagramLayerSettings::OutlineColor, c.expressionContext(), s.penColor );
s.penWidth = properties.valueAsDouble( QgsDiagramLayerSettings::OutlineWidth, c.expressionContext(), s.penWidth );
}

mDiagram->renderDiagram( feature, c, s, pos );
}

Expand Down
33 changes: 32 additions & 1 deletion src/core/qgsdiagramrenderer.h
Expand Up @@ -27,6 +27,8 @@
#include "qgsfields.h"
#include "qgscoordinatetransform.h"
#include "qgssymbol.h"
#include "qgsproperty.h"


class QgsDiagram;
class QgsDiagramRenderer;
Expand Down Expand Up @@ -73,6 +75,18 @@ class CORE_EXPORT QgsDiagramLayerSettings
};
Q_DECLARE_FLAGS( LinePlacementFlags, LinePlacementFlag )

/** Data definable properties.
* @note added in QGIS 3.0
*/
enum Properties
{
Size, //!< Overall diagram size
BackgroundColor, //!< Diagram background color
OutlineColor, //!< Outline color
OutlineWidth, //!< Outline width
Opacity, //!< Diagram opacity
};

QgsDiagramLayerSettings();

//! Copy constructor
Expand Down Expand Up @@ -237,6 +251,16 @@ class CORE_EXPORT QgsDiagramLayerSettings
//TODO QGIS 3.0 - remove need for fields parameter
QSet< QString > referencedFields( const QgsExpressionContext& context = QgsExpressionContext(), const QgsFields& fields = QgsFields() ) const;

/** Returns a reference to the diagram's property collection, used for data defined overrides.
* @note added in QGIS 3.0
*/
QgsPropertyCollection& properties() { return mProperties; }

/** Returns a reference to the diagram's property collection, used for data defined overrides.
* @note added in QGIS 3.0
*/
const QgsPropertyCollection& properties() const { return mProperties; }

private:

//! Associated coordinate transform, or invalid transform for no transformation
Expand Down Expand Up @@ -267,6 +291,13 @@ class CORE_EXPORT QgsDiagramLayerSettings

//! Whether to show all diagrams, including overlapping diagrams
bool mShowAll = true;

//! Property collection for data defined diagram settings
QgsPropertyCollection mProperties;

static QMap< int, QString > sPropertyNameMap;

void init();
};

/** \ingroup core
Expand Down Expand Up @@ -418,7 +449,7 @@ class CORE_EXPORT QgsDiagramRenderer
*/
virtual QSet< QString > referencedFields( const QgsExpressionContext& context = QgsExpressionContext() ) const;

void renderDiagram( const QgsFeature& feature, QgsRenderContext& c, QPointF pos ) const;
void renderDiagram( const QgsFeature& feature, QgsRenderContext& c, QPointF pos, const QgsPropertyCollection& properties = QgsPropertyCollection() ) const;

void setDiagram( QgsDiagram* d );
QgsDiagram* diagram() const { return mDiagram; }
Expand Down
4 changes: 3 additions & 1 deletion src/core/qgsvectorlayerdiagramprovider.cpp
Expand Up @@ -132,6 +132,8 @@ void QgsVectorLayerDiagramProvider::drawLabel( QgsRenderContext& context, pal::L
feature.setId( label->getFeaturePart()->featureId() );
feature.setAttributes( dlf->attributes() );

context.expressionContext().setFeature( feature );

//calculate top-left point for diagram
//first, calculate the centroid of the label (accounts for PAL creating
//rotated labels when we do not want to draw the diagrams rotated)
Expand All @@ -147,7 +149,7 @@ void QgsVectorLayerDiagramProvider::drawLabel( QgsRenderContext& context, pal::L
QgsPoint centerPt = xform.transform( outPt.x() - label->getWidth() / 2,
outPt.y() - label->getHeight() / 2 );

mSettings.renderer()->renderDiagram( feature, context, centerPt.toQPointF() );
mSettings.renderer()->renderDiagram( feature, context, centerPt.toQPointF(), mSettings.properties() );

//insert into label search tree to manipulate position interactively
mEngine->results()->mLabelSearchTree->insertLabel( label, label->getFeaturePart()->featureId(), mLayerId, QString(), QFont(), true, false );
Expand Down

0 comments on commit 43a3286

Please sign in to comment.