29#include "moc_qgslayoutchartwidget.cpp"
33 , mChartItem( chartItem )
39 mainLayout->addWidget( mItemPropertiesWidget );
42 for (
auto plotTypesIterator = plotTypes.keyValueBegin(); plotTypesIterator != plotTypes.keyValueEnd(); ++plotTypesIterator )
44 mChartTypeComboBox->addItem( plotTypesIterator->second, plotTypesIterator->first );
49 connect( mChartTypeComboBox,
static_cast<void ( QComboBox::* )(
int )
>( &QComboBox::currentIndexChanged ),
this, &QgsLayoutChartWidget::mChartTypeComboBox_currentIndexChanged );
50 connect( mChartPropertiesButton, &QPushButton::clicked,
this, &QgsLayoutChartWidget::mChartPropertiesButton_clicked );
51 connect( mFlipAxesCheckBox, &QCheckBox::stateChanged,
this, &QgsLayoutChartWidget::mFlipAxesCheckBox_stateChanged );
55 connect( mSortCheckBox, &QCheckBox::stateChanged,
this, &QgsLayoutChartWidget::mSortCheckBox_stateChanged );
57 connect( mSortDirectionButton, &QToolButton::clicked,
this, &QgsLayoutChartWidget::mSortDirectionButton_clicked );
59 connect( mGenerateCategoriesFromRendererCheckBox, &QCheckBox::stateChanged,
this, &QgsLayoutChartWidget::mGenerateCategoriesFromRendererCheckBox_stateChanged );
60 connect( mApplyRendererStyleCheckBox, &QCheckBox::stateChanged,
this, &QgsLayoutChartWidget::mApplyRendererStyleCheckBox_stateChanged );
62 connect( mSeriesListWidget, &QListWidget::currentItemChanged,
this, &QgsLayoutChartWidget::mSeriesListWidget_currentItemChanged );
63 connect( mSeriesListWidget, &QListWidget::itemChanged,
this, &QgsLayoutChartWidget::mSeriesListWidget_itemChanged );
64 connect( mAddSeriesPushButton, &QPushButton::clicked,
this, &QgsLayoutChartWidget::mAddSeriesPushButton_clicked );
65 connect( mRemoveSeriesPushButton, &QPushButton::clicked,
this, &QgsLayoutChartWidget::mRemoveSeriesPushButton_clicked );
66 connect( mSeriesPropertiesButton, &QPushButton::clicked,
this, &QgsLayoutChartWidget::mSeriesPropertiesButton_clicked );
68 mLinkedMapComboBox->setCurrentLayout( mChartItem->layout() );
72 connect( mFilterOnlyVisibleFeaturesCheckBox, &QCheckBox::stateChanged,
this, &QgsLayoutChartWidget::mFilterOnlyVisibleFeaturesCheckBox_stateChanged );
73 connect( mIntersectAtlasCheckBox, &QCheckBox::stateChanged,
this, &QgsLayoutChartWidget::mIntersectAtlasCheckBox_stateChanged );
75 setGuiElementValues();
81 layoutAtlasToggled( atlas->enabled() );
89 if ( mItemPropertiesWidget )
90 mItemPropertiesWidget->setMasterLayout( masterLayout );
103 mChartItem = qobject_cast<QgsLayoutItemChart *>( item );
104 mItemPropertiesWidget->setItem( mChartItem );
111 setGuiElementValues();
116void QgsLayoutChartWidget::setGuiElementValues()
120 whileBlocking( mChartTypeComboBox )->setCurrentIndex( mChartTypeComboBox->findData( mChartItem->plot()->type() ) );
121 whileBlocking( mLayerComboBox )->setLayer( mChartItem->sourceLayer() );
126 mFlipAxesCheckBox->setEnabled(
true );
131 mFlipAxesCheckBox->setEnabled(
false );
135 whileBlocking( mGenerateCategoriesFromRendererCheckBox )->setCheckState( mChartItem->generateCategoriesFromRenderer() ? Qt::Checked : Qt::Unchecked );
136 whileBlocking( mApplyRendererStyleCheckBox )->setCheckState( mChartItem->applyRendererStyle() ? Qt::Checked : Qt::Unchecked );
138 whileBlocking( mSortCheckBox )->setCheckState( mChartItem->sortFeatures() ? Qt::Checked : Qt::Unchecked );
139 whileBlocking( mSortDirectionButton )->setEnabled( mChartItem->sortFeatures() );
140 whileBlocking( mSortDirectionButton )->setArrowType( mChartItem->sortAscending() ? Qt::UpArrow : Qt::DownArrow );
141 whileBlocking( mSortExpressionWidget )->setEnabled( mChartItem->sortFeatures() );
142 whileBlocking( mSortExpressionWidget )->setLayer( mChartItem->sourceLayer() );
143 whileBlocking( mSortExpressionWidget )->setField( mChartItem->sortExpression() );
145 mSeriesListWidget->clear();
146 const QList<QgsLayoutItemChart::SeriesDetails> seriesList = mChartItem->seriesList();
147 for (
const QgsLayoutItemChart::SeriesDetails &series : seriesList )
149 addSeriesListItem( series.name() );
152 if ( !seriesList.isEmpty() )
154 mSeriesListWidget->setCurrentRow( 0 );
158 mSeriesPropertiesButton->setEnabled(
false );
161 whileBlocking( mFilterOnlyVisibleFeaturesCheckBox )->setChecked( mChartItem->filterOnlyVisibleFeatures() );
162 mLinkedMapLabel->setEnabled( mFilterOnlyVisibleFeaturesCheckBox->isChecked() );
163 mLinkedMapComboBox->setEnabled( mFilterOnlyVisibleFeaturesCheckBox->isChecked() );
164 whileBlocking( mLinkedMapComboBox )->setItem( mChartItem->map() );
166 whileBlocking( mIntersectAtlasCheckBox )->setChecked( mChartItem->filterToAtlasFeature() );
170 mSeriesListWidget->clear();
174void QgsLayoutChartWidget::mChartTypeComboBox_currentIndexChanged(
int )
181 const QString plotType = mChartTypeComboBox->currentData().toString();
182 if ( mChartItem->plot()->type() == plotType )
187 QgsPlot *oldPlot = mChartItem->plot();
191 Qgs2DXyPlot *newPlot2DXy =
dynamic_cast<Qgs2DXyPlot *
>( newPlot );
194 mFlipAxesCheckBox->setEnabled(
true );
195 mFlipAxesCheckBox->setChecked( newPlot2DXy->
flipAxes() );
199 mFlipAxesCheckBox->setEnabled(
false );
200 mFlipAxesCheckBox->setChecked(
false );
203 mChartItem->beginCommand( tr(
"Change Chart Type" ) );
204 mChartItem->setPlot( newPlot );
205 mChartItem->update();
206 mChartItem->endCommand();
209void QgsLayoutChartWidget::mChartPropertiesButton_clicked()
218 const QString plotType = mChartTypeComboBox->currentData().toString();
220 if ( !abstractMetadata )
232 widget->
setPlot( mChartItem->plot() );
240 mChartItem->beginCommand( tr(
"Modify Chart" ) );
242 mChartItem->endCommand();
243 mChartItem->update();
249void QgsLayoutChartWidget::mFlipAxesCheckBox_stateChanged(
int state )
256 Qgs2DXyPlot *plot2DXy =
dynamic_cast<Qgs2DXyPlot *
>( mChartItem->plot() );
262 mChartItem->beginCommand( tr(
"Modify Chart" ) );
264 mChartItem->endCommand();
265 mChartItem->update();
268void QgsLayoutChartWidget::changeLayer(
QgsMapLayer *layer )
275 QgsVectorLayer *vl = qobject_cast<QgsVectorLayer *>( layer );
281 mChartItem->beginCommand( tr(
"Change Chart Source Layer" ) );
282 mChartItem->setSourceLayer( vl );
283 mChartItem->update();
284 mChartItem->endCommand();
285 updateButtonsState();
288void QgsLayoutChartWidget::changeSortExpression(
const QString &expression,
bool )
295 mChartItem->beginCommand( tr(
"Change Chart Source Sort Expression" ) );
296 mChartItem->setSortExpression( expression );
297 mChartItem->update();
298 mChartItem->endCommand();
301void QgsLayoutChartWidget::mSortCheckBox_stateChanged(
int state )
306 if ( state == Qt::Checked )
308 mSortDirectionButton->setEnabled(
true );
309 mSortExpressionWidget->setEnabled(
true );
313 mSortDirectionButton->setEnabled(
false );
314 mSortExpressionWidget->setEnabled(
false );
317 mChartItem->beginCommand( tr(
"Toggle Atlas Sorting" ) );
318 mChartItem->setSortFeatures( state == Qt::Checked );
319 mChartItem->update();
320 mChartItem->endCommand();
323void QgsLayoutChartWidget::mSortDirectionButton_clicked()
330 Qt::ArrowType at = mSortDirectionButton->arrowType();
331 at = ( at == Qt::UpArrow ) ? Qt::DownArrow : Qt::UpArrow;
332 mSortDirectionButton->setArrowType( at );
334 mChartItem->beginCommand( tr(
"Change Chart Source Sort Direction" ) );
335 mChartItem->setSortAscending( at == Qt::UpArrow );
336 mChartItem->update();
337 mChartItem->endCommand();
340QListWidgetItem *QgsLayoutChartWidget::addSeriesListItem(
const QString &name )
342 QListWidgetItem *item =
new QListWidgetItem( name,
nullptr );
343 item->setFlags( Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable );
344 mSeriesListWidget->addItem( item );
348void QgsLayoutChartWidget::mSeriesListWidget_currentItemChanged( QListWidgetItem *current, QListWidgetItem * )
350 mSeriesPropertiesButton->setEnabled(
static_cast<bool>( current ) );
353void QgsLayoutChartWidget::mSeriesListWidget_itemChanged( QListWidgetItem *item )
360 QList<QgsLayoutItemChart::SeriesDetails> seriesList = mChartItem->seriesList();
361 const int idx = mSeriesListWidget->row( item );
362 if ( idx >= seriesList.size() )
367 mChartItem->beginCommand( tr(
"Rename Chart Series" ) );
368 seriesList[idx].setName( item->text() );
369 mChartItem->setSeriesList( seriesList );
370 mChartItem->endCommand();
373void QgsLayoutChartWidget::mAddSeriesPushButton_clicked()
380 QList<QgsLayoutItemChart::SeriesDetails> seriesList = mChartItem->seriesList();
381 const QString itemName = tr(
"Series %1" ).arg( seriesList.size() + 1 );
382 addSeriesListItem( itemName );
384 mChartItem->beginCommand( tr(
"Add Chart Series" ) );
385 seriesList << QgsLayoutItemChart::SeriesDetails( itemName );
386 mChartItem->setSeriesList( seriesList );
387 mChartItem->endCommand();
388 mChartItem->update();
390 mSeriesListWidget->setCurrentRow( mSeriesListWidget->count() - 1 );
391 mSeriesListWidget_currentItemChanged( mSeriesListWidget->currentItem(),
nullptr );
392 updateButtonsState();
395void QgsLayoutChartWidget::mRemoveSeriesPushButton_clicked()
397 QListWidgetItem *item = mSeriesListWidget->currentItem();
398 if ( !item || !mChartItem )
403 QList<QgsLayoutItemChart::SeriesDetails> seriesList = mChartItem->seriesList();
404 const int idx = mSeriesListWidget->row( item );
405 if ( idx >= seriesList.size() )
410 QListWidgetItem *deletedItem = mSeriesListWidget->takeItem( mSeriesListWidget->row( item ) );
413 mChartItem->beginCommand( tr(
"Remove Chart Series" ) );
414 seriesList.removeAt( idx );
415 mChartItem->setSeriesList( seriesList );
416 mChartItem->endCommand();
417 mChartItem->update();
418 updateButtonsState();
421void QgsLayoutChartWidget::mSeriesPropertiesButton_clicked()
423 QListWidgetItem *item = mSeriesListWidget->currentItem();
424 if ( !item || !mChartItem )
429 QList<QgsLayoutItemChart::SeriesDetails> seriesList = mChartItem->seriesList();
430 const int idx = mSeriesListWidget->row( item );
431 if ( idx >= seriesList.size() )
436 QgsLayoutChartSeriesDetailsWidget *widget =
new QgsLayoutChartSeriesDetailsWidget( mChartItem->sourceLayer(), idx, seriesList[idx], mGenerateCategoriesFromRendererCheckBox->isChecked(),
this );
445 QList<QgsLayoutItemChart::SeriesDetails> seriesList = mChartItem->seriesList();
446 const int idx = widget->
index();
447 if ( idx >= seriesList.size() )
452 mChartItem->beginCommand( tr(
"Modify Chart Series" ) );
453 seriesList[idx].setXExpression( widget->
xExpression() );
454 seriesList[idx].setYExpression( widget->
yExpression() );
456 mChartItem->setSeriesList( seriesList );
457 mChartItem->endCommand();
458 mChartItem->update();
464void QgsLayoutChartWidget::mLinkedMapComboBox_itemChanged(
QgsLayoutItem *item )
471 mChartItem->beginCommand( tr(
"Change Chart Map Item" ) );
472 mChartItem->setMap( qobject_cast<QgsLayoutItemMap *>( item ) );
473 mChartItem->endCommand();
474 mChartItem->update();
477void QgsLayoutChartWidget::mGenerateCategoriesFromRendererCheckBox_stateChanged(
int state )
484 mChartItem->beginCommand( tr(
"Toggle Generate Categories from Layer Renderer" ) );
485 const bool generateCategoriesFromRenderer = ( state == Qt::Checked );
486 mChartItem->setGenerateCategoriesFromRenderer( generateCategoriesFromRenderer );
487 mChartItem->endCommand();
488 mChartItem->update();
490 mApplyRendererStyleCheckBox->setEnabled( mGenerateCategoriesFromRendererCheckBox->isChecked() );
493void QgsLayoutChartWidget::mApplyRendererStyleCheckBox_stateChanged(
int state )
500 mChartItem->beginCommand( tr(
"Toggle Apply Layer Renderer Style" ) );
501 const bool applyRendererStyle = ( state == Qt::Checked );
502 mChartItem->setApplyRendererStyle( applyRendererStyle );
503 mChartItem->endCommand();
504 mChartItem->update();
507void QgsLayoutChartWidget::mFilterOnlyVisibleFeaturesCheckBox_stateChanged(
int state )
514 mChartItem->beginCommand( tr(
"Toggle Visible Features Only Filter" ) );
515 const bool useOnlyVisibleFeatures = ( state == Qt::Checked );
516 mChartItem->setFilterOnlyVisibleFeatures( useOnlyVisibleFeatures );
517 mChartItem->endCommand();
518 mChartItem->update();
521 mLinkedMapComboBox->setEnabled( state == Qt::Checked );
522 mLinkedMapLabel->setEnabled( state == Qt::Checked );
525void QgsLayoutChartWidget::mIntersectAtlasCheckBox_stateChanged(
int state )
532 mChartItem->beginCommand( tr(
"Toggle Chart Atlas Filter" ) );
533 const bool filterToAtlas = ( state == Qt::Checked );
534 mChartItem->setFilterToAtlasFeature( filterToAtlas );
535 mChartItem->endCommand();
536 mChartItem->update();
539void QgsLayoutChartWidget::updateButtonsState()
546 const bool enable = qobject_cast<QgsVectorLayer *>( mLayerComboBox->currentLayer() ) !=
nullptr;
547 mGenerateCategoriesFromRendererCheckBox->setEnabled( enable );
548 mApplyRendererStyleCheckBox->setEnabled( enable && mGenerateCategoriesFromRendererCheckBox->isChecked() );
549 mSortCheckBox->setEnabled( enable );
550 mAddSeriesPushButton->setEnabled( enable );
551 mRemoveSeriesPushButton->setEnabled( mSeriesListWidget->count() > 0 );
554void QgsLayoutChartWidget::layoutAtlasToggled(
bool atlasEnabled )
558 mIntersectAtlasCheckBox->setEnabled(
true );
562 mIntersectAtlasCheckBox->setEnabled(
false );
563 mIntersectAtlasCheckBox->setChecked(
false );
Base class for 2-dimensional plot/chart/graphs with an X and Y axes.
void setFlipAxes(bool flipAxes)
Sets whether the X and Y axes are flipped.
bool flipAxes() const
Returns whether the X and Y axes are flipped.
static QgsApplication * instance()
Returns the singleton instance of the QgsApplication.
static QgsPlotRegistry * plotRegistry()
Returns the application's plot registry, used for plot types.
static void initPlotWidgets()
Initializes plot widgets.
Used to render QgsLayout as an atlas, by iterating over the features from an associated vector layer.
void toggled(bool enabled)
Emitted when atlas is enabled or disabled.
A layout item subclass that renders chart plots.
void itemChanged(QgsLayoutItem *item)
Emitted whenever the currently selected item changes.
Base class for graphical items within a QgsLayout.
int type() const override
Returns a unique graphics item type identifier.
void changed()
Emitted when the object's properties change.
void layerChanged(QgsMapLayer *layer)
Emitted whenever the currently selected layer changes.
Base class for all map layer types.
Interface for master layout type objects, such as print layouts and reports.
QgsPlot * createPlot(const QString &type) const
Creates a new instance of a plot given the type.
QMap< QString, QString > plotTypes() const
Returns a map of available plot types to translated name.
QgsPlotAbstractMetadata * plotMetadata(const QString &type) const
Returns the metadata for the specified plot type.
virtual void initFromPlot(const QgsPlot *plot)
Initializes properties of this plot from an existing plot, transferring all applicable settings.
QgsSignalBlocker< Object > whileBlocking(Object *object)
Temporarily blocks signals from a QObject while calling a single method from the object.