Skip to content

Commit ea0b689

Browse files
committedJun 20, 2017
Manual configuration of classes in legend with data-defined sizes
1 parent c9c4216 commit ea0b689

File tree

6 files changed

+146
-13
lines changed

6 files changed

+146
-13
lines changed
 

‎python/gui/symbology-ng/qgsdatadefinedsizelegenddialog.sip

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212

1313

14+
1415
class QgsDataDefinedSizeLegendDialog : QDialog
1516
{
1617
%Docstring

‎src/core/qgsdatadefinedsizelegend.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,9 @@ void QgsDataDefinedSizeLegend::updateFromSymbolAndProperty( const QgsMarkerSymbo
6969

7070
mTitleLabel = ddSize.propertyType() == QgsProperty::ExpressionBasedProperty ? ddSize.expressionString() : ddSize.field();
7171

72+
if ( !mSizeClasses.isEmpty() )
73+
return; // manually generated classes
74+
7275
// automatically generated classes
7376
if ( const QgsSizeScaleTransformer *sizeTransformer = dynamic_cast< const QgsSizeScaleTransformer * >( ddSize.transformer() ) )
7477
{

‎src/core/qgsdiagramrenderer.cpp

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -779,16 +779,20 @@ QList< QgsLayerTreeModelLegendNode * > QgsLinearlyInterpolatedDiagramRenderer::l
779779
legendSymbol->setSizeUnit( mSettings.sizeType );
780780
legendSymbol->setSizeMapUnitScale( mSettings.sizeScale );
781781

782-
QList<QgsDataDefinedSizeLegend::SizeClass> sizeClasses;
783-
Q_FOREACH ( double v, QgsSymbolLayerUtils::prettyBreaks( mInterpolationSettings.lowerValue, mInterpolationSettings.upperValue, 4 ) )
784-
{
785-
double size = mDiagram->legendSize( v, mSettings, mInterpolationSettings );
786-
sizeClasses << QgsDataDefinedSizeLegend::SizeClass( size, QString::number( v ) );
787-
}
788-
789782
QgsDataDefinedSizeLegend ddSizeLegend( *mDataDefinedSizeLegend );
790783
ddSizeLegend.setSymbol( legendSymbol ); // transfers ownership
791-
ddSizeLegend.setClasses( sizeClasses );
784+
785+
if ( ddSizeLegend.classes().isEmpty() )
786+
{
787+
// automatic class creation if the classes are not defined manually
788+
QList<QgsDataDefinedSizeLegend::SizeClass> sizeClasses;
789+
Q_FOREACH ( double v, QgsSymbolLayerUtils::prettyBreaks( mInterpolationSettings.lowerValue, mInterpolationSettings.upperValue, 4 ) )
790+
{
791+
double size = mDiagram->legendSize( v, mSettings, mInterpolationSettings );
792+
sizeClasses << QgsDataDefinedSizeLegend::SizeClass( size, QString::number( v ) );
793+
}
794+
ddSizeLegend.setClasses( sizeClasses );
795+
}
792796

793797
Q_FOREACH ( const QgsLegendSymbolItem &si, ddSizeLegend.legendSymbolList() )
794798
{

‎src/gui/symbology-ng/qgsdatadefinedsizelegenddialog.cpp

Lines changed: 63 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515

1616
#include "qgsdatadefinedsizelegenddialog.h"
1717

18+
#include <QInputDialog>
19+
1820
#include "qgsdatadefinedsizelegend.h"
1921
#include "qgslayertree.h"
2022
#include "qgslayertreemodel.h"
@@ -51,7 +53,7 @@ QgsDataDefinedSizeLegendDialog::QgsDataDefinedSizeLegendDialog( const QgsDataDef
5153
else
5254
cboAlignSymbols->setCurrentIndex( 1 );
5355

54-
symbol = ddsLegend->symbol(); // may be null (undefined)
56+
symbol = ddsLegend->symbol() ? ddsLegend->symbol()->clone() : nullptr; // may be null (undefined)
5557
}
5658

5759
if ( overrideSymbol )
@@ -71,6 +73,28 @@ QgsDataDefinedSizeLegendDialog::QgsDataDefinedSizeLegendDialog( const QgsDataDef
7173
QIcon icon = QgsSymbolLayerUtils::symbolPreviewIcon( mSourceSymbol.get(), btnChangeSymbol->iconSize() );
7274
btnChangeSymbol->setIcon( icon );
7375

76+
mSizeClassesModel = new QStandardItemModel( viewSizeClasses );
77+
mSizeClassesModel->setHorizontalHeaderLabels( QStringList() << tr( "Value" ) );
78+
mSizeClassesModel->setSortRole( Qt::UserRole + 1 );
79+
if ( ddsLegend )
80+
{
81+
groupManualSizeClasses->setChecked( !ddsLegend->classes().isEmpty() );
82+
Q_FOREACH ( const QgsDataDefinedSizeLegend::SizeClass &sc, ddsLegend->classes() )
83+
{
84+
QStandardItem *item = new QStandardItem( sc.label );
85+
item->setEditable( false );
86+
item->setData( sc.label.toInt() );
87+
mSizeClassesModel->appendRow( item );
88+
}
89+
mSizeClassesModel->sort( 0 );
90+
}
91+
92+
connect( groupManualSizeClasses, &QGroupBox::clicked, this, &QgsDataDefinedSizeLegendDialog::updatePreview );
93+
connect( btnAddClass, &QToolButton::clicked, this, &QgsDataDefinedSizeLegendDialog::addSizeClass );
94+
connect( btnRemoveClass, &QToolButton::clicked, this, &QgsDataDefinedSizeLegendDialog::removeSizeClass );
95+
96+
viewSizeClasses->setModel( mSizeClassesModel );
97+
7498
// prepare layer and model to preview legend
7599
mPreviewLayer = new QgsVectorLayer( "Point?crs=EPSG:4326", "Preview", "memory" );
76100
mPreviewTree = new QgsLayerTree;
@@ -107,6 +131,18 @@ QgsDataDefinedSizeLegend *QgsDataDefinedSizeLegendDialog::dataDefinedSizeLegend(
107131
{
108132
ddsLegend->setSymbol( mSourceSymbol->clone() );
109133
}
134+
if ( groupManualSizeClasses->isChecked() )
135+
{
136+
const QgsSizeScaleTransformer *transformer = dynamic_cast<const QgsSizeScaleTransformer *>( mSizeProperty.transformer() );
137+
QList<QgsDataDefinedSizeLegend::SizeClass> classes;
138+
for ( int i = 0; i < mSizeClassesModel->rowCount(); ++i )
139+
{
140+
double value = mSizeClassesModel->data( mSizeClassesModel->index( i, 0 ), Qt::UserRole + 1 ).toDouble();
141+
double size = transformer ? transformer->size( value ) : value;
142+
classes << QgsDataDefinedSizeLegend::SizeClass( size, QString::number( value ) );
143+
}
144+
ddsLegend->setClasses( classes );
145+
}
110146
return ddsLegend;
111147
}
112148

@@ -150,3 +186,29 @@ void QgsDataDefinedSizeLegendDialog::changeSymbol()
150186

151187
updatePreview();
152188
}
189+
190+
void QgsDataDefinedSizeLegendDialog::addSizeClass()
191+
{
192+
bool ok;
193+
double v = QInputDialog::getDouble( this, tr( "Add Size Class" ), tr( "Enter value for a new class" ),
194+
0, -2147483647, 2147483647, 6, &ok );
195+
if ( !ok )
196+
return;
197+
198+
QStandardItem *item = new QStandardItem( QString::number( v ) );
199+
item->setEditable( false );
200+
item->setData( v );
201+
mSizeClassesModel->appendRow( item );
202+
mSizeClassesModel->sort( 0 );
203+
updatePreview();
204+
}
205+
206+
void QgsDataDefinedSizeLegendDialog::removeSizeClass()
207+
{
208+
QModelIndex idx = viewSizeClasses->currentIndex();
209+
if ( !idx.isValid() )
210+
return;
211+
212+
mSizeClassesModel->removeRow( idx.row() );
213+
updatePreview();
214+
}

‎src/gui/symbology-ng/qgsdatadefinedsizelegenddialog.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@
2525

2626
#include "qgsproperty.h"
2727

28+
class QStandardItemModel;
29+
2830
class QgsDataDefinedSizeLegend;
2931
class QgsLayerTree;
3032
class QgsLayerTreeLayer;
@@ -58,6 +60,8 @@ class GUI_EXPORT QgsDataDefinedSizeLegendDialog : public QDialog, private Ui::Qg
5860
private slots:
5961
void updatePreview();
6062
void changeSymbol();
63+
void addSizeClass();
64+
void removeSizeClass();
6165

6266
private:
6367
std::unique_ptr<QgsMarkerSymbol> mSourceSymbol; //!< Source symbol (without data-defined size set)
@@ -68,6 +72,7 @@ class GUI_EXPORT QgsDataDefinedSizeLegendDialog : public QDialog, private Ui::Qg
6872
QgsLayerTreeLayer *mPreviewLayerNode;
6973
QgsVectorLayer *mPreviewLayer;
7074
QgsMapCanvas *mMapCanvas = nullptr;
75+
QStandardItemModel *mSizeClassesModel;
7176
};
7277

7378
#endif // QGSDATADEFINEDSIZELEGENDDIALOG_H

‎src/ui/qgsdatadefinedsizelegenddialog.ui

Lines changed: 62 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@
66
<rect>
77
<x>0</x>
88
<y>0</y>
9-
<width>674</width>
10-
<height>492</height>
9+
<width>718</width>
10+
<height>749</height>
1111
</rect>
1212
</property>
1313
<property name="windowTitle">
@@ -47,6 +47,59 @@
4747
</property>
4848
</widget>
4949
</item>
50+
<item>
51+
<widget class="QGroupBox" name="groupManualSizeClasses">
52+
<property name="title">
53+
<string>Manual size classes</string>
54+
</property>
55+
<property name="checkable">
56+
<bool>true</bool>
57+
</property>
58+
<property name="checked">
59+
<bool>false</bool>
60+
</property>
61+
<layout class="QVBoxLayout" name="verticalLayout_2">
62+
<item>
63+
<layout class="QHBoxLayout" name="horizontalLayout_2">
64+
<item>
65+
<widget class="QToolButton" name="btnAddClass">
66+
<property name="text">
67+
<string>Add</string>
68+
</property>
69+
</widget>
70+
</item>
71+
<item>
72+
<widget class="QToolButton" name="btnRemoveClass">
73+
<property name="text">
74+
<string>Remove</string>
75+
</property>
76+
</widget>
77+
</item>
78+
<item>
79+
<spacer name="horizontalSpacer">
80+
<property name="orientation">
81+
<enum>Qt::Horizontal</enum>
82+
</property>
83+
<property name="sizeHint" stdset="0">
84+
<size>
85+
<width>40</width>
86+
<height>20</height>
87+
</size>
88+
</property>
89+
</spacer>
90+
</item>
91+
</layout>
92+
</item>
93+
<item>
94+
<widget class="QTreeView" name="viewSizeClasses">
95+
<property name="rootIsDecorated">
96+
<bool>false</bool>
97+
</property>
98+
</widget>
99+
</item>
100+
</layout>
101+
</widget>
102+
</item>
50103
<item>
51104
<widget class="QGroupBox" name="groupBox">
52105
<property name="title">
@@ -79,14 +132,14 @@
79132
</item>
80133
</layout>
81134
</item>
82-
<item row="0" column="1">
135+
<item row="0" column="2">
83136
<widget class="QTreeView" name="viewLayerTree">
84137
<property name="headerHidden">
85138
<bool>true</bool>
86139
</property>
87140
</widget>
88141
</item>
89-
<item row="1" column="0" colspan="2">
142+
<item row="1" column="0" colspan="3">
90143
<widget class="QDialogButtonBox" name="buttonBox">
91144
<property name="orientation">
92145
<enum>Qt::Horizontal</enum>
@@ -102,6 +155,11 @@
102155
<tabstop>radDisabled</tabstop>
103156
<tabstop>radSeparated</tabstop>
104157
<tabstop>radCollapsed</tabstop>
158+
<tabstop>btnChangeSymbol</tabstop>
159+
<tabstop>groupManualSizeClasses</tabstop>
160+
<tabstop>btnAddClass</tabstop>
161+
<tabstop>btnRemoveClass</tabstop>
162+
<tabstop>viewSizeClasses</tabstop>
105163
<tabstop>cboAlignSymbols</tabstop>
106164
<tabstop>viewLayerTree</tabstop>
107165
</tabstops>

0 commit comments

Comments
 (0)
Please sign in to comment.