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 );
105 mDiagramTypeComboBox->blockSignals(
true );
114 mDiagramTypeComboBox->blockSignals(
false );
117 mAxisLineStyleButton->setDialogTitle( tr(
"Axis Line Symbol" ) );
119 mScaleRangeWidget->setMapCanvas( mMapCanvas );
120 mSizeFieldExpressionWidget->registerExpressionContextGenerator(
this );
122 mBackgroundColorButton->setColorDialogTitle( tr(
"Select Background Color" ) );
123 mBackgroundColorButton->setAllowOpacity(
true );
124 mBackgroundColorButton->setContext( QStringLiteral(
"symbology" ) );
125 mBackgroundColorButton->setShowNoColor(
true );
126 mBackgroundColorButton->setNoColorString( tr(
"Transparent Background" ) );
127 mDiagramPenColorButton->setColorDialogTitle( tr(
"Select Pen Color" ) );
128 mDiagramPenColorButton->setAllowOpacity(
true );
129 mDiagramPenColorButton->setContext( QStringLiteral(
"symbology" ) );
130 mDiagramPenColorButton->setShowNoColor(
true );
131 mDiagramPenColorButton->setNoColorString( tr(
"Transparent Stroke" ) );
133 mMaxValueSpinBox->setShowClearButton(
false );
134 mSizeSpinBox->setClearValue( 5 );
136 mDiagramAttributesTreeWidget->setItemDelegateForColumn( ColumnAttributeExpression,
new EditBlockerDelegate(
this ) );
137 mDiagramAttributesTreeWidget->setItemDelegateForColumn( ColumnColor,
new QgsColorSwatchDelegate(
this ) );
139 mDiagramAttributesTreeWidget->setColumnWidth( ColumnColor,
Qgis::UI_SCALE_FACTOR * fontMetrics().horizontalAdvance(
'X' ) * 6.6 );
158 mDiagramTypeComboBox->setEnabled(
false );
159 mOptionsTab->setEnabled(
false );
160 mDiagramFrame->setEnabled(
false );
168 stackedPlacement->setCurrentWidget( pagePoint );
169 mLinePlacementFrame->setVisible(
false );
172 stackedPlacement->setCurrentWidget( pageLine );
173 mLinePlacementFrame->setVisible(
true );
176 stackedPlacement->setCurrentWidget( pagePolygon );
177 mLinePlacementFrame->setVisible(
false );
186 mPlacePointBtnGrp =
new QButtonGroup(
this );
187 mPlacePointBtnGrp->addButton( radAroundPoint );
188 mPlacePointBtnGrp->addButton( radOverPoint );
189 mPlacePointBtnGrp->setExclusive(
true );
193 mPlaceLineBtnGrp =
new QButtonGroup(
this );
194 mPlaceLineBtnGrp->addButton( radAroundLine );
195 mPlaceLineBtnGrp->addButton( radOverLine );
196 mPlaceLineBtnGrp->setExclusive(
true );
200 mPlacePolygonBtnGrp =
new QButtonGroup(
this );
201 mPlacePolygonBtnGrp->addButton( radAroundCentroid );
202 mPlacePolygonBtnGrp->addButton( radOverCentroid );
203 mPlacePolygonBtnGrp->addButton( radPolygonPerimeter );
204 mPlacePolygonBtnGrp->addButton( radInsidePolygon );
205 mPlacePolygonBtnGrp->setExclusive(
true );
211 mScaleDependencyComboBox->addItem( tr(
"Area" ),
true );
212 mScaleDependencyComboBox->addItem( tr(
"Diameter" ),
false );
214 mAngleOffsetComboBox->addItem( tr(
"Top" ), 270 );
215 mAngleOffsetComboBox->addItem( tr(
"Right" ), 0 );
216 mAngleOffsetComboBox->addItem( tr(
"Bottom" ), 90 );
217 mAngleOffsetComboBox->addItem( tr(
"Left" ), 180 );
225 QSizePolicy policy( mDiagramOptionsListFrame->sizePolicy() );
226 policy.setHorizontalStretch( 0 );
227 mDiagramOptionsListFrame->setSizePolicy( policy );
228 if ( !settings.
contains( QStringLiteral(
"/Windows/Diagrams/OptionsSplitState" ) ) )
231 QList<int> splitsizes;
233 mDiagramOptionsSplitter->setSizes( splitsizes );
237 mDiagramOptionsSplitter->restoreState( settings.
value( QStringLiteral(
"Windows/Diagrams/OptionsSplitState" ) ).toByteArray() );
238 mDiagramOptionsListWidget->setCurrentRow( settings.
value( QStringLiteral(
"Windows/Diagrams/Tab" ), 0 ).toInt() );
241 whileBlocking( mOptionsTab )->setCurrentIndex( mDiagramStackedWidget->currentIndex() );
242 mOptionsTab->tabBar()->setUsesScrollButtons(
true );
245 mSizeFieldExpressionWidget->setLayer( mLayer );
249 mSizeFieldExpressionWidget->setGeomCalculator( myDa );
253 for (
int idx = 0; idx < layerFields.
count(); ++idx )
255 QTreeWidgetItem *newItem =
new QTreeWidgetItem( mAttributesTreeWidget );
256 const QString name = QStringLiteral(
"\"%1\"" ).arg( layerFields.
at( idx ).
name() );
257 newItem->setText( 0, name );
258 newItem->setData( 0, RoleAttributeExpression, name );
259 newItem->setFlags( newItem->flags() & ~Qt::ItemIsDropEnabled );
263 mPaintEffect->setEnabled(
false );
276 mPaintEffectWidget->setPaintEffect( mPaintEffect.get() );
294 QList<QWidget *> widgets;
295 widgets << chkLineAbove;
296 widgets << chkLineBelow;
297 widgets << chkLineOn;
298 widgets << chkLineOrientationDependent;
299 widgets << mAngleDirectionComboBox;
300 widgets << mAngleOffsetComboBox;
301 widgets << mAttributeBasedScalingRadio;
302 widgets << mAxisLineStyleButton;
303 widgets << mBackgroundColorButton;
304 widgets << mBarSpacingSpinBox;
305 widgets << mBarSpacingUnitComboBox;
306 widgets << mBarWidthSpinBox;
307 widgets << mCheckBoxAttributeLegend;
308 widgets << mDiagramAttributesTreeWidget;
309 widgets << mDiagramDistanceSpinBox;
310 widgets << mDiagramFontButton;
311 widgets << mDiagramPenColorButton;
312 widgets << mDiagramSizeSpinBox;
313 widgets << mDiagramLineUnitComboBox;
314 widgets << mDiagramTypeComboBox;
315 widgets << mDiagramUnitComboBox;
316 widgets << mEnableDiagramCheckBox;
317 widgets << mFixedSizeRadio;
318 widgets << mIncreaseMinimumSizeSpinBox;
319 widgets << mIncreaseSmallDiagramsGroupBox;
320 widgets << mLabelPlacementComboBox;
321 widgets << mMaxValueSpinBox;
322 widgets << mPaintEffectWidget;
323 widgets << mPenWidthSpinBox;
324 widgets << mPrioritySlider;
325 widgets << mOpacityWidget;
326 widgets << mOrientationDownButton;
327 widgets << mOrientationLeftButton;
328 widgets << mOrientationRightButton;
329 widgets << mOrientationUpButton;
330 widgets << mScaleDependencyComboBox;
331 widgets << mScaleRangeWidget;
332 widgets << mScaleVisibilityGroupBox;
333 widgets << mShowAllCheckBox;
334 widgets << mShowAxisGroupBox;
335 widgets << mSizeFieldExpressionWidget;
336 widgets << mSizeSpinBox;
337 widgets << mZIndexSpinBox;
338 widgets << radAroundCentroid;
339 widgets << radAroundLine;
340 widgets << radAroundPoint;
341 widgets << radInsidePolygon;
342 widgets << radOverCentroid;
343 widgets << radOverLine;
344 widgets << radOverPoint;
345 widgets << radPolygonPerimeter;
347 connectValueChanged( widgets );
353 mOptionsTab->setVisible(
dockMode );
354 mOptionsTab->setTabToolTip( 0, tr(
"Attributes" ) );
355 mOptionsTab->setTabToolTip( 1, tr(
"Rendering" ) );
356 mOptionsTab->setTabToolTip( 2, tr(
"Size" ) );
357 mOptionsTab->setTabToolTip( 3, tr(
"Placement" ) );
358 mOptionsTab->setTabToolTip( 4, tr(
"Options" ) );
359 mOptionsTab->setTabToolTip( 5, tr(
"Legend" ) );
360 mDiagramOptionsListFrame->setVisible( !
dockMode );
365 mDiagramType = diagramType;
367 mDiagramTypeComboBox->setVisible(
false );
368 mDiagramTypeComboBox->blockSignals(
true );
369 mDiagramTypeComboBox->setCurrentIndex( mDiagramTypeComboBox->findData( mDiagramType ) );
370 mDiagramTypeComboBox->blockSignals(
false );
376void QgsDiagramProperties::insertDefaults()
378 mFixedSizeRadio->setChecked(
true );
381 mLabelPlacementComboBox->setCurrentIndex( mLabelPlacementComboBox->findText( tr(
"x-height" ) ) );
382 mDiagramSizeSpinBox->setEnabled(
true );
383 mDiagramSizeSpinBox->setValue( 15 );
384 mLinearScaleFrame->setEnabled(
false );
385 mBarWidthSpinBox->setValue( 5 );
388 mShowAllCheckBox->setChecked(
true );
389 mCheckBoxAttributeLegend->setChecked(
true );
394 radAroundPoint->setChecked(
true );
398 radAroundLine->setChecked(
true );
399 chkLineAbove->setChecked(
true );
400 chkLineBelow->setChecked(
false );
401 chkLineOn->setChecked(
false );
402 chkLineOrientationDependent->setChecked(
false );
406 radOverCentroid->setChecked(
true );
407 mDiagramDistanceLabel->setEnabled(
false );
408 mDiagramDistanceSpinBox->setEnabled(
false );
409 mDistanceDDBtn->setEnabled(
false );
416 mBackgroundColorButton->setColor( QColor( 255, 255, 255, 255 ) );
417 mDiagramPenColorButton->setColor( QColor( 0, 0, 0, 255 ) );
432 renderer = stackedRenderer->
renderer( 0 );
443 mDiagramAttributesTreeWidget->clear();
454 mFixedSizeRadio->setChecked(
true );
458 mAttributeBasedScalingRadio->setChecked(
true );
460 mDiagramSizeSpinBox->setEnabled( mFixedSizeRadio->isChecked() );
461 mLinearScaleFrame->setEnabled( mAttributeBasedScalingRadio->isChecked() );
466 if ( !settingList.isEmpty() )
468 setDiagramEnabled( settingList.at( 0 ).enabled );
469 mDiagramFontButton->setCurrentFont( settingList.at( 0 ).font );
470 const QSizeF size = settingList.at( 0 ).size;
471 mBackgroundColorButton->setColor( settingList.at( 0 ).backgroundColor );
472 mOpacityWidget->setOpacity( settingList.at( 0 ).opacity );
473 mDiagramPenColorButton->setColor( settingList.at( 0 ).penColor );
474 mPenWidthSpinBox->setValue( settingList.at( 0 ).penWidth );
475 mDiagramSizeSpinBox->setValue( ( size.width() + size.height() ) / 2.0 );
476 mScaleRangeWidget->setScaleRange( ( settingList.at( 0 ).minimumScale > 0 ? settingList.at( 0 ).minimumScale : mLayer->
minimumScale() ),
477 ( settingList.at( 0 ).maximumScale > 0 ? settingList.at( 0 ).maximumScale : mLayer->
maximumScale() ) );
478 mScaleVisibilityGroupBox->setChecked( settingList.at( 0 ).scaleBasedVisibility );
479 mDiagramUnitComboBox->setUnit( settingList.at( 0 ).sizeType );
480 mDiagramUnitComboBox->setMapUnitScale( settingList.at( 0 ).sizeScale );
481 mDiagramLineUnitComboBox->setUnit( settingList.at( 0 ).lineSizeUnit );
482 mDiagramLineUnitComboBox->setMapUnitScale( settingList.at( 0 ).lineSizeScale );
486 mLabelPlacementComboBox->setCurrentIndex( 0 );
490 mLabelPlacementComboBox->setCurrentIndex( 1 );
493 if ( settingList.at( 0 ).paintEffect() )
494 mPaintEffect.reset( settingList.at( 0 ).paintEffect()->clone() );
496 mAngleOffsetComboBox->setCurrentIndex( mAngleOffsetComboBox->findData( settingList.at( 0 ).rotationOffset ) );
497 mAngleDirectionComboBox->setCurrentIndex( mAngleDirectionComboBox->findData( settingList.at( 0 ).direction() ) );
499 switch ( settingList.at( 0 ).diagramOrientation )
502 mOrientationLeftButton->setChecked(
true );
506 mOrientationRightButton->setChecked(
true );
510 mOrientationUpButton->setChecked(
true );
514 mOrientationDownButton->setChecked(
true );
518 mBarWidthSpinBox->setValue( settingList.at( 0 ).barWidth );
519 mBarSpacingSpinBox->setValue( settingList.at( 0 ).spacing() );
520 mBarSpacingUnitComboBox->setUnit( settingList.at( 0 ).spacingUnit() );
521 mBarSpacingUnitComboBox->setMapUnitScale( settingList.at( 0 ).spacingMapUnitScale() );
523 mShowAxisGroupBox->setChecked( settingList.at( 0 ).showAxis() );
524 if ( settingList.at( 0 ).axisLineSymbol() )
525 mAxisLineStyleButton->setSymbol( settingList.at( 0 ).axisLineSymbol()->clone() );
527 mIncreaseSmallDiagramsGroupBox->setChecked( settingList.at( 0 ).minimumSize != 0 );
528 mIncreaseMinimumSizeSpinBox->setValue( settingList.at( 0 ).minimumSize );
530 if ( settingList.at( 0 ).scaleByArea )
532 mScaleDependencyComboBox->setCurrentIndex( 0 );
536 mScaleDependencyComboBox->setCurrentIndex( 1 );
539 const QList< QColor > categoryColors = settingList.at( 0 ).categoryColors;
540 const QList< QString > categoryAttributes = settingList.at( 0 ).categoryAttributes;
541 const QList< QString > categoryLabels = settingList.at( 0 ).categoryLabels;
542 QList< QString >::const_iterator catIt = categoryAttributes.constBegin();
543 QList< QColor >::const_iterator coIt = categoryColors.constBegin();
544 QList< QString >::const_iterator labIt = categoryLabels.constBegin();
545 for ( ; catIt != categoryAttributes.constEnd(); ++catIt, ++coIt, ++labIt )
547 QTreeWidgetItem *newItem =
new QTreeWidgetItem( mDiagramAttributesTreeWidget );
548 newItem->setText( 0, *catIt );
549 newItem->setData( 0, RoleAttributeExpression, *catIt );
550 newItem->setFlags( newItem->flags() & ~Qt::ItemIsDropEnabled );
551 newItem->setData( ColumnColor, Qt::EditRole, *coIt );
552 newItem->setText( 2, *labIt );
553 newItem->setFlags( newItem->flags() | Qt::ItemIsEditable );
562 mDiagramSizeSpinBox->setEnabled(
false );
563 mLinearScaleFrame->setEnabled(
true );
564 mMaxValueSpinBox->setValue( lidr->
upperValue() );
565 mSizeSpinBox->setValue( ( lidr->
upperSize().width() + lidr->
upperSize().height() ) / 2 );
583 mDiagramTypeComboBox->blockSignals(
true );
584 mDiagramTypeComboBox->setCurrentIndex( mDiagramTypeComboBox->findData( mDiagramType ) );
585 mDiagramTypeComboBox->blockSignals(
false );
590 mPaintEffectWidget->setPaintEffect( mPaintEffect.get() );
597 mDiagramDistanceSpinBox->setValue( dls->
distance() );
598 mPrioritySlider->setValue( dls->
priority() );
599 mZIndexSpinBox->setValue( dls->
zIndex() );
604 radAroundPoint->setChecked(
true );
605 radAroundCentroid->setChecked(
true );
609 radOverPoint->setChecked(
true );
610 radOverCentroid->setChecked(
true );
614 radAroundLine->setChecked(
true );
615 radPolygonPerimeter->setChecked(
true );
619 radOverLine->setChecked(
true );
620 radInsidePolygon->setChecked(
true );
631 chkLineOrientationDependent->setChecked(
true );
643 settings.
setValue( QStringLiteral(
"Windows/Diagrams/OptionsSplitState" ), mDiagramOptionsSplitter->saveState() );
644 settings.
setValue( QStringLiteral(
"Windows/Diagrams/Tab" ), mDiagramOptionsListWidget->currentRow() );
655void QgsDiagramProperties::updateProperty()
665 mDiagramType = mDiagramTypeComboBox->itemData( index ).toString();
669 mTextOptionsFrame->show();
670 mBackgroundColorLabel->show();
671 mBackgroundColorButton->show();
672 mBackgroundColorDDBtn->show();
673 mDiagramFontButton->show();
677 mTextOptionsFrame->hide();
678 mBackgroundColorLabel->hide();
679 mBackgroundColorButton->hide();
680 mBackgroundColorDDBtn->hide();
681 mDiagramFontButton->hide();
686 mBarWidthLabel->show();
687 mBarWidthSpinBox->show();
688 mBarSpacingLabel->show();
689 mBarSpacingSpinBox->show();
690 mBarSpacingUnitComboBox->show();
691 mBarOptionsFrame->show();
692 mShowAxisGroupBox->show();
694 mAttributeBasedScalingRadio->setChecked(
true );
697 mLinearlyScalingLabel->setText( tr(
"Bar length: Scale linearly, so that the following value matches the specified bar length:" ) );
698 mSizeLabel->setText( tr(
"Bar length" ) );
699 mFrameIncreaseSize->setVisible(
false );
703 mBarWidthLabel->hide();
704 mBarWidthSpinBox->hide();
705 mBarSpacingLabel->hide();
706 mBarSpacingSpinBox->hide();
707 mBarSpacingUnitComboBox->hide();
708 mShowAxisGroupBox->hide();
709 mBarOptionsFrame->hide();
710 mLinearlyScalingLabel->setText( tr(
"Scale linearly between 0 and the following attribute value / diagram size:" ) );
711 mSizeLabel->setText( tr(
"Size" ) );
712 mAttributeBasedScalingRadio->setEnabled(
true );
713 mFixedSizeRadio->setEnabled(
true );
714 mDiagramSizeSpinBox->setEnabled( mFixedSizeRadio->isChecked() );
715 mFrameIncreaseSize->setVisible(
true );
720 mScaleDependencyComboBox->show();
721 mScaleDependencyLabel->show();
725 mScaleDependencyComboBox->hide();
726 mScaleDependencyLabel->hide();
731 mAngleOffsetComboBox->show();
732 mAngleDirectionComboBox->show();
733 mAngleDirectionLabel->show();
734 mAngleOffsetLabel->show();
735 mStartAngleDDBtn->show();
739 mAngleOffsetComboBox->hide();
740 mAngleDirectionComboBox->hide();
741 mAngleDirectionLabel->hide();
742 mAngleOffsetLabel->hide();
743 mStartAngleDDBtn->hide();
747QString QgsDiagramProperties::guessLegendText(
const QString &expression )
750 QString text = expression.mid( expression.startsWith(
'\"' ) ? 1 : 0 );
751 if ( text.endsWith(
'\"' ) )
758 QTreeWidgetItem *newItem =
new QTreeWidgetItem( mDiagramAttributesTreeWidget );
760 newItem->setText( 0, item->text( 0 ) );
761 newItem->setText( 2, guessLegendText( item->text( 0 ) ) );
762 newItem->setData( 0, RoleAttributeExpression, item->data( 0, RoleAttributeExpression ) );
763 newItem->setFlags( ( newItem->flags() | Qt::ItemIsEditable ) & ~Qt::ItemIsDropEnabled );
766 const int red = QRandomGenerator::global()->bounded( 1, 256 );
767 const int green = QRandomGenerator::global()->bounded( 1, 256 );
768 const int blue = QRandomGenerator::global()->bounded( 1, 256 );
769 const QColor randomColor( red, green, blue );
770 newItem->setData( ColumnColor, Qt::EditRole, randomColor );
771 mDiagramAttributesTreeWidget->addTopLevelItem( newItem );
776 const auto constSelectedItems = mAttributesTreeWidget->selectedItems();
777 for ( QTreeWidgetItem *attributeItem : constSelectedItems )
791 const auto constSelectedItems = mDiagramAttributesTreeWidget->selectedItems();
792 for ( QTreeWidgetItem *attributeItem : constSelectedItems )
794 delete attributeItem;
803 float maxValue = 0.0;
806 const QString sizeFieldNameOrExp = mSizeFieldExpressionWidget->currentField( &isExpression );
824 maxValue = std::max( maxValue, exp.
evaluate( &context ).toFloat() );
835 maxValue = mLayer->
maximumValue( attributeNumber ).toFloat();
838 mMaxValueSpinBox->setValue( maxValue );
845 case ColumnAttributeExpression:
847 const QString currentExpression = item->data( 0, RoleAttributeExpression ).toString();
849 const QString newExpression = showExpressionBuilder( currentExpression );
850 if ( !newExpression.isEmpty() )
852 item->setData( 0, Qt::DisplayRole, newExpression );
853 item->setData( 0, RoleAttributeExpression, newExpression );
861 case ColumnLegendText:
866std::unique_ptr< QgsDiagram > QgsDiagramProperties::createDiagramObject()
868 std::unique_ptr< QgsDiagram > diagram;
872 diagram = std::make_unique< QgsTextDiagram >();
876 diagram = std::make_unique< QgsPieDiagram >();
880 diagram = std::make_unique< QgsStackedBarDiagram >();
884 diagram = std::make_unique< QgsHistogramDiagram >();
889std::unique_ptr<QgsDiagramSettings> QgsDiagramProperties::createDiagramSettings()
891 std::unique_ptr< QgsDiagramSettings > ds = std::make_unique< QgsDiagramSettings>();
892 ds->enabled = isDiagramEnabled();
893 ds->font = mDiagramFontButton->currentFont();
894 ds->opacity = mOpacityWidget->opacity();
896 QList<QColor> categoryColors;
897 QList<QString> categoryAttributes;
898 QList<QString> categoryLabels;
899 categoryColors.reserve( mDiagramAttributesTreeWidget->topLevelItemCount() );
900 categoryAttributes.reserve( mDiagramAttributesTreeWidget->topLevelItemCount() );
901 categoryLabels.reserve( mDiagramAttributesTreeWidget->topLevelItemCount() );
902 for (
int i = 0; i < mDiagramAttributesTreeWidget->topLevelItemCount(); ++i )
904 QColor color = mDiagramAttributesTreeWidget->topLevelItem( i )->data( ColumnColor, Qt::EditRole ).value<QColor>();
905 categoryColors.append( color );
906 categoryAttributes.append( mDiagramAttributesTreeWidget->topLevelItem( i )->data( 0, RoleAttributeExpression ).toString() );
907 categoryLabels.append( mDiagramAttributesTreeWidget->topLevelItem( i )->text( 2 ) );
909 ds->categoryColors = categoryColors;
910 ds->categoryAttributes = categoryAttributes;
911 ds->categoryLabels = categoryLabels;
912 ds->size = QSizeF( mDiagramSizeSpinBox->value(), mDiagramSizeSpinBox->value() );
913 ds->sizeType = mDiagramUnitComboBox->unit();
914 ds->sizeScale = mDiagramUnitComboBox->getMapUnitScale();
915 ds->lineSizeUnit = mDiagramLineUnitComboBox->unit();
916 ds->lineSizeScale = mDiagramLineUnitComboBox->getMapUnitScale();
920 if ( mIncreaseSmallDiagramsGroupBox->isChecked() )
922 ds->minimumSize = mIncreaseMinimumSizeSpinBox->value();
929 ds->backgroundColor = mBackgroundColorButton->color();
930 ds->penColor = mDiagramPenColorButton->color();
931 ds->penWidth = mPenWidthSpinBox->value();
932 ds->minimumScale = mScaleRangeWidget->minimumScale();
933 ds->maximumScale = mScaleRangeWidget->maximumScale();
934 ds->scaleBasedVisibility = mScaleVisibilityGroupBox->isChecked();
937 ds->rotationOffset = mAngleOffsetComboBox->currentData().toInt();
943 ds->barWidth = mBarWidthSpinBox->value();
945 ds->setAxisLineSymbol( mAxisLineStyleButton->clonedSymbol<
QgsLineSymbol >() );
946 ds->setShowAxis( mShowAxisGroupBox->isChecked() );
948 ds->setSpacing( mBarSpacingSpinBox->value() );
949 ds->setSpacingUnit( mBarSpacingUnitComboBox->unit() );
950 ds->setSpacingMapUnitScale( mBarSpacingUnitComboBox->getMapUnitScale() );
953 ds->setPaintEffect( mPaintEffect->clone() );
955 ds->setPaintEffect(
nullptr );
960std::unique_ptr<QgsDiagramRenderer> QgsDiagramProperties::createRenderer()
962 std::unique_ptr< QgsDiagramSettings > ds = createDiagramSettings();
964 std::unique_ptr< QgsDiagramRenderer > renderer;
965 if ( mFixedSizeRadio->isChecked() )
967 std::unique_ptr< QgsSingleCategoryDiagramRenderer > dr = std::make_unique< QgsSingleCategoryDiagramRenderer >();
968 dr->setDiagramSettings( *ds );
969 renderer = std::move( dr );
973 std::unique_ptr< QgsLinearlyInterpolatedDiagramRenderer > dr = std::make_unique< QgsLinearlyInterpolatedDiagramRenderer >();
974 dr->setLowerValue( 0.0 );
975 dr->setLowerSize( QSizeF( 0.0, 0.0 ) );
976 dr->setUpperValue( mMaxValueSpinBox->value() );
977 dr->setUpperSize( QSizeF( mSizeSpinBox->value(), mSizeSpinBox->value() ) );
980 const QString sizeFieldNameOrExp = mSizeFieldExpressionWidget->currentField( &isExpression );
981 dr->setClassificationAttributeIsExpression( isExpression );
984 dr->setClassificationAttributeExpression( sizeFieldNameOrExp );
988 dr->setClassificationField( sizeFieldNameOrExp );
990 dr->setDiagramSettings( *ds );
994 renderer = std::move( dr );
997 renderer->setAttributeLegend( mCheckBoxAttributeLegend->isChecked() );
999 std::unique_ptr< QgsDiagram > diagram = createDiagramObject();
1000 renderer->setDiagram( diagram.release() );
1009 dls.
setDistance( mDiagramDistanceSpinBox->value() );
1011 dls.
setZIndex( mZIndexSpinBox->value() );
1014 QWidget *curWdgt = stackedPlacement->currentWidget();
1015 if ( ( curWdgt == pagePoint && radAroundPoint->isChecked() )
1016 || ( curWdgt == pagePolygon && radAroundCentroid->isChecked() ) )
1020 else if ( ( curWdgt == pagePoint && radOverPoint->isChecked() )
1021 || ( curWdgt == pagePolygon && radOverCentroid->isChecked() ) )
1025 else if ( ( curWdgt == pageLine && radAroundLine->isChecked() )
1026 || ( curWdgt == pagePolygon && radPolygonPerimeter->isChecked() ) )
1030 else if ( ( curWdgt == pageLine && radOverLine->isChecked() )
1031 || ( curWdgt == pagePolygon && radInsidePolygon->isChecked() ) )
1037 qFatal(
"Invalid settings" );
1041 if ( chkLineAbove->isChecked() )
1043 if ( chkLineBelow->isChecked() )
1045 if ( chkLineOn->isChecked() )
1047 if ( ! chkLineOrientationDependent->isChecked() )
1058 if ( !
dockMode() || !settings.
value( QStringLiteral(
"UI/autoApplyStyling" ),
true ).toBool() )
1060 if ( isDiagramEnabled() && 0 == mDiagramAttributesTreeWidget->topLevelItemCount() )
1062 QMessageBox::warning(
this, tr(
"Diagrams: No attributes added." ),
1063 tr(
"You did not add any attributes to this diagram layer. Please specify the attributes to visualize on the diagrams or disable diagrams." ) );
1067 std::unique_ptr< QgsDiagramRenderer > renderer = createRenderer();
1078QString QgsDiagramProperties::showExpressionBuilder(
const QString &initialExpression )
1083 dlg.setWindowTitle( tr(
"Expression Based Attribute" ) );
1088 dlg.setGeomCalculator( myDa );
1090 if ( dlg.exec() == QDialog::Accepted )
1092 return dlg.expressionText();
1103 QList<QTreeWidgetItem *> selections = mAttributesTreeWidget->selectedItems();
1104 if ( !selections.empty() )
1106 expression = selections[0]->text( 0 );
1109 const QString newExpression = showExpressionBuilder( expression );
1112 if ( !newExpression.isEmpty() )
1114 QTreeWidgetItem *newItem =
new QTreeWidgetItem( mDiagramAttributesTreeWidget );
1116 newItem->setText( 0, newExpression );
1117 newItem->setText( 2, newExpression );
1118 newItem->setData( 0, RoleAttributeExpression, newExpression );
1119 newItem->setFlags( ( newItem->flags() | Qt::ItemIsEditable ) & ~Qt::ItemIsDropEnabled );
1122 QRandomGenerator colorGenerator;
1123 const int red = colorGenerator.bounded( 1, 256 );
1124 const int green = colorGenerator.bounded( 1, 256 );
1125 const int blue = colorGenerator.bounded( 1, 256 );
1127 const QColor randomColor( red, green, blue );
1128 newItem->setData( ColumnColor, Qt::EditRole, randomColor );
1129 mDiagramAttributesTreeWidget->addTopLevelItem( newItem );
1136 mDiagramOptionsListWidget->blockSignals(
true );
1137 mDiagramOptionsListWidget->setCurrentRow( index );
1138 mDiagramOptionsListWidget->blockSignals(
false );
1143 QWidget *curWdgt = stackedPlacement->currentWidget();
1145 if ( ( curWdgt == pagePoint && radAroundPoint->isChecked() )
1146 || ( curWdgt == pageLine && radAroundLine->isChecked() )
1147 || ( curWdgt == pagePolygon && radAroundCentroid->isChecked() ) )
1149 mDiagramDistanceLabel->setEnabled(
true );
1150 mDiagramDistanceSpinBox->setEnabled(
true );
1151 mDistanceDDBtn->setEnabled(
true );
1155 mDiagramDistanceLabel->setEnabled(
false );
1156 mDiagramDistanceSpinBox->setEnabled(
false );
1157 mDistanceDDBtn->setEnabled(
false );
1161 chkLineAbove->setEnabled( linePlacementEnabled );
1162 chkLineBelow->setEnabled( linePlacementEnabled );
1163 chkLineOn->setEnabled( linePlacementEnabled );
1164 chkLineOrientationDependent->setEnabled( linePlacementEnabled );
1169 mButtonSizeLegendSettings->setEnabled( mAttributeBasedScalingRadio->isChecked() );
1174 mAllowedToEditDls = allowed;
1176 label_16->setVisible( allowed );
1177 mZIndexSpinBox->setVisible( allowed );
1178 mZOrderDDBtn->setVisible( allowed );
1179 mShowAllCheckBox->setVisible( allowed );
1180 mDlsLabel_1->setVisible( !allowed );
1182 mCoordinatesGrpBox->setVisible( allowed );
1183 mLinePlacementFrame->setVisible( allowed );
1184 mObstaclesGrpBox->setVisible( allowed );
1185 mPlacementFrame->setVisible( allowed );
1186 mPriorityGrpBox->setVisible( allowed );
1187 stackedPlacement->setVisible( allowed );
1188 mDlsLabel_2->setVisible( !allowed );
1193 return mAllowedToEditDls;
1200 const QString sizeFieldNameOrExp = mSizeFieldExpressionWidget->currentField( &isExpression );
1202 const bool scaleByArea = mScaleDependencyComboBox->currentData().toBool();
1204 0.0, mMaxValueSpinBox->value(), 0.0, mSizeSpinBox->value() ) );
1209 dlg.setLayout(
new QVBoxLayout() );
1211 dlg.layout()->addWidget( panel );
1212 QDialogButtonBox *buttonBox =
new QDialogButtonBox( QDialogButtonBox::Cancel | QDialogButtonBox::Help | QDialogButtonBox::Ok );
1213 connect( buttonBox, &QDialogButtonBox::accepted, &dlg, &QDialog::accept );
1214 connect( buttonBox, &QDialogButtonBox::helpRequested,
this, &QgsDiagramProperties::showHelp );
1215 connect( buttonBox, &QDialogButtonBox::rejected, &dlg, &QDialog::reject );
1216 dlg.layout()->addWidget( buttonBox );
1221void QgsDiagramProperties::showHelp()
1223 QgsHelp::openHelp( QStringLiteral(
"working_with_vector/vector_properties.html#legend" ) );
1226void QgsDiagramProperties::createAuxiliaryField()
1250 property.setActive(
true );
1258void QgsDiagramProperties::connectValueChanged(
const QList<QWidget *> &widgets )
1260 const auto constWidgets = widgets;
1261 for ( QWidget *widget : constWidgets )
1271 else if (
QgsOpacityWidget *w = qobject_cast< QgsOpacityWidget *>( widget ) )
1279 else if ( QComboBox *w = qobject_cast<QComboBox *>( widget ) )
1283 else if ( QSpinBox *w = qobject_cast<QSpinBox *>( widget ) )
1287 else if ( QDoubleSpinBox *w = qobject_cast<QDoubleSpinBox *>( widget ) )
1291 else if (
QgsColorButton *w = qobject_cast<QgsColorButton *>( widget ) )
1295 else if ( QCheckBox *w = qobject_cast<QCheckBox *>( widget ) )
1299 else if ( QRadioButton *w = qobject_cast<QRadioButton *>( widget ) )
1303 else if ( QSlider *w = qobject_cast<QSlider *>( widget ) )
1307 else if ( QGroupBox *w = qobject_cast<QGroupBox *>( widget ) )
1311 else if ( QTreeWidget *w = qobject_cast<QTreeWidget *>( widget ) )
1323 else if (
QgsFontButton *w = qobject_cast<QgsFontButton *>( widget ) )
1329 QgsLogger::warning( QStringLiteral(
"Could not create connection for widget %1" ).arg( widget->objectName() ) );
1334void QgsDiagramProperties::setDiagramEnabled(
bool enabled )
1336 mEnableDiagramCheckBox->setChecked( enabled );
1339bool QgsDiagramProperties::isDiagramEnabled()
const
1341 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)