From 3039f9354bfd361e57e03afc2910d796c36475ed Mon Sep 17 00:00:00 2001 From: Matthias Kuhn Date: Mon, 6 Aug 2012 11:36:21 +0200 Subject: [PATCH 1/9] Change vertical alignment Use x-height for vertical offset rather than font-height/2 --- src/core/qgsdiagram.cpp | 595 ++++++++++++++++++++-------------------- 1 file changed, 297 insertions(+), 298 deletions(-) diff --git a/src/core/qgsdiagram.cpp b/src/core/qgsdiagram.cpp index 74b98587e37..520250c97a2 100644 --- a/src/core/qgsdiagram.cpp +++ b/src/core/qgsdiagram.cpp @@ -1,298 +1,297 @@ -/*************************************************************************** - qgsdiagram.cpp - --------------------- - begin : March 2011 - copyright : (C) 2011 by Marco Hugentobler - email : marco dot hugentobler at sourcepole dot ch - *************************************************************************** - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - ***************************************************************************/ -#include "qgsdiagram.h" -#include "qgsdiagramrendererv2.h" -#include "qgsrendercontext.h" - -#include - -void QgsDiagram::setPenWidth( QPen& pen, const QgsDiagramSettings& s, const QgsRenderContext& c ) -{ - if ( s.sizeType == QgsDiagramSettings::MM ) - { - pen.setWidthF( s.penWidth * c.scaleFactor() ); - } - else - { - pen.setWidthF( s.penWidth / c.mapToPixel().mapUnitsPerPixel() ); - } -} - -QSizeF QgsDiagram::sizePainterUnits( const QSizeF& size, const QgsDiagramSettings& s, const QgsRenderContext& c ) -{ - Q_UNUSED( size ); - if ( s.sizeType == QgsDiagramSettings::MM ) - { - return QSizeF( s.size.width() * c.scaleFactor(), s.size.height() * c.scaleFactor() ); - } - else - { - return QSizeF( s.size.width() / c.mapToPixel().mapUnitsPerPixel(), s.size.height() / c.mapToPixel().mapUnitsPerPixel() ); - } -} - -QFont QgsDiagram::scaledFont( const QgsDiagramSettings& s, const QgsRenderContext& c ) -{ - QFont f = s.font; - if ( s.sizeType == QgsDiagramSettings::MM ) - { - f.setPixelSize( s.font.pointSizeF() * 0.376 * c.scaleFactor() ); - } - else - { - f.setPixelSize( s.font.pointSizeF() / c.mapToPixel().mapUnitsPerPixel() ); - } - - return f; -} - -QgsTextDiagram::QgsTextDiagram(): mOrientation( Vertical ), mShape( Circle ) -{ - mPen.setWidthF( 2.0 ); - mPen.setColor( QColor( 0, 0, 0 ) ); - mPen.setCapStyle( Qt::FlatCap ); - mBrush.setStyle( Qt::SolidPattern ); -} - -QgsTextDiagram::~QgsTextDiagram() -{ -} - -void QgsTextDiagram::renderDiagram( const QgsAttributeMap& att, QgsRenderContext& c, const QgsDiagramSettings& s, const QPointF& position ) -{ - QPainter* p = c.painter(); - if ( !p ) - { - return; - } - - double scaleDenominator = c.rendererScale(); - if (( s.minScaleDenominator != -1 && scaleDenominator < s.minScaleDenominator ) - || ( s.maxScaleDenominator != -1 && scaleDenominator > s.maxScaleDenominator ) ) - { - return; - } - - //convert from mm / map units to painter units - QSizeF spu = sizePainterUnits( s.size, s, c ); - double w = spu.width(); - double h = spu.height(); - - double baseX = position.x(); - double baseY = position.y() - h; - - QList textPositions; //midpoints for text placement - int nCategories = s.categoryIndices.size(); - for ( int i = 0; i < nCategories; ++i ) - { - if ( mOrientation == Horizontal ) - { - textPositions.push_back( QPointF( baseX + ( w / nCategories ) * i + w / nCategories / 2.0 , baseY + h / 2.0 ) ); - } - else //vertical - { - textPositions.push_back( QPointF( baseX + w / 2.0, baseY + h / nCategories * i + w / nCategories / 2.0 ) ); - } - } - - mPen.setColor( s.penColor ); - setPenWidth( mPen, s, c ); - p->setPen( mPen ); - mBrush.setColor( s.backgroundColor ); - p->setBrush( mBrush ); - - //draw shapes and separator lines first - if ( mShape == Circle ) - { - p->drawEllipse( baseX, baseY, w, h ); - - //draw separator lines - QList intersect; //intersections between shape and separation lines - QPointF center( baseX + w / 2.0, baseY + h / 2.0 ); - double r1 = w / 2.0; double r2 = h / 2.0; - - for ( int i = 1; i < nCategories; ++i ) - { - if ( mOrientation == Horizontal ) - { - lineEllipseIntersection( QPointF( baseX + w / nCategories * i, baseY ), QPointF( baseX + w / nCategories * i, baseY + h ), center, r1, r2, intersect ); - } - else //vertical - { - lineEllipseIntersection( QPointF( baseX, baseY + h / nCategories * i ), QPointF( baseX + w, baseY + h / nCategories * i ), center, r1, r2, intersect ); - } - if ( intersect.size() > 1 ) - { - p->drawLine( intersect.at( 0 ), intersect.at( 1 ) ); - } - } - } - else if ( mShape == Rectangle ) - { - p->drawRect( QRectF( baseX, baseY, w, h ) ); - for ( int i = 1; i < nCategories; ++i ) - { - if ( mOrientation == Horizontal ) - { - p->drawLine( QPointF( baseX + w / nCategories * i , baseY ), QPointF( baseX + w / nCategories * i, baseY + h ) ); - } - else - { - p->drawLine( QPointF( baseX, baseY + h / nCategories * i ) , QPointF( baseX + w, baseY + h / nCategories * i ) ); - } - } - } - else //triangle - { - QPolygonF triangle; - triangle << QPointF( baseX, baseY + h ) << QPointF( baseX + w, baseY + h ) << QPointF( baseX + w / 2.0, baseY ); - p->drawPolygon( triangle ); - - QLineF triangleEdgeLeft( baseX + w / 2.0, baseY, baseX, baseY + h ); - QLineF triangleEdgeRight( baseX + w, baseY + h, baseX + w / 2.0, baseY ); - QPointF intersectionPoint1, intersectionPoint2; - - for ( int i = 1; i < nCategories; ++i ) - { - if ( mOrientation == Horizontal ) - { - QLineF verticalLine( baseX + w / nCategories * i, baseY + h, baseX + w / nCategories * i, baseY ); - if ( baseX + w / nCategories * i < baseX + w / 2.0 ) - { - verticalLine.intersect( triangleEdgeLeft, &intersectionPoint1 ); - } - else - { - verticalLine.intersect( triangleEdgeRight, &intersectionPoint1 ); - } - p->drawLine( QPointF( baseX + w / nCategories * i, baseY + h ), intersectionPoint1 ); - } - else //vertical - { - QLineF horizontalLine( baseX, baseY + h / nCategories * i, baseX + w, baseY + h / nCategories * i ); - horizontalLine.intersect( triangleEdgeLeft, &intersectionPoint1 ); - horizontalLine.intersect( triangleEdgeRight, &intersectionPoint2 ); - p->drawLine( intersectionPoint1, intersectionPoint2 ); - } - } - } - - //draw text - QFont sFont = scaledFont( s, c ); - QFontMetricsF fontMetrics( sFont ); - p->setFont( sFont ); - - for ( int i = 0; i < textPositions.size(); ++i ) - { - QString val = att[ s.categoryIndices.at( i )].toString(); - //find out dimensions - double textHeight = fontMetrics.height(); - double textWidth = fontMetrics.width( val ); - mPen.setColor( s.categoryColors.at( i ) ); - p->setPen( mPen ); - QPointF position = textPositions.at( i ); - p->drawText( QPointF( position.x() - textWidth / 2.0, position.y() + textHeight / 2.0 ), val ); - } -} - -void QgsTextDiagram::lineEllipseIntersection( const QPointF& lineStart, const QPointF& lineEnd, const QPointF& ellipseMid, double r1, double r2, QList& result ) const -{ - result.clear(); - - double rrx = r1 * r1; - double rry = r2 * r2; - double x21 = lineEnd.x() - lineStart.x(); - double y21 = lineEnd.y() - lineStart.y(); - double x10 = lineStart.x() - ellipseMid.x(); - double y10 = lineStart.y() - ellipseMid.y(); - double a = x21 * x21 / rrx + y21 * y21 / rry; - double b = x21 * x10 / rrx + y21 * y10 / rry; - double c = x10 * x10 / rrx + y10 * y10 / rry; - double d = b * b - a * ( c - 1 ); - if ( d > 0 ) - { - double e = sqrt( d ); - double u1 = ( -b - e ) / a; - double u2 = ( -b + e ) / a; - //work with a tolerance of 0.00001 because of limited numerical precision - if ( -0.00001 <= u1 && u1 < 1.00001 ) - { - result.push_back( QPointF( lineStart.x() + x21 * u1, lineStart.y() + y21 * u1 ) ); - } - if ( -0.00001 <= u2 && u2 <= 1.00001 ) - { - result.push_back( QPointF( lineStart.x() + x21 * u2, lineStart.y() + y21 * u2 ) ); - } - } -} - -QgsPieDiagram::QgsPieDiagram() -{ - mCategoryBrush.setStyle( Qt::SolidPattern ); - mPen.setStyle( Qt::SolidLine ); -} - -QgsPieDiagram::~QgsPieDiagram() -{ -} - -void QgsPieDiagram::renderDiagram( const QgsAttributeMap& att, QgsRenderContext& c, const QgsDiagramSettings& s, const QPointF& position ) -{ - QPainter* p = c.painter(); - if ( !p ) - { - return; - } - - //get sum of values - QList values; - double currentVal = 0; - double valSum = 0; - - QList::const_iterator catIt = s.categoryIndices.constBegin(); - for ( ; catIt != s.categoryIndices.constEnd(); ++catIt ) - { - currentVal = att[*catIt].toDouble(); - values.push_back( currentVal ); - valSum += currentVal; - } - - //draw the slices - double totalAngle = 0; - double currentAngle; - - //convert from mm / map units to painter units - QSizeF spu = sizePainterUnits( s.size, s, c ); - double w = spu.width(); - double h = spu.height(); - - double baseX = position.x(); - double baseY = position.y() - h; - - mPen.setColor( s.penColor ); - setPenWidth( mPen, s, c ); - p->setPen( mPen ); - - QList::const_iterator valIt = values.constBegin(); - QList< QColor >::const_iterator colIt = s.categoryColors.constBegin(); - for ( ; valIt != values.constEnd(); ++valIt, ++colIt ) - { - currentAngle = *valIt / valSum * 360 * 16; - mCategoryBrush.setColor( *colIt ); - p->setBrush( mCategoryBrush ); - p->drawPie( baseX, baseY, w, h, totalAngle, currentAngle ); - totalAngle += currentAngle; - } -} +/*************************************************************************** + qgsdiagram.cpp + --------------------- + begin : March 2011 + copyright : (C) 2011 by Marco Hugentobler + email : marco dot hugentobler at sourcepole dot ch + *************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ +#include "qgsdiagram.h" +#include "qgsdiagramrendererv2.h" +#include "qgsrendercontext.h" + +#include + +void QgsDiagram::setPenWidth( QPen& pen, const QgsDiagramSettings& s, const QgsRenderContext& c ) +{ + if ( s.sizeType == QgsDiagramSettings::MM ) + { + pen.setWidthF( s.penWidth * c.scaleFactor() ); + } + else + { + pen.setWidthF( s.penWidth / c.mapToPixel().mapUnitsPerPixel() ); + } +} + +QSizeF QgsDiagram::sizePainterUnits( const QSizeF& size, const QgsDiagramSettings& s, const QgsRenderContext& c ) +{ + Q_UNUSED( size ); + if ( s.sizeType == QgsDiagramSettings::MM ) + { + return QSizeF( s.size.width() * c.scaleFactor(), s.size.height() * c.scaleFactor() ); + } + else + { + return QSizeF( s.size.width() / c.mapToPixel().mapUnitsPerPixel(), s.size.height() / c.mapToPixel().mapUnitsPerPixel() ); + } +} + +QFont QgsDiagram::scaledFont( const QgsDiagramSettings& s, const QgsRenderContext& c ) +{ + QFont f = s.font; + if ( s.sizeType == QgsDiagramSettings::MM ) + { + f.setPixelSize( s.font.pointSizeF() * 0.376 * c.scaleFactor() ); + } + else + { + f.setPixelSize( s.font.pointSizeF() / c.mapToPixel().mapUnitsPerPixel() ); + } + + return f; +} + +QgsTextDiagram::QgsTextDiagram(): mOrientation( Vertical ), mShape( Circle ) +{ + mPen.setWidthF( 2.0 ); + mPen.setColor( QColor( 0, 0, 0 ) ); + mPen.setCapStyle( Qt::FlatCap ); + mBrush.setStyle( Qt::SolidPattern ); +} + +QgsTextDiagram::~QgsTextDiagram() +{ +} + +void QgsTextDiagram::renderDiagram( const QgsAttributeMap& att, QgsRenderContext& c, const QgsDiagramSettings& s, const QPointF& position ) +{ + QPainter* p = c.painter(); + if ( !p ) + { + return; + } + + double scaleDenominator = c.rendererScale(); + if (( s.minScaleDenominator != -1 && scaleDenominator < s.minScaleDenominator ) + || ( s.maxScaleDenominator != -1 && scaleDenominator > s.maxScaleDenominator ) ) + { + return; + } + + //convert from mm / map units to painter units + QSizeF spu = sizePainterUnits( s.size, s, c ); + double w = spu.width(); + double h = spu.height(); + + double baseX = position.x(); + double baseY = position.y() - h; + + QList textPositions; //midpoints for text placement + int nCategories = s.categoryIndices.size(); + for ( int i = 0; i < nCategories; ++i ) + { + if ( mOrientation == Horizontal ) + { + textPositions.push_back( QPointF( baseX + ( w / nCategories ) * i + w / nCategories / 2.0 , baseY + h / 2.0 ) ); + } + else //vertical + { + textPositions.push_back( QPointF( baseX + w / 2.0, baseY + h / nCategories * i + w / nCategories / 2.0 ) ); + } + } + + mPen.setColor( s.penColor ); + setPenWidth( mPen, s, c ); + p->setPen( mPen ); + mBrush.setColor( s.backgroundColor ); + p->setBrush( mBrush ); + + //draw shapes and separator lines first + if ( mShape == Circle ) + { + p->drawEllipse( baseX, baseY, w, h ); + + //draw separator lines + QList intersect; //intersections between shape and separation lines + QPointF center( baseX + w / 2.0, baseY + h / 2.0 ); + double r1 = w / 2.0; double r2 = h / 2.0; + + for ( int i = 1; i < nCategories; ++i ) + { + if ( mOrientation == Horizontal ) + { + lineEllipseIntersection( QPointF( baseX + w / nCategories * i, baseY ), QPointF( baseX + w / nCategories * i, baseY + h ), center, r1, r2, intersect ); + } + else //vertical + { + lineEllipseIntersection( QPointF( baseX, baseY + h / nCategories * i ), QPointF( baseX + w, baseY + h / nCategories * i ), center, r1, r2, intersect ); + } + if ( intersect.size() > 1 ) + { + p->drawLine( intersect.at( 0 ), intersect.at( 1 ) ); + } + } + } + else if ( mShape == Rectangle ) + { + p->drawRect( QRectF( baseX, baseY, w, h ) ); + for ( int i = 1; i < nCategories; ++i ) + { + if ( mOrientation == Horizontal ) + { + p->drawLine( QPointF( baseX + w / nCategories * i , baseY ), QPointF( baseX + w / nCategories * i, baseY + h ) ); + } + else + { + p->drawLine( QPointF( baseX, baseY + h / nCategories * i ) , QPointF( baseX + w, baseY + h / nCategories * i ) ); + } + } + } + else //triangle + { + QPolygonF triangle; + triangle << QPointF( baseX, baseY + h ) << QPointF( baseX + w, baseY + h ) << QPointF( baseX + w / 2.0, baseY ); + p->drawPolygon( triangle ); + + QLineF triangleEdgeLeft( baseX + w / 2.0, baseY, baseX, baseY + h ); + QLineF triangleEdgeRight( baseX + w, baseY + h, baseX + w / 2.0, baseY ); + QPointF intersectionPoint1, intersectionPoint2; + + for ( int i = 1; i < nCategories; ++i ) + { + if ( mOrientation == Horizontal ) + { + QLineF verticalLine( baseX + w / nCategories * i, baseY + h, baseX + w / nCategories * i, baseY ); + if ( baseX + w / nCategories * i < baseX + w / 2.0 ) + { + verticalLine.intersect( triangleEdgeLeft, &intersectionPoint1 ); + } + else + { + verticalLine.intersect( triangleEdgeRight, &intersectionPoint1 ); + } + p->drawLine( QPointF( baseX + w / nCategories * i, baseY + h ), intersectionPoint1 ); + } + else //vertical + { + QLineF horizontalLine( baseX, baseY + h / nCategories * i, baseX + w, baseY + h / nCategories * i ); + horizontalLine.intersect( triangleEdgeLeft, &intersectionPoint1 ); + horizontalLine.intersect( triangleEdgeRight, &intersectionPoint2 ); + p->drawLine( intersectionPoint1, intersectionPoint2 ); + } + } + } + + //draw text + QFont sFont = scaledFont( s, c ); + QFontMetricsF fontMetrics( sFont ); + p->setFont( sFont ); + + for ( int i = 0; i < textPositions.size(); ++i ) + { + QString val = att[ s.categoryIndices.at( i )].toString(); + //find out dimensions + double textWidth = fontMetrics.width( val ); + mPen.setColor( s.categoryColors.at( i ) ); + p->setPen( mPen ); + QPointF position = textPositions.at( i ); + p->drawText( QPointF( position.x() - textWidth / 2.0, position.y() + fontMetrics.xHeight() ), val ); + } +} + +void QgsTextDiagram::lineEllipseIntersection( const QPointF& lineStart, const QPointF& lineEnd, const QPointF& ellipseMid, double r1, double r2, QList& result ) const +{ + result.clear(); + + double rrx = r1 * r1; + double rry = r2 * r2; + double x21 = lineEnd.x() - lineStart.x(); + double y21 = lineEnd.y() - lineStart.y(); + double x10 = lineStart.x() - ellipseMid.x(); + double y10 = lineStart.y() - ellipseMid.y(); + double a = x21 * x21 / rrx + y21 * y21 / rry; + double b = x21 * x10 / rrx + y21 * y10 / rry; + double c = x10 * x10 / rrx + y10 * y10 / rry; + double d = b * b - a * ( c - 1 ); + if ( d > 0 ) + { + double e = sqrt( d ); + double u1 = ( -b - e ) / a; + double u2 = ( -b + e ) / a; + //work with a tolerance of 0.00001 because of limited numerical precision + if ( -0.00001 <= u1 && u1 < 1.00001 ) + { + result.push_back( QPointF( lineStart.x() + x21 * u1, lineStart.y() + y21 * u1 ) ); + } + if ( -0.00001 <= u2 && u2 <= 1.00001 ) + { + result.push_back( QPointF( lineStart.x() + x21 * u2, lineStart.y() + y21 * u2 ) ); + } + } +} + +QgsPieDiagram::QgsPieDiagram() +{ + mCategoryBrush.setStyle( Qt::SolidPattern ); + mPen.setStyle( Qt::SolidLine ); +} + +QgsPieDiagram::~QgsPieDiagram() +{ +} + +void QgsPieDiagram::renderDiagram( const QgsAttributeMap& att, QgsRenderContext& c, const QgsDiagramSettings& s, const QPointF& position ) +{ + QPainter* p = c.painter(); + if ( !p ) + { + return; + } + + //get sum of values + QList values; + double currentVal = 0; + double valSum = 0; + + QList::const_iterator catIt = s.categoryIndices.constBegin(); + for ( ; catIt != s.categoryIndices.constEnd(); ++catIt ) + { + currentVal = att[*catIt].toDouble(); + values.push_back( currentVal ); + valSum += currentVal; + } + + //draw the slices + double totalAngle = 0; + double currentAngle; + + //convert from mm / map units to painter units + QSizeF spu = sizePainterUnits( s.size, s, c ); + double w = spu.width(); + double h = spu.height(); + + double baseX = position.x(); + double baseY = position.y() - h; + + mPen.setColor( s.penColor ); + setPenWidth( mPen, s, c ); + p->setPen( mPen ); + + QList::const_iterator valIt = values.constBegin(); + QList< QColor >::const_iterator colIt = s.categoryColors.constBegin(); + for ( ; valIt != values.constEnd(); ++valIt, ++colIt ) + { + currentAngle = *valIt / valSum * 360 * 16; + mCategoryBrush.setColor( *colIt ); + p->setBrush( mCategoryBrush ); + p->drawPie( baseX, baseY, w, h, totalAngle, currentAngle ); + totalAngle += currentAngle; + } +} From 35e747b28c553688c0f6d202c03df1a352d6cdcc Mon Sep 17 00:00:00 2001 From: Matthias Kuhn Date: Mon, 6 Aug 2012 17:12:36 +0200 Subject: [PATCH 2/9] Text diagrams: new label placement method (x-height) --- src/app/qgsvectorlayerproperties.cpp | 41 ++ src/app/qgsvectorlayerproperties.h | 1 + src/core/qgsdiagram.cpp | 20 +- src/core/qgsdiagramrendererv2.cpp | 739 +++++++++++++------------ src/core/qgsdiagramrendererv2.h | 501 ++++++++--------- src/ui/qgsvectorlayerpropertiesbase.ui | 400 ++++++------- 6 files changed, 901 insertions(+), 801 deletions(-) diff --git a/src/app/qgsvectorlayerproperties.cpp b/src/app/qgsvectorlayerproperties.cpp index 2e675d64b7e..9c1d4909916 100755 --- a/src/app/qgsvectorlayerproperties.cpp +++ b/src/app/qgsvectorlayerproperties.cpp @@ -845,6 +845,16 @@ void QgsVectorLayerProperties::apply() { ds.sizeType = QgsDiagramSettings::MM; } + + if ( !tr( "Height" ).compare( mLabelPlacementComboBox->currentText() ) ) + { + ds.labelPlacementMethod = QgsDiagramSettings::Height; + } + else if ( !tr( "x-height" ).compare( mLabelPlacementComboBox->currentText() ) ) + { + ds.labelPlacementMethod = QgsDiagramSettings::XHeight; + } + ds.backgroundColor = mBackgroundColorButton->color(); ds.penColor = mDiagramPenColorButton->color(); ds.penWidth = mPenWidthSpinBox->value(); @@ -1306,6 +1316,19 @@ void QgsVectorLayerProperties::handleDiagramItemDoubleClick( QTreeWidgetItem * i } } +void QgsVectorLayerProperties::handleDiagramTypeChanged( const QString& itemtext ) +{ + if ( tr( "Text diagram" ) == itemtext ) + { + mLabelPlacementComboBox->show(); + mLabelPlacementLabel->show(); + } + else { + mLabelPlacementComboBox->hide(); + mLabelPlacementLabel->hide(); + } +} + void QgsVectorLayerProperties::useNewSymbology() { int res = QMessageBox::question( this, tr( "Symbology" ), @@ -1565,6 +1588,9 @@ void QgsVectorLayerProperties::initDiagramTab() mDiagramTypeComboBox->addItem( tr( "Pie chart" ) ); mDiagramTypeComboBox->addItem( tr( "Text diagram" ) ); + mLabelPlacementComboBox->addItem( tr( "Height" ) ); + mLabelPlacementComboBox->addItem( tr( "x-height" ) ); + //insert all attributes into the combo boxes const QgsFieldMap& layerFields = layer->pendingFields(); QgsFieldMap::const_iterator fieldIt = layerFields.constBegin(); @@ -1594,6 +1620,7 @@ void QgsVectorLayerProperties::initDiagramTab() mDisplayDiagramsCheckBox->setChecked( false ); mFixedSizeCheckBox->setChecked( true ); mDiagramUnitComboBox->setCurrentIndex( mDiagramUnitComboBox->findText( tr( "MM" ) ) ); + mLabelPlacementComboBox->setCurrentIndex( mLabelPlacementComboBox->findText( tr( "XHeight" ) ) ); mDiagramSizeSpinBox->setValue( 30 ); mScaleDependentDiagramVisibilityCheckBox->setChecked( false ); @@ -1645,6 +1672,15 @@ void QgsVectorLayerProperties::initDiagramTab() mDiagramUnitComboBox->setCurrentIndex( 1 ); } + if ( settingList.at( 0 ).labelPlacementMethod == QgsDiagramSettings::Height ) + { + mLabelPlacementComboBox->setCurrentIndex( 0 ); + } + else + { + mLabelPlacementComboBox->setCurrentIndex( 1 ); + } + QList< QColor > categoryColors = settingList.at( 0 ).categoryColors; @@ -1696,5 +1732,10 @@ void QgsVectorLayerProperties::initDiagramTab() } } } + + // Hide/Show diagram specific widgets + handleDiagramTypeChanged( mDiagramTypeComboBox->currentText() ); + QObject::connect( mDiagramAttributesTreeWidget, SIGNAL( itemDoubleClicked( QTreeWidgetItem*, int ) ), this, SLOT( handleDiagramItemDoubleClick( QTreeWidgetItem*, int ) ) ); + QObject::connect( mDiagramTypeComboBox, SIGNAL( currentIndexChanged( const QString& ) ), this, SLOT( handleDiagramTypeChanged( const QString& ) ) ); } diff --git a/src/app/qgsvectorlayerproperties.h b/src/app/qgsvectorlayerproperties.h index 89758a9d596..b76b2621b8a 100644 --- a/src/app/qgsvectorlayerproperties.h +++ b/src/app/qgsvectorlayerproperties.h @@ -144,6 +144,7 @@ class QgsVectorLayerProperties : public QDialog, private Ui::QgsVectorLayerPrope /**Set color for diagram category*/ void handleDiagramItemDoubleClick( QTreeWidgetItem * item, int column ); + void handleDiagramTypeChanged( const QString& itemtext ); signals: diff --git a/src/core/qgsdiagram.cpp b/src/core/qgsdiagram.cpp index 520250c97a2..0e6d7bc7531 100644 --- a/src/core/qgsdiagram.cpp +++ b/src/core/qgsdiagram.cpp @@ -197,12 +197,28 @@ void QgsTextDiagram::renderDiagram( const QgsAttributeMap& att, QgsRenderContext for ( int i = 0; i < textPositions.size(); ++i ) { QString val = att[ s.categoryIndices.at( i )].toString(); - //find out dimensions + //find out dimesions double textWidth = fontMetrics.width( val ); + double textHeight = fontMetrics.height(); + mPen.setColor( s.categoryColors.at( i ) ); p->setPen( mPen ); QPointF position = textPositions.at( i ); - p->drawText( QPointF( position.x() - textWidth / 2.0, position.y() + fontMetrics.xHeight() ), val ); + + // Calculate vertical placement + double xOffset = 0; + + switch( s.labelPlacementMethod ) + { + case QgsDiagramSettings::Height: + xOffset = textHeight / 2.0; + break; + + case QgsDiagramSettings::XHeight: + xOffset = fontMetrics.xHeight(); + break; + } + p->drawText( QPointF( position.x() - textWidth / 2.0, position.y() + xOffset ), val ); } } diff --git a/src/core/qgsdiagramrendererv2.cpp b/src/core/qgsdiagramrendererv2.cpp index 36c2ff677ab..2a0dc68db33 100644 --- a/src/core/qgsdiagramrendererv2.cpp +++ b/src/core/qgsdiagramrendererv2.cpp @@ -1,359 +1,380 @@ -/*************************************************************************** - qgsdiagramrendererv2.cpp - --------------------- - begin : March 2011 - copyright : (C) 2011 by Marco Hugentobler - email : marco dot hugentobler at sourcepole dot ch - *************************************************************************** - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - ***************************************************************************/ -#include "qgsdiagramrendererv2.h" -#include "qgsdiagram.h" -#include "qgsrendercontext.h" -#include -#include - - -void QgsDiagramLayerSettings::readXML( const QDomElement& elem ) -{ - placement = ( Placement )elem.attribute( "placement" ).toInt(); - placementFlags = ( LinePlacementFlags )elem.attribute( "linePlacementFlags" ).toInt(); - priority = elem.attribute( "priority" ).toInt(); - obstacle = elem.attribute( "obstacle" ).toInt(); - dist = elem.attribute( "dist" ).toDouble(); - xPosColumn = elem.attribute( "xPosColumn" ).toInt(); - yPosColumn = elem.attribute( "yPosColumn" ).toInt(); -} - -void QgsDiagramLayerSettings::writeXML( QDomElement& layerElem, QDomDocument& doc ) const -{ - QDomElement diagramLayerElem = doc.createElement( "DiagramLayerSettings" ); - diagramLayerElem.setAttribute( "placement", placement ); - diagramLayerElem.setAttribute( "linePlacementFlags", placementFlags ); - diagramLayerElem.setAttribute( "priority", priority ); - diagramLayerElem.setAttribute( "obstacle", obstacle ); - diagramLayerElem.setAttribute( "dist", QString::number( dist ) ); - diagramLayerElem.setAttribute( "xPosColumn", xPosColumn ); - diagramLayerElem.setAttribute( "yPosColumn", yPosColumn ); - layerElem.appendChild( diagramLayerElem ); -} - -void QgsDiagramSettings::readXML( const QDomElement& elem ) -{ - font.fromString( elem.attribute( "font" ) ); - backgroundColor.setNamedColor( elem.attribute( "backgroundColor" ) ); - backgroundColor.setAlpha( elem.attribute( "backgroundAlpha" ).toInt() ); - size.setWidth( elem.attribute( "width" ).toDouble() ); - size.setHeight( elem.attribute( "height" ).toDouble() ); - penColor.setNamedColor( elem.attribute( "penColor" ) ); - penWidth = elem.attribute( "penWidth" ).toDouble(); - minScaleDenominator = elem.attribute( "minScaleDenominator", "-1" ).toDouble(); - maxScaleDenominator = elem.attribute( "maxScaleDenominator", "-1" ).toDouble(); - - //mm vs map units - if ( elem.attribute( "sizeType" ) == "MM" ) - { - sizeType = MM; - } - else - { - sizeType = MapUnits; - } - - //colors - categoryColors.clear(); - QStringList colorList = elem.attribute( "colors" ).split( "/" ); - QStringList::const_iterator colorIt = colorList.constBegin(); - for ( ; colorIt != colorList.constEnd(); ++colorIt ) - { - categoryColors.append( QColor( *colorIt ) ); - } - - //attribute indices - categoryIndices.clear(); - QStringList catList = elem.attribute( "categories" ).split( "/" ); - QStringList::const_iterator catIt = catList.constBegin(); - for ( ; catIt != catList.constEnd(); ++catIt ) - { - categoryIndices.append( catIt->toInt() ); - } -} - -void QgsDiagramSettings::writeXML( QDomElement& rendererElem, QDomDocument& doc ) const -{ - QDomElement categoryElem = doc.createElement( "DiagramCategory" ); - categoryElem.setAttribute( "font", font.toString() ); - categoryElem.setAttribute( "backgroundColor", backgroundColor.name() ); - categoryElem.setAttribute( "backgroundAlpha", backgroundColor.alpha() ); - categoryElem.setAttribute( "width", QString::number( size.width() ) ); - categoryElem.setAttribute( "height", QString::number( size.height() ) ); - categoryElem.setAttribute( "penColor", penColor.name() ); - categoryElem.setAttribute( "penWidth", QString::number( penWidth ) ); - categoryElem.setAttribute( "minScaleDenominator", QString::number( minScaleDenominator ) ); - categoryElem.setAttribute( "maxScaleDenominator", QString::number( maxScaleDenominator ) ); - if ( sizeType == MM ) - { - categoryElem.setAttribute( "sizeType", "MM" ); - } - else - { - categoryElem.setAttribute( "sizeType", "MapUnits" ); - } - - QString colors; - for ( int i = 0; i < categoryColors.size(); ++i ) - { - if ( i > 0 ) - { - colors.append( "/" ); - } - colors.append( categoryColors.at( i ).name() ); - } - categoryElem.setAttribute( "colors", colors ); - - QString categories; - for ( int i = 0; i < categoryIndices.size(); ++i ) - { - if ( i > 0 ) - { - categories.append( "/" ); - } - categories.append( QString::number( categoryIndices.at( i ) ) ); - } - categoryElem.setAttribute( "categories", categories ); - - rendererElem.appendChild( categoryElem ); -} - -QgsDiagramRendererV2::QgsDiagramRendererV2(): mDiagram( 0 ) -{ -} - -QgsDiagramRendererV2::~QgsDiagramRendererV2() -{ - delete mDiagram; -} - -void QgsDiagramRendererV2::setDiagram( QgsDiagram* d ) -{ - delete mDiagram; - mDiagram = d; -} - -void QgsDiagramRendererV2::renderDiagram( const QgsAttributeMap& att, QgsRenderContext& c, const QPointF& pos ) -{ - if ( !mDiagram ) - { - return; - } - - QgsDiagramSettings s; - if ( !diagramSettings( att, c, s ) ) - { - return; - } - - mDiagram->renderDiagram( att, c, s, pos ); -} - -QSizeF QgsDiagramRendererV2::sizeMapUnits( const QgsAttributeMap& attributes, const QgsRenderContext& c ) -{ - QgsDiagramSettings s; - if ( !diagramSettings( attributes, c, s ) ) - { - return QSizeF(); - } - - QSizeF size = diagramSize( attributes, c ); - if ( s.sizeType == QgsDiagramSettings::MM ) - { - convertSizeToMapUnits( size, c ); - } - return size; -} - -void QgsDiagramRendererV2::convertSizeToMapUnits( QSizeF& size, const QgsRenderContext& context ) const -{ - if ( !size.isValid() ) - { - return; - } - - int dpi = dpiPaintDevice( context.constPainter() ); - if ( dpi < 0 ) - { - return; - } - - double pixelToMap = dpi / 25.4 * context.mapToPixel().mapUnitsPerPixel(); - size.rwidth() *= pixelToMap; - size.rheight() *= pixelToMap; -} - -int QgsDiagramRendererV2::dpiPaintDevice( const QPainter* painter ) -{ - if ( painter ) - { - QPaintDevice* device = painter->device(); - if ( device ) - { - return device->logicalDpiX(); - } - } - return -1; -} - -void QgsDiagramRendererV2::_readXML( const QDomElement& elem ) -{ - delete mDiagram; - QString diagramType = elem.attribute( "diagramType" ); - if ( diagramType == "Pie" ) - { - mDiagram = new QgsPieDiagram(); - } - else if ( diagramType == "Text" ) - { - mDiagram = new QgsTextDiagram(); - } - else - { - mDiagram = 0; - } -} - -void QgsDiagramRendererV2::_writeXML( QDomElement& rendererElem, QDomDocument& doc ) const -{ - Q_UNUSED( doc ); - if ( mDiagram ) - { - rendererElem.setAttribute( "diagramType", mDiagram->diagramName() ); - } -} - -QgsSingleCategoryDiagramRenderer::QgsSingleCategoryDiagramRenderer(): QgsDiagramRendererV2() -{ -} - -QgsSingleCategoryDiagramRenderer::~QgsSingleCategoryDiagramRenderer() -{ -} - -bool QgsSingleCategoryDiagramRenderer::diagramSettings( const QgsAttributeMap&, const QgsRenderContext& c, QgsDiagramSettings& s ) -{ - Q_UNUSED( c ); - s = mSettings; - return true; -} - -QList QgsSingleCategoryDiagramRenderer::diagramSettings() const -{ - QList settingsList; - settingsList.push_back( mSettings ); - return settingsList; -} - -void QgsSingleCategoryDiagramRenderer::readXML( const QDomElement& elem ) -{ - QDomElement categoryElem = elem.firstChildElement( "DiagramCategory" ); - if ( categoryElem.isNull() ) - { - return; - } - - mSettings.readXML( categoryElem ); - _readXML( elem ); -} - -void QgsSingleCategoryDiagramRenderer::writeXML( QDomElement& layerElem, QDomDocument& doc ) const -{ - QDomElement rendererElem = doc.createElement( "SingleCategoryDiagramRenderer" ); - mSettings.writeXML( rendererElem, doc ); - _writeXML( rendererElem, doc ); - layerElem.appendChild( rendererElem ); -} - - -QgsLinearlyInterpolatedDiagramRenderer::QgsLinearlyInterpolatedDiagramRenderer(): QgsDiagramRendererV2() -{ -} - -QgsLinearlyInterpolatedDiagramRenderer::~QgsLinearlyInterpolatedDiagramRenderer() -{ -} - -QList QgsLinearlyInterpolatedDiagramRenderer::diagramSettings() const -{ - QList settingsList; - settingsList.push_back( mSettings ); - return settingsList; -} - -bool QgsLinearlyInterpolatedDiagramRenderer::diagramSettings( const QgsAttributeMap& attributes, const QgsRenderContext& c, QgsDiagramSettings& s ) -{ - s = mSettings; - s.size = diagramSize( attributes, c ); - return true; -} - -QList QgsLinearlyInterpolatedDiagramRenderer::diagramAttributes() const -{ - QList attributes = mSettings.categoryIndices; - if ( !attributes.contains( mClassificationAttribute ) ) - { - attributes.push_back( mClassificationAttribute ); - } - return attributes; -} - -QSizeF QgsLinearlyInterpolatedDiagramRenderer::diagramSize( const QgsAttributeMap& attributes, const QgsRenderContext& c ) -{ - Q_UNUSED( c ); - QgsAttributeMap::const_iterator attIt = attributes.find( mClassificationAttribute ); - if ( attIt == attributes.constEnd() ) - { - return QSizeF(); //zero size if attribute is missing - } - double value = attIt.value().toDouble(); - - //interpolate size - double ratio = ( value - mLowerValue ) / ( mUpperValue - mLowerValue ); - return QSizeF( mUpperSize.width() * ratio + mLowerSize.width() * ( 1 - ratio ), - mUpperSize.height() * ratio + mLowerSize.height() * ( 1 - ratio ) ); -} - -void QgsLinearlyInterpolatedDiagramRenderer::readXML( const QDomElement& elem ) -{ - mLowerValue = elem.attribute( "lowerValue" ).toDouble(); - mUpperValue = elem.attribute( "upperValue" ).toDouble(); - mLowerSize.setWidth( elem.attribute( "lowerWidth" ).toDouble() ); - mLowerSize.setHeight( elem.attribute( "lowerHeight" ).toDouble() ); - mUpperSize.setWidth( elem.attribute( "upperWidth" ).toDouble() ); - mUpperSize.setHeight( elem.attribute( "upperHeight" ).toDouble() ); - mClassificationAttribute = elem.attribute( "classificationAttribute" ).toInt(); - QDomElement settingsElem = elem.firstChildElement( "DiagramCategory" ); - if ( !settingsElem.isNull() ) - { - mSettings.readXML( settingsElem ); - } - _readXML( elem ); -} - -void QgsLinearlyInterpolatedDiagramRenderer::writeXML( QDomElement& layerElem, QDomDocument& doc ) const -{ - QDomElement rendererElem = doc.createElement( "LinearlyInterpolatedDiagramRenderer" ); - rendererElem.setAttribute( "lowerValue", QString::number( mLowerValue ) ); - rendererElem.setAttribute( "upperValue", QString::number( mUpperValue ) ); - rendererElem.setAttribute( "lowerWidth", QString::number( mLowerSize.width() ) ); - rendererElem.setAttribute( "lowerHeight", QString::number( mLowerSize.height() ) ); - rendererElem.setAttribute( "upperWidth", QString::number( mUpperSize.width() ) ); - rendererElem.setAttribute( "upperHeight", QString::number( mUpperSize.height() ) ); - rendererElem.setAttribute( "classificationAttribute", mClassificationAttribute ); - mSettings.writeXML( rendererElem, doc ); - _writeXML( rendererElem, doc ); - layerElem.appendChild( rendererElem ); -} +/*************************************************************************** + qgsdiagramrendererv2.cpp + --------------------- + begin : March 2011 + copyright : (C) 2011 by Marco Hugentobler + email : marco dot hugentobler at sourcepole dot ch + *************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ +#include "qgsdiagramrendererv2.h" +#include "qgsdiagram.h" +#include "qgsrendercontext.h" +#include +#include + + +void QgsDiagramLayerSettings::readXML( const QDomElement& elem ) +{ + placement = ( Placement )elem.attribute( "placement" ).toInt(); + placementFlags = ( LinePlacementFlags )elem.attribute( "linePlacementFlags" ).toInt(); + priority = elem.attribute( "priority" ).toInt(); + obstacle = elem.attribute( "obstacle" ).toInt(); + dist = elem.attribute( "dist" ).toDouble(); + xPosColumn = elem.attribute( "xPosColumn" ).toInt(); + yPosColumn = elem.attribute( "yPosColumn" ).toInt(); +} + +void QgsDiagramLayerSettings::writeXML( QDomElement& layerElem, QDomDocument& doc ) const +{ + QDomElement diagramLayerElem = doc.createElement( "DiagramLayerSettings" ); + diagramLayerElem.setAttribute( "placement", placement ); + diagramLayerElem.setAttribute( "linePlacementFlags", placementFlags ); + diagramLayerElem.setAttribute( "priority", priority ); + diagramLayerElem.setAttribute( "obstacle", obstacle ); + diagramLayerElem.setAttribute( "dist", QString::number( dist ) ); + diagramLayerElem.setAttribute( "xPosColumn", xPosColumn ); + diagramLayerElem.setAttribute( "yPosColumn", yPosColumn ); + layerElem.appendChild( diagramLayerElem ); +} + +void QgsDiagramSettings::readXML( const QDomElement& elem ) +{ + font.fromString( elem.attribute( "font" ) ); + backgroundColor.setNamedColor( elem.attribute( "backgroundColor" ) ); + backgroundColor.setAlpha( elem.attribute( "backgroundAlpha" ).toInt() ); + size.setWidth( elem.attribute( "width" ).toDouble() ); + size.setHeight( elem.attribute( "height" ).toDouble() ); + penColor.setNamedColor( elem.attribute( "penColor" ) ); + penWidth = elem.attribute( "penWidth" ).toDouble(); + minScaleDenominator = elem.attribute( "minScaleDenominator", "-1" ).toDouble(); + maxScaleDenominator = elem.attribute( "maxScaleDenominator", "-1" ).toDouble(); + + //mm vs map units + if ( elem.attribute( "sizeType" ) == "MM" ) + { + sizeType = MM; + } + else + { + sizeType = MapUnits; + } + + //label placement method + if ( elem.attribute( "labelPlacementMethod" ) == "Height" ) + { + labelPlacementMethod = Height; + } + else + { + labelPlacementMethod = XHeight; + } + + + //colors + categoryColors.clear(); + QStringList colorList = elem.attribute( "colors" ).split( "/" ); + QStringList::const_iterator colorIt = colorList.constBegin(); + for ( ; colorIt != colorList.constEnd(); ++colorIt ) + { + categoryColors.append( QColor( *colorIt ) ); + } + + //attribute indices + categoryIndices.clear(); + QStringList catList = elem.attribute( "categories" ).split( "/" ); + QStringList::const_iterator catIt = catList.constBegin(); + for ( ; catIt != catList.constEnd(); ++catIt ) + { + categoryIndices.append( catIt->toInt() ); + } +} + +void QgsDiagramSettings::writeXML( QDomElement& rendererElem, QDomDocument& doc ) const +{ + QDomElement categoryElem = doc.createElement( "DiagramCategory" ); + categoryElem.setAttribute( "font", font.toString() ); + categoryElem.setAttribute( "backgroundColor", backgroundColor.name() ); + categoryElem.setAttribute( "backgroundAlpha", backgroundColor.alpha() ); + categoryElem.setAttribute( "width", QString::number( size.width() ) ); + categoryElem.setAttribute( "height", QString::number( size.height() ) ); + categoryElem.setAttribute( "penColor", penColor.name() ); + categoryElem.setAttribute( "penWidth", QString::number( penWidth ) ); + categoryElem.setAttribute( "minScaleDenominator", QString::number( minScaleDenominator ) ); + categoryElem.setAttribute( "maxScaleDenominator", QString::number( maxScaleDenominator ) ); + if ( sizeType == MM ) + { + categoryElem.setAttribute( "sizeType", "MM" ); + } + else + { + categoryElem.setAttribute( "sizeType", "MapUnits" ); + } + + if ( labelPlacementMethod == Height ) + { + categoryElem.setAttribute( "labelPlacementMethod", "Height" ); + } + else + { + categoryElem.setAttribute( "labelPlacementMethod", "XHeight" ); + } + + + QString colors; + for ( int i = 0; i < categoryColors.size(); ++i ) + { + if ( i > 0 ) + { + colors.append( "/" ); + } + colors.append( categoryColors.at( i ).name() ); + } + categoryElem.setAttribute( "colors", colors ); + + QString categories; + for ( int i = 0; i < categoryIndices.size(); ++i ) + { + if ( i > 0 ) + { + categories.append( "/" ); + } + categories.append( QString::number( categoryIndices.at( i ) ) ); + } + categoryElem.setAttribute( "categories", categories ); + + rendererElem.appendChild( categoryElem ); +} + +QgsDiagramRendererV2::QgsDiagramRendererV2(): mDiagram( 0 ) +{ +} + +QgsDiagramRendererV2::~QgsDiagramRendererV2() +{ + delete mDiagram; +} + +void QgsDiagramRendererV2::setDiagram( QgsDiagram* d ) +{ + delete mDiagram; + mDiagram = d; +} + +void QgsDiagramRendererV2::renderDiagram( const QgsAttributeMap& att, QgsRenderContext& c, const QPointF& pos ) +{ + if ( !mDiagram ) + { + return; + } + + QgsDiagramSettings s; + if ( !diagramSettings( att, c, s ) ) + { + return; + } + + mDiagram->renderDiagram( att, c, s, pos ); +} + +QSizeF QgsDiagramRendererV2::sizeMapUnits( const QgsAttributeMap& attributes, const QgsRenderContext& c ) +{ + QgsDiagramSettings s; + if ( !diagramSettings( attributes, c, s ) ) + { + return QSizeF(); + } + + QSizeF size = diagramSize( attributes, c ); + if ( s.sizeType == QgsDiagramSettings::MM ) + { + convertSizeToMapUnits( size, c ); + } + return size; +} + +void QgsDiagramRendererV2::convertSizeToMapUnits( QSizeF& size, const QgsRenderContext& context ) const +{ + if ( !size.isValid() ) + { + return; + } + + int dpi = dpiPaintDevice( context.constPainter() ); + if ( dpi < 0 ) + { + return; + } + + double pixelToMap = dpi / 25.4 * context.mapToPixel().mapUnitsPerPixel(); + size.rwidth() *= pixelToMap; + size.rheight() *= pixelToMap; +} + +int QgsDiagramRendererV2::dpiPaintDevice( const QPainter* painter ) +{ + if ( painter ) + { + QPaintDevice* device = painter->device(); + if ( device ) + { + return device->logicalDpiX(); + } + } + return -1; +} + +void QgsDiagramRendererV2::_readXML( const QDomElement& elem ) +{ + delete mDiagram; + QString diagramType = elem.attribute( "diagramType" ); + if ( diagramType == "Pie" ) + { + mDiagram = new QgsPieDiagram(); + } + else if ( diagramType == "Text" ) + { + mDiagram = new QgsTextDiagram(); + } + else + { + mDiagram = 0; + } +} + +void QgsDiagramRendererV2::_writeXML( QDomElement& rendererElem, QDomDocument& doc ) const +{ + Q_UNUSED( doc ); + if ( mDiagram ) + { + rendererElem.setAttribute( "diagramType", mDiagram->diagramName() ); + } +} + +QgsSingleCategoryDiagramRenderer::QgsSingleCategoryDiagramRenderer(): QgsDiagramRendererV2() +{ +} + +QgsSingleCategoryDiagramRenderer::~QgsSingleCategoryDiagramRenderer() +{ +} + +bool QgsSingleCategoryDiagramRenderer::diagramSettings( const QgsAttributeMap&, const QgsRenderContext& c, QgsDiagramSettings& s ) +{ + Q_UNUSED( c ); + s = mSettings; + return true; +} + +QList QgsSingleCategoryDiagramRenderer::diagramSettings() const +{ + QList settingsList; + settingsList.push_back( mSettings ); + return settingsList; +} + +void QgsSingleCategoryDiagramRenderer::readXML( const QDomElement& elem ) +{ + QDomElement categoryElem = elem.firstChildElement( "DiagramCategory" ); + if ( categoryElem.isNull() ) + { + return; + } + + mSettings.readXML( categoryElem ); + _readXML( elem ); +} + +void QgsSingleCategoryDiagramRenderer::writeXML( QDomElement& layerElem, QDomDocument& doc ) const +{ + QDomElement rendererElem = doc.createElement( "SingleCategoryDiagramRenderer" ); + mSettings.writeXML( rendererElem, doc ); + _writeXML( rendererElem, doc ); + layerElem.appendChild( rendererElem ); +} + + +QgsLinearlyInterpolatedDiagramRenderer::QgsLinearlyInterpolatedDiagramRenderer(): QgsDiagramRendererV2() +{ +} + +QgsLinearlyInterpolatedDiagramRenderer::~QgsLinearlyInterpolatedDiagramRenderer() +{ +} + +QList QgsLinearlyInterpolatedDiagramRenderer::diagramSettings() const +{ + QList settingsList; + settingsList.push_back( mSettings ); + return settingsList; +} + +bool QgsLinearlyInterpolatedDiagramRenderer::diagramSettings( const QgsAttributeMap& attributes, const QgsRenderContext& c, QgsDiagramSettings& s ) +{ + s = mSettings; + s.size = diagramSize( attributes, c ); + return true; +} + +QList QgsLinearlyInterpolatedDiagramRenderer::diagramAttributes() const +{ + QList attributes = mSettings.categoryIndices; + if ( !attributes.contains( mClassificationAttribute ) ) + { + attributes.push_back( mClassificationAttribute ); + } + return attributes; +} + +QSizeF QgsLinearlyInterpolatedDiagramRenderer::diagramSize( const QgsAttributeMap& attributes, const QgsRenderContext& c ) +{ + Q_UNUSED( c ); + QgsAttributeMap::const_iterator attIt = attributes.find( mClassificationAttribute ); + if ( attIt == attributes.constEnd() ) + { + return QSizeF(); //zero size if attribute is missing + } + double value = attIt.value().toDouble(); + + //interpolate size + double ratio = ( value - mLowerValue ) / ( mUpperValue - mLowerValue ); + return QSizeF( mUpperSize.width() * ratio + mLowerSize.width() * ( 1 - ratio ), + mUpperSize.height() * ratio + mLowerSize.height() * ( 1 - ratio ) ); +} + +void QgsLinearlyInterpolatedDiagramRenderer::readXML( const QDomElement& elem ) +{ + mLowerValue = elem.attribute( "lowerValue" ).toDouble(); + mUpperValue = elem.attribute( "upperValue" ).toDouble(); + mLowerSize.setWidth( elem.attribute( "lowerWidth" ).toDouble() ); + mLowerSize.setHeight( elem.attribute( "lowerHeight" ).toDouble() ); + mUpperSize.setWidth( elem.attribute( "upperWidth" ).toDouble() ); + mUpperSize.setHeight( elem.attribute( "upperHeight" ).toDouble() ); + mClassificationAttribute = elem.attribute( "classificationAttribute" ).toInt(); + QDomElement settingsElem = elem.firstChildElement( "DiagramCategory" ); + if ( !settingsElem.isNull() ) + { + mSettings.readXML( settingsElem ); + } + _readXML( elem ); +} + +void QgsLinearlyInterpolatedDiagramRenderer::writeXML( QDomElement& layerElem, QDomDocument& doc ) const +{ + QDomElement rendererElem = doc.createElement( "LinearlyInterpolatedDiagramRenderer" ); + rendererElem.setAttribute( "lowerValue", QString::number( mLowerValue ) ); + rendererElem.setAttribute( "upperValue", QString::number( mUpperValue ) ); + rendererElem.setAttribute( "lowerWidth", QString::number( mLowerSize.width() ) ); + rendererElem.setAttribute( "lowerHeight", QString::number( mLowerSize.height() ) ); + rendererElem.setAttribute( "upperWidth", QString::number( mUpperSize.width() ) ); + rendererElem.setAttribute( "upperHeight", QString::number( mUpperSize.height() ) ); + rendererElem.setAttribute( "classificationAttribute", mClassificationAttribute ); + mSettings.writeXML( rendererElem, doc ); + _writeXML( rendererElem, doc ); + layerElem.appendChild( rendererElem ); +} diff --git a/src/core/qgsdiagramrendererv2.h b/src/core/qgsdiagramrendererv2.h index ea2a08642de..5022455bd07 100644 --- a/src/core/qgsdiagramrendererv2.h +++ b/src/core/qgsdiagramrendererv2.h @@ -1,247 +1,254 @@ -/*************************************************************************** - qgsdiagramrendererv2.h - --------------------- - begin : March 2011 - copyright : (C) 2011 by Marco Hugentobler - email : marco dot hugentobler at sourcepole dot ch - *************************************************************************** - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - ***************************************************************************/ -#ifndef QGSDIAGRAMRENDERERV2_H -#define QGSDIAGRAMRENDERERV2_H - -#include -#include -#include -#include -#include -#include "qgsfeature.h" -#include "qgspallabeling.h" - -class QgsDiagram; -class QgsDiagramRendererV2; -class QgsFeature; -class QgsRenderContext; -class QDomElement; -namespace pal { class Layer; } - -struct CORE_EXPORT QgsDiagramLayerSettings -{ - //avoid inclusion of QgsPalLabeling - enum Placement - { - AroundPoint, // Point / Polygon - OverPoint, // Point / Polygon - Line, // Line / Polygon - Curved, // Line - Horizontal, // Polygon - Free // Polygon - }; - - enum LinePlacementFlags - { - OnLine = 1, - AboveLine = 2, - BelowLine = 4, - MapOrientation = 8 - }; - - QgsDiagramLayerSettings() - : placement( AroundPoint ) - , placementFlags( OnLine ) - , priority( 5 ) - , obstacle( false ) - , dist( 0.0 ) - , renderer( 0 ) - , palLayer( 0 ) - , ct( 0 ) - , xform( 0 ) - , xPosColumn( -1 ) - , yPosColumn( -1 ) - { - } - - //pal placement properties - Placement placement; - LinePlacementFlags placementFlags; - int priority; // 0 = low, 10 = high - bool obstacle; // whether it's an obstacle - double dist; // distance from the feature (in mm) - QgsDiagramRendererV2* renderer; - - //assigned when layer gets prepared - pal::Layer* palLayer; - const QgsCoordinateTransform* ct; - const QgsMapToPixel* xform; - QList geometries; - - int xPosColumn; //attribute index for x coordinate (or -1 if position not data defined) - int yPosColumn;//attribute index for y coordinate (or -1 if position not data defined) - - void readXML( const QDomElement& elem ); - void writeXML( QDomElement& layerElem, QDomDocument& doc ) const; -}; - -//diagram settings for rendering -struct CORE_EXPORT QgsDiagramSettings -{ - enum SizeType - { - MM, - MapUnits - }; - - QgsDiagramSettings(): sizeType( MM ), minScaleDenominator( -1 ), maxScaleDenominator( -1 ) - {} - QFont font; - QList< QColor > categoryColors; - QList< int > categoryIndices; - QSizeF size; //size - SizeType sizeType; //mm or map units - QColor backgroundColor; - QColor penColor; - double penWidth; - - //scale range (-1 if no lower / upper bound ) - double minScaleDenominator; - double maxScaleDenominator; - - void readXML( const QDomElement& elem ); - void writeXML( QDomElement& rendererElem, QDomDocument& doc ) const; -}; - -/**Returns diagram settings for a feature*/ -class CORE_EXPORT QgsDiagramRendererV2 -{ - public: - - QgsDiagramRendererV2(); - virtual ~QgsDiagramRendererV2(); - - /**Returns size of the diagram for feature f in map units. Returns an invalid QSizeF in case of error*/ - virtual QSizeF sizeMapUnits( const QgsAttributeMap& attributes, const QgsRenderContext& c ); - - virtual QString rendererName() const = 0; - - /**Returns attribute indices needed for diagram rendering*/ - virtual QList diagramAttributes() const = 0; - - void renderDiagram( const QgsAttributeMap& att, QgsRenderContext& c, const QPointF& pos ); - - void setDiagram( QgsDiagram* d ); - const QgsDiagram* diagram() const { return mDiagram; } - - /**Returns list with all diagram settings in the renderer*/ - virtual QList diagramSettings() const = 0; - - virtual void readXML( const QDomElement& elem ) = 0; - virtual void writeXML( QDomElement& layerElem, QDomDocument& doc ) const = 0; - - protected: - - /**Returns diagram settings for a feature (or false if the diagram for the feature is not to be rendered). Used internally within renderDiagram() - * @param att attribute map - * @param c render context - * @param s out: diagram settings for the feature - */ - virtual bool diagramSettings( const QgsAttributeMap& att, const QgsRenderContext& c, QgsDiagramSettings& s ) = 0; - - /**Returns size of the diagram (in painter units) or an invalid size in case of error*/ - virtual QSizeF diagramSize( const QgsAttributeMap& attributes, const QgsRenderContext& c ) = 0; - - /**Converts size from mm to map units*/ - void convertSizeToMapUnits( QSizeF& size, const QgsRenderContext& context ) const; - - /**Returns the paint device dpi (or -1 in case of error*/ - static int dpiPaintDevice( const QPainter* ); - - //read / write diagram - void _readXML( const QDomElement& elem ); - void _writeXML( QDomElement& rendererElem, QDomDocument& doc ) const; - - /**Reference to the object that does the real diagram rendering*/ - QgsDiagram* mDiagram; -}; - -/**Renders the diagrams for all features with the same settings*/ -class CORE_EXPORT QgsSingleCategoryDiagramRenderer: public QgsDiagramRendererV2 -{ - public: - QgsSingleCategoryDiagramRenderer(); - ~QgsSingleCategoryDiagramRenderer(); - - QString rendererName() const { return "SingleCategory"; } - - QList diagramAttributes() const { return mSettings.categoryIndices; } - - void setDiagramSettings( const QgsDiagramSettings& s ) { mSettings = s; } - - QList diagramSettings() const; - - void readXML( const QDomElement& elem ); - void writeXML( QDomElement& layerElem, QDomDocument& doc ) const; - - protected: - bool diagramSettings( const QgsAttributeMap&, const QgsRenderContext& c, QgsDiagramSettings& s ); - - QSizeF diagramSize( const QgsAttributeMap& attributes, const QgsRenderContext& c ) - { Q_UNUSED( attributes ); Q_UNUSED( c ); return mSettings.size; } - - private: - QgsDiagramSettings mSettings; -}; - -class CORE_EXPORT QgsLinearlyInterpolatedDiagramRenderer: public QgsDiagramRendererV2 -{ - public: - QgsLinearlyInterpolatedDiagramRenderer(); - ~QgsLinearlyInterpolatedDiagramRenderer(); - - /**Returns list with all diagram settings in the renderer*/ - QList diagramSettings() const; - - void setDiagramSettings( const QgsDiagramSettings& s ) { mSettings = s; } - - QList diagramAttributes() const; - - QString rendererName() const { return "LinearlyInterpolated"; } - - void setLowerValue( double val ) { mLowerValue = val; } - double lowerValue() const { return mLowerValue; } - - void setUpperValue( double val ) { mUpperValue = val; } - double upperValue() const { return mUpperValue; } - - void setLowerSize( QSizeF s ) { mLowerSize = s; } - QSizeF lowerSize() const { return mLowerSize; } - - void setUpperSize( QSizeF s ) { mUpperSize = s; } - QSizeF upperSize() const { return mUpperSize; } - - int classificationAttribute() const { return mClassificationAttribute; } - void setClassificationAttribute( int index ) { mClassificationAttribute = index; } - - void readXML( const QDomElement& elem ); - void writeXML( QDomElement& layerElem, QDomDocument& doc ) const; - - protected: - bool diagramSettings( const QgsAttributeMap&, const QgsRenderContext& c, QgsDiagramSettings& s ); - - QSizeF diagramSize( const QgsAttributeMap& attributes, const QgsRenderContext& c ); - - private: - QgsDiagramSettings mSettings; - QSizeF mLowerSize; - QSizeF mUpperSize; - double mLowerValue; - double mUpperValue; - /**Index of the classification attribute*/ - int mClassificationAttribute; -}; - -#endif // QGSDIAGRAMRENDERERV2_H +/*************************************************************************** + qgsdiagramrendererv2.h + --------------------- + begin : March 2011 + copyright : (C) 2011 by Marco Hugentobler + email : marco dot hugentobler at sourcepole dot ch + *************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ +#ifndef QGSDIAGRAMRENDERERV2_H +#define QGSDIAGRAMRENDERERV2_H + +#include +#include +#include +#include +#include +#include "qgsfeature.h" +#include "qgspallabeling.h" + +class QgsDiagram; +class QgsDiagramRendererV2; +class QgsFeature; +class QgsRenderContext; +class QDomElement; +namespace pal { class Layer; } + +struct CORE_EXPORT QgsDiagramLayerSettings +{ + //avoid inclusion of QgsPalLabeling + enum Placement + { + AroundPoint, // Point / Polygon + OverPoint, // Point / Polygon + Line, // Line / Polygon + Curved, // Line + Horizontal, // Polygon + Free // Polygon + }; + + enum LinePlacementFlags + { + OnLine = 1, + AboveLine = 2, + BelowLine = 4, + MapOrientation = 8 + }; + + QgsDiagramLayerSettings() + : placement( AroundPoint ) + , placementFlags( OnLine ) + , priority( 5 ) + , obstacle( false ) + , dist( 0.0 ) + , renderer( 0 ) + , palLayer( 0 ) + , ct( 0 ) + , xform( 0 ) + , xPosColumn( -1 ) + , yPosColumn( -1 ) + { + } + + //pal placement properties + Placement placement; + LinePlacementFlags placementFlags; + int priority; // 0 = low, 10 = high + bool obstacle; // whether it's an obstacle + double dist; // distance from the feature (in mm) + QgsDiagramRendererV2* renderer; + + //assigned when layer gets prepared + pal::Layer* palLayer; + const QgsCoordinateTransform* ct; + const QgsMapToPixel* xform; + QList geometries; + + int xPosColumn; //attribute index for x coordinate (or -1 if position not data defined) + int yPosColumn;//attribute index for y coordinate (or -1 if position not data defined) + + void readXML( const QDomElement& elem ); + void writeXML( QDomElement& layerElem, QDomDocument& doc ) const; +}; + +//diagram settings for rendering +struct CORE_EXPORT QgsDiagramSettings +{ + enum SizeType + { + MM, + MapUnits + }; + + enum LabelPlacementMethod + { + Height, + XHeight + }; + + QgsDiagramSettings(): sizeType( MM ), minScaleDenominator( -1 ), maxScaleDenominator( -1 ) + {} + QFont font; + QList< QColor > categoryColors; + QList< int > categoryIndices; + QSizeF size; //size + SizeType sizeType; //mm or map units + QColor backgroundColor; + QColor penColor; + double penWidth; + LabelPlacementMethod labelPlacementMethod; + + //scale range (-1 if no lower / upper bound ) + double minScaleDenominator; + double maxScaleDenominator; + + void readXML( const QDomElement& elem ); + void writeXML( QDomElement& rendererElem, QDomDocument& doc ) const; +}; + +/**Returns diagram settings for a feature*/ +class CORE_EXPORT QgsDiagramRendererV2 +{ + public: + + QgsDiagramRendererV2(); + virtual ~QgsDiagramRendererV2(); + + /**Returns size of the diagram for feature f in map units. Returns an invalid QSizeF in case of error*/ + virtual QSizeF sizeMapUnits( const QgsAttributeMap& attributes, const QgsRenderContext& c ); + + virtual QString rendererName() const = 0; + + /**Returns attribute indices needed for diagram rendering*/ + virtual QList diagramAttributes() const = 0; + + void renderDiagram( const QgsAttributeMap& att, QgsRenderContext& c, const QPointF& pos ); + + void setDiagram( QgsDiagram* d ); + const QgsDiagram* diagram() const { return mDiagram; } + + /**Returns list with all diagram settings in the renderer*/ + virtual QList diagramSettings() const = 0; + + virtual void readXML( const QDomElement& elem ) = 0; + virtual void writeXML( QDomElement& layerElem, QDomDocument& doc ) const = 0; + + protected: + + /**Returns diagram settings for a feature (or false if the diagram for the feature is not to be rendered). Used internally within renderDiagram() + * @param att attribute map + * @param c render context + * @param s out: diagram settings for the feature + */ + virtual bool diagramSettings( const QgsAttributeMap& att, const QgsRenderContext& c, QgsDiagramSettings& s ) = 0; + + /**Returns size of the diagram (in painter units) or an invalid size in case of error*/ + virtual QSizeF diagramSize( const QgsAttributeMap& attributes, const QgsRenderContext& c ) = 0; + + /**Converts size from mm to map units*/ + void convertSizeToMapUnits( QSizeF& size, const QgsRenderContext& context ) const; + + /**Returns the paint device dpi (or -1 in case of error*/ + static int dpiPaintDevice( const QPainter* ); + + //read / write diagram + void _readXML( const QDomElement& elem ); + void _writeXML( QDomElement& rendererElem, QDomDocument& doc ) const; + + /**Reference to the object that does the real diagram rendering*/ + QgsDiagram* mDiagram; +}; + +/**Renders the diagrams for all features with the same settings*/ +class CORE_EXPORT QgsSingleCategoryDiagramRenderer: public QgsDiagramRendererV2 +{ + public: + QgsSingleCategoryDiagramRenderer(); + ~QgsSingleCategoryDiagramRenderer(); + + QString rendererName() const { return "SingleCategory"; } + + QList diagramAttributes() const { return mSettings.categoryIndices; } + + void setDiagramSettings( const QgsDiagramSettings& s ) { mSettings = s; } + + QList diagramSettings() const; + + void readXML( const QDomElement& elem ); + void writeXML( QDomElement& layerElem, QDomDocument& doc ) const; + + protected: + bool diagramSettings( const QgsAttributeMap&, const QgsRenderContext& c, QgsDiagramSettings& s ); + + QSizeF diagramSize( const QgsAttributeMap& attributes, const QgsRenderContext& c ) + { Q_UNUSED( attributes ); Q_UNUSED( c ); return mSettings.size; } + + private: + QgsDiagramSettings mSettings; +}; + +class CORE_EXPORT QgsLinearlyInterpolatedDiagramRenderer: public QgsDiagramRendererV2 +{ + public: + QgsLinearlyInterpolatedDiagramRenderer(); + ~QgsLinearlyInterpolatedDiagramRenderer(); + + /**Returns list with all diagram settings in the renderer*/ + QList diagramSettings() const; + + void setDiagramSettings( const QgsDiagramSettings& s ) { mSettings = s; } + + QList diagramAttributes() const; + + QString rendererName() const { return "LinearlyInterpolated"; } + + void setLowerValue( double val ) { mLowerValue = val; } + double lowerValue() const { return mLowerValue; } + + void setUpperValue( double val ) { mUpperValue = val; } + double upperValue() const { return mUpperValue; } + + void setLowerSize( QSizeF s ) { mLowerSize = s; } + QSizeF lowerSize() const { return mLowerSize; } + + void setUpperSize( QSizeF s ) { mUpperSize = s; } + QSizeF upperSize() const { return mUpperSize; } + + int classificationAttribute() const { return mClassificationAttribute; } + void setClassificationAttribute( int index ) { mClassificationAttribute = index; } + + void readXML( const QDomElement& elem ); + void writeXML( QDomElement& layerElem, QDomDocument& doc ) const; + + protected: + bool diagramSettings( const QgsAttributeMap&, const QgsRenderContext& c, QgsDiagramSettings& s ); + + QSizeF diagramSize( const QgsAttributeMap& attributes, const QgsRenderContext& c ); + + private: + QgsDiagramSettings mSettings; + QSizeF mLowerSize; + QSizeF mUpperSize; + double mLowerValue; + double mUpperValue; + /**Index of the classification attribute*/ + int mClassificationAttribute; +}; + +#endif // QGSDIAGRAMRENDERERV2_H diff --git a/src/ui/qgsvectorlayerpropertiesbase.ui b/src/ui/qgsvectorlayerpropertiesbase.ui index 6402a8855e5..dd9f444a2e3 100644 --- a/src/ui/qgsvectorlayerpropertiesbase.ui +++ b/src/ui/qgsvectorlayerpropertiesbase.ui @@ -14,7 +14,7 @@ Layer Properties - + :/images/icons/qgis-icon-16x16.png:/images/icons/qgis-icon-16x16.png @@ -76,7 +76,7 @@ - + :/images/themes/default/propertyicons/symbology.png:/images/themes/default/propertyicons/symbology.png @@ -186,7 +186,7 @@ - + :/images/themes/default/propertyicons/labels.png:/images/themes/default/propertyicons/labels.png @@ -250,7 +250,7 @@ - + :/images/themes/default/propertyicons/attributes.png:/images/themes/default/propertyicons/attributes.png @@ -273,7 +273,7 @@ - ../../../../../.designer/xpm/new_attribute.png../../../../../.designer/xpm/new_attribute.png + ../../../../../../.designer/xpm/new_attribute.png../../../../../../.designer/xpm/new_attribute.png Ctrl+N @@ -290,7 +290,7 @@ - ../../../../../.designer/xpm/delete_attribute.png../../../../../.designer/xpm/delete_attribute.png + ../../../../../../.designer/xpm/delete_attribute.png../../../../../../.designer/xpm/delete_attribute.png Ctrl+X @@ -365,7 +365,7 @@ - + :/images/themes/default/propertyicons/general.png:/images/themes/default/propertyicons/general.png @@ -737,7 +737,7 @@ - + :/images/themes/default/propertyicons/metadata.png:/images/themes/default/propertyicons/metadata.png @@ -822,7 +822,7 @@ - + :/images/themes/default/propertyicons/action.png:/images/themes/default/propertyicons/action.png @@ -849,7 +849,7 @@ - + :/images/themes/default/propertyicons/join.png:/images/themes/default/propertyicons/join.png @@ -883,7 +883,7 @@ - + :/images/themes/default/symbologyAdd.png:/images/themes/default/symbologyAdd.png @@ -894,7 +894,7 @@ - + :/images/themes/default/symbologyRemove.png:/images/themes/default/symbologyRemove.png @@ -942,7 +942,7 @@ - + :/images/themes/default/propertyicons/diagram.png:/images/themes/default/propertyicons/diagram.png @@ -1182,6 +1182,199 @@ + + + + Position + + + + + + + + Placement + + + + + + + + + + + + + + Line Options + + + + + + + + + + + + + + Distance + + + + + + + + + + + + Data defined position + + + + + + + + + + 0 + 0 + + + + x + + + + + + + + + + + + + + + 0 + 0 + + + + y + + + + + + + + + + + + + + Label placement: + + + + + + + + + + + + + + + Attributes + + + + + + + + 0 + 0 + + + + + + + + Qt::Horizontal + + + + 241 + 23 + + + + + + + + + 0 + 0 + + + + + + + + :/images/themes/default/symbologyRemove.png:/images/themes/default/symbologyRemove.png + + + + + + + + 0 + 0 + + + + + + + + :/images/themes/default/symbologyAdd.png:/images/themes/default/symbologyAdd.png + + + + + + + 2 + + + + Attribute + + + + + Color + + + + @@ -1280,185 +1473,6 @@ - - - - Position - - - - - - - - Placement - - - - - - - - - - - - - - Line Options - - - - - - - - - - - - - - Distance - - - - - - - - - - - - Data defined position - - - - - - - - - - 0 - 0 - - - - x - - - - - - - - - - - - - - - 0 - 0 - - - - y - - - - - - - - - - - - - - - Attributes - - - - - - - - 0 - 0 - - - - - - - - Qt::Horizontal - - - - 241 - 23 - - - - - - - - - 0 - 0 - - - - - - - - :/images/themes/default/symbologyRemove.png:/images/themes/default/symbologyRemove.png - - - - - - - - 0 - 0 - - - - - - - - :/images/themes/default/symbologyAdd.png:/images/themes/default/symbologyAdd.png - - - - - - - 2 - - - - Attribute - - - - - Color - - - - @@ -1485,7 +1499,7 @@ pbnQueryBuilder - + From d81df7c4051dd083b78f23aa75d773b75750cac0 Mon Sep 17 00:00:00 2001 From: Matthias Kuhn Date: Tue, 7 Aug 2012 15:40:11 +0200 Subject: [PATCH 3/9] Add .project file to .gitignore (eclipse) --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 41cf1d4bdf4..77e5342300c 100644 --- a/.gitignore +++ b/.gitignore @@ -43,3 +43,4 @@ scripts/RelWithDebInfo /CMakeLists.txt.user qgis-test.ctest i18n/*.qm +.project From bb8f1d6386ab1020c742fe17044b7bf71e274658 Mon Sep 17 00:00:00 2001 From: Matthias Kuhn Date: Tue, 7 Aug 2012 15:40:38 +0200 Subject: [PATCH 4/9] Add minimum size option for diagrams. (Will be scaled if smaller) --- src/app/qgsvectorlayerproperties.cpp | 44 ++++++++-- src/app/qgsvectorlayerproperties.h | 3 + src/core/qgsdiagramrendererv2.cpp | 12 ++- src/core/qgsdiagramrendererv2.h | 3 + src/ui/qgsvectorlayerpropertiesbase.ui | 114 ++++++++++++++++++------- 5 files changed, 134 insertions(+), 42 deletions(-) diff --git a/src/app/qgsvectorlayerproperties.cpp b/src/app/qgsvectorlayerproperties.cpp index 9c1d4909916..f14ab71f1e3 100755 --- a/src/app/qgsvectorlayerproperties.cpp +++ b/src/app/qgsvectorlayerproperties.cpp @@ -846,15 +846,24 @@ void QgsVectorLayerProperties::apply() ds.sizeType = QgsDiagramSettings::MM; } - if ( !tr( "Height" ).compare( mLabelPlacementComboBox->currentText() ) ) + if ( tr( "Height" ) == mLabelPlacementComboBox->currentText() ) { ds.labelPlacementMethod = QgsDiagramSettings::Height; } - else if ( !tr( "x-height" ).compare( mLabelPlacementComboBox->currentText() ) ) + else if ( tr( "x-height" ) == mLabelPlacementComboBox->currentText() ) { ds.labelPlacementMethod = QgsDiagramSettings::XHeight; } + if ( mIncreaseSmallDiagramsCheckBox->isChecked() ) + { + ds.mMinimumSize = mIncreaseMinimumSizeSpinBox->value(); + } + else + { + ds.mMinimumSize = 0; + } + ds.backgroundColor = mBackgroundColorButton->color(); ds.penColor = mDiagramPenColorButton->color(); ds.penWidth = mPenWidthSpinBox->value(); @@ -1329,6 +1338,20 @@ void QgsVectorLayerProperties::handleDiagramTypeChanged( const QString& itemtext } } +void QgsVectorLayerProperties::on_mIncreaseSmallDiagramsCheckBox_stateChanged( int state ) +{ + if ( Qt::Checked == state ) + { + mIncreaseMinimumSizeLabel->setEnabled( true ); + mIncreaseMinimumSizeSpinBox->setEnabled( true ); + } + else + { + mIncreaseMinimumSizeLabel->setEnabled( false ); + mIncreaseMinimumSizeSpinBox->setEnabled( false ); + } +} + void QgsVectorLayerProperties::useNewSymbology() { int res = QMessageBox::question( this, tr( "Symbology" ), @@ -1476,6 +1499,9 @@ void QgsVectorLayerProperties::on_mFixedSizeCheckBox_stateChanged( int state ) //enable / disable all widget in the scaling layout mLinearlyScalingLabel->setEnabled( state != Qt::Checked ); + mIncreaseSmallDiagramsCheckBox->setEnabled( state != Qt::Checked ); + mIncreaseMinimumSizeLabel->setEnabled( state != Qt::Checked && mIncreaseSmallDiagramsCheckBox->isChecked() == Qt::Checked ); + mIncreaseMinimumSizeSpinBox->setEnabled( state != Qt::Checked && mIncreaseSmallDiagramsCheckBox->isChecked() == Qt::Checked ); QWidget* currentWidget = 0; for ( int i = 0; i < mLinearlyScalingLayout->count(); ++i ) { @@ -1485,6 +1511,7 @@ void QgsVectorLayerProperties::on_mFixedSizeCheckBox_stateChanged( int state ) currentWidget->setEnabled( state != Qt::Checked ); } } + } void QgsVectorLayerProperties::on_mScaleDependentDiagramVisibilityCheckBox_stateChanged( int state ) @@ -1681,7 +1708,8 @@ void QgsVectorLayerProperties::initDiagramTab() mLabelPlacementComboBox->setCurrentIndex( 1 ); } - + mIncreaseSmallDiagramsCheckBox->setChecked( settingList.at( 0 ).mMinimumSize != 0 ); + mIncreaseMinimumSizeSpinBox->setValue( settingList.at( 0 ).mMinimumSize ); QList< QColor > categoryColors = settingList.at( 0 ).categoryColors; QList< int > categoryIndices = settingList.at( 0 ).categoryIndices; @@ -1734,8 +1762,10 @@ void QgsVectorLayerProperties::initDiagramTab() } // Hide/Show diagram specific widgets - handleDiagramTypeChanged( mDiagramTypeComboBox->currentText() ); - - QObject::connect( mDiagramAttributesTreeWidget, SIGNAL( itemDoubleClicked( QTreeWidgetItem*, int ) ), this, SLOT( handleDiagramItemDoubleClick( QTreeWidgetItem*, int ) ) ); - QObject::connect( mDiagramTypeComboBox, SIGNAL( currentIndexChanged( const QString& ) ), this, SLOT( handleDiagramTypeChanged( const QString& ) ) ); + // handleDiagramTypeChanged( mDiagramTypeComboBox->currentText() ); + // Enable / disable small diagram scaling related widgets + // on_mFixedSizeCheckBox_stateChanged( mIncreaseSmallDiagramsCheckBox->checkState() ); + connect( mDiagramAttributesTreeWidget, SIGNAL( itemDoubleClicked( QTreeWidgetItem*, int ) ), this, SLOT( handleDiagramItemDoubleClick( QTreeWidgetItem*, int ) ) ); + connect( mDiagramTypeComboBox, SIGNAL( currentIndexChanged( const QString& ) ), this, SLOT( handleDiagramTypeChanged( const QString& ) ) ); +// connect( mIncreaseSmallDiagramsCheckBox, SIGNAL( stateChanged( int ) ), this, SLOT( handleIncreaseSmallDiagramsChanged( int ) ) ); } diff --git a/src/app/qgsvectorlayerproperties.h b/src/app/qgsvectorlayerproperties.h index b76b2621b8a..7ddde792a2c 100644 --- a/src/app/qgsvectorlayerproperties.h +++ b/src/app/qgsvectorlayerproperties.h @@ -128,6 +128,7 @@ class QgsVectorLayerProperties : public QDialog, private Ui::QgsVectorLayerPrope void on_mBackgroundColorButton_clicked(); void on_mDiagramPenColorButton_clicked(); void on_pbnUpdateExtents_clicked(); + void on_mIncreaseSmallDiagramsCheckBox_stateChanged( int state ); void enableLabelOptions( bool theFlag ); void addAttribute(); @@ -145,6 +146,8 @@ class QgsVectorLayerProperties : public QDialog, private Ui::QgsVectorLayerPrope /**Set color for diagram category*/ void handleDiagramItemDoubleClick( QTreeWidgetItem * item, int column ); void handleDiagramTypeChanged( const QString& itemtext ); + /** The checkbox for small diagram scaling has been changed*/ + // void handleIncreaseSmallDiagramsChanged( int state ); signals: diff --git a/src/core/qgsdiagramrendererv2.cpp b/src/core/qgsdiagramrendererv2.cpp index 2a0dc68db33..c8718934d7f 100644 --- a/src/core/qgsdiagramrendererv2.cpp +++ b/src/core/qgsdiagramrendererv2.cpp @@ -343,8 +343,16 @@ QSizeF QgsLinearlyInterpolatedDiagramRenderer::diagramSize( const QgsAttributeMa //interpolate size double ratio = ( value - mLowerValue ) / ( mUpperValue - mLowerValue ); - return QSizeF( mUpperSize.width() * ratio + mLowerSize.width() * ( 1 - ratio ), - mUpperSize.height() * ratio + mLowerSize.height() * ( 1 - ratio ) ); + QSizeF size = QSizeF( mUpperSize.width() * ratio + mLowerSize.width() * ( 1 - ratio ), + mUpperSize.height() * ratio + mLowerSize.height() * ( 1 - ratio ) ); + + // Scale, if extension is smaller than the specified minimum + if ( size.width() <= mSettings.mMinimumSize && size.height() <= mSettings.mMinimumSize ) + { + size.scale( mSettings.mMinimumSize, mSettings.mMinimumSize, Qt::KeepAspectRatio ); + } + + return size; } void QgsLinearlyInterpolatedDiagramRenderer::readXML( const QDomElement& elem ) diff --git a/src/core/qgsdiagramrendererv2.h b/src/core/qgsdiagramrendererv2.h index 5022455bd07..302f29c093c 100644 --- a/src/core/qgsdiagramrendererv2.h +++ b/src/core/qgsdiagramrendererv2.h @@ -118,6 +118,9 @@ struct CORE_EXPORT QgsDiagramSettings double minScaleDenominator; double maxScaleDenominator; + //! Scale diagrams smaller than mMinimumSize to mMinimumSize + double mMinimumSize; + void readXML( const QDomElement& elem ); void writeXML( QDomElement& rendererElem, QDomDocument& doc ) const; }; diff --git a/src/ui/qgsvectorlayerpropertiesbase.ui b/src/ui/qgsvectorlayerpropertiesbase.ui index dd9f444a2e3..ea91b6fc01d 100644 --- a/src/ui/qgsvectorlayerpropertiesbase.ui +++ b/src/ui/qgsvectorlayerpropertiesbase.ui @@ -6,7 +6,7 @@ 0 0 - 762 + 842 672 @@ -14,7 +14,7 @@ Layer Properties - + :/images/icons/qgis-icon-16x16.png:/images/icons/qgis-icon-16x16.png @@ -76,7 +76,7 @@ - + :/images/themes/default/propertyicons/symbology.png:/images/themes/default/propertyicons/symbology.png @@ -186,7 +186,7 @@ - + :/images/themes/default/propertyicons/labels.png:/images/themes/default/propertyicons/labels.png @@ -250,7 +250,7 @@ - + :/images/themes/default/propertyicons/attributes.png:/images/themes/default/propertyicons/attributes.png @@ -365,7 +365,7 @@ - + :/images/themes/default/propertyicons/general.png:/images/themes/default/propertyicons/general.png @@ -391,8 +391,8 @@ 0 0 - 740 - 558 + 820 + 540 @@ -737,7 +737,7 @@ - + :/images/themes/default/propertyicons/metadata.png:/images/themes/default/propertyicons/metadata.png @@ -760,8 +760,8 @@ 0 0 - 722 - 540 + 802 + 522 @@ -822,7 +822,7 @@ - + :/images/themes/default/propertyicons/action.png:/images/themes/default/propertyicons/action.png @@ -849,7 +849,7 @@ - + :/images/themes/default/propertyicons/join.png:/images/themes/default/propertyicons/join.png @@ -872,8 +872,8 @@ 0 0 - 722 - 540 + 802 + 522 @@ -883,7 +883,7 @@ - + :/images/themes/default/symbologyAdd.png:/images/themes/default/symbologyAdd.png @@ -894,7 +894,7 @@ - + :/images/themes/default/symbologyRemove.png:/images/themes/default/symbologyRemove.png @@ -942,7 +942,7 @@ - + :/images/themes/default/propertyicons/diagram.png:/images/themes/default/propertyicons/diagram.png @@ -1284,10 +1284,17 @@ Label placement: + + false + - + + + false + + @@ -1336,7 +1343,7 @@ - + :/images/themes/default/symbologyRemove.png:/images/themes/default/symbologyRemove.png @@ -1353,7 +1360,7 @@ - + :/images/themes/default/symbologyAdd.png:/images/themes/default/symbologyAdd.png @@ -1381,6 +1388,16 @@ Size + + + + Scale linearly between 0 and the following attribute value / diagram size: + + + true + + + @@ -1408,17 +1425,7 @@ - - - - Scale linearly between 0 and the following attribute value / diagram size: - - - true - - - - + @@ -1470,6 +1477,47 @@ + + + + Increase size of small diagrams + + + + + + + + + false + + + Minimum size + + + + + + + false + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + @@ -1499,7 +1547,7 @@ pbnQueryBuilder - + From 98e637cf972e139656ea1419a6506bcbbe4e3dd4 Mon Sep 17 00:00:00 2001 From: Matthias Kuhn Date: Tue, 7 Aug 2012 16:38:12 +0200 Subject: [PATCH 5/9] Save settings for scaling small diagrams --- src/core/qgsdiagramrendererv2.cpp | 6 ++++-- src/core/qgsdiagramrendererv2.h | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/core/qgsdiagramrendererv2.cpp b/src/core/qgsdiagramrendererv2.cpp index c8718934d7f..32f6f2b67ae 100644 --- a/src/core/qgsdiagramrendererv2.cpp +++ b/src/core/qgsdiagramrendererv2.cpp @@ -75,6 +75,7 @@ void QgsDiagramSettings::readXML( const QDomElement& elem ) labelPlacementMethod = XHeight; } + minimumSize = elem.attribute( "minimumSize" ).toDouble(); //colors categoryColors.clear(); @@ -125,6 +126,7 @@ void QgsDiagramSettings::writeXML( QDomElement& rendererElem, QDomDocument& doc categoryElem.setAttribute( "labelPlacementMethod", "XHeight" ); } + categoryElem.setAttribute( "minimumSize", QString::number( minimumSize ) ); QString colors; for ( int i = 0; i < categoryColors.size(); ++i ) @@ -347,9 +349,9 @@ QSizeF QgsLinearlyInterpolatedDiagramRenderer::diagramSize( const QgsAttributeMa mUpperSize.height() * ratio + mLowerSize.height() * ( 1 - ratio ) ); // Scale, if extension is smaller than the specified minimum - if ( size.width() <= mSettings.mMinimumSize && size.height() <= mSettings.mMinimumSize ) + if ( size.width() <= mSettings.minimumSize && size.height() <= mSettings.minimumSize ) { - size.scale( mSettings.mMinimumSize, mSettings.mMinimumSize, Qt::KeepAspectRatio ); + size.scale( mSettings.minimumSize, mSettings.minimumSize, Qt::KeepAspectRatio ); } return size; diff --git a/src/core/qgsdiagramrendererv2.h b/src/core/qgsdiagramrendererv2.h index 302f29c093c..1784bad33b3 100644 --- a/src/core/qgsdiagramrendererv2.h +++ b/src/core/qgsdiagramrendererv2.h @@ -119,7 +119,7 @@ struct CORE_EXPORT QgsDiagramSettings double maxScaleDenominator; //! Scale diagrams smaller than mMinimumSize to mMinimumSize - double mMinimumSize; + double minimumSize; void readXML( const QDomElement& elem ); void writeXML( QDomElement& rendererElem, QDomDocument& doc ) const; From 79d537a9ef13b7c5870b4337a61bd08cce165300 Mon Sep 17 00:00:00 2001 From: Matthias Kuhn Date: Tue, 7 Aug 2012 16:56:35 +0200 Subject: [PATCH 6/9] Place pie charts on point --- src/core/qgsdiagram.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/qgsdiagram.cpp b/src/core/qgsdiagram.cpp index 0e6d7bc7531..f63c40d404b 100644 --- a/src/core/qgsdiagram.cpp +++ b/src/core/qgsdiagram.cpp @@ -293,8 +293,8 @@ void QgsPieDiagram::renderDiagram( const QgsAttributeMap& att, QgsRenderContext& double w = spu.width(); double h = spu.height(); - double baseX = position.x(); - double baseY = position.y() - h; + double baseX = position.x() - w / 2; + double baseY = position.y() - h / 2; mPen.setColor( s.penColor ); setPenWidth( mPen, s, c ); From 20f97d27dc741959980f78cd711f945b1147e3aa Mon Sep 17 00:00:00 2001 From: Matthias Kuhn Date: Wed, 8 Aug 2012 12:31:02 +0200 Subject: [PATCH 7/9] revert bad patch (placement) --- src/core/qgsdiagram.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/qgsdiagram.cpp b/src/core/qgsdiagram.cpp index f63c40d404b..0e6d7bc7531 100644 --- a/src/core/qgsdiagram.cpp +++ b/src/core/qgsdiagram.cpp @@ -293,8 +293,8 @@ void QgsPieDiagram::renderDiagram( const QgsAttributeMap& att, QgsRenderContext& double w = spu.width(); double h = spu.height(); - double baseX = position.x() - w / 2; - double baseY = position.y() - h / 2; + double baseX = position.x(); + double baseY = position.y() - h; mPen.setColor( s.penColor ); setPenWidth( mPen, s, c ); From 2c6b15210cdbe64924b64ab9c4e2275e88e17c4b Mon Sep 17 00:00:00 2001 From: Matthias Kuhn Date: Wed, 8 Aug 2012 15:26:12 +0200 Subject: [PATCH 8/9] Add histogram --- src/app/qgsvectorlayerproperties.cpp | 59 +++- src/core/qgsdiagram.cpp | 82 +++++ src/core/qgsdiagram.h | 16 + src/core/qgsdiagramrendererv2.cpp | 48 +++ src/core/qgsdiagramrendererv2.h | 10 + src/ui/qgsvectorlayerpropertiesbase.ui | 463 +++++++++++++++---------- 6 files changed, 490 insertions(+), 188 deletions(-) diff --git a/src/app/qgsvectorlayerproperties.cpp b/src/app/qgsvectorlayerproperties.cpp index f14ab71f1e3..8dccf02a01c 100755 --- a/src/app/qgsvectorlayerproperties.cpp +++ b/src/app/qgsvectorlayerproperties.cpp @@ -824,6 +824,10 @@ void QgsVectorLayerProperties::apply() { diagram = new QgsPieDiagram(); } + else if ( mDiagramTypeComboBox->currentText() == tr( "Histogram" ) ) + { + diagram = new QgsHistogramDiagram(); + } QgsDiagramSettings ds; ds.font = mDiagramFont; @@ -857,11 +861,11 @@ void QgsVectorLayerProperties::apply() if ( mIncreaseSmallDiagramsCheckBox->isChecked() ) { - ds.mMinimumSize = mIncreaseMinimumSizeSpinBox->value(); + ds.minimumSize = mIncreaseMinimumSizeSpinBox->value(); } else { - ds.mMinimumSize = 0; + ds.minimumSize = 0; } ds.backgroundColor = mBackgroundColorButton->color(); @@ -878,6 +882,24 @@ void QgsVectorLayerProperties::apply() ds.maxScaleDenominator = -1; } + // Diagram orientation (histogram) + if ( tr( "Up" ) == mOrientationButtonGroup->checkedButton()->text() ) + { + ds.diagramOrientation = QgsDiagramSettings::Up; + } + else if ( tr( "Down" ) == mOrientationButtonGroup->checkedButton()->text() ) + { + ds.diagramOrientation = QgsDiagramSettings::Down; + } + else if ( tr( "Right" ) == mOrientationButtonGroup->checkedButton()->text() ) + { + ds.diagramOrientation = QgsDiagramSettings::Right; + } + else if ( tr( "Left" ) == mOrientationButtonGroup->checkedButton()->text() ) + { + ds.diagramOrientation = QgsDiagramSettings::Left; + } + if ( mFixedSizeCheckBox->isChecked() ) { QgsSingleCategoryDiagramRenderer* dr = new QgsSingleCategoryDiagramRenderer(); @@ -1500,8 +1522,8 @@ void QgsVectorLayerProperties::on_mFixedSizeCheckBox_stateChanged( int state ) //enable / disable all widget in the scaling layout mLinearlyScalingLabel->setEnabled( state != Qt::Checked ); mIncreaseSmallDiagramsCheckBox->setEnabled( state != Qt::Checked ); - mIncreaseMinimumSizeLabel->setEnabled( state != Qt::Checked && mIncreaseSmallDiagramsCheckBox->isChecked() == Qt::Checked ); - mIncreaseMinimumSizeSpinBox->setEnabled( state != Qt::Checked && mIncreaseSmallDiagramsCheckBox->isChecked() == Qt::Checked ); + mIncreaseMinimumSizeLabel->setEnabled( state != Qt::Checked && mIncreaseSmallDiagramsCheckBox->isChecked() ); + mIncreaseMinimumSizeSpinBox->setEnabled( state != Qt::Checked && mIncreaseSmallDiagramsCheckBox->isChecked() ); QWidget* currentWidget = 0; for ( int i = 0; i < mLinearlyScalingLayout->count(); ++i ) { @@ -1614,6 +1636,7 @@ void QgsVectorLayerProperties::initDiagramTab() mDiagramTypeComboBox->addItem( tr( "Pie chart" ) ); mDiagramTypeComboBox->addItem( tr( "Text diagram" ) ); + mDiagramTypeComboBox->addItem( tr( "Histogram" ) ); mLabelPlacementComboBox->addItem( tr( "Height" ) ); mLabelPlacementComboBox->addItem( tr( "x-height" ) ); @@ -1708,8 +1731,28 @@ void QgsVectorLayerProperties::initDiagramTab() mLabelPlacementComboBox->setCurrentIndex( 1 ); } - mIncreaseSmallDiagramsCheckBox->setChecked( settingList.at( 0 ).mMinimumSize != 0 ); - mIncreaseMinimumSizeSpinBox->setValue( settingList.at( 0 ).mMinimumSize ); + switch( settingList.at( 0 ).diagramOrientation ) + { + case QgsDiagramSettings::Left: + mOrientationLeftButton->setChecked( true ); + break; + + case QgsDiagramSettings::Right: + mOrientationRightButton->setChecked( true ); + break; + + case QgsDiagramSettings::Up: + mOrientationUpButton->setChecked( true ); + break; + + case QgsDiagramSettings::Down: + mOrientationDownButton->setChecked( true ); + break; + + } + + mIncreaseSmallDiagramsCheckBox->setChecked( settingList.at( 0 ).minimumSize != 0 ); + mIncreaseMinimumSizeSpinBox->setValue( settingList.at( 0 ).minimumSize ); QList< QColor > categoryColors = settingList.at( 0 ).categoryColors; QList< int > categoryIndices = settingList.at( 0 ).categoryIndices; @@ -1758,6 +1801,10 @@ void QgsVectorLayerProperties::initDiagramTab() { mDiagramTypeComboBox->setCurrentIndex( mDiagramTypeComboBox->findText( tr( "Pie chart" ) ) ); } + else if ( diagramName == "Histogram" ) + { + mDiagramTypeComboBox->setCurrentIndex( mDiagramTypeComboBox->findText( tr( "Histogram" ) ) ); + } } } diff --git a/src/core/qgsdiagram.cpp b/src/core/qgsdiagram.cpp index 0e6d7bc7531..a281be2c2de 100644 --- a/src/core/qgsdiagram.cpp +++ b/src/core/qgsdiagram.cpp @@ -43,6 +43,18 @@ QSizeF QgsDiagram::sizePainterUnits( const QSizeF& size, const QgsDiagramSetting } } +float QgsDiagram::sizePainterUnits( float l, const QgsDiagramSettings& s, const QgsRenderContext& c ) +{ + if ( s.sizeType == QgsDiagramSettings::MM ) + { + return l * c.scaleFactor(); + } + else + { + return l / c.mapToPixel().mapUnitsPerPixel(); + } +} + QFont QgsDiagram::scaledFont( const QgsDiagramSettings& s, const QgsRenderContext& c ) { QFont f = s.font; @@ -311,3 +323,73 @@ void QgsPieDiagram::renderDiagram( const QgsAttributeMap& att, QgsRenderContext& totalAngle += currentAngle; } } + +QgsHistogramDiagram::QgsHistogramDiagram() +{ + mCategoryBrush.setStyle( Qt::SolidPattern ); + mPen.setStyle( Qt::SolidLine ); +} + +QgsHistogramDiagram::~QgsHistogramDiagram() +{ +} + +void QgsHistogramDiagram::renderDiagram( const QgsAttributeMap& att, QgsRenderContext& c, const QgsDiagramSettings& s, const QPointF& position ) +{ + QPainter* p = c.painter(); + if ( !p ) + { + return; + } + + QList values; + + QList::const_iterator catIt = s.categoryIndices.constBegin(); + for ( ; catIt != s.categoryIndices.constEnd(); ++catIt ) + { + double currentVal = att[*catIt].toDouble(); + values.push_back( currentVal ); + } + + double currentOffset = 0; + + double baseX = position.x(); + double baseY = position.y(); + + mPen.setColor( s.penColor ); + setPenWidth( mPen, s, c ); + p->setPen( mPen ); + + p->drawPoint( baseX, baseY ); + + QList::const_iterator valIt = values.constBegin(); + QList< QColor >::const_iterator colIt = s.categoryColors.constBegin(); + for ( ; valIt != values.constEnd(); ++valIt, ++colIt ) + { + double length = sizePainterUnits( *valIt, s, c ); + + mCategoryBrush.setColor( *colIt ); + p->setBrush( mCategoryBrush ); + + switch ( s.diagramOrientation ) + { + case QgsDiagramSettings::Up: + p->drawRect( baseX + currentOffset, baseY, 10, 0 - length ); + break; + + case QgsDiagramSettings::Down: + p->drawRect( baseX + currentOffset, baseY, 10, length ); + break; + + case QgsDiagramSettings::Right: + p->drawRect( baseX, baseY + currentOffset, 0 - length, 10 ); + break; + + case QgsDiagramSettings::Left: + p->drawRect( baseX, baseY + currentOffset, length, 10 ); + break; + } + + currentOffset += 10; + } +} diff --git a/src/core/qgsdiagram.h b/src/core/qgsdiagram.h index 522b248890c..480d76353a2 100644 --- a/src/core/qgsdiagram.h +++ b/src/core/qgsdiagram.h @@ -37,6 +37,7 @@ class CORE_EXPORT QgsDiagram protected: void setPenWidth( QPen& pen, const QgsDiagramSettings& s, const QgsRenderContext& c ); QSizeF sizePainterUnits( const QSizeF& size, const QgsDiagramSettings& s, const QgsRenderContext& c ); + float sizePainterUnits( float l, const QgsDiagramSettings& s, const QgsRenderContext& c ); QFont scaledFont( const QgsDiagramSettings& s, const QgsRenderContext& c ); }; @@ -87,4 +88,19 @@ class CORE_EXPORT QgsPieDiagram: public QgsDiagram QPen mPen; }; +class CORE_EXPORT QgsHistogramDiagram: public QgsDiagram +{ + public: + QgsHistogramDiagram(); + ~QgsHistogramDiagram(); + + void renderDiagram( const QgsAttributeMap& att, QgsRenderContext& c, const QgsDiagramSettings& s, const QPointF& position ); + QString diagramName() const { return "Histogram"; } + + private: + QBrush mCategoryBrush; + QPen mPen; +}; + + #endif // QGSDIAGRAM_H diff --git a/src/core/qgsdiagramrendererv2.cpp b/src/core/qgsdiagramrendererv2.cpp index 32f6f2b67ae..f7c6cca8793 100644 --- a/src/core/qgsdiagramrendererv2.cpp +++ b/src/core/qgsdiagramrendererv2.cpp @@ -75,6 +75,24 @@ void QgsDiagramSettings::readXML( const QDomElement& elem ) labelPlacementMethod = XHeight; } + // orientation + if ( elem.attribute( "diagramOrientation" ) == "Left" ) + { + diagramOrientation = Left; + } + else if ( elem.attribute( "diagramOrientation" ) == "Right" ) + { + diagramOrientation = Right; + } + else if ( elem.attribute( "diagramOrientation" ) == "Down" ) + { + diagramOrientation = Down; + } + else + { + diagramOrientation = Up; + } + minimumSize = elem.attribute( "minimumSize" ).toDouble(); //colors @@ -108,6 +126,8 @@ void QgsDiagramSettings::writeXML( QDomElement& rendererElem, QDomDocument& doc categoryElem.setAttribute( "penWidth", QString::number( penWidth ) ); categoryElem.setAttribute( "minScaleDenominator", QString::number( minScaleDenominator ) ); categoryElem.setAttribute( "maxScaleDenominator", QString::number( maxScaleDenominator ) ); + + // site type (mm vs. map units) if ( sizeType == MM ) { categoryElem.setAttribute( "sizeType", "MM" ); @@ -117,6 +137,7 @@ void QgsDiagramSettings::writeXML( QDomElement& rendererElem, QDomDocument& doc categoryElem.setAttribute( "sizeType", "MapUnits" ); } + // label placement method (text diagram) if ( labelPlacementMethod == Height ) { categoryElem.setAttribute( "labelPlacementMethod", "Height" ); @@ -126,6 +147,29 @@ void QgsDiagramSettings::writeXML( QDomElement& rendererElem, QDomDocument& doc categoryElem.setAttribute( "labelPlacementMethod", "XHeight" ); } + // orientation (histogram) + switch ( diagramOrientation ) { + case Left: + categoryElem.setAttribute( "diagramOrientation", "Left" ); + break; + + case Right: + categoryElem.setAttribute( "diagramOrientation", "Right" ); + break; + + case Down: + categoryElem.setAttribute( "diagramOrientation", "Down" ); + break; + + case Up: + categoryElem.setAttribute( "diagramOrientation", "Up" ); + break; + + default: + categoryElem.setAttribute( "diagramOrientation", "Up" ); + break; + } + categoryElem.setAttribute( "minimumSize", QString::number( minimumSize ) ); QString colors; @@ -243,6 +287,10 @@ void QgsDiagramRendererV2::_readXML( const QDomElement& elem ) { mDiagram = new QgsTextDiagram(); } + else if ( diagramType == "Histogram" ) + { + mDiagram = new QgsHistogramDiagram(); + } else { mDiagram = 0; diff --git a/src/core/qgsdiagramrendererv2.h b/src/core/qgsdiagramrendererv2.h index 1784bad33b3..3acdddf1d5a 100644 --- a/src/core/qgsdiagramrendererv2.h +++ b/src/core/qgsdiagramrendererv2.h @@ -102,6 +102,15 @@ struct CORE_EXPORT QgsDiagramSettings XHeight }; + //! Orientation of histogram + enum DiagramOrientation + { + Up, + Down, + Left, + Right + }; + QgsDiagramSettings(): sizeType( MM ), minScaleDenominator( -1 ), maxScaleDenominator( -1 ) {} QFont font; @@ -113,6 +122,7 @@ struct CORE_EXPORT QgsDiagramSettings QColor penColor; double penWidth; LabelPlacementMethod labelPlacementMethod; + DiagramOrientation diagramOrientation; //scale range (-1 if no lower / upper bound ) double minScaleDenominator; diff --git a/src/ui/qgsvectorlayerpropertiesbase.ui b/src/ui/qgsvectorlayerpropertiesbase.ui index ea91b6fc01d..fef3b270d0e 100644 --- a/src/ui/qgsvectorlayerpropertiesbase.ui +++ b/src/ui/qgsvectorlayerpropertiesbase.ui @@ -273,7 +273,7 @@ - ../../../../../../.designer/xpm/new_attribute.png../../../../../../.designer/xpm/new_attribute.png + M:/../.designer/xpm/new_attribute.pngM:/../.designer/xpm/new_attribute.png Ctrl+N @@ -290,7 +290,7 @@ - ../../../../../../.designer/xpm/delete_attribute.png../../../../../../.designer/xpm/delete_attribute.png + M:/../.designer/xpm/delete_attribute.pngM:/../.designer/xpm/delete_attribute.png Ctrl+X @@ -392,7 +392,7 @@ 0 0 820 - 540 + 558 @@ -761,7 +761,7 @@ 0 0 802 - 522 + 540 @@ -873,7 +873,7 @@ 0 0 802 - 522 + 540 @@ -970,34 +970,7 @@ - - - - Display diagrams - - - - - - - 6 - - - 0 - - - - - Diagram type - - - - - - - - - + @@ -1044,145 +1017,7 @@ - - - - Appearance - - - - - - - - Pen color - - - - - - - - 0 - 0 - - - - - 25 - 0 - - - - - - - - - - - - - - - Pen width - - - - - - - 5 - - - 99999.990000000005239 - - - - - - - - - - - Scale dependent visibility - - - - - - - Minimum - - - - - - - - - - Maximum - - - - - - - - - - - - - - - - Background color - - - - - - - - 0 - 0 - - - - - 25 - 0 - - - - - - - - - - - - - - - - 0 - 0 - - - - Font... - - - - - - - + Position @@ -1281,12 +1116,12 @@ - - Label placement: - false + + Label placement: + @@ -1301,14 +1136,14 @@ - + Attributes - + @@ -1318,7 +1153,7 @@ - + Qt::Horizontal @@ -1331,7 +1166,7 @@ - + @@ -1348,7 +1183,7 @@ - + @@ -1365,7 +1200,7 @@ - + 2 @@ -1382,7 +1217,7 @@ - + Size @@ -1521,6 +1356,267 @@ + + + + Visibility + + + + + + + + Scale dependent visibility + + + + + + + Minimum + + + + + + + + + + Maximum + + + + + + + + + + + + Collision handling + + + + + + + Hide diagrams + + + + + + + Raise small diagrams + + + + + + + + + + Appearance + + + + + + + + Line color + + + + + + + + 0 + 0 + + + + + 25 + 0 + + + + + + + + + + + + + + + Line width + + + + + + + 5 + + + 99999.990000000005239 + + + + + + + + + + + + + Background color + + + + + + + + 0 + 0 + + + + + 25 + 0 + + + + + + + + + + + + + + + + 0 + 0 + + + + Font... + + + + + + + + + + + + Display diagrams + + + + + + + 6 + + + 0 + + + + + Diagram type + + + + + + + + + + + + + + Diagram options + + + false + + + + + + Up + + + true + + + mOrientationButtonGroup + + + + + + + Left + + + mOrientationButtonGroup + + + + + + + Right + + + mOrientationButtonGroup + + + + + + + Down + + + mOrientationButtonGroup + + + + + + + Orientation + + + + + + @@ -1631,4 +1727,7 @@ + + + From cceb1fbcb3a8ab949b3e15e8088c98c7a02d4a0b Mon Sep 17 00:00:00 2001 From: Matthias Kuhn Date: Wed, 8 Aug 2012 15:47:47 +0200 Subject: [PATCH 9/9] Make bar width configurable --- src/app/qgsvectorlayerproperties.cpp | 5 ++++- src/core/qgsdiagram.cpp | 15 +++++++-------- src/core/qgsdiagramrendererv2.cpp | 3 +++ src/core/qgsdiagramrendererv2.h | 1 + src/ui/qgsvectorlayerpropertiesbase.ui | 14 ++++++++++++++ 5 files changed, 29 insertions(+), 9 deletions(-) diff --git a/src/app/qgsvectorlayerproperties.cpp b/src/app/qgsvectorlayerproperties.cpp index 8dccf02a01c..95e9a3faecf 100755 --- a/src/app/qgsvectorlayerproperties.cpp +++ b/src/app/qgsvectorlayerproperties.cpp @@ -900,6 +900,8 @@ void QgsVectorLayerProperties::apply() ds.diagramOrientation = QgsDiagramSettings::Left; } + ds.barWidth = mBarWidthSpinBox->value(); + if ( mFixedSizeCheckBox->isChecked() ) { QgsSingleCategoryDiagramRenderer* dr = new QgsSingleCategoryDiagramRenderer(); @@ -1748,9 +1750,10 @@ void QgsVectorLayerProperties::initDiagramTab() case QgsDiagramSettings::Down: mOrientationDownButton->setChecked( true ); break; - } + mBarWidthSpinBox->setValue( settingList.at( 0 ).barWidth ); + mIncreaseSmallDiagramsCheckBox->setChecked( settingList.at( 0 ).minimumSize != 0 ); mIncreaseMinimumSizeSpinBox->setValue( settingList.at( 0 ).minimumSize ); diff --git a/src/core/qgsdiagram.cpp b/src/core/qgsdiagram.cpp index a281be2c2de..60dcb563663 100644 --- a/src/core/qgsdiagram.cpp +++ b/src/core/qgsdiagram.cpp @@ -351,7 +351,8 @@ void QgsHistogramDiagram::renderDiagram( const QgsAttributeMap& att, QgsRenderCo values.push_back( currentVal ); } - double currentOffset = 0; + double currentOffset = 0 - ( values.size() * s.barWidth ) / 2; + double scaledWidth = sizePainterUnits( s.barWidth, s, c ); double baseX = position.x(); double baseY = position.y(); @@ -360,8 +361,6 @@ void QgsHistogramDiagram::renderDiagram( const QgsAttributeMap& att, QgsRenderCo setPenWidth( mPen, s, c ); p->setPen( mPen ); - p->drawPoint( baseX, baseY ); - QList::const_iterator valIt = values.constBegin(); QList< QColor >::const_iterator colIt = s.categoryColors.constBegin(); for ( ; valIt != values.constEnd(); ++valIt, ++colIt ) @@ -374,22 +373,22 @@ void QgsHistogramDiagram::renderDiagram( const QgsAttributeMap& att, QgsRenderCo switch ( s.diagramOrientation ) { case QgsDiagramSettings::Up: - p->drawRect( baseX + currentOffset, baseY, 10, 0 - length ); + p->drawRect( baseX + currentOffset, baseY, scaledWidth, 0 - length ); break; case QgsDiagramSettings::Down: - p->drawRect( baseX + currentOffset, baseY, 10, length ); + p->drawRect( baseX + currentOffset, baseY, scaledWidth, length ); break; case QgsDiagramSettings::Right: - p->drawRect( baseX, baseY + currentOffset, 0 - length, 10 ); + p->drawRect( baseX, baseY + currentOffset, 0 - length, scaledWidth ); break; case QgsDiagramSettings::Left: - p->drawRect( baseX, baseY + currentOffset, length, 10 ); + p->drawRect( baseX, baseY + currentOffset, length, scaledWidth ); break; } - currentOffset += 10; + currentOffset += scaledWidth; } } diff --git a/src/core/qgsdiagramrendererv2.cpp b/src/core/qgsdiagramrendererv2.cpp index f7c6cca8793..40e56a41957 100644 --- a/src/core/qgsdiagramrendererv2.cpp +++ b/src/core/qgsdiagramrendererv2.cpp @@ -93,6 +93,8 @@ void QgsDiagramSettings::readXML( const QDomElement& elem ) diagramOrientation = Up; } + barWidth = elem.attribute( "barWidth" ).toDouble(); + minimumSize = elem.attribute( "minimumSize" ).toDouble(); //colors @@ -170,6 +172,7 @@ void QgsDiagramSettings::writeXML( QDomElement& rendererElem, QDomDocument& doc break; } + categoryElem.setAttribute( "barWidth", QString::number( barWidth ) ); categoryElem.setAttribute( "minimumSize", QString::number( minimumSize ) ); QString colors; diff --git a/src/core/qgsdiagramrendererv2.h b/src/core/qgsdiagramrendererv2.h index 3acdddf1d5a..2dd132e405d 100644 --- a/src/core/qgsdiagramrendererv2.h +++ b/src/core/qgsdiagramrendererv2.h @@ -123,6 +123,7 @@ struct CORE_EXPORT QgsDiagramSettings double penWidth; LabelPlacementMethod labelPlacementMethod; DiagramOrientation diagramOrientation; + double barWidth; //scale range (-1 if no lower / upper bound ) double minScaleDenominator; diff --git a/src/ui/qgsvectorlayerpropertiesbase.ui b/src/ui/qgsvectorlayerpropertiesbase.ui index fef3b270d0e..a27f9758ca1 100644 --- a/src/ui/qgsvectorlayerpropertiesbase.ui +++ b/src/ui/qgsvectorlayerpropertiesbase.ui @@ -1353,6 +1353,20 @@ + + + + + + Bar width + + + + + + + +