29#include "moc_qgsdiagramproperties.cpp"
47#include <QStyledItemDelegate>
48#include <QRandomGenerator>
72 , mMapCanvas( canvas )
89 mDiagramOptionsListWidget->setAttribute( Qt::WA_MacShowFocusRect,
false );
92 mOptionsTab->setIconSize( QSize( iconSize, iconSize ) );
93 mDiagramOptionsListWidget->setIconSize( QSize( iconSize, iconSize ) );
95 mBarSpacingSpinBox->setClearValue( 0 );
100 mDiagramTypeComboBox->blockSignals(
true );
109 mDiagramTypeComboBox->blockSignals(
false );
112 mAxisLineStyleButton->setDialogTitle( tr(
"Axis Line Symbol" ) );
114 mScaleRangeWidget->setMapCanvas( mMapCanvas );
115 mSizeFieldExpressionWidget->registerExpressionContextGenerator(
this );
117 mBackgroundColorButton->setColorDialogTitle( tr(
"Select Background Color" ) );
118 mBackgroundColorButton->setAllowOpacity(
true );
119 mBackgroundColorButton->setContext( QStringLiteral(
"symbology" ) );
120 mBackgroundColorButton->setShowNoColor(
true );
121 mBackgroundColorButton->setNoColorString( tr(
"Transparent Background" ) );
122 mDiagramPenColorButton->setColorDialogTitle( tr(
"Select Pen Color" ) );
123 mDiagramPenColorButton->setAllowOpacity(
true );
124 mDiagramPenColorButton->setContext( QStringLiteral(
"symbology" ) );
125 mDiagramPenColorButton->setShowNoColor(
true );
126 mDiagramPenColorButton->setNoColorString( tr(
"Transparent Stroke" ) );
128 mMaxValueSpinBox->setShowClearButton(
false );
129 mSizeSpinBox->setClearValue( 5 );
131 mDiagramAttributesTreeWidget->setItemDelegateForColumn( ColumnAttributeExpression,
new EditBlockerDelegate(
this ) );
132 mDiagramAttributesTreeWidget->setItemDelegateForColumn( ColumnColor,
new QgsColorSwatchDelegate(
this ) );
134 mDiagramAttributesTreeWidget->setColumnWidth( ColumnColor,
Qgis::UI_SCALE_FACTOR * fontMetrics().horizontalAdvance(
'X' ) * 6.6 );
145 mDiagramTypeComboBox->setEnabled(
false );
146 mOptionsTab->setEnabled(
false );
147 mDiagramFrame->setEnabled(
false );
155 stackedPlacement->setCurrentWidget( pagePoint );
156 mLinePlacementFrame->setVisible(
false );
159 stackedPlacement->setCurrentWidget( pageLine );
160 mLinePlacementFrame->setVisible(
true );
163 stackedPlacement->setCurrentWidget( pagePolygon );
164 mLinePlacementFrame->setVisible(
false );
173 mPlacePointBtnGrp =
new QButtonGroup(
this );
174 mPlacePointBtnGrp->addButton( radAroundPoint );
175 mPlacePointBtnGrp->addButton( radOverPoint );
176 mPlacePointBtnGrp->setExclusive(
true );
180 mPlaceLineBtnGrp =
new QButtonGroup(
this );
181 mPlaceLineBtnGrp->addButton( radAroundLine );
182 mPlaceLineBtnGrp->addButton( radOverLine );
183 mPlaceLineBtnGrp->setExclusive(
true );
187 mPlacePolygonBtnGrp =
new QButtonGroup(
this );
188 mPlacePolygonBtnGrp->addButton( radAroundCentroid );
189 mPlacePolygonBtnGrp->addButton( radOverCentroid );
190 mPlacePolygonBtnGrp->addButton( radPolygonPerimeter );
191 mPlacePolygonBtnGrp->addButton( radInsidePolygon );
192 mPlacePolygonBtnGrp->setExclusive(
true );
198 mScaleDependencyComboBox->addItem( tr(
"Area" ),
true );
199 mScaleDependencyComboBox->addItem( tr(
"Diameter" ),
false );
201 mAngleOffsetComboBox->addItem( tr(
"Top" ), 270 );
202 mAngleOffsetComboBox->addItem( tr(
"Right" ), 0 );
203 mAngleOffsetComboBox->addItem( tr(
"Bottom" ), 90 );
204 mAngleOffsetComboBox->addItem( tr(
"Left" ), 180 );
212 QSizePolicy policy( mDiagramOptionsListFrame->sizePolicy() );
213 policy.setHorizontalStretch( 0 );
214 mDiagramOptionsListFrame->setSizePolicy( policy );
215 if ( !settings.
contains( QStringLiteral(
"/Windows/Diagrams/OptionsSplitState" ) ) )
218 QList<int> splitsizes;
220 mDiagramOptionsSplitter->setSizes( splitsizes );
224 mDiagramOptionsSplitter->restoreState( settings.
value( QStringLiteral(
"Windows/Diagrams/OptionsSplitState" ) ).toByteArray() );
225 mDiagramOptionsListWidget->setCurrentRow( settings.
value( QStringLiteral(
"Windows/Diagrams/Tab" ), 0 ).toInt() );
228 whileBlocking( mOptionsTab )->setCurrentIndex( mDiagramStackedWidget->currentIndex() );
229 mOptionsTab->tabBar()->setUsesScrollButtons(
true );
232 mSizeFieldExpressionWidget->setLayer( mLayer );
236 mSizeFieldExpressionWidget->setGeomCalculator( myDa );
240 for (
int idx = 0; idx < layerFields.
count(); ++idx )
242 QTreeWidgetItem *newItem =
new QTreeWidgetItem( mAttributesTreeWidget );
243 const QString name = QStringLiteral(
"\"%1\"" ).arg( layerFields.
at( idx ).
name() );
244 newItem->setText( 0, name );
245 newItem->setData( 0, RoleAttributeExpression, name );
246 newItem->setFlags( newItem->flags() & ~Qt::ItemIsDropEnabled );
250 mPaintEffect->setEnabled(
false );
263 mPaintEffectWidget->setPaintEffect( mPaintEffect.get() );
281 QList<QWidget *> widgets;
282 widgets << chkLineAbove;
283 widgets << chkLineBelow;
284 widgets << chkLineOn;
285 widgets << chkLineOrientationDependent;
286 widgets << mAngleDirectionComboBox;
287 widgets << mAngleOffsetComboBox;
288 widgets << mAttributeBasedScalingRadio;
289 widgets << mAxisLineStyleButton;
290 widgets << mBackgroundColorButton;
291 widgets << mBarSpacingSpinBox;
292 widgets << mBarSpacingUnitComboBox;
293 widgets << mBarWidthSpinBox;
294 widgets << mCheckBoxAttributeLegend;
295 widgets << mDiagramAttributesTreeWidget;
296 widgets << mDiagramDistanceSpinBox;
297 widgets << mDiagramFontButton;
298 widgets << mDiagramPenColorButton;
299 widgets << mDiagramSizeSpinBox;
300 widgets << mDiagramLineUnitComboBox;
301 widgets << mDiagramTypeComboBox;
302 widgets << mDiagramUnitComboBox;
303 widgets << mEnableDiagramCheckBox;
304 widgets << mFixedSizeRadio;
305 widgets << mIncreaseMinimumSizeSpinBox;
306 widgets << mIncreaseSmallDiagramsGroupBox;
307 widgets << mLabelPlacementComboBox;
308 widgets << mMaxValueSpinBox;
309 widgets << mPaintEffectWidget;
310 widgets << mPenWidthSpinBox;
311 widgets << mPrioritySlider;
312 widgets << mOpacityWidget;
313 widgets << mOrientationDownButton;
314 widgets << mOrientationLeftButton;
315 widgets << mOrientationRightButton;
316 widgets << mOrientationUpButton;
317 widgets << mScaleDependencyComboBox;
318 widgets << mScaleRangeWidget;
319 widgets << mScaleVisibilityGroupBox;
320 widgets << mShowAllCheckBox;
321 widgets << mShowAxisGroupBox;
322 widgets << mSizeFieldExpressionWidget;
323 widgets << mSizeSpinBox;
324 widgets << mZIndexSpinBox;
325 widgets << radAroundCentroid;
326 widgets << radAroundLine;
327 widgets << radAroundPoint;
328 widgets << radInsidePolygon;
329 widgets << radOverCentroid;
330 widgets << radOverLine;
331 widgets << radOverPoint;
332 widgets << radPolygonPerimeter;
334 connectValueChanged( widgets );
340 mOptionsTab->setVisible(
dockMode );
341 mOptionsTab->setTabToolTip( 0, tr(
"Attributes" ) );
342 mOptionsTab->setTabToolTip( 1, tr(
"Rendering" ) );
343 mOptionsTab->setTabToolTip( 2, tr(
"Size" ) );
344 mOptionsTab->setTabToolTip( 3, tr(
"Placement" ) );
345 mOptionsTab->setTabToolTip( 4, tr(
"Options" ) );
346 mOptionsTab->setTabToolTip( 5, tr(
"Legend" ) );
347 mDiagramOptionsListFrame->setVisible( !
dockMode );
352 mDiagramType = diagramType;
354 mDiagramTypeComboBox->setVisible(
false );
355 mDiagramTypeComboBox->blockSignals(
true );
356 mDiagramTypeComboBox->setCurrentIndex( mDiagramTypeComboBox->findData( mDiagramType ) );
357 mDiagramTypeComboBox->blockSignals(
false );
363void QgsDiagramProperties::insertDefaults()
365 mFixedSizeRadio->setChecked(
true );
368 mLabelPlacementComboBox->setCurrentIndex( mLabelPlacementComboBox->findText( tr(
"x-height" ) ) );
369 mDiagramSizeSpinBox->setEnabled(
true );
370 mDiagramSizeSpinBox->setValue( 15 );
371 mLinearScaleFrame->setEnabled(
false );
372 mBarWidthSpinBox->setValue( 5 );
375 mShowAllCheckBox->setChecked(
true );
376 mCheckBoxAttributeLegend->setChecked(
true );
381 radAroundPoint->setChecked(
true );
385 radAroundLine->setChecked(
true );
386 chkLineAbove->setChecked(
true );
387 chkLineBelow->setChecked(
false );
388 chkLineOn->setChecked(
false );
389 chkLineOrientationDependent->setChecked(
false );
393 radOverCentroid->setChecked(
true );
394 mDiagramDistanceLabel->setEnabled(
false );
395 mDiagramDistanceSpinBox->setEnabled(
false );
396 mDistanceDDBtn->setEnabled(
false );
403 mBackgroundColorButton->setColor( QColor( 255, 255, 255, 255 ) );
404 mDiagramPenColorButton->setColor( QColor( 0, 0, 0, 255 ) );
419 renderer = stackedRenderer->
renderer( 0 );
430 mDiagramAttributesTreeWidget->clear();
441 mFixedSizeRadio->setChecked(
true );
445 mAttributeBasedScalingRadio->setChecked(
true );
447 mDiagramSizeSpinBox->setEnabled( mFixedSizeRadio->isChecked() );
448 mLinearScaleFrame->setEnabled( mAttributeBasedScalingRadio->isChecked() );
453 if ( !settingList.isEmpty() )
455 setDiagramEnabled( settingList.at( 0 ).enabled );
456 mDiagramFontButton->setCurrentFont( settingList.at( 0 ).font );
457 const QSizeF size = settingList.at( 0 ).size;
458 mBackgroundColorButton->setColor( settingList.at( 0 ).backgroundColor );
459 mOpacityWidget->setOpacity( settingList.at( 0 ).opacity );
460 mDiagramPenColorButton->setColor( settingList.at( 0 ).penColor );
461 mPenWidthSpinBox->setValue( settingList.at( 0 ).penWidth );
462 mDiagramSizeSpinBox->setValue( ( size.width() + size.height() ) / 2.0 );
463 mScaleRangeWidget->setScaleRange( ( settingList.at( 0 ).minimumScale > 0 ? settingList.at( 0 ).minimumScale : mLayer->
minimumScale() ), ( settingList.at( 0 ).maximumScale > 0 ? settingList.at( 0 ).maximumScale : mLayer->
maximumScale() ) );
464 mScaleVisibilityGroupBox->setChecked( settingList.at( 0 ).scaleBasedVisibility );
465 mDiagramUnitComboBox->setUnit( settingList.at( 0 ).sizeType );
466 mDiagramUnitComboBox->setMapUnitScale( settingList.at( 0 ).sizeScale );
467 mDiagramLineUnitComboBox->setUnit( settingList.at( 0 ).lineSizeUnit );
468 mDiagramLineUnitComboBox->setMapUnitScale( settingList.at( 0 ).lineSizeScale );
472 mLabelPlacementComboBox->setCurrentIndex( 0 );
476 mLabelPlacementComboBox->setCurrentIndex( 1 );
479 if ( settingList.at( 0 ).paintEffect() )
480 mPaintEffect.reset( settingList.at( 0 ).paintEffect()->clone() );
482 mAngleOffsetComboBox->setCurrentIndex( mAngleOffsetComboBox->findData( settingList.at( 0 ).rotationOffset ) );
483 mAngleDirectionComboBox->setCurrentIndex( mAngleDirectionComboBox->findData( settingList.at( 0 ).direction() ) );
485 switch ( settingList.at( 0 ).diagramOrientation )
488 mOrientationLeftButton->setChecked(
true );
492 mOrientationRightButton->setChecked(
true );
496 mOrientationUpButton->setChecked(
true );
500 mOrientationDownButton->setChecked(
true );
504 mBarWidthSpinBox->setValue( settingList.at( 0 ).barWidth );
505 mBarSpacingSpinBox->setValue( settingList.at( 0 ).spacing() );
506 mBarSpacingUnitComboBox->setUnit( settingList.at( 0 ).spacingUnit() );
507 mBarSpacingUnitComboBox->setMapUnitScale( settingList.at( 0 ).spacingMapUnitScale() );
509 mShowAxisGroupBox->setChecked( settingList.at( 0 ).showAxis() );
510 if ( settingList.at( 0 ).axisLineSymbol() )
511 mAxisLineStyleButton->setSymbol( settingList.at( 0 ).axisLineSymbol()->clone() );
513 mIncreaseSmallDiagramsGroupBox->setChecked( settingList.at( 0 ).minimumSize != 0 );
514 mIncreaseMinimumSizeSpinBox->setValue( settingList.at( 0 ).minimumSize );
516 if ( settingList.at( 0 ).scaleByArea )
518 mScaleDependencyComboBox->setCurrentIndex( 0 );
522 mScaleDependencyComboBox->setCurrentIndex( 1 );
525 const QList<QColor> categoryColors = settingList.at( 0 ).categoryColors;
526 const QList<QString> categoryAttributes = settingList.at( 0 ).categoryAttributes;
527 const QList<QString> categoryLabels = settingList.at( 0 ).categoryLabels;
528 QList<QString>::const_iterator catIt = categoryAttributes.constBegin();
529 QList<QColor>::const_iterator coIt = categoryColors.constBegin();
530 QList<QString>::const_iterator labIt = categoryLabels.constBegin();
531 for ( ; catIt != categoryAttributes.constEnd(); ++catIt, ++coIt, ++labIt )
533 QTreeWidgetItem *newItem =
new QTreeWidgetItem( mDiagramAttributesTreeWidget );
534 newItem->setText( 0, *catIt );
535 newItem->setData( 0, RoleAttributeExpression, *catIt );
536 newItem->setFlags( newItem->flags() & ~Qt::ItemIsDropEnabled );
537 newItem->setData( ColumnColor, Qt::EditRole, *coIt );
538 newItem->setText( 2, *labIt );
539 newItem->setFlags( newItem->flags() | Qt::ItemIsEditable );
548 mDiagramSizeSpinBox->setEnabled(
false );
549 mLinearScaleFrame->setEnabled(
true );
550 mMaxValueSpinBox->setValue( lidr->
upperValue() );
551 mSizeSpinBox->setValue( ( lidr->
upperSize().width() + lidr->
upperSize().height() ) / 2 );
569 mDiagramTypeComboBox->blockSignals(
true );
570 mDiagramTypeComboBox->setCurrentIndex( mDiagramTypeComboBox->findData( mDiagramType ) );
571 mDiagramTypeComboBox->blockSignals(
false );
576 mPaintEffectWidget->setPaintEffect( mPaintEffect.get() );
583 mDiagramDistanceSpinBox->setValue( dls->
distance() );
584 mPrioritySlider->setValue( dls->
priority() );
585 mZIndexSpinBox->setValue( dls->
zIndex() );
590 radAroundPoint->setChecked(
true );
591 radAroundCentroid->setChecked(
true );
595 radOverPoint->setChecked(
true );
596 radOverCentroid->setChecked(
true );
600 radAroundLine->setChecked(
true );
601 radPolygonPerimeter->setChecked(
true );
605 radOverLine->setChecked(
true );
606 radInsidePolygon->setChecked(
true );
617 chkLineOrientationDependent->setChecked(
true );
629 settings.
setValue( QStringLiteral(
"Windows/Diagrams/OptionsSplitState" ), mDiagramOptionsSplitter->saveState() );
630 settings.
setValue( QStringLiteral(
"Windows/Diagrams/Tab" ), mDiagramOptionsListWidget->currentRow() );
641void QgsDiagramProperties::updateProperty()
651 mDiagramType = mDiagramTypeComboBox->itemData( index ).toString();
655 mTextOptionsFrame->show();
656 mBackgroundColorLabel->show();
657 mBackgroundColorButton->show();
658 mBackgroundColorDDBtn->show();
659 mDiagramFontButton->show();
663 mTextOptionsFrame->hide();
664 mBackgroundColorLabel->hide();
665 mBackgroundColorButton->hide();
666 mBackgroundColorDDBtn->hide();
667 mDiagramFontButton->hide();
672 mBarWidthLabel->show();
673 mBarWidthSpinBox->show();
674 mBarSpacingLabel->show();
675 mBarSpacingSpinBox->show();
676 mBarSpacingUnitComboBox->show();
677 mBarOptionsFrame->show();
678 mShowAxisGroupBox->show();
680 mAttributeBasedScalingRadio->setChecked(
true );
683 mLinearlyScalingLabel->setText( tr(
"Bar length: Scale linearly, so that the following value matches the specified bar length:" ) );
684 mSizeLabel->setText( tr(
"Bar length" ) );
685 mFrameIncreaseSize->setVisible(
false );
689 mBarWidthLabel->hide();
690 mBarWidthSpinBox->hide();
691 mBarSpacingLabel->hide();
692 mBarSpacingSpinBox->hide();
693 mBarSpacingUnitComboBox->hide();
694 mShowAxisGroupBox->hide();
695 mBarOptionsFrame->hide();
696 mLinearlyScalingLabel->setText( tr(
"Scale linearly between 0 and the following attribute value / diagram size:" ) );
697 mSizeLabel->setText( tr(
"Size" ) );
698 mAttributeBasedScalingRadio->setEnabled(
true );
699 mFixedSizeRadio->setEnabled(
true );
700 mDiagramSizeSpinBox->setEnabled( mFixedSizeRadio->isChecked() );
701 mFrameIncreaseSize->setVisible(
true );
706 mScaleDependencyComboBox->show();
707 mScaleDependencyLabel->show();
711 mScaleDependencyComboBox->hide();
712 mScaleDependencyLabel->hide();
717 mAngleOffsetComboBox->show();
718 mAngleDirectionComboBox->show();
719 mAngleDirectionLabel->show();
720 mAngleOffsetLabel->show();
721 mStartAngleDDBtn->show();
725 mAngleOffsetComboBox->hide();
726 mAngleDirectionComboBox->hide();
727 mAngleDirectionLabel->hide();
728 mAngleOffsetLabel->hide();
729 mStartAngleDDBtn->hide();
733QString QgsDiagramProperties::guessLegendText(
const QString &expression )
736 QString text = expression.mid( expression.startsWith(
'\"' ) ? 1 : 0 );
737 if ( text.endsWith(
'\"' ) )
744 QTreeWidgetItem *newItem =
new QTreeWidgetItem( mDiagramAttributesTreeWidget );
746 newItem->setText( 0, item->text( 0 ) );
747 newItem->setText( 2, guessLegendText( item->text( 0 ) ) );
748 newItem->setData( 0, RoleAttributeExpression, item->data( 0, RoleAttributeExpression ) );
749 newItem->setFlags( ( newItem->flags() | Qt::ItemIsEditable ) & ~Qt::ItemIsDropEnabled );
752 const int red = QRandomGenerator::global()->bounded( 1, 256 );
753 const int green = QRandomGenerator::global()->bounded( 1, 256 );
754 const int blue = QRandomGenerator::global()->bounded( 1, 256 );
755 const QColor randomColor( red, green, blue );
756 newItem->setData( ColumnColor, Qt::EditRole, randomColor );
757 mDiagramAttributesTreeWidget->addTopLevelItem( newItem );
762 const auto constSelectedItems = mAttributesTreeWidget->selectedItems();
763 for ( QTreeWidgetItem *attributeItem : constSelectedItems )
777 const auto constSelectedItems = mDiagramAttributesTreeWidget->selectedItems();
778 for ( QTreeWidgetItem *attributeItem : constSelectedItems )
780 delete attributeItem;
789 float maxValue = 0.0;
792 const QString sizeFieldNameOrExp = mSizeFieldExpressionWidget->currentField( &isExpression );
810 maxValue = std::max( maxValue, exp.
evaluate( &context ).toFloat() );
821 maxValue = mLayer->
maximumValue( attributeNumber ).toFloat();
824 mMaxValueSpinBox->setValue( maxValue );
831 case ColumnAttributeExpression:
833 const QString currentExpression = item->data( 0, RoleAttributeExpression ).toString();
835 const QString newExpression = showExpressionBuilder( currentExpression );
836 if ( !newExpression.isEmpty() )
838 item->setData( 0, Qt::DisplayRole, newExpression );
839 item->setData( 0, RoleAttributeExpression, newExpression );
847 case ColumnLegendText:
852std::unique_ptr<QgsDiagram> QgsDiagramProperties::createDiagramObject()
854 std::unique_ptr<QgsDiagram> diagram;
858 diagram = std::make_unique<QgsTextDiagram>();
862 diagram = std::make_unique<QgsPieDiagram>();
866 diagram = std::make_unique<QgsStackedBarDiagram>();
870 diagram = std::make_unique<QgsHistogramDiagram>();
875std::unique_ptr<QgsDiagramSettings> QgsDiagramProperties::createDiagramSettings()
877 std::unique_ptr<QgsDiagramSettings> ds = std::make_unique<QgsDiagramSettings>();
878 ds->enabled = isDiagramEnabled();
879 ds->font = mDiagramFontButton->currentFont();
880 ds->opacity = mOpacityWidget->opacity();
882 QList<QColor> categoryColors;
883 QList<QString> categoryAttributes;
884 QList<QString> categoryLabels;
885 categoryColors.reserve( mDiagramAttributesTreeWidget->topLevelItemCount() );
886 categoryAttributes.reserve( mDiagramAttributesTreeWidget->topLevelItemCount() );
887 categoryLabels.reserve( mDiagramAttributesTreeWidget->topLevelItemCount() );
888 for (
int i = 0; i < mDiagramAttributesTreeWidget->topLevelItemCount(); ++i )
890 QColor color = mDiagramAttributesTreeWidget->topLevelItem( i )->data( ColumnColor, Qt::EditRole ).value<QColor>();
891 categoryColors.append( color );
892 categoryAttributes.append( mDiagramAttributesTreeWidget->topLevelItem( i )->data( 0, RoleAttributeExpression ).toString() );
893 categoryLabels.append( mDiagramAttributesTreeWidget->topLevelItem( i )->text( 2 ) );
895 ds->categoryColors = categoryColors;
896 ds->categoryAttributes = categoryAttributes;
897 ds->categoryLabels = categoryLabels;
898 ds->size = QSizeF( mDiagramSizeSpinBox->value(), mDiagramSizeSpinBox->value() );
899 ds->sizeType = mDiagramUnitComboBox->unit();
900 ds->sizeScale = mDiagramUnitComboBox->getMapUnitScale();
901 ds->lineSizeUnit = mDiagramLineUnitComboBox->unit();
902 ds->lineSizeScale = mDiagramLineUnitComboBox->getMapUnitScale();
906 if ( mIncreaseSmallDiagramsGroupBox->isChecked() )
908 ds->minimumSize = mIncreaseMinimumSizeSpinBox->value();
915 ds->backgroundColor = mBackgroundColorButton->color();
916 ds->penColor = mDiagramPenColorButton->color();
917 ds->penWidth = mPenWidthSpinBox->value();
918 ds->minimumScale = mScaleRangeWidget->minimumScale();
919 ds->maximumScale = mScaleRangeWidget->maximumScale();
920 ds->scaleBasedVisibility = mScaleVisibilityGroupBox->isChecked();
923 ds->rotationOffset = mAngleOffsetComboBox->currentData().toInt();
929 ds->barWidth = mBarWidthSpinBox->value();
931 ds->setAxisLineSymbol( mAxisLineStyleButton->clonedSymbol<
QgsLineSymbol>() );
932 ds->setShowAxis( mShowAxisGroupBox->isChecked() );
934 ds->setSpacing( mBarSpacingSpinBox->value() );
935 ds->setSpacingUnit( mBarSpacingUnitComboBox->unit() );
936 ds->setSpacingMapUnitScale( mBarSpacingUnitComboBox->getMapUnitScale() );
939 ds->setPaintEffect( mPaintEffect->clone() );
941 ds->setPaintEffect(
nullptr );
946std::unique_ptr<QgsDiagramRenderer> QgsDiagramProperties::createRenderer()
948 std::unique_ptr<QgsDiagramSettings> ds = createDiagramSettings();
950 std::unique_ptr<QgsDiagramRenderer> renderer;
951 if ( mFixedSizeRadio->isChecked() )
953 std::unique_ptr<QgsSingleCategoryDiagramRenderer> dr = std::make_unique<QgsSingleCategoryDiagramRenderer>();
954 dr->setDiagramSettings( *ds );
955 renderer = std::move( dr );
959 std::unique_ptr<QgsLinearlyInterpolatedDiagramRenderer> dr = std::make_unique<QgsLinearlyInterpolatedDiagramRenderer>();
960 dr->setLowerValue( 0.0 );
961 dr->setLowerSize( QSizeF( 0.0, 0.0 ) );
962 dr->setUpperValue( mMaxValueSpinBox->value() );
963 dr->setUpperSize( QSizeF( mSizeSpinBox->value(), mSizeSpinBox->value() ) );
966 const QString sizeFieldNameOrExp = mSizeFieldExpressionWidget->currentField( &isExpression );
967 dr->setClassificationAttributeIsExpression( isExpression );
970 dr->setClassificationAttributeExpression( sizeFieldNameOrExp );
974 dr->setClassificationField( sizeFieldNameOrExp );
976 dr->setDiagramSettings( *ds );
980 renderer = std::move( dr );
983 renderer->setAttributeLegend( mCheckBoxAttributeLegend->isChecked() );
985 std::unique_ptr<QgsDiagram> diagram = createDiagramObject();
986 renderer->setDiagram( diagram.release() );
995 dls.
setDistance( mDiagramDistanceSpinBox->value() );
997 dls.
setZIndex( mZIndexSpinBox->value() );
1000 QWidget *curWdgt = stackedPlacement->currentWidget();
1001 if ( ( curWdgt == pagePoint && radAroundPoint->isChecked() )
1002 || ( curWdgt == pagePolygon && radAroundCentroid->isChecked() ) )
1006 else if ( ( curWdgt == pagePoint && radOverPoint->isChecked() )
1007 || ( curWdgt == pagePolygon && radOverCentroid->isChecked() ) )
1011 else if ( ( curWdgt == pageLine && radAroundLine->isChecked() )
1012 || ( curWdgt == pagePolygon && radPolygonPerimeter->isChecked() ) )
1016 else if ( ( curWdgt == pageLine && radOverLine->isChecked() )
1017 || ( curWdgt == pagePolygon && radInsidePolygon->isChecked() ) )
1023 qFatal(
"Invalid settings" );
1027 if ( chkLineAbove->isChecked() )
1029 if ( chkLineBelow->isChecked() )
1031 if ( chkLineOn->isChecked() )
1033 if ( !chkLineOrientationDependent->isChecked() )
1044 if ( !
dockMode() || !settings.
value( QStringLiteral(
"UI/autoApplyStyling" ),
true ).toBool() )
1046 if ( isDiagramEnabled() && 0 == mDiagramAttributesTreeWidget->topLevelItemCount() )
1048 QMessageBox::warning(
this, tr(
"Diagrams: No attributes added." ), tr(
"You did not add any attributes to this diagram layer. Please specify the attributes to visualize on the diagrams or disable diagrams." ) );
1052 std::unique_ptr<QgsDiagramRenderer> renderer = createRenderer();
1063QString QgsDiagramProperties::showExpressionBuilder(
const QString &initialExpression )
1068 dlg.setWindowTitle( tr(
"Expression Based Attribute" ) );
1073 dlg.setGeomCalculator( myDa );
1075 if ( dlg.exec() == QDialog::Accepted )
1077 return dlg.expressionText();
1088 QList<QTreeWidgetItem *> selections = mAttributesTreeWidget->selectedItems();
1089 if ( !selections.empty() )
1091 expression = selections[0]->text( 0 );
1094 const QString newExpression = showExpressionBuilder( expression );
1097 if ( !newExpression.isEmpty() )
1099 QTreeWidgetItem *newItem =
new QTreeWidgetItem( mDiagramAttributesTreeWidget );
1101 newItem->setText( 0, newExpression );
1102 newItem->setText( 2, newExpression );
1103 newItem->setData( 0, RoleAttributeExpression, newExpression );
1104 newItem->setFlags( ( newItem->flags() | Qt::ItemIsEditable ) & ~Qt::ItemIsDropEnabled );
1107 QRandomGenerator colorGenerator;
1108 const int red = colorGenerator.bounded( 1, 256 );
1109 const int green = colorGenerator.bounded( 1, 256 );
1110 const int blue = colorGenerator.bounded( 1, 256 );
1112 const QColor randomColor( red, green, blue );
1113 newItem->setData( ColumnColor, Qt::EditRole, randomColor );
1114 mDiagramAttributesTreeWidget->addTopLevelItem( newItem );
1121 mDiagramOptionsListWidget->blockSignals(
true );
1122 mDiagramOptionsListWidget->setCurrentRow( index );
1123 mDiagramOptionsListWidget->blockSignals(
false );
1128 QWidget *curWdgt = stackedPlacement->currentWidget();
1130 if ( ( curWdgt == pagePoint && radAroundPoint->isChecked() )
1131 || ( curWdgt == pageLine && radAroundLine->isChecked() )
1132 || ( curWdgt == pagePolygon && radAroundCentroid->isChecked() ) )
1134 mDiagramDistanceLabel->setEnabled(
true );
1135 mDiagramDistanceSpinBox->setEnabled(
true );
1136 mDistanceDDBtn->setEnabled(
true );
1140 mDiagramDistanceLabel->setEnabled(
false );
1141 mDiagramDistanceSpinBox->setEnabled(
false );
1142 mDistanceDDBtn->setEnabled(
false );
1146 chkLineAbove->setEnabled( linePlacementEnabled );
1147 chkLineBelow->setEnabled( linePlacementEnabled );
1148 chkLineOn->setEnabled( linePlacementEnabled );
1149 chkLineOrientationDependent->setEnabled( linePlacementEnabled );
1154 mButtonSizeLegendSettings->setEnabled( mAttributeBasedScalingRadio->isChecked() );
1159 mAllowedToEditDls = allowed;
1161 label_16->setVisible( allowed );
1162 mZIndexSpinBox->setVisible( allowed );
1163 mZOrderDDBtn->setVisible( allowed );
1164 mShowAllCheckBox->setVisible( allowed );
1165 mDlsLabel_1->setVisible( !allowed );
1167 mCoordinatesGrpBox->setVisible( allowed );
1168 mLinePlacementFrame->setVisible( allowed );
1169 mObstaclesGrpBox->setVisible( allowed );
1170 mPlacementFrame->setVisible( allowed );
1171 mPriorityGrpBox->setVisible( allowed );
1172 stackedPlacement->setVisible( allowed );
1173 mDlsLabel_2->setVisible( !allowed );
1178 return mAllowedToEditDls;
1185 const QString sizeFieldNameOrExp = mSizeFieldExpressionWidget->currentField( &isExpression );
1187 const bool scaleByArea = mScaleDependencyComboBox->currentData().toBool();
1193 dlg.setLayout(
new QVBoxLayout() );
1195 dlg.layout()->addWidget( panel );
1196 QDialogButtonBox *buttonBox =
new QDialogButtonBox( QDialogButtonBox::Cancel | QDialogButtonBox::Help | QDialogButtonBox::Ok );
1197 connect( buttonBox, &QDialogButtonBox::accepted, &dlg, &QDialog::accept );
1198 connect( buttonBox, &QDialogButtonBox::helpRequested,
this, &QgsDiagramProperties::showHelp );
1199 connect( buttonBox, &QDialogButtonBox::rejected, &dlg, &QDialog::reject );
1200 dlg.layout()->addWidget( buttonBox );
1205void QgsDiagramProperties::showHelp()
1207 QgsHelp::openHelp( QStringLiteral(
"working_with_vector/vector_properties.html#legend" ) );
1210void QgsDiagramProperties::createAuxiliaryField()
1234 property.setActive(
true );
1242void QgsDiagramProperties::connectValueChanged(
const QList<QWidget *> &widgets )
1244 const auto constWidgets = widgets;
1245 for ( QWidget *widget : constWidgets )
1255 else if (
QgsOpacityWidget *w = qobject_cast<QgsOpacityWidget *>( widget ) )
1263 else if ( QComboBox *w = qobject_cast<QComboBox *>( widget ) )
1267 else if ( QSpinBox *w = qobject_cast<QSpinBox *>( widget ) )
1271 else if ( QDoubleSpinBox *w = qobject_cast<QDoubleSpinBox *>( widget ) )
1275 else if (
QgsColorButton *w = qobject_cast<QgsColorButton *>( widget ) )
1279 else if ( QCheckBox *w = qobject_cast<QCheckBox *>( widget ) )
1283 else if ( QRadioButton *w = qobject_cast<QRadioButton *>( widget ) )
1287 else if ( QSlider *w = qobject_cast<QSlider *>( widget ) )
1291 else if ( QGroupBox *w = qobject_cast<QGroupBox *>( widget ) )
1295 else if ( QTreeWidget *w = qobject_cast<QTreeWidget *>( widget ) )
1307 else if (
QgsFontButton *w = qobject_cast<QgsFontButton *>( widget ) )
1313 QgsLogger::warning( QStringLiteral(
"Could not create connection for widget %1" ).arg( widget->objectName() ) );
1318void QgsDiagramProperties::setDiagramEnabled(
bool enabled )
1320 mEnableDiagramCheckBox->setChecked( enabled );
1323bool QgsDiagramProperties::isDiagramEnabled()
const
1325 return mEnableDiagramCheckBox->isChecked();
GeometryType
The geometry types are used to group Qgis::WkbType in a coarse way.
@ Millimeters
Millimeters.
@ Points
Points (e.g., for font sizes)
@ MetersInMapUnits
Meters value as Map units.
static const double UI_SCALE_FACTOR
UI scaling factor.
static QIcon getThemeIcon(const QString &name, const QColor &fillColor=QColor(), const QColor &strokeColor=QColor())
Helper to get a theme icon.
static QString nameFromProperty(const QgsPropertyDefinition &def, bool joined=false)
Returns the name of the auxiliary field for a property definition.
bool addAuxiliaryField(const QgsPropertyDefinition &definition)
Adds an auxiliary field for the given property.
bool exists(const QgsPropertyDefinition &definition) const
Returns true if the property is stored in the layer already, false otherwise.
A delegate for showing a color swatch in a list.
Object that keeps configuration of appearance of marker symbol's data-defined size in legend.
Stores the settings for rendering of all diagrams for a layer.
void setZIndex(double index)
Sets the diagram z-index.
Placement placement() const
Returns the diagram placement.
QFlags< LinePlacementFlag > LinePlacementFlags
bool showAllDiagrams() const
Returns whether the layer should show all diagrams, including overlapping diagrams.
QgsPropertyCollection & dataDefinedProperties()
Returns a reference to the diagram's property collection, used for data defined overrides.
LinePlacementFlags linePlacementFlags() const
Returns the diagram placement flags.
Property
Data definable properties.
@ PositionX
X-coordinate data defined diagram position.
@ Distance
Distance to diagram from feature.
@ PositionY
Y-coordinate data defined diagram position.
@ Show
Whether to show the diagram.
@ Priority
Diagram priority (between 0 and 10)
@ ZIndex
Z-index for diagram ordering.
@ StrokeColor
Stroke color.
@ BackgroundColor
Diagram background color.
@ StartAngle
Angle offset for pie diagram.
@ IsObstacle
Whether diagram features act as obstacles for other diagrams/labels.
@ StrokeWidth
Stroke width.
@ AlwaysShow
Whether the diagram should always be shown, even if it overlaps other diagrams/labels.
void setShowAllDiagrams(bool showAllDiagrams)
Sets whether the layer should show all diagrams, including overlapping diagrams.
void setDistance(double distance)
Sets the distance between the diagram and the feature.
static const QgsPropertiesDefinition & propertyDefinitions()
Returns the diagram property definitions.
void setPriority(int value)
Sets the diagram priority.
int priority() const
Returns the diagram priority.
void setPlacement(Placement value)
Sets the diagram placement.
void setLinePlacementFlags(LinePlacementFlags flags)
Sets the the diagram placement flags.
void setDataDefinedProperties(const QgsPropertyCollection &collection)
Sets the diagram's property collection, used for data defined overrides.
double zIndex() const
Returns the diagram z-index.
double distance() const
Returns the distance between the diagram and the feature (in mm).
void syncToSettings(const QgsDiagramLayerSettings *dls)
Updates the widget to reflect the diagram layer settings.
void scalingTypeChanged()
void setDockMode(bool dockMode) override
Sets the widget in dock mode.
void mDiagramAttributesTreeWidget_itemDoubleClicked(QTreeWidgetItem *item, int column)
void mAddCategoryPushButton_clicked()
bool isAllowedToEditDiagramLayerSettings() const
Returns whether this widget is allowed to edit diagram layer settings.
void mDiagramTypeComboBox_currentIndexChanged(int index)
~QgsDiagramProperties() override
void syncToLayer()
Updates the widget to reflect the layer's current diagram settings.
void mRemoveCategoryPushButton_clicked()
QgsDiagramProperties(QgsVectorLayer *layer, QWidget *parent, QgsMapCanvas *canvas)
void showSizeLegendDialog()
void setDiagramType(const QString diagramType)
Defines the widget's diagram type and lets it know it should hide the type comboBox.
void addAttribute(QTreeWidgetItem *item)
Adds an attribute from the list of available attributes to the assigned attributes with a random colo...
void mFindMaximumValueButton_clicked()
void showAddAttributeExpressionDialog()
void syncToRenderer(const QgsDiagramRenderer *dr)
Updates the widget to reflect the diagram renderer.
void mAttributesTreeWidget_itemDoubleClicked(QTreeWidgetItem *item, int column)
void auxiliaryFieldCreated()
void updatePlacementWidgets()
void setAllowedToEditDiagramLayerSettings(bool allowed)
Sets whether the widget should show diagram layer settings.
void mDiagramStackedWidget_currentChanged(int index)
Evaluates and returns the diagram settings relating to a diagram for a specific feature.
virtual QString rendererName() const =0
QgsDiagram * diagram() const
virtual QList< QgsDiagramSettings > diagramSettings() const =0
Returns list with all diagram settings in the renderer.
bool attributeLegend() const
Returns true if renderer will show legend items for diagram attributes.
DiagramOrientation
Orientation of histogram.
Direction
Angular directions.
@ Counterclockwise
Counter-clockwise orientation.
@ Clockwise
Clockwise orientation.
virtual QString diagramName() const =0
Gets a descriptive name for this diagram type.
A general purpose distance and area calculator, capable of performing ellipsoid based calculations.
void setSourceCrs(const QgsCoordinateReferenceSystem &crs, const QgsCoordinateTransformContext &context)
Sets source spatial reference system crs.
bool setEllipsoid(const QString &ellipsoid)
Sets the ellipsoid by its acronym.
A generic dialog for building expression strings.
static QgsExpressionContextScope * projectScope(const QgsProject *project)
Creates a new scope which contains variables and functions relating to a QGIS project.
static QgsExpressionContextScope * atlasScope(const QgsLayoutAtlas *atlas)
Creates a new scope which contains variables and functions relating to a QgsLayoutAtlas.
static QgsExpressionContextScope * mapSettingsScope(const QgsMapSettings &mapSettings)
Creates a new scope which contains variables and functions relating to a QgsMapSettings object.
static QgsExpressionContextScope * layerScope(const QgsMapLayer *layer)
Creates a new scope which contains variables and functions relating to a QgsMapLayer.
static QgsExpressionContextScope * globalScope()
Creates a new scope which contains variables and functions relating to the global QGIS context.
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
void setFeature(const QgsFeature &feature)
Convenience function for setting a feature for the context.
Class for parsing and evaluation of expressions (formerly called "search strings").
bool prepare(const QgsExpressionContext *context)
Gets the expression ready for evaluation - find out column indexes.
QString evalErrorString() const
Returns evaluation error.
bool hasEvalError() const
Returns true if an error occurred when evaluating last input.
QVariant evaluate()
Evaluate the feature and return the result.
Wrapper for iterator of features from vector data provider or vector layer.
bool nextFeature(QgsFeature &f)
Fetch next feature and stores in f, returns true on success.
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
Container of fields for a vector layer.
QgsField at(int i) const
Returns the field at particular index (must be in range 0..N-1).
Q_INVOKABLE int lookupField(const QString &fieldName) const
Looks up field's index from the field name.
static void openHelp(const QString &key)
Opens help topic for the given help key using default system web browser.
static const QString DIAGRAM_NAME_HISTOGRAM
A line symbol type, for rendering LineString and MultiLineString geometries.
Alters the size of rendered diagrams using a linear scaling.
double upperValue() const
QString classificationAttributeExpression() const
QString classificationField() const
Returns the field name used for interpolating the diagram size.
bool classificationAttributeIsExpression() const
QgsDataDefinedSizeLegend * dataDefinedSizeLegend() const
Returns configuration of appearance of legend.
static const QString DIAGRAM_RENDERER_NAME_LINEARLY_INTERPOLATED
static void warning(const QString &msg)
Goes to qWarning.
Map canvas is a class for displaying all GIS data types on a canvas.
QgsExpressionContext createExpressionContext() const override
This method needs to be reimplemented in all classes which implement this interface and return an exp...
const QgsMapSettings & mapSettings() const
Gets access to properties used for map rendering.
QgsCoordinateReferenceSystem crs
void triggerRepaint(bool deferredUpdate=false)
Will advise the map canvas (and any other interested party) that this layer requires to be repainted.
bool hasScaleBasedVisibility() const
Returns whether scale based visibility is enabled for the layer.
double minimumScale() const
Returns the minimum map scale (i.e.
double maximumScale() const
Returns the maximum map scale (i.e.
The QgsMapSettings class contains configuration for rendering of the map.
A dialog to create a new auxiliary layer.
static QgsPaintEffect * defaultStack()
Returns a new effect stack consisting of a sensible selection of default effects.
static bool isDefaultStack(QgsPaintEffect *effect)
Tests whether a paint effect matches the default effects stack.
static const QString DIAGRAM_NAME_PIE
static QgsProject * instance()
Returns the QgsProject singleton instance.
QgsCoordinateTransformContext transformContext
void setDirty(bool b=true)
Flag the project as dirty (modified).
void setProperty(int key, const QgsProperty &property)
Adds a property to the collection and takes ownership of it.
Definition for a property.
A store for object properties.
void setTransformer(QgsPropertyTransformer *transformer)
Sets an optional transformer to use for manipulating the calculated values for the property.
static QgsProperty fromExpression(const QString &expression, bool isActive=true)
Returns a new ExpressionBasedProperty created from the specified expression.
void setField(const QString &field)
Sets the field name the property references.
static QgsProperty fromField(const QString &fieldName, bool isActive=true)
Returns a new FieldBasedProperty created from the specified field name.
This class is a composition of two QSettings instances:
QVariant value(const QString &key, const QVariant &defaultValue=QVariant(), Section section=NoSection) const
Returns the value for setting key.
bool contains(const QString &key, QgsSettings::Section section=QgsSettings::NoSection) const
Returns true if there exists a setting called key; returns false otherwise.
void setValue(const QString &key, const QVariant &value, QgsSettings::Section section=QgsSettings::NoSection)
Sets the value of setting key to value.
static const QString DIAGRAM_RENDERER_NAME_SINGLE_CATEGORY
static const QString DIAGRAM_NAME_STACKED_BAR
Renders diagrams using mixed diagram render types.
static const QString DIAGRAM_RENDERER_NAME_STACKED
const QgsDiagramRenderer * renderer(const int index) const
Returns the renderer at the given index.
int rendererCount() const
Returns the number of sub renderers in the stacked diagram renderer.
static const QString DIAGRAM_NAME_TEXT
Represents a vector layer which manages a vector based data sets.
QVariant maximumValue(int index) const FINAL
Returns the maximum value for an attribute column or an invalid variant in case of error.
const QgsDiagramLayerSettings * diagramLayerSettings() const
QgsFeatureIterator getFeatures(const QgsFeatureRequest &request=QgsFeatureRequest()) const FINAL
Queries the layer for features specified in request.
QgsAuxiliaryLayer * auxiliaryLayer()
Returns the current auxiliary layer.
Q_INVOKABLE Qgis::GeometryType geometryType() const
Returns point, line or polygon.
void setDiagramLayerSettings(const QgsDiagramLayerSettings &s)
void setDiagramRenderer(QgsDiagramRenderer *r)
Sets diagram rendering object (takes ownership)
const QgsDiagramRenderer * diagramRenderer() const
int scaleIconSize(int standardSize)
Scales an icon size to compensate for display pixel density, making the icon size hi-dpi friendly,...
QgsSignalBlocker< Object > whileBlocking(Object *object)
Temporarily blocks signals from a QObject while calling a single method from the object.
#define QgsDebugMsgLevel(str, level)