Skip to content

Commit 2c6b152

Browse files
committed
Add histogram
1 parent 20f97d2 commit 2c6b152

6 files changed

+490
-188
lines changed

src/app/qgsvectorlayerproperties.cpp

+53-6
Original file line numberDiff line numberDiff line change
@@ -824,6 +824,10 @@ void QgsVectorLayerProperties::apply()
824824
{
825825
diagram = new QgsPieDiagram();
826826
}
827+
else if ( mDiagramTypeComboBox->currentText() == tr( "Histogram" ) )
828+
{
829+
diagram = new QgsHistogramDiagram();
830+
}
827831

828832
QgsDiagramSettings ds;
829833
ds.font = mDiagramFont;
@@ -857,11 +861,11 @@ void QgsVectorLayerProperties::apply()
857861

858862
if ( mIncreaseSmallDiagramsCheckBox->isChecked() )
859863
{
860-
ds.mMinimumSize = mIncreaseMinimumSizeSpinBox->value();
864+
ds.minimumSize = mIncreaseMinimumSizeSpinBox->value();
861865
}
862866
else
863867
{
864-
ds.mMinimumSize = 0;
868+
ds.minimumSize = 0;
865869
}
866870

867871
ds.backgroundColor = mBackgroundColorButton->color();
@@ -878,6 +882,24 @@ void QgsVectorLayerProperties::apply()
878882
ds.maxScaleDenominator = -1;
879883
}
880884

885+
// Diagram orientation (histogram)
886+
if ( tr( "Up" ) == mOrientationButtonGroup->checkedButton()->text() )
887+
{
888+
ds.diagramOrientation = QgsDiagramSettings::Up;
889+
}
890+
else if ( tr( "Down" ) == mOrientationButtonGroup->checkedButton()->text() )
891+
{
892+
ds.diagramOrientation = QgsDiagramSettings::Down;
893+
}
894+
else if ( tr( "Right" ) == mOrientationButtonGroup->checkedButton()->text() )
895+
{
896+
ds.diagramOrientation = QgsDiagramSettings::Right;
897+
}
898+
else if ( tr( "Left" ) == mOrientationButtonGroup->checkedButton()->text() )
899+
{
900+
ds.diagramOrientation = QgsDiagramSettings::Left;
901+
}
902+
881903
if ( mFixedSizeCheckBox->isChecked() )
882904
{
883905
QgsSingleCategoryDiagramRenderer* dr = new QgsSingleCategoryDiagramRenderer();
@@ -1500,8 +1522,8 @@ void QgsVectorLayerProperties::on_mFixedSizeCheckBox_stateChanged( int state )
15001522
//enable / disable all widget in the scaling layout
15011523
mLinearlyScalingLabel->setEnabled( state != Qt::Checked );
15021524
mIncreaseSmallDiagramsCheckBox->setEnabled( state != Qt::Checked );
1503-
mIncreaseMinimumSizeLabel->setEnabled( state != Qt::Checked && mIncreaseSmallDiagramsCheckBox->isChecked() == Qt::Checked );
1504-
mIncreaseMinimumSizeSpinBox->setEnabled( state != Qt::Checked && mIncreaseSmallDiagramsCheckBox->isChecked() == Qt::Checked );
1525+
mIncreaseMinimumSizeLabel->setEnabled( state != Qt::Checked && mIncreaseSmallDiagramsCheckBox->isChecked() );
1526+
mIncreaseMinimumSizeSpinBox->setEnabled( state != Qt::Checked && mIncreaseSmallDiagramsCheckBox->isChecked() );
15051527
QWidget* currentWidget = 0;
15061528
for ( int i = 0; i < mLinearlyScalingLayout->count(); ++i )
15071529
{
@@ -1614,6 +1636,7 @@ void QgsVectorLayerProperties::initDiagramTab()
16141636

16151637
mDiagramTypeComboBox->addItem( tr( "Pie chart" ) );
16161638
mDiagramTypeComboBox->addItem( tr( "Text diagram" ) );
1639+
mDiagramTypeComboBox->addItem( tr( "Histogram" ) );
16171640

16181641
mLabelPlacementComboBox->addItem( tr( "Height" ) );
16191642
mLabelPlacementComboBox->addItem( tr( "x-height" ) );
@@ -1708,8 +1731,28 @@ void QgsVectorLayerProperties::initDiagramTab()
17081731
mLabelPlacementComboBox->setCurrentIndex( 1 );
17091732
}
17101733

1711-
mIncreaseSmallDiagramsCheckBox->setChecked( settingList.at( 0 ).mMinimumSize != 0 );
1712-
mIncreaseMinimumSizeSpinBox->setValue( settingList.at( 0 ).mMinimumSize );
1734+
switch( settingList.at( 0 ).diagramOrientation )
1735+
{
1736+
case QgsDiagramSettings::Left:
1737+
mOrientationLeftButton->setChecked( true );
1738+
break;
1739+
1740+
case QgsDiagramSettings::Right:
1741+
mOrientationRightButton->setChecked( true );
1742+
break;
1743+
1744+
case QgsDiagramSettings::Up:
1745+
mOrientationUpButton->setChecked( true );
1746+
break;
1747+
1748+
case QgsDiagramSettings::Down:
1749+
mOrientationDownButton->setChecked( true );
1750+
break;
1751+
1752+
}
1753+
1754+
mIncreaseSmallDiagramsCheckBox->setChecked( settingList.at( 0 ).minimumSize != 0 );
1755+
mIncreaseMinimumSizeSpinBox->setValue( settingList.at( 0 ).minimumSize );
17131756

17141757
QList< QColor > categoryColors = settingList.at( 0 ).categoryColors;
17151758
QList< int > categoryIndices = settingList.at( 0 ).categoryIndices;
@@ -1758,6 +1801,10 @@ void QgsVectorLayerProperties::initDiagramTab()
17581801
{
17591802
mDiagramTypeComboBox->setCurrentIndex( mDiagramTypeComboBox->findText( tr( "Pie chart" ) ) );
17601803
}
1804+
else if ( diagramName == "Histogram" )
1805+
{
1806+
mDiagramTypeComboBox->setCurrentIndex( mDiagramTypeComboBox->findText( tr( "Histogram" ) ) );
1807+
}
17611808
}
17621809
}
17631810

src/core/qgsdiagram.cpp

+82
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,18 @@ QSizeF QgsDiagram::sizePainterUnits( const QSizeF& size, const QgsDiagramSetting
4343
}
4444
}
4545

46+
float QgsDiagram::sizePainterUnits( float l, const QgsDiagramSettings& s, const QgsRenderContext& c )
47+
{
48+
if ( s.sizeType == QgsDiagramSettings::MM )
49+
{
50+
return l * c.scaleFactor();
51+
}
52+
else
53+
{
54+
return l / c.mapToPixel().mapUnitsPerPixel();
55+
}
56+
}
57+
4658
QFont QgsDiagram::scaledFont( const QgsDiagramSettings& s, const QgsRenderContext& c )
4759
{
4860
QFont f = s.font;
@@ -311,3 +323,73 @@ void QgsPieDiagram::renderDiagram( const QgsAttributeMap& att, QgsRenderContext&
311323
totalAngle += currentAngle;
312324
}
313325
}
326+
327+
QgsHistogramDiagram::QgsHistogramDiagram()
328+
{
329+
mCategoryBrush.setStyle( Qt::SolidPattern );
330+
mPen.setStyle( Qt::SolidLine );
331+
}
332+
333+
QgsHistogramDiagram::~QgsHistogramDiagram()
334+
{
335+
}
336+
337+
void QgsHistogramDiagram::renderDiagram( const QgsAttributeMap& att, QgsRenderContext& c, const QgsDiagramSettings& s, const QPointF& position )
338+
{
339+
QPainter* p = c.painter();
340+
if ( !p )
341+
{
342+
return;
343+
}
344+
345+
QList<double> values;
346+
347+
QList<int>::const_iterator catIt = s.categoryIndices.constBegin();
348+
for ( ; catIt != s.categoryIndices.constEnd(); ++catIt )
349+
{
350+
double currentVal = att[*catIt].toDouble();
351+
values.push_back( currentVal );
352+
}
353+
354+
double currentOffset = 0;
355+
356+
double baseX = position.x();
357+
double baseY = position.y();
358+
359+
mPen.setColor( s.penColor );
360+
setPenWidth( mPen, s, c );
361+
p->setPen( mPen );
362+
363+
p->drawPoint( baseX, baseY );
364+
365+
QList<double>::const_iterator valIt = values.constBegin();
366+
QList< QColor >::const_iterator colIt = s.categoryColors.constBegin();
367+
for ( ; valIt != values.constEnd(); ++valIt, ++colIt )
368+
{
369+
double length = sizePainterUnits( *valIt, s, c );
370+
371+
mCategoryBrush.setColor( *colIt );
372+
p->setBrush( mCategoryBrush );
373+
374+
switch ( s.diagramOrientation )
375+
{
376+
case QgsDiagramSettings::Up:
377+
p->drawRect( baseX + currentOffset, baseY, 10, 0 - length );
378+
break;
379+
380+
case QgsDiagramSettings::Down:
381+
p->drawRect( baseX + currentOffset, baseY, 10, length );
382+
break;
383+
384+
case QgsDiagramSettings::Right:
385+
p->drawRect( baseX, baseY + currentOffset, 0 - length, 10 );
386+
break;
387+
388+
case QgsDiagramSettings::Left:
389+
p->drawRect( baseX, baseY + currentOffset, length, 10 );
390+
break;
391+
}
392+
393+
currentOffset += 10;
394+
}
395+
}

src/core/qgsdiagram.h

+16
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ class CORE_EXPORT QgsDiagram
3737
protected:
3838
void setPenWidth( QPen& pen, const QgsDiagramSettings& s, const QgsRenderContext& c );
3939
QSizeF sizePainterUnits( const QSizeF& size, const QgsDiagramSettings& s, const QgsRenderContext& c );
40+
float sizePainterUnits( float l, const QgsDiagramSettings& s, const QgsRenderContext& c );
4041
QFont scaledFont( const QgsDiagramSettings& s, const QgsRenderContext& c );
4142
};
4243

@@ -87,4 +88,19 @@ class CORE_EXPORT QgsPieDiagram: public QgsDiagram
8788
QPen mPen;
8889
};
8990

91+
class CORE_EXPORT QgsHistogramDiagram: public QgsDiagram
92+
{
93+
public:
94+
QgsHistogramDiagram();
95+
~QgsHistogramDiagram();
96+
97+
void renderDiagram( const QgsAttributeMap& att, QgsRenderContext& c, const QgsDiagramSettings& s, const QPointF& position );
98+
QString diagramName() const { return "Histogram"; }
99+
100+
private:
101+
QBrush mCategoryBrush;
102+
QPen mPen;
103+
};
104+
105+
90106
#endif // QGSDIAGRAM_H

src/core/qgsdiagramrendererv2.cpp

+48
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,24 @@ void QgsDiagramSettings::readXML( const QDomElement& elem )
7575
labelPlacementMethod = XHeight;
7676
}
7777

78+
// orientation
79+
if ( elem.attribute( "diagramOrientation" ) == "Left" )
80+
{
81+
diagramOrientation = Left;
82+
}
83+
else if ( elem.attribute( "diagramOrientation" ) == "Right" )
84+
{
85+
diagramOrientation = Right;
86+
}
87+
else if ( elem.attribute( "diagramOrientation" ) == "Down" )
88+
{
89+
diagramOrientation = Down;
90+
}
91+
else
92+
{
93+
diagramOrientation = Up;
94+
}
95+
7896
minimumSize = elem.attribute( "minimumSize" ).toDouble();
7997

8098
//colors
@@ -108,6 +126,8 @@ void QgsDiagramSettings::writeXML( QDomElement& rendererElem, QDomDocument& doc
108126
categoryElem.setAttribute( "penWidth", QString::number( penWidth ) );
109127
categoryElem.setAttribute( "minScaleDenominator", QString::number( minScaleDenominator ) );
110128
categoryElem.setAttribute( "maxScaleDenominator", QString::number( maxScaleDenominator ) );
129+
130+
// site type (mm vs. map units)
111131
if ( sizeType == MM )
112132
{
113133
categoryElem.setAttribute( "sizeType", "MM" );
@@ -117,6 +137,7 @@ void QgsDiagramSettings::writeXML( QDomElement& rendererElem, QDomDocument& doc
117137
categoryElem.setAttribute( "sizeType", "MapUnits" );
118138
}
119139

140+
// label placement method (text diagram)
120141
if ( labelPlacementMethod == Height )
121142
{
122143
categoryElem.setAttribute( "labelPlacementMethod", "Height" );
@@ -126,6 +147,29 @@ void QgsDiagramSettings::writeXML( QDomElement& rendererElem, QDomDocument& doc
126147
categoryElem.setAttribute( "labelPlacementMethod", "XHeight" );
127148
}
128149

150+
// orientation (histogram)
151+
switch ( diagramOrientation ) {
152+
case Left:
153+
categoryElem.setAttribute( "diagramOrientation", "Left" );
154+
break;
155+
156+
case Right:
157+
categoryElem.setAttribute( "diagramOrientation", "Right" );
158+
break;
159+
160+
case Down:
161+
categoryElem.setAttribute( "diagramOrientation", "Down" );
162+
break;
163+
164+
case Up:
165+
categoryElem.setAttribute( "diagramOrientation", "Up" );
166+
break;
167+
168+
default:
169+
categoryElem.setAttribute( "diagramOrientation", "Up" );
170+
break;
171+
}
172+
129173
categoryElem.setAttribute( "minimumSize", QString::number( minimumSize ) );
130174

131175
QString colors;
@@ -243,6 +287,10 @@ void QgsDiagramRendererV2::_readXML( const QDomElement& elem )
243287
{
244288
mDiagram = new QgsTextDiagram();
245289
}
290+
else if ( diagramType == "Histogram" )
291+
{
292+
mDiagram = new QgsHistogramDiagram();
293+
}
246294
else
247295
{
248296
mDiagram = 0;

src/core/qgsdiagramrendererv2.h

+10
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,15 @@ struct CORE_EXPORT QgsDiagramSettings
102102
XHeight
103103
};
104104

105+
//! Orientation of histogram
106+
enum DiagramOrientation
107+
{
108+
Up,
109+
Down,
110+
Left,
111+
Right
112+
};
113+
105114
QgsDiagramSettings(): sizeType( MM ), minScaleDenominator( -1 ), maxScaleDenominator( -1 )
106115
{}
107116
QFont font;
@@ -113,6 +122,7 @@ struct CORE_EXPORT QgsDiagramSettings
113122
QColor penColor;
114123
double penWidth;
115124
LabelPlacementMethod labelPlacementMethod;
125+
DiagramOrientation diagramOrientation;
116126

117127
//scale range (-1 if no lower / upper bound )
118128
double minScaleDenominator;

0 commit comments

Comments
 (0)