Skip to content

Commit 07839fa

Browse files
committed
let diagrams decide how much space they need themselves
1 parent 55ff09e commit 07839fa

File tree

4 files changed

+187
-57
lines changed

4 files changed

+187
-57
lines changed

src/core/qgsdiagram.cpp

+128-3
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,34 @@ QgsTextDiagram::~QgsTextDiagram()
8282
{
8383
}
8484

85+
QSizeF QgsTextDiagram::diagramSize( const QgsAttributeMap& attributes, const QgsRenderContext& c, const QgsDiagramSettings& s, const QgsDiagramInterpolationSettings& is )
86+
{
87+
QgsAttributeMap::const_iterator attIt = attributes.find( is.classificationAttribute );
88+
if ( attIt == attributes.constEnd() )
89+
{
90+
return QSizeF(); //zero size if attribute is missing
91+
}
92+
double value = attIt.value().toDouble();
93+
94+
//interpolate size
95+
double ratio = ( value - is.lowerValue ) / ( is.upperValue - is.lowerValue );
96+
QSizeF size = QSizeF( is.upperSize.width() * ratio + is.lowerSize.width() * ( 1 - ratio ),
97+
is.upperSize.height() * ratio + is.lowerSize.height() * ( 1 - ratio ) );
98+
99+
// Scale, if extension is smaller than the specified minimum
100+
if ( size.width() <= s.minimumSize && size.height() <= s.minimumSize )
101+
{
102+
size.scale( s.minimumSize, s.minimumSize, Qt::KeepAspectRatio );
103+
}
104+
105+
return size;
106+
}
107+
108+
QSizeF QgsTextDiagram::diagramSize( const QgsAttributeMap& attributes, const QgsRenderContext& c, const QgsDiagramSettings& s )
109+
{
110+
return s.size;
111+
}
112+
85113
void QgsTextDiagram::renderDiagram( const QgsAttributeMap& att, QgsRenderContext& c, const QgsDiagramSettings& s, const QPointF& position )
86114
{
87115
QPainter* p = c.painter();
@@ -275,6 +303,34 @@ QgsPieDiagram::~QgsPieDiagram()
275303
{
276304
}
277305

306+
QSizeF QgsPieDiagram::diagramSize( const QgsAttributeMap& attributes, const QgsRenderContext& c, const QgsDiagramSettings& s, const QgsDiagramInterpolationSettings& is )
307+
{
308+
QgsAttributeMap::const_iterator attIt = attributes.find( is.classificationAttribute );
309+
if ( attIt == attributes.constEnd() )
310+
{
311+
return QSizeF(); //zero size if attribute is missing
312+
}
313+
double value = attIt.value().toDouble();
314+
315+
//interpolate size
316+
double ratio = ( value - is.lowerValue ) / ( is.upperValue - is.lowerValue );
317+
QSizeF size = QSizeF( is.upperSize.width() * ratio + is.lowerSize.width() * ( 1 - ratio ),
318+
is.upperSize.height() * ratio + is.lowerSize.height() * ( 1 - ratio ) );
319+
320+
// Scale, if extension is smaller than the specified minimum
321+
if ( size.width() <= s.minimumSize && size.height() <= s.minimumSize )
322+
{
323+
size.scale( s.minimumSize, s.minimumSize, Qt::KeepAspectRatio );
324+
}
325+
326+
return size;
327+
}
328+
329+
QSizeF QgsPieDiagram::diagramSize( const QgsAttributeMap& attributes, const QgsRenderContext& c, const QgsDiagramSettings& s )
330+
{
331+
return s.size;
332+
}
333+
278334
void QgsPieDiagram::renderDiagram( const QgsAttributeMap& att, QgsRenderContext& c, const QgsDiagramSettings& s, const QPointF& position )
279335
{
280336
QPainter* p = c.painter();
@@ -328,12 +384,81 @@ QgsHistogramDiagram::QgsHistogramDiagram()
328384
{
329385
mCategoryBrush.setStyle( Qt::SolidPattern );
330386
mPen.setStyle( Qt::SolidLine );
387+
mScaleFactor = 0;
331388
}
332389

333390
QgsHistogramDiagram::~QgsHistogramDiagram()
334391
{
335392
}
336393

394+
QSizeF QgsHistogramDiagram::diagramSize( const QgsAttributeMap& attributes, const QgsRenderContext& c, const QgsDiagramSettings& s, const QgsDiagramInterpolationSettings& is )
395+
{
396+
QgsAttributeMap::const_iterator attIt = attributes.constBegin();
397+
if ( attIt == attributes.constEnd() )
398+
{
399+
return QSizeF(); //zero size if no attributes
400+
}
401+
402+
double maxValue = attIt.value().toDouble();
403+
404+
for ( ; attIt != attributes.constEnd(); ++attIt )
405+
{
406+
maxValue = qMax( attIt.value().toDouble(), maxValue );
407+
}
408+
409+
// Scale, if extension is smaller than the specified minimum
410+
if ( maxValue < s.minimumSize )
411+
{
412+
maxValue = s.minimumSize;
413+
}
414+
415+
mScaleFactor = ( maxValue - is.lowerValue ) / ( is.upperValue - is.lowerValue );
416+
417+
switch ( s.diagramOrientation )
418+
{
419+
case QgsDiagramSettings::Up:
420+
case QgsDiagramSettings::Down:
421+
return QSizeF( s.barWidth * attributes.size(), maxValue );
422+
423+
case QgsDiagramSettings::Right:
424+
case QgsDiagramSettings::Left:
425+
return QSizeF( maxValue, s.barWidth * attributes.size() );
426+
}
427+
428+
return QSizeF();
429+
}
430+
431+
QSizeF QgsHistogramDiagram::diagramSize( const QgsAttributeMap& attributes, const QgsRenderContext& c, const QgsDiagramSettings& s )
432+
{
433+
QgsAttributeMap::const_iterator attIt = attributes.constBegin();
434+
if ( attIt == attributes.constEnd() )
435+
{
436+
return QSizeF(); //zero size if no attributes
437+
}
438+
439+
double maxValue = attIt.value().toDouble();
440+
441+
for ( ; attIt != attributes.constEnd(); ++attIt )
442+
{
443+
maxValue = qMax( attIt.value().toDouble(), maxValue );
444+
}
445+
446+
switch ( s.diagramOrientation )
447+
{
448+
case QgsDiagramSettings::Up:
449+
case QgsDiagramSettings::Down:
450+
mScaleFactor = maxValue / s.size.height();
451+
return QSizeF( s.barWidth * attributes.size(), s.size.height() );
452+
453+
case QgsDiagramSettings::Right:
454+
case QgsDiagramSettings::Left:
455+
mScaleFactor = maxValue / s.size.width();
456+
return QSizeF( s.size.width(), s.barWidth * attributes.size() );
457+
}
458+
459+
return QSizeF();
460+
}
461+
337462
void QgsHistogramDiagram::renderDiagram( const QgsAttributeMap& att, QgsRenderContext& c, const QgsDiagramSettings& s, const QPointF& position )
338463
{
339464
QPainter* p = c.painter();
@@ -365,14 +490,14 @@ void QgsHistogramDiagram::renderDiagram( const QgsAttributeMap& att, QgsRenderCo
365490
QList< QColor >::const_iterator colIt = s.categoryColors.constBegin();
366491
for ( ; valIt != values.constEnd(); ++valIt, ++colIt )
367492
{
368-
double length = sizePainterUnits( *valIt, s, c );
493+
double length = sizePainterUnits( *valIt * mScaleFactor, s, c );
369494

370495
mCategoryBrush.setColor( *colIt );
371496
p->setBrush( mCategoryBrush );
372497

373498
switch ( s.diagramOrientation )
374499
{
375-
case QgsDiagramSettings::Up:
500+
case QgsDiagramSettings::Up:
376501
p->drawRect( baseX + currentOffset, baseY, scaledWidth, 0 - length );
377502
break;
378503

@@ -391,4 +516,4 @@ void QgsHistogramDiagram::renderDiagram( const QgsAttributeMap& att, QgsRenderCo
391516

392517
currentOffset += scaledWidth;
393518
}
394-
}
519+
}

src/core/qgsdiagram.h

+14
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,12 @@
2222
class QPainter;
2323
class QPointF;
2424
struct QgsDiagramSettings;
25+
struct QgsDiagramInterpolationSettings;
2526

2627
class QgsRenderContext;
2728

29+
30+
2831
/**Base class for all diagram types*/
2932
class CORE_EXPORT QgsDiagram
3033
{
@@ -33,6 +36,10 @@ class CORE_EXPORT QgsDiagram
3336
/**Draws the diagram at the given position (in pixel coordinates)*/
3437
virtual void renderDiagram( const QgsAttributeMap& att, QgsRenderContext& c, const QgsDiagramSettings& s, const QPointF& position ) = 0;
3538
virtual QString diagramName() const = 0;
39+
/**Returns the size in map units the diagram will use to render.*/
40+
virtual QSizeF diagramSize( const QgsAttributeMap& attributes, const QgsRenderContext& c, const QgsDiagramSettings& s ) = 0;
41+
/**Returns the size in map units the diagram will use to render. Interpolat size*/
42+
virtual QSizeF diagramSize( const QgsAttributeMap& attributes, const QgsRenderContext& c, const QgsDiagramSettings& s, const QgsDiagramInterpolationSettings& is ) = 0;
3643

3744
protected:
3845
void setPenWidth( QPen& pen, const QgsDiagramSettings& s, const QgsRenderContext& c );
@@ -60,6 +67,8 @@ class CORE_EXPORT QgsTextDiagram: public QgsDiagram
6067
QgsTextDiagram();
6168
~QgsTextDiagram();
6269
void renderDiagram( const QgsAttributeMap& att, QgsRenderContext& c, const QgsDiagramSettings& s, const QPointF& position );
70+
QSizeF diagramSize( const QgsAttributeMap& attributes, const QgsRenderContext& c, const QgsDiagramSettings& s );
71+
QSizeF diagramSize( const QgsAttributeMap& attributes, const QgsRenderContext& c, const QgsDiagramSettings& s, const QgsDiagramInterpolationSettings& is );
6372

6473
QString diagramName() const { return "Text"; }
6574

@@ -81,6 +90,8 @@ class CORE_EXPORT QgsPieDiagram: public QgsDiagram
8190
~QgsPieDiagram();
8291

8392
void renderDiagram( const QgsAttributeMap& att, QgsRenderContext& c, const QgsDiagramSettings& s, const QPointF& position );
93+
QSizeF diagramSize( const QgsAttributeMap& attributes, const QgsRenderContext& c, const QgsDiagramSettings& s );
94+
QSizeF diagramSize( const QgsAttributeMap& attributes, const QgsRenderContext& c, const QgsDiagramSettings& s, const QgsDiagramInterpolationSettings& is );
8495
QString diagramName() const { return "Pie"; }
8596

8697
private:
@@ -95,11 +106,14 @@ class CORE_EXPORT QgsHistogramDiagram: public QgsDiagram
95106
~QgsHistogramDiagram();
96107

97108
void renderDiagram( const QgsAttributeMap& att, QgsRenderContext& c, const QgsDiagramSettings& s, const QPointF& position );
109+
QSizeF diagramSize( const QgsAttributeMap& attributes, const QgsRenderContext& c, const QgsDiagramSettings& s );
110+
QSizeF diagramSize( const QgsAttributeMap& attributes, const QgsRenderContext& c, const QgsDiagramSettings& s, const QgsDiagramInterpolationSettings& is );
98111
QString diagramName() const { return "Histogram"; }
99112

100113
private:
101114
QBrush mCategoryBrush;
102115
QPen mPen;
116+
double mScaleFactor;
103117
};
104118

105119

src/core/qgsdiagramrendererv2.cpp

+22-36
Original file line numberDiff line numberDiff line change
@@ -324,6 +324,11 @@ bool QgsSingleCategoryDiagramRenderer::diagramSettings( const QgsAttributeMap&,
324324
return true;
325325
}
326326

327+
QSizeF QgsSingleCategoryDiagramRenderer::diagramSize(const QgsAttributeMap &attributes, const QgsRenderContext &c)
328+
{
329+
return mDiagram->diagramSize( attributes, c, mSettings );
330+
}
331+
327332
QList<QgsDiagramSettings> QgsSingleCategoryDiagramRenderer::diagramSettings() const
328333
{
329334
QList<QgsDiagramSettings> settingsList;
@@ -377,46 +382,27 @@ bool QgsLinearlyInterpolatedDiagramRenderer::diagramSettings( const QgsAttribute
377382
QList<int> QgsLinearlyInterpolatedDiagramRenderer::diagramAttributes() const
378383
{
379384
QList<int> attributes = mSettings.categoryIndices;
380-
if ( !attributes.contains( mClassificationAttribute ) )
385+
if ( !attributes.contains( mInterpolationSettings.classificationAttribute ) )
381386
{
382-
attributes.push_back( mClassificationAttribute );
387+
attributes.push_back( mInterpolationSettings.classificationAttribute );
383388
}
384389
return attributes;
385390
}
386391

387392
QSizeF QgsLinearlyInterpolatedDiagramRenderer::diagramSize( const QgsAttributeMap& attributes, const QgsRenderContext& c )
388393
{
389-
Q_UNUSED( c );
390-
QgsAttributeMap::const_iterator attIt = attributes.find( mClassificationAttribute );
391-
if ( attIt == attributes.constEnd() )
392-
{
393-
return QSizeF(); //zero size if attribute is missing
394-
}
395-
double value = attIt.value().toDouble();
396-
397-
//interpolate size
398-
double ratio = ( value - mLowerValue ) / ( mUpperValue - mLowerValue );
399-
QSizeF size = QSizeF( mUpperSize.width() * ratio + mLowerSize.width() * ( 1 - ratio ),
400-
mUpperSize.height() * ratio + mLowerSize.height() * ( 1 - ratio ) );
401-
402-
// Scale, if extension is smaller than the specified minimum
403-
if ( size.width() <= mSettings.minimumSize && size.height() <= mSettings.minimumSize )
404-
{
405-
size.scale( mSettings.minimumSize, mSettings.minimumSize, Qt::KeepAspectRatio );
406-
}
407-
408-
return size;
394+
return mDiagram->diagramSize( attributes, c, mSettings, mInterpolationSettings );
409395
}
410396

411397
void QgsLinearlyInterpolatedDiagramRenderer::readXML( const QDomElement& elem )
412398
{
413-
mLowerValue = elem.attribute( "lowerValue" ).toDouble();
414-
mUpperValue = elem.attribute( "upperValue" ).toDouble();
415-
mLowerSize.setWidth( elem.attribute( "lowerWidth" ).toDouble() );
416-
mLowerSize.setHeight( elem.attribute( "lowerHeight" ).toDouble() );
417-
mUpperSize.setWidth( elem.attribute( "upperWidth" ).toDouble() );
418-
mUpperSize.setHeight( elem.attribute( "upperHeight" ).toDouble() );
419-
mClassificationAttribute = elem.attribute( "classificationAttribute" ).toInt();
399+
mInterpolationSettings.lowerValue = elem.attribute( "lowerValue" ).toDouble();
400+
mInterpolationSettings.upperValue = elem.attribute( "upperValue" ).toDouble();
401+
mInterpolationSettings.lowerSize.setWidth( elem.attribute( "lowerWidth" ).toDouble() );
402+
mInterpolationSettings.lowerSize.setHeight( elem.attribute( "lowerHeight" ).toDouble() );
403+
mInterpolationSettings.upperSize.setWidth( elem.attribute( "upperWidth" ).toDouble() );
404+
mInterpolationSettings.upperSize.setHeight( elem.attribute( "upperHeight" ).toDouble() );
405+
mInterpolationSettings.classificationAttribute = elem.attribute( "classificationAttribute" ).toInt();
420406
QDomElement settingsElem = elem.firstChildElement( "DiagramCategory" );
421407
if ( !settingsElem.isNull() )
422408
{
@@ -428,13 +414,13 @@ void QgsLinearlyInterpolatedDiagramRenderer::readXML( const QDomElement& elem )
428414
void QgsLinearlyInterpolatedDiagramRenderer::writeXML( QDomElement& layerElem, QDomDocument& doc ) const
429415
{
430416
QDomElement rendererElem = doc.createElement( "LinearlyInterpolatedDiagramRenderer" );
431-
rendererElem.setAttribute( "lowerValue", QString::number( mLowerValue ) );
432-
rendererElem.setAttribute( "upperValue", QString::number( mUpperValue ) );
433-
rendererElem.setAttribute( "lowerWidth", QString::number( mLowerSize.width() ) );
434-
rendererElem.setAttribute( "lowerHeight", QString::number( mLowerSize.height() ) );
435-
rendererElem.setAttribute( "upperWidth", QString::number( mUpperSize.width() ) );
436-
rendererElem.setAttribute( "upperHeight", QString::number( mUpperSize.height() ) );
437-
rendererElem.setAttribute( "classificationAttribute", mClassificationAttribute );
417+
rendererElem.setAttribute( "lowerValue", QString::number( mInterpolationSettings.lowerValue ) );
418+
rendererElem.setAttribute( "upperValue", QString::number( mInterpolationSettings.upperValue ) );
419+
rendererElem.setAttribute( "lowerWidth", QString::number( mInterpolationSettings.lowerSize.width() ) );
420+
rendererElem.setAttribute( "lowerHeight", QString::number( mInterpolationSettings.lowerSize.height() ) );
421+
rendererElem.setAttribute( "upperWidth", QString::number( mInterpolationSettings.upperSize.width() ) );
422+
rendererElem.setAttribute( "upperHeight", QString::number( mInterpolationSettings.upperSize.height() ) );
423+
rendererElem.setAttribute( "classificationAttribute", mInterpolationSettings.classificationAttribute );
438424
mSettings.writeXML( rendererElem, doc );
439425
_writeXML( rendererElem, doc );
440426
layerElem.appendChild( rendererElem );

src/core/qgsdiagramrendererv2.h

+23-18
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,17 @@ struct CORE_EXPORT QgsDiagramSettings
136136
void writeXML( QDomElement& rendererElem, QDomDocument& doc ) const;
137137
};
138138

139+
//additional diagram settings for interpolated size rendering
140+
struct CORE_EXPORT QgsDiagramInterpolationSettings
141+
{
142+
QSizeF lowerSize;
143+
QSizeF upperSize;
144+
double lowerValue;
145+
double upperValue;
146+
/**Index of the classification attribute*/
147+
int classificationAttribute;
148+
};
149+
139150
/**Returns diagram settings for a feature*/
140151
class CORE_EXPORT QgsDiagramRendererV2
141152
{
@@ -210,8 +221,7 @@ class CORE_EXPORT QgsSingleCategoryDiagramRenderer: public QgsDiagramRendererV2
210221
protected:
211222
bool diagramSettings( const QgsAttributeMap&, const QgsRenderContext& c, QgsDiagramSettings& s );
212223

213-
QSizeF diagramSize( const QgsAttributeMap& attributes, const QgsRenderContext& c )
214-
{ Q_UNUSED( attributes ); Q_UNUSED( c ); return mSettings.size; }
224+
QSizeF diagramSize( const QgsAttributeMap& attributes, const QgsRenderContext& c );
215225

216226
private:
217227
QgsDiagramSettings mSettings;
@@ -232,20 +242,20 @@ class CORE_EXPORT QgsLinearlyInterpolatedDiagramRenderer: public QgsDiagramRende
232242

233243
QString rendererName() const { return "LinearlyInterpolated"; }
234244

235-
void setLowerValue( double val ) { mLowerValue = val; }
236-
double lowerValue() const { return mLowerValue; }
245+
void setLowerValue( double val ) { mInterpolationSettings.lowerValue = val; }
246+
double lowerValue() const { return mInterpolationSettings.lowerValue; }
237247

238-
void setUpperValue( double val ) { mUpperValue = val; }
239-
double upperValue() const { return mUpperValue; }
248+
void setUpperValue( double val ) { mInterpolationSettings.upperValue = val; }
249+
double upperValue() const { return mInterpolationSettings.upperValue; }
240250

241-
void setLowerSize( QSizeF s ) { mLowerSize = s; }
242-
QSizeF lowerSize() const { return mLowerSize; }
251+
void setLowerSize( QSizeF s ) { mInterpolationSettings.lowerSize = s; }
252+
QSizeF lowerSize() const { return mInterpolationSettings.lowerSize; }
243253

244-
void setUpperSize( QSizeF s ) { mUpperSize = s; }
245-
QSizeF upperSize() const { return mUpperSize; }
254+
void setUpperSize( QSizeF s ) { mInterpolationSettings.upperSize = s; }
255+
QSizeF upperSize() const { return mInterpolationSettings.upperSize; }
246256

247-
int classificationAttribute() const { return mClassificationAttribute; }
248-
void setClassificationAttribute( int index ) { mClassificationAttribute = index; }
257+
int classificationAttribute() const { return mInterpolationSettings.classificationAttribute; }
258+
void setClassificationAttribute( int index ) { mInterpolationSettings.classificationAttribute = index; }
249259

250260
void readXML( const QDomElement& elem );
251261
void writeXML( QDomElement& layerElem, QDomDocument& doc ) const;
@@ -257,12 +267,7 @@ class CORE_EXPORT QgsLinearlyInterpolatedDiagramRenderer: public QgsDiagramRende
257267

258268
private:
259269
QgsDiagramSettings mSettings;
260-
QSizeF mLowerSize;
261-
QSizeF mUpperSize;
262-
double mLowerValue;
263-
double mUpperValue;
264-
/**Index of the classification attribute*/
265-
int mClassificationAttribute;
270+
QgsDiagramInterpolationSettings mInterpolationSettings;
266271
};
267272

268273
#endif // QGSDIAGRAMRENDERERV2_H

0 commit comments

Comments
 (0)