46#include <QStyledItemDelegate>
47#include <QRandomGenerator>
71 , mMapCanvas( canvas )
88 mDiagramOptionsListWidget->setAttribute( Qt::WA_MacShowFocusRect,
false );
91 mOptionsTab->setIconSize( QSize( iconSize, iconSize ) );
92 mDiagramOptionsListWidget->setIconSize( QSize( iconSize, iconSize ) ) ;
94 mBarSpacingSpinBox->setClearValue( 0 );
104 mDiagramTypeComboBox->blockSignals(
true );
113 mDiagramTypeComboBox->blockSignals(
false );
116 mAxisLineStyleButton->setDialogTitle( tr(
"Axis Line Symbol" ) );
118 mScaleRangeWidget->setMapCanvas( mMapCanvas );
119 mSizeFieldExpressionWidget->registerExpressionContextGenerator(
this );
121 mBackgroundColorButton->setColorDialogTitle( tr(
"Select Background Color" ) );
122 mBackgroundColorButton->setAllowOpacity(
true );
123 mBackgroundColorButton->setContext( QStringLiteral(
"symbology" ) );
124 mBackgroundColorButton->setShowNoColor(
true );
125 mBackgroundColorButton->setNoColorString( tr(
"Transparent Background" ) );
126 mDiagramPenColorButton->setColorDialogTitle( tr(
"Select Pen Color" ) );
127 mDiagramPenColorButton->setAllowOpacity(
true );
128 mDiagramPenColorButton->setContext( QStringLiteral(
"symbology" ) );
129 mDiagramPenColorButton->setShowNoColor(
true );
130 mDiagramPenColorButton->setNoColorString( tr(
"Transparent Stroke" ) );
132 mMaxValueSpinBox->setShowClearButton(
false );
133 mSizeSpinBox->setClearValue( 5 );
135 mDiagramAttributesTreeWidget->setItemDelegateForColumn( ColumnAttributeExpression,
new EditBlockerDelegate(
this ) );
136 mDiagramAttributesTreeWidget->setItemDelegateForColumn( ColumnColor,
new QgsColorSwatchDelegate(
this ) );
138 mDiagramAttributesTreeWidget->setColumnWidth( ColumnColor,
Qgis::UI_SCALE_FACTOR * fontMetrics().horizontalAdvance(
'X' ) * 6.6 );
157 mDiagramTypeComboBox->setEnabled(
false );
158 mOptionsTab->setEnabled(
false );
159 mDiagramFrame->setEnabled(
false );
167 stackedPlacement->setCurrentWidget( pagePoint );
168 mLinePlacementFrame->setVisible(
false );
171 stackedPlacement->setCurrentWidget( pageLine );
172 mLinePlacementFrame->setVisible(
true );
175 stackedPlacement->setCurrentWidget( pagePolygon );
176 mLinePlacementFrame->setVisible(
false );
185 mPlacePointBtnGrp =
new QButtonGroup(
this );
186 mPlacePointBtnGrp->addButton( radAroundPoint );
187 mPlacePointBtnGrp->addButton( radOverPoint );
188 mPlacePointBtnGrp->setExclusive(
true );
192 mPlaceLineBtnGrp =
new QButtonGroup(
this );
193 mPlaceLineBtnGrp->addButton( radAroundLine );
194 mPlaceLineBtnGrp->addButton( radOverLine );
195 mPlaceLineBtnGrp->setExclusive(
true );
199 mPlacePolygonBtnGrp =
new QButtonGroup(
this );
200 mPlacePolygonBtnGrp->addButton( radAroundCentroid );
201 mPlacePolygonBtnGrp->addButton( radOverCentroid );
202 mPlacePolygonBtnGrp->addButton( radPolygonPerimeter );
203 mPlacePolygonBtnGrp->addButton( radInsidePolygon );
204 mPlacePolygonBtnGrp->setExclusive(
true );
210 mScaleDependencyComboBox->addItem( tr(
"Area" ),
true );
211 mScaleDependencyComboBox->addItem( tr(
"Diameter" ),
false );
213 mAngleOffsetComboBox->addItem( tr(
"Top" ), 270 );
214 mAngleOffsetComboBox->addItem( tr(
"Right" ), 0 );
215 mAngleOffsetComboBox->addItem( tr(
"Bottom" ), 90 );
216 mAngleOffsetComboBox->addItem( tr(
"Left" ), 180 );
224 QSizePolicy policy( mDiagramOptionsListFrame->sizePolicy() );
225 policy.setHorizontalStretch( 0 );
226 mDiagramOptionsListFrame->setSizePolicy( policy );
227 if ( !settings.
contains( QStringLiteral(
"/Windows/Diagrams/OptionsSplitState" ) ) )
230 QList<int> splitsizes;
232 mDiagramOptionsSplitter->setSizes( splitsizes );
236 mDiagramOptionsSplitter->restoreState( settings.
value( QStringLiteral(
"Windows/Diagrams/OptionsSplitState" ) ).toByteArray() );
237 mDiagramOptionsListWidget->setCurrentRow( settings.
value( QStringLiteral(
"Windows/Diagrams/Tab" ), 0 ).toInt() );
240 whileBlocking( mOptionsTab )->setCurrentIndex( mDiagramStackedWidget->currentIndex() );
241 mOptionsTab->tabBar()->setUsesScrollButtons(
true );
244 mSizeFieldExpressionWidget->setLayer( mLayer );
248 mSizeFieldExpressionWidget->setGeomCalculator( myDa );
252 for (
int idx = 0; idx < layerFields.
count(); ++idx )
254 QTreeWidgetItem *newItem =
new QTreeWidgetItem( mAttributesTreeWidget );
255 const QString name = QStringLiteral(
"\"%1\"" ).arg( layerFields.
at( idx ).
name() );
256 newItem->setText( 0, name );
257 newItem->setData( 0, RoleAttributeExpression, name );
258 newItem->setFlags( newItem->flags() & ~Qt::ItemIsDropEnabled );
262 mPaintEffect->setEnabled(
false );
275 mPaintEffectWidget->setPaintEffect( mPaintEffect.get() );
293 QList<QWidget *> widgets;
294 widgets << chkLineAbove;
295 widgets << chkLineBelow;
296 widgets << chkLineOn;
297 widgets << chkLineOrientationDependent;
298 widgets << mAngleDirectionComboBox;
299 widgets << mAngleOffsetComboBox;
300 widgets << mAttributeBasedScalingRadio;
301 widgets << mAxisLineStyleButton;
302 widgets << mBackgroundColorButton;
303 widgets << mBarSpacingSpinBox;
304 widgets << mBarSpacingUnitComboBox;
305 widgets << mBarWidthSpinBox;
306 widgets << mCheckBoxAttributeLegend;
307 widgets << mDiagramAttributesTreeWidget;
308 widgets << mDiagramDistanceSpinBox;
309 widgets << mDiagramFontButton;
310 widgets << mDiagramPenColorButton;
311 widgets << mDiagramSizeSpinBox;
312 widgets << mDiagramLineUnitComboBox;
313 widgets << mDiagramTypeComboBox;
314 widgets << mDiagramUnitComboBox;
315 widgets << mEnableDiagramCheckBox;
316 widgets << mFixedSizeRadio;
317 widgets << mIncreaseMinimumSizeSpinBox;
318 widgets << mIncreaseSmallDiagramsGroupBox;
319 widgets << mLabelPlacementComboBox;
320 widgets << mMaxValueSpinBox;
321 widgets << mPaintEffectWidget;
322 widgets << mPenWidthSpinBox;
323 widgets << mPrioritySlider;
324 widgets << mOpacityWidget;
325 widgets << mOrientationDownButton;
326 widgets << mOrientationLeftButton;
327 widgets << mOrientationRightButton;
328 widgets << mOrientationUpButton;
329 widgets << mScaleDependencyComboBox;
330 widgets << mScaleRangeWidget;
331 widgets << mScaleVisibilityGroupBox;
332 widgets << mShowAllCheckBox;
333 widgets << mShowAxisGroupBox;
334 widgets << mSizeFieldExpressionWidget;
335 widgets << mSizeSpinBox;
336 widgets << mZIndexSpinBox;
337 widgets << radAroundCentroid;
338 widgets << radAroundLine;
339 widgets << radAroundPoint;
340 widgets << radInsidePolygon;
341 widgets << radOverCentroid;
342 widgets << radOverLine;
343 widgets << radOverPoint;
344 widgets << radPolygonPerimeter;
346 connectValueChanged( widgets );
352 mOptionsTab->setVisible(
dockMode );
353 mOptionsTab->setTabToolTip( 0, tr(
"Attributes" ) );
354 mOptionsTab->setTabToolTip( 1, tr(
"Rendering" ) );
355 mOptionsTab->setTabToolTip( 2, tr(
"Size" ) );
356 mOptionsTab->setTabToolTip( 3, tr(
"Placement" ) );
357 mOptionsTab->setTabToolTip( 4, tr(
"Options" ) );
358 mOptionsTab->setTabToolTip( 5, tr(
"Legend" ) );
359 mDiagramOptionsListFrame->setVisible( !
dockMode );
364 mDiagramType = diagramType;
366 mDiagramTypeComboBox->setVisible(
false );
367 mDiagramTypeComboBox->blockSignals(
true );
368 mDiagramTypeComboBox->setCurrentIndex( mDiagramTypeComboBox->findData( mDiagramType ) );
369 mDiagramTypeComboBox->blockSignals(
false );
375void QgsDiagramProperties::insertDefaults()
377 mFixedSizeRadio->setChecked(
true );
380 mLabelPlacementComboBox->setCurrentIndex( mLabelPlacementComboBox->findText( tr(
"x-height" ) ) );
381 mDiagramSizeSpinBox->setEnabled(
true );
382 mDiagramSizeSpinBox->setValue( 15 );
383 mLinearScaleFrame->setEnabled(
false );
384 mBarWidthSpinBox->setValue( 5 );
387 mShowAllCheckBox->setChecked(
true );
388 mCheckBoxAttributeLegend->setChecked(
true );
393 radAroundPoint->setChecked(
true );
397 radAroundLine->setChecked(
true );
398 chkLineAbove->setChecked(
true );
399 chkLineBelow->setChecked(
false );
400 chkLineOn->setChecked(
false );
401 chkLineOrientationDependent->setChecked(
false );
405 radOverCentroid->setChecked(
true );
406 mDiagramDistanceLabel->setEnabled(
false );
407 mDiagramDistanceSpinBox->setEnabled(
false );
408 mDistanceDDBtn->setEnabled(
false );
415 mBackgroundColorButton->setColor( QColor( 255, 255, 255, 255 ) );
416 mDiagramPenColorButton->setColor( QColor( 0, 0, 0, 255 ) );
431 renderer = stackedRenderer->
renderer( 0 );
442 mDiagramAttributesTreeWidget->clear();
453 mFixedSizeRadio->setChecked(
true );
457 mAttributeBasedScalingRadio->setChecked(
true );
459 mDiagramSizeSpinBox->setEnabled( mFixedSizeRadio->isChecked() );
460 mLinearScaleFrame->setEnabled( mAttributeBasedScalingRadio->isChecked() );
465 if ( !settingList.isEmpty() )
467 setDiagramEnabled( settingList.at( 0 ).enabled );
468 mDiagramFontButton->setCurrentFont( settingList.at( 0 ).font );
469 const QSizeF size = settingList.at( 0 ).size;
470 mBackgroundColorButton->setColor( settingList.at( 0 ).backgroundColor );
471 mOpacityWidget->setOpacity( settingList.at( 0 ).opacity );
472 mDiagramPenColorButton->setColor( settingList.at( 0 ).penColor );
473 mPenWidthSpinBox->setValue( settingList.at( 0 ).penWidth );
474 mDiagramSizeSpinBox->setValue( ( size.width() + size.height() ) / 2.0 );
475 mScaleRangeWidget->setScaleRange( ( settingList.at( 0 ).minimumScale > 0 ? settingList.at( 0 ).minimumScale : mLayer->
minimumScale() ),
476 ( settingList.at( 0 ).maximumScale > 0 ? settingList.at( 0 ).maximumScale : mLayer->
maximumScale() ) );
477 mScaleVisibilityGroupBox->setChecked( settingList.at( 0 ).scaleBasedVisibility );
478 mDiagramUnitComboBox->setUnit( settingList.at( 0 ).sizeType );
479 mDiagramUnitComboBox->setMapUnitScale( settingList.at( 0 ).sizeScale );
480 mDiagramLineUnitComboBox->setUnit( settingList.at( 0 ).lineSizeUnit );
481 mDiagramLineUnitComboBox->setMapUnitScale( settingList.at( 0 ).lineSizeScale );
485 mLabelPlacementComboBox->setCurrentIndex( 0 );
489 mLabelPlacementComboBox->setCurrentIndex( 1 );
492 if ( settingList.at( 0 ).paintEffect() )
493 mPaintEffect.reset( settingList.at( 0 ).paintEffect()->clone() );
495 mAngleOffsetComboBox->setCurrentIndex( mAngleOffsetComboBox->findData( settingList.at( 0 ).rotationOffset ) );
496 mAngleDirectionComboBox->setCurrentIndex( mAngleDirectionComboBox->findData( settingList.at( 0 ).direction() ) );
498 switch ( settingList.at( 0 ).diagramOrientation )
501 mOrientationLeftButton->setChecked(
true );
505 mOrientationRightButton->setChecked(
true );
509 mOrientationUpButton->setChecked(
true );
513 mOrientationDownButton->setChecked(
true );
517 mBarWidthSpinBox->setValue( settingList.at( 0 ).barWidth );
518 mBarSpacingSpinBox->setValue( settingList.at( 0 ).spacing() );
519 mBarSpacingUnitComboBox->setUnit( settingList.at( 0 ).spacingUnit() );
520 mBarSpacingUnitComboBox->setMapUnitScale( settingList.at( 0 ).spacingMapUnitScale() );
522 mShowAxisGroupBox->setChecked( settingList.at( 0 ).showAxis() );
523 if ( settingList.at( 0 ).axisLineSymbol() )
524 mAxisLineStyleButton->setSymbol( settingList.at( 0 ).axisLineSymbol()->clone() );
526 mIncreaseSmallDiagramsGroupBox->setChecked( settingList.at( 0 ).minimumSize != 0 );
527 mIncreaseMinimumSizeSpinBox->setValue( settingList.at( 0 ).minimumSize );
529 if ( settingList.at( 0 ).scaleByArea )
531 mScaleDependencyComboBox->setCurrentIndex( 0 );
535 mScaleDependencyComboBox->setCurrentIndex( 1 );
538 const QList< QColor > categoryColors = settingList.at( 0 ).categoryColors;
539 const QList< QString > categoryAttributes = settingList.at( 0 ).categoryAttributes;
540 const QList< QString > categoryLabels = settingList.at( 0 ).categoryLabels;
541 QList< QString >::const_iterator catIt = categoryAttributes.constBegin();
542 QList< QColor >::const_iterator coIt = categoryColors.constBegin();
543 QList< QString >::const_iterator labIt = categoryLabels.constBegin();
544 for ( ; catIt != categoryAttributes.constEnd(); ++catIt, ++coIt, ++labIt )
546 QTreeWidgetItem *newItem =
new QTreeWidgetItem( mDiagramAttributesTreeWidget );
547 newItem->setText( 0, *catIt );
548 newItem->setData( 0, RoleAttributeExpression, *catIt );
549 newItem->setFlags( newItem->flags() & ~Qt::ItemIsDropEnabled );
550 newItem->setData( ColumnColor, Qt::EditRole, *coIt );
551 newItem->setText( 2, *labIt );
552 newItem->setFlags( newItem->flags() | Qt::ItemIsEditable );
561 mDiagramSizeSpinBox->setEnabled(
false );
562 mLinearScaleFrame->setEnabled(
true );
563 mMaxValueSpinBox->setValue( lidr->
upperValue() );
564 mSizeSpinBox->setValue( ( lidr->
upperSize().width() + lidr->
upperSize().height() ) / 2 );
582 mDiagramTypeComboBox->blockSignals(
true );
583 mDiagramTypeComboBox->setCurrentIndex( mDiagramTypeComboBox->findData( mDiagramType ) );
584 mDiagramTypeComboBox->blockSignals(
false );
589 mPaintEffectWidget->setPaintEffect( mPaintEffect.get() );
596 mDiagramDistanceSpinBox->setValue( dls->
distance() );
597 mPrioritySlider->setValue( dls->
priority() );
598 mZIndexSpinBox->setValue( dls->
zIndex() );
603 radAroundPoint->setChecked(
true );
604 radAroundCentroid->setChecked(
true );
608 radOverPoint->setChecked(
true );
609 radOverCentroid->setChecked(
true );
613 radAroundLine->setChecked(
true );
614 radPolygonPerimeter->setChecked(
true );
618 radOverLine->setChecked(
true );
619 radInsidePolygon->setChecked(
true );
630 chkLineOrientationDependent->setChecked(
true );
642 settings.
setValue( QStringLiteral(
"Windows/Diagrams/OptionsSplitState" ), mDiagramOptionsSplitter->saveState() );
643 settings.
setValue( QStringLiteral(
"Windows/Diagrams/Tab" ), mDiagramOptionsListWidget->currentRow() );
654void QgsDiagramProperties::updateProperty()
664 mDiagramType = mDiagramTypeComboBox->itemData( index ).toString();
668 mTextOptionsFrame->show();
669 mBackgroundColorLabel->show();
670 mBackgroundColorButton->show();
671 mBackgroundColorDDBtn->show();
672 mDiagramFontButton->show();
676 mTextOptionsFrame->hide();
677 mBackgroundColorLabel->hide();
678 mBackgroundColorButton->hide();
679 mBackgroundColorDDBtn->hide();
680 mDiagramFontButton->hide();
685 mBarWidthLabel->show();
686 mBarWidthSpinBox->show();
687 mBarSpacingLabel->show();
688 mBarSpacingSpinBox->show();
689 mBarSpacingUnitComboBox->show();
690 mBarOptionsFrame->show();
691 mShowAxisGroupBox->show();
693 mAttributeBasedScalingRadio->setChecked(
true );
696 mLinearlyScalingLabel->setText( tr(
"Bar length: Scale linearly, so that the following value matches the specified bar length:" ) );
697 mSizeLabel->setText( tr(
"Bar length" ) );
698 mFrameIncreaseSize->setVisible(
false );
702 mBarWidthLabel->hide();
703 mBarWidthSpinBox->hide();
704 mBarSpacingLabel->hide();
705 mBarSpacingSpinBox->hide();
706 mBarSpacingUnitComboBox->hide();
707 mShowAxisGroupBox->hide();
708 mBarOptionsFrame->hide();
709 mLinearlyScalingLabel->setText( tr(
"Scale linearly between 0 and the following attribute value / diagram size:" ) );
710 mSizeLabel->setText( tr(
"Size" ) );
711 mAttributeBasedScalingRadio->setEnabled(
true );
712 mFixedSizeRadio->setEnabled(
true );
713 mDiagramSizeSpinBox->setEnabled( mFixedSizeRadio->isChecked() );
714 mFrameIncreaseSize->setVisible(
true );
719 mScaleDependencyComboBox->show();
720 mScaleDependencyLabel->show();
724 mScaleDependencyComboBox->hide();
725 mScaleDependencyLabel->hide();
730 mAngleOffsetComboBox->show();
731 mAngleDirectionComboBox->show();
732 mAngleDirectionLabel->show();
733 mAngleOffsetLabel->show();
734 mStartAngleDDBtn->show();
738 mAngleOffsetComboBox->hide();
739 mAngleDirectionComboBox->hide();
740 mAngleDirectionLabel->hide();
741 mAngleOffsetLabel->hide();
742 mStartAngleDDBtn->hide();
746QString QgsDiagramProperties::guessLegendText(
const QString &expression )
749 QString text = expression.mid( expression.startsWith(
'\"' ) ? 1 : 0 );
750 if ( text.endsWith(
'\"' ) )
757 QTreeWidgetItem *newItem =
new QTreeWidgetItem( mDiagramAttributesTreeWidget );
759 newItem->setText( 0, item->text( 0 ) );
760 newItem->setText( 2, guessLegendText( item->text( 0 ) ) );
761 newItem->setData( 0, RoleAttributeExpression, item->data( 0, RoleAttributeExpression ) );
762 newItem->setFlags( ( newItem->flags() | Qt::ItemIsEditable ) & ~Qt::ItemIsDropEnabled );
765 const int red = QRandomGenerator::global()->bounded( 1, 256 );
766 const int green = QRandomGenerator::global()->bounded( 1, 256 );
767 const int blue = QRandomGenerator::global()->bounded( 1, 256 );
768 const QColor randomColor( red, green, blue );
769 newItem->setData( ColumnColor, Qt::EditRole, randomColor );
770 mDiagramAttributesTreeWidget->addTopLevelItem( newItem );
775 const auto constSelectedItems = mAttributesTreeWidget->selectedItems();
776 for ( QTreeWidgetItem *attributeItem : constSelectedItems )
790 const auto constSelectedItems = mDiagramAttributesTreeWidget->selectedItems();
791 for ( QTreeWidgetItem *attributeItem : constSelectedItems )
793 delete attributeItem;
802 float maxValue = 0.0;
805 const QString sizeFieldNameOrExp = mSizeFieldExpressionWidget->currentField( &isExpression );
823 maxValue = std::max( maxValue, exp.
evaluate( &context ).toFloat() );
834 maxValue = mLayer->
maximumValue( attributeNumber ).toFloat();
837 mMaxValueSpinBox->setValue( maxValue );
844 case ColumnAttributeExpression:
846 const QString currentExpression = item->data( 0, RoleAttributeExpression ).toString();
848 const QString newExpression = showExpressionBuilder( currentExpression );
849 if ( !newExpression.isEmpty() )
851 item->setData( 0, Qt::DisplayRole, newExpression );
852 item->setData( 0, RoleAttributeExpression, newExpression );
860 case ColumnLegendText:
865std::unique_ptr< QgsDiagram > QgsDiagramProperties::createDiagramObject()
867 std::unique_ptr< QgsDiagram > diagram;
871 diagram = std::make_unique< QgsTextDiagram >();
875 diagram = std::make_unique< QgsPieDiagram >();
879 diagram = std::make_unique< QgsStackedBarDiagram >();
883 diagram = std::make_unique< QgsHistogramDiagram >();
888std::unique_ptr<QgsDiagramSettings> QgsDiagramProperties::createDiagramSettings()
890 std::unique_ptr< QgsDiagramSettings > ds = std::make_unique< QgsDiagramSettings>();
891 ds->enabled = isDiagramEnabled();
892 ds->font = mDiagramFontButton->currentFont();
893 ds->opacity = mOpacityWidget->opacity();
895 QList<QColor> categoryColors;
896 QList<QString> categoryAttributes;
897 QList<QString> categoryLabels;
898 categoryColors.reserve( mDiagramAttributesTreeWidget->topLevelItemCount() );
899 categoryAttributes.reserve( mDiagramAttributesTreeWidget->topLevelItemCount() );
900 categoryLabels.reserve( mDiagramAttributesTreeWidget->topLevelItemCount() );
901 for (
int i = 0; i < mDiagramAttributesTreeWidget->topLevelItemCount(); ++i )
903 QColor color = mDiagramAttributesTreeWidget->topLevelItem( i )->data( ColumnColor, Qt::EditRole ).value<QColor>();
904 categoryColors.append( color );
905 categoryAttributes.append( mDiagramAttributesTreeWidget->topLevelItem( i )->data( 0, RoleAttributeExpression ).toString() );
906 categoryLabels.append( mDiagramAttributesTreeWidget->topLevelItem( i )->text( 2 ) );
908 ds->categoryColors = categoryColors;
909 ds->categoryAttributes = categoryAttributes;
910 ds->categoryLabels = categoryLabels;
911 ds->size = QSizeF( mDiagramSizeSpinBox->value(), mDiagramSizeSpinBox->value() );
912 ds->sizeType = mDiagramUnitComboBox->unit();
913 ds->sizeScale = mDiagramUnitComboBox->getMapUnitScale();
914 ds->lineSizeUnit = mDiagramLineUnitComboBox->unit();
915 ds->lineSizeScale = mDiagramLineUnitComboBox->getMapUnitScale();
919 if ( mIncreaseSmallDiagramsGroupBox->isChecked() )
921 ds->minimumSize = mIncreaseMinimumSizeSpinBox->value();
928 ds->backgroundColor = mBackgroundColorButton->color();
929 ds->penColor = mDiagramPenColorButton->color();
930 ds->penWidth = mPenWidthSpinBox->value();
931 ds->minimumScale = mScaleRangeWidget->minimumScale();
932 ds->maximumScale = mScaleRangeWidget->maximumScale();
933 ds->scaleBasedVisibility = mScaleVisibilityGroupBox->isChecked();
936 ds->rotationOffset = mAngleOffsetComboBox->currentData().toInt();
942 ds->barWidth = mBarWidthSpinBox->value();
944 ds->setAxisLineSymbol( mAxisLineStyleButton->clonedSymbol<
QgsLineSymbol >() );
945 ds->setShowAxis( mShowAxisGroupBox->isChecked() );
947 ds->setSpacing( mBarSpacingSpinBox->value() );
948 ds->setSpacingUnit( mBarSpacingUnitComboBox->unit() );
949 ds->setSpacingMapUnitScale( mBarSpacingUnitComboBox->getMapUnitScale() );
952 ds->setPaintEffect( mPaintEffect->clone() );
954 ds->setPaintEffect(
nullptr );
959std::unique_ptr<QgsDiagramRenderer> QgsDiagramProperties::createRenderer()
961 std::unique_ptr< QgsDiagramSettings > ds = createDiagramSettings();
963 std::unique_ptr< QgsDiagramRenderer > renderer;
964 if ( mFixedSizeRadio->isChecked() )
966 std::unique_ptr< QgsSingleCategoryDiagramRenderer > dr = std::make_unique< QgsSingleCategoryDiagramRenderer >();
967 dr->setDiagramSettings( *ds );
968 renderer = std::move( dr );
972 std::unique_ptr< QgsLinearlyInterpolatedDiagramRenderer > dr = std::make_unique< QgsLinearlyInterpolatedDiagramRenderer >();
973 dr->setLowerValue( 0.0 );
974 dr->setLowerSize( QSizeF( 0.0, 0.0 ) );
975 dr->setUpperValue( mMaxValueSpinBox->value() );
976 dr->setUpperSize( QSizeF( mSizeSpinBox->value(), mSizeSpinBox->value() ) );
979 const QString sizeFieldNameOrExp = mSizeFieldExpressionWidget->currentField( &isExpression );
980 dr->setClassificationAttributeIsExpression( isExpression );
983 dr->setClassificationAttributeExpression( sizeFieldNameOrExp );
987 dr->setClassificationField( sizeFieldNameOrExp );
989 dr->setDiagramSettings( *ds );
993 renderer = std::move( dr );
996 renderer->setAttributeLegend( mCheckBoxAttributeLegend->isChecked() );
998 std::unique_ptr< QgsDiagram > diagram = createDiagramObject();
999 renderer->setDiagram( diagram.release() );
1008 dls.
setDistance( mDiagramDistanceSpinBox->value() );
1010 dls.
setZIndex( mZIndexSpinBox->value() );
1013 QWidget *curWdgt = stackedPlacement->currentWidget();
1014 if ( ( curWdgt == pagePoint && radAroundPoint->isChecked() )
1015 || ( curWdgt == pagePolygon && radAroundCentroid->isChecked() ) )
1019 else if ( ( curWdgt == pagePoint && radOverPoint->isChecked() )
1020 || ( curWdgt == pagePolygon && radOverCentroid->isChecked() ) )
1024 else if ( ( curWdgt == pageLine && radAroundLine->isChecked() )
1025 || ( curWdgt == pagePolygon && radPolygonPerimeter->isChecked() ) )
1029 else if ( ( curWdgt == pageLine && radOverLine->isChecked() )
1030 || ( curWdgt == pagePolygon && radInsidePolygon->isChecked() ) )
1036 qFatal(
"Invalid settings" );
1040 if ( chkLineAbove->isChecked() )
1042 if ( chkLineBelow->isChecked() )
1044 if ( chkLineOn->isChecked() )
1046 if ( ! chkLineOrientationDependent->isChecked() )
1057 if ( !
dockMode() || !settings.
value( QStringLiteral(
"UI/autoApplyStyling" ),
true ).toBool() )
1059 if ( isDiagramEnabled() && 0 == mDiagramAttributesTreeWidget->topLevelItemCount() )
1061 QMessageBox::warning(
this, tr(
"Diagrams: No attributes added." ),
1062 tr(
"You did not add any attributes to this diagram layer. Please specify the attributes to visualize on the diagrams or disable diagrams." ) );
1066 std::unique_ptr< QgsDiagramRenderer > renderer = createRenderer();
1077QString QgsDiagramProperties::showExpressionBuilder(
const QString &initialExpression )
1082 dlg.setWindowTitle( tr(
"Expression Based Attribute" ) );
1087 dlg.setGeomCalculator( myDa );
1089 if ( dlg.exec() == QDialog::Accepted )
1091 return dlg.expressionText();
1102 QList<QTreeWidgetItem *> selections = mAttributesTreeWidget->selectedItems();
1103 if ( !selections.empty() )
1105 expression = selections[0]->text( 0 );
1108 const QString newExpression = showExpressionBuilder( expression );
1111 if ( !newExpression.isEmpty() )
1113 QTreeWidgetItem *newItem =
new QTreeWidgetItem( mDiagramAttributesTreeWidget );
1115 newItem->setText( 0, newExpression );
1116 newItem->setText( 2, newExpression );
1117 newItem->setData( 0, RoleAttributeExpression, newExpression );
1118 newItem->setFlags( ( newItem->flags() | Qt::ItemIsEditable ) & ~Qt::ItemIsDropEnabled );
1121 QRandomGenerator colorGenerator;
1122 const int red = colorGenerator.bounded( 1, 256 );
1123 const int green = colorGenerator.bounded( 1, 256 );
1124 const int blue = colorGenerator.bounded( 1, 256 );
1126 const QColor randomColor( red, green, blue );
1127 newItem->setData( ColumnColor, Qt::EditRole, randomColor );
1128 mDiagramAttributesTreeWidget->addTopLevelItem( newItem );
1135 mDiagramOptionsListWidget->blockSignals(
true );
1136 mDiagramOptionsListWidget->setCurrentRow( index );
1137 mDiagramOptionsListWidget->blockSignals(
false );
1142 QWidget *curWdgt = stackedPlacement->currentWidget();
1144 if ( ( curWdgt == pagePoint && radAroundPoint->isChecked() )
1145 || ( curWdgt == pageLine && radAroundLine->isChecked() )
1146 || ( curWdgt == pagePolygon && radAroundCentroid->isChecked() ) )
1148 mDiagramDistanceLabel->setEnabled(
true );
1149 mDiagramDistanceSpinBox->setEnabled(
true );
1150 mDistanceDDBtn->setEnabled(
true );
1154 mDiagramDistanceLabel->setEnabled(
false );
1155 mDiagramDistanceSpinBox->setEnabled(
false );
1156 mDistanceDDBtn->setEnabled(
false );
1160 chkLineAbove->setEnabled( linePlacementEnabled );
1161 chkLineBelow->setEnabled( linePlacementEnabled );
1162 chkLineOn->setEnabled( linePlacementEnabled );
1163 chkLineOrientationDependent->setEnabled( linePlacementEnabled );
1168 mButtonSizeLegendSettings->setEnabled( mAttributeBasedScalingRadio->isChecked() );
1173 mAllowedToEditDls = allowed;
1175 label_16->setVisible( allowed );
1176 mZIndexSpinBox->setVisible( allowed );
1177 mZOrderDDBtn->setVisible( allowed );
1178 mShowAllCheckBox->setVisible( allowed );
1179 mDlsLabel_1->setVisible( !allowed );
1181 mCoordinatesGrpBox->setVisible( allowed );
1182 mLinePlacementFrame->setVisible( allowed );
1183 mObstaclesGrpBox->setVisible( allowed );
1184 mPlacementFrame->setVisible( allowed );
1185 mPriorityGrpBox->setVisible( allowed );
1186 stackedPlacement->setVisible( allowed );
1187 mDlsLabel_2->setVisible( !allowed );
1192 return mAllowedToEditDls;
1199 const QString sizeFieldNameOrExp = mSizeFieldExpressionWidget->currentField( &isExpression );
1201 const bool scaleByArea = mScaleDependencyComboBox->currentData().toBool();
1203 0.0, mMaxValueSpinBox->value(), 0.0, mSizeSpinBox->value() ) );
1208 dlg.setLayout(
new QVBoxLayout() );
1210 dlg.layout()->addWidget( panel );
1211 QDialogButtonBox *buttonBox =
new QDialogButtonBox( QDialogButtonBox::Cancel | QDialogButtonBox::Help | QDialogButtonBox::Ok );
1212 connect( buttonBox, &QDialogButtonBox::accepted, &dlg, &QDialog::accept );
1213 connect( buttonBox, &QDialogButtonBox::helpRequested,
this, &QgsDiagramProperties::showHelp );
1214 connect( buttonBox, &QDialogButtonBox::rejected, &dlg, &QDialog::reject );
1215 dlg.layout()->addWidget( buttonBox );
1220void QgsDiagramProperties::showHelp()
1222 QgsHelp::openHelp( QStringLiteral(
"working_with_vector/vector_properties.html#legend" ) );
1225void QgsDiagramProperties::createAuxiliaryField()
1249 property.setActive(
true );
1257void QgsDiagramProperties::connectValueChanged(
const QList<QWidget *> &widgets )
1259 const auto constWidgets = widgets;
1260 for ( QWidget *widget : constWidgets )
1270 else if (
QgsOpacityWidget *w = qobject_cast< QgsOpacityWidget *>( widget ) )
1278 else if ( QComboBox *w = qobject_cast<QComboBox *>( widget ) )
1282 else if ( QSpinBox *w = qobject_cast<QSpinBox *>( widget ) )
1286 else if ( QDoubleSpinBox *w = qobject_cast<QDoubleSpinBox *>( widget ) )
1290 else if (
QgsColorButton *w = qobject_cast<QgsColorButton *>( widget ) )
1294 else if ( QCheckBox *w = qobject_cast<QCheckBox *>( widget ) )
1298 else if ( QRadioButton *w = qobject_cast<QRadioButton *>( widget ) )
1302 else if ( QSlider *w = qobject_cast<QSlider *>( widget ) )
1306 else if ( QGroupBox *w = qobject_cast<QGroupBox *>( widget ) )
1310 else if ( QTreeWidget *w = qobject_cast<QTreeWidget *>( widget ) )
1322 else if (
QgsFontButton *w = qobject_cast<QgsFontButton *>( widget ) )
1328 QgsLogger::warning( QStringLiteral(
"Could not create connection for widget %1" ).arg( widget->objectName() ) );
1333void QgsDiagramProperties::setDiagramEnabled(
bool enabled )
1335 mEnableDiagramCheckBox->setChecked( enabled );
1338bool QgsDiagramProperties::isDiagramEnabled()
const
1340 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)