Port diagrams to use properties

This commit is contained in:
Nyall Dawson 2017-01-02 11:31:35 +10:00
parent f1c1589550
commit 43a328687d
4 changed files with 99 additions and 4 deletions

View File

@ -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
@ -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
@ -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;

View File

@ -31,6 +31,7 @@ QgsDiagramLayerSettings::QgsDiagramLayerSettings()
, showColumn( -1 )
, mRenderer( nullptr )
{
init();
}
QgsDiagramLayerSettings::QgsDiagramLayerSettings( const QgsDiagramLayerSettings& rh )
@ -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 )
@ -63,6 +66,7 @@ QgsDiagramLayerSettings&QgsDiagramLayerSettings::operator=( const QgsDiagramLaye
yPosColumn = rh.yPosColumn;
showColumn = rh.showColumn;
mShowAll = rh.mShowAll;
mProperties = rh.mProperties;
return *this;
}
@ -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();
@ -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 );
@ -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();
@ -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 )
{
@ -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 );
}

View File

@ -27,6 +27,8 @@
#include "qgsfields.h"
#include "qgscoordinatetransform.h"
#include "qgssymbol.h"
#include "qgsproperty.h"
class QgsDiagram;
class QgsDiagramRenderer;
@ -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
@ -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
@ -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
@ -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; }

View File

@ -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)
@ -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 );