QGIS API Documentation 3.99.0-Master (21b3aa880ba)
Loading...
Searching...
No Matches
qgsplotwidget.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsplotwidget.cpp
3 -----------------
4 begin : August 2025
5 copyright : (C) 2025 by Mathieu Pellerin
6 email : mathieu dot opengis dot ch
7 ***************************************************************************
8 * *
9 * This program is free software; you can redistribute it and/or modify *
10 * it under the terms of the GNU General Public License as published by *
11 * the Free Software Foundation; either version 2 of the License, or *
12 * (at your option) any later version. *
13 * *
14 ***************************************************************************/
15
16#include "qgsplotwidget.h"
17
18#include "qgsapplication.h"
19#include "qgsbarchartplot.h"
20#include "qgscolorrampbutton.h"
22#include "qgsfillsymbol.h"
23#include "qgslinechartplot.h"
24#include "qgslinesymbol.h"
26#include "qgspiechartplot.h"
27#include "qgsplotregistry.h"
28
29#include "moc_qgsplotwidget.cpp"
30
32{
33 mExpressionContextGenerator = generator;
34}
35
37{
39 if ( mExpressionContextGenerator )
40 {
41 context = mExpressionContextGenerator->createExpressionContext();
42 }
43 else
44 {
46 }
47
48 auto plotScope = std::make_unique<QgsExpressionContextScope>( QStringLiteral( "plot" ) );
49 plotScope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "plot_axis" ), QString(), true ) );
50 plotScope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "plot_axis_value" ), 0.0, true ) );
51 context.appendScope( plotScope.release() );
52
53 auto chartScope = std::make_unique<QgsExpressionContextScope>( QStringLiteral( "chart" ) );
54 chartScope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "chart_category" ), QString(), true ) );
55 chartScope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "chart_value" ), 0.0, true ) );
56 context.appendScope( chartScope.release() );
57
58 context.setHighlightedVariables( { QStringLiteral( "plot_axis" ), QStringLiteral( "plot_axis_value" ), QStringLiteral( "chart_category" ), QStringLiteral( "chart_value" ) } );
59
60 return context;
61}
62
64{
65 button->blockSignals( true );
66 button->init( static_cast< int >( key ), mPropertyCollection, QgsPlot::propertyDefinitions(), nullptr );
67 connect( button, &QgsPropertyOverrideButton::changed, this, &QgsPlotWidget::updateProperty );
69 button->blockSignals( false );
70}
71
73{
74 if ( !button )
75 {
76 return;
77 }
78
79 if ( button->propertyKey() < 0 )
80 {
81 return;
82 }
83
84 const QgsPlot::DataDefinedProperty key = static_cast<QgsPlot::DataDefinedProperty>( button->propertyKey() );
85 whileBlocking( button )->setToProperty( mPropertyCollection.property( key ) );
86}
87
88void QgsPlotWidget::updateProperty()
89{
90 QgsPropertyOverrideButton *button = qobject_cast<QgsPropertyOverrideButton *>( sender() );
91 const QgsPlot::DataDefinedProperty key = static_cast<QgsPlot::DataDefinedProperty>( button->propertyKey() );
93 emit widgetChanged();
94}
95
96
98 : QgsPlotWidget( parent )
99{
100 setupUi( this );
101
102 setPanelTitle( tr( "Bar Chart Plot Properties" ) );
103
104 mSymbolsList->setColumnCount( 2 );
105 mSymbolsList->setSelectionBehavior( QAbstractItemView::SelectRows );
106 mSymbolsList->setSelectionMode( QAbstractItemView::ExtendedSelection );
107 mSymbolsList->setSortingEnabled( false );
108 mSymbolsList->horizontalHeader()->setSectionResizeMode( 0, QHeaderView::Stretch );
109 mSymbolsList->horizontalHeader()->setSectionResizeMode( 1, QHeaderView::Stretch );
110 mSymbolsList->horizontalHeader()->hide();
111 mSymbolsList->verticalHeader()->hide();
112
113 connect( mAddSymbolPushButton, &QPushButton::clicked, this, &QgsBarChartPlotWidget::mAddSymbolPushButton_clicked );
114 connect( mRemoveSymbolPushButton, &QPushButton::clicked, this, &QgsBarChartPlotWidget::mRemoveSymbolPushButton_clicked );
115
116 mSpinMinXAxis->setClearValue( 0 );
117 connect( mSpinMinXAxis, qOverload<double>( &QDoubleSpinBox::valueChanged ), this, [this]( double ) {
118 if ( mBlockChanges )
119 return;
120 emit widgetChanged();
121 } );
122
123 connect( mSpinMaxXAxis, qOverload<double>( &QDoubleSpinBox::valueChanged ), this, [this]( double ) {
124 if ( mBlockChanges )
125 return;
126 emit widgetChanged();
127 } );
128
129 mSpinMinYAxis->setClearValue( 0 );
130 connect( mSpinMinYAxis, qOverload<double>( &QDoubleSpinBox::valueChanged ), this, [this]( double ) {
131 if ( mBlockChanges )
132 return;
133 emit widgetChanged();
134 } );
135
136 mSpinMaxYAxis->setClearValue( 0 );
137 connect( mSpinMaxYAxis, qOverload<double>( &QDoubleSpinBox::valueChanged ), this, [this]( double ) {
138 if ( mBlockChanges )
139 return;
140 emit widgetChanged();
141 } );
142
143 mXAxisMajorLinesSymbolButton->setSymbolType( Qgis::SymbolType::Line );
144 connect( mXAxisMajorLinesSymbolButton, &QgsSymbolButton::changed, this, [this] {
145 if ( mBlockChanges )
146 return;
147 emit widgetChanged();
148 } );
149 mXAxisMajorLinesSymbolButton->setDefaultSymbol( QgsPlotDefaultSettings::axisGridMajorSymbol() );
150
151 mXAxisMinorLinesSymbolButton->setSymbolType( Qgis::SymbolType::Line );
152 connect( mXAxisMinorLinesSymbolButton, &QgsSymbolButton::changed, this, [this] {
153 if ( mBlockChanges )
154 return;
155 emit widgetChanged();
156 } );
157 mXAxisMinorLinesSymbolButton->setDefaultSymbol( QgsPlotDefaultSettings::axisGridMinorSymbol() );
158
159 connect( mXAxisMajorIntervalSpin, qOverload<double>( &QDoubleSpinBox::valueChanged ), this, [this]( double ) {
160 if ( mBlockChanges )
161 return;
162 emit widgetChanged();
163 } );
164
165 connect( mXAxisMinorIntervalSpin, qOverload<double>( &QDoubleSpinBox::valueChanged ), this, [this]( double ) {
166 if ( mBlockChanges )
167 return;
168 emit widgetChanged();
169 } );
170
171 connect( mXAxisLabelIntervalSpin, qOverload<double>( &QDoubleSpinBox::valueChanged ), this, [this]( double ) {
172 if ( mBlockChanges )
173 return;
174 emit widgetChanged();
175 } );
176
177 mYAxisMajorLinesSymbolButton->setSymbolType( Qgis::SymbolType::Line );
178 connect( mYAxisMajorLinesSymbolButton, &QgsSymbolButton::changed, this, [this] {
179 if ( mBlockChanges )
180 return;
181 emit widgetChanged();
182 } );
183 mYAxisMajorLinesSymbolButton->setDefaultSymbol( QgsPlotDefaultSettings::axisGridMajorSymbol() );
184
185 mYAxisMinorLinesSymbolButton->setSymbolType( Qgis::SymbolType::Line );
186 connect( mYAxisMinorLinesSymbolButton, &QgsSymbolButton::changed, this, [this] {
187 if ( mBlockChanges )
188 return;
189 emit widgetChanged();
190 } );
191 mYAxisMinorLinesSymbolButton->setDefaultSymbol( QgsPlotDefaultSettings::axisGridMinorSymbol() );
192
193 connect( mYAxisLabelIntervalSpin, qOverload<double>( &QDoubleSpinBox::valueChanged ), this, [this]( double ) {
194 if ( mBlockChanges )
195 return;
196 emit widgetChanged();
197 } );
198
199 connect( mYAxisMajorIntervalSpin, qOverload<double>( &QDoubleSpinBox::valueChanged ), this, [this]( double ) {
200 if ( mBlockChanges )
201 return;
202 emit widgetChanged();
203 } );
204
205 connect( mYAxisMinorIntervalSpin, qOverload<double>( &QDoubleSpinBox::valueChanged ), this, [this]( double ) {
206 if ( mBlockChanges )
207 return;
208 emit widgetChanged();
209 } );
210
211 mChartBackgroundSymbolButton->setSymbolType( Qgis::SymbolType::Fill );
212 connect( mChartBackgroundSymbolButton, &QgsSymbolButton::changed, this, [this] {
213 if ( mBlockChanges )
214 return;
215 emit widgetChanged();
216 } );
217 mChartBackgroundSymbolButton->setDefaultSymbol( QgsPlotDefaultSettings::chartBackgroundSymbol() );
218
219 mChartBorderSymbolButton->setSymbolType( Qgis::SymbolType::Fill );
220 connect( mChartBorderSymbolButton, &QgsSymbolButton::changed, this, [this] {
221 if ( mBlockChanges )
222 return;
223 emit widgetChanged();
224 } );
225 mChartBorderSymbolButton->setDefaultSymbol( QgsPlotDefaultSettings::chartBorderSymbol() );
226
227 connect( mXAxisLabelFormatButton, &QPushButton::clicked, this, [this] {
229 widget->setPanelTitle( tr( "X Axis Number Format" ) );
230 widget->setFormat( mXAxisNumericFormat.get() );
231 connect( widget, &QgsNumericFormatSelectorWidget::changed, this, [this, widget] {
232 mXAxisNumericFormat.reset( widget->format() );
233 emit widgetChanged();
234 } );
235 openPanel( widget );
236 } );
237
238 connect( mYAxisLabelFormatButton, &QPushButton::clicked, this, [this] {
240 widget->setPanelTitle( tr( "Y Axis Number Format" ) );
241 widget->setFormat( mYAxisNumericFormat.get() );
242 connect( widget, &QgsNumericFormatSelectorWidget::changed, this, [this, widget] {
243 mYAxisNumericFormat.reset( widget->format() );
244 emit widgetChanged();
245 } );
246 openPanel( widget );
247 } );
248
249 mXAxisLabelFontButton->setDialogTitle( tr( "X Axis Label Font" ) );
250 mYAxisLabelFontButton->setDialogTitle( tr( "Y Axis Label Font" ) );
251 mXAxisLabelFontButton->setMode( QgsFontButton::ModeTextRenderer );
252 mYAxisLabelFontButton->setMode( QgsFontButton::ModeTextRenderer );
253
254 connect( mXAxisLabelFontButton, &QgsFontButton::changed, this, [this] {
255 if ( mBlockChanges )
256 return;
257 emit widgetChanged();
258 } );
259
260 connect( mYAxisLabelFontButton, &QgsFontButton::changed, this, [this] {
261 if ( mBlockChanges )
262 return;
263 emit widgetChanged();
264 } );
265
266 mSpinLeftMargin->setClearValue( 0 );
267 connect( mSpinLeftMargin, qOverload<double>( &QDoubleSpinBox::valueChanged ), this, [this]( double ) {
268 if ( mBlockChanges )
269 return;
270 emit widgetChanged();
271 } );
272
273 mSpinRightMargin->setClearValue( 0 );
274 connect( mSpinRightMargin, qOverload<double>( &QDoubleSpinBox::valueChanged ), this, [this]( double ) {
275 if ( mBlockChanges )
276 return;
277 emit widgetChanged();
278 } );
279
280 mSpinTopMargin->setClearValue( 0 );
281 connect( mSpinTopMargin, qOverload<double>( &QDoubleSpinBox::valueChanged ), this, [this]( double ) {
282 if ( mBlockChanges )
283 return;
284 emit widgetChanged();
285 } );
286
287 mSpinBottomMargin->setClearValue( 0 );
288 connect( mSpinBottomMargin, qOverload<double>( &QDoubleSpinBox::valueChanged ), this, [this]( double ) {
289 if ( mBlockChanges )
290 return;
291 emit widgetChanged();
292 } );
293
294 mXAxisTypeCombo->addItem( tr( "Interval" ), QVariant::fromValue( Qgis::PlotAxisType::Interval ) );
295 mXAxisTypeCombo->addItem( tr( "Categorical" ), QVariant::fromValue( Qgis::PlotAxisType::Categorical ) );
296 connect( mXAxisTypeCombo, qOverload<int>( &QComboBox::currentIndexChanged ), this, [this]( int ) {
297 if ( mBlockChanges )
298 return;
299 emit widgetChanged();
300 } );
301
302 mXAxisLabelsCombo->addItem( tr( "None" ), QVariant::fromValue( Qgis::PlotAxisSuffixPlacement::NoLabels ) );
303 mXAxisLabelsCombo->addItem( tr( "Every Value" ), QVariant::fromValue( Qgis::PlotAxisSuffixPlacement::EveryLabel ) );
304 mXAxisLabelsCombo->addItem( tr( "First Value" ), QVariant::fromValue( Qgis::PlotAxisSuffixPlacement::FirstLabel ) );
305 mXAxisLabelsCombo->addItem( tr( "Last Value" ), QVariant::fromValue( Qgis::PlotAxisSuffixPlacement::LastLabel ) );
306 mXAxisLabelsCombo->addItem( tr( "First and Last Values" ), QVariant::fromValue( Qgis::PlotAxisSuffixPlacement::FirstAndLastLabels ) );
307 connect( mXAxisLabelsCombo, qOverload<int>( &QComboBox::currentIndexChanged ), this, [this]( int ) {
308 if ( mBlockChanges )
309 return;
310 emit widgetChanged();
311 } );
312
313 mXAxisMajorLinesSymbolButton->registerExpressionContextGenerator( this );
314 mXAxisMinorLinesSymbolButton->registerExpressionContextGenerator( this );
315 mXAxisLabelFontButton->registerExpressionContextGenerator( this );
316 mYAxisMajorLinesSymbolButton->registerExpressionContextGenerator( this );
317 mYAxisMinorLinesSymbolButton->registerExpressionContextGenerator( this );
318 mYAxisLabelFontButton->registerExpressionContextGenerator( this );
319 mChartBackgroundSymbolButton->registerExpressionContextGenerator( this );
320 mChartBorderSymbolButton->registerExpressionContextGenerator( this );
321
326
333
338}
339
340void QgsBarChartPlotWidget::mAddSymbolPushButton_clicked()
341{
342 const int row = mSymbolsList->rowCount();
343 mSymbolsList->insertRow( row );
344
345 QTableWidgetItem *item = new QTableWidgetItem();
346 item->setData( Qt::DisplayRole, tr( "Symbol" ) );
347 mSymbolsList->setItem( row, 0, item );
348
349 QgsSymbolButton *symbolButton = new QgsSymbolButton( this );
350 symbolButton->setSymbolType( Qgis::SymbolType::Fill );
351 symbolButton->setShowNull( true );
353 symbolButton->registerExpressionContextGenerator( this );
354 connect( symbolButton, &QgsSymbolButton::changed, this, [this] {
355 if ( mBlockChanges )
356 return;
357 emit widgetChanged();
358 } );
359 mSymbolsList->setCellWidget( row, 1, symbolButton );
360
361 emit widgetChanged();
362}
363
364void QgsBarChartPlotWidget::mRemoveSymbolPushButton_clicked()
365{
366 QTableWidgetItem *item = mSymbolsList->currentItem();
367 if ( !item )
368 {
369 return;
370 }
371
372 mSymbolsList->removeRow( mSymbolsList->row( item ) );
373
374 emit widgetChanged();
375}
376
378{
379 QgsBarChartPlot *chartPlot = dynamic_cast<QgsBarChartPlot *>( plot );
380 if ( !chartPlot )
381 {
382 return;
383 }
384
385 mBlockChanges++;
386
387 mSymbolsList->clear();
388 const int symbolCount = chartPlot->fillSymbolCount();
389 for ( int i = 0; i < symbolCount; i++ )
390 {
391 const int row = mSymbolsList->rowCount();
392 mSymbolsList->insertRow( row );
393
394 QTableWidgetItem *item = new QTableWidgetItem();
395 item->setData( Qt::DisplayRole, tr( "Symbol" ) );
396 mSymbolsList->setItem( row, 0, item );
397
398 QgsSymbolButton *symbolButton = new QgsSymbolButton( this );
399 symbolButton->setSymbolType( Qgis::SymbolType::Fill );
400 symbolButton->setShowNull( true );
401 symbolButton->setSymbol( chartPlot->fillSymbolAt( i )->clone() );
402 symbolButton->registerExpressionContextGenerator( this );
403 connect( symbolButton, &QgsSymbolButton::changed, this, [this] {
404 if ( mBlockChanges )
405 return;
406 emit widgetChanged();
407 } );
408 mSymbolsList->setCellWidget( row, 1, symbolButton );
409 }
410
411 mSpinMinXAxis->setValue( chartPlot->xMinimum() );
412 mSpinMaxXAxis->setValue( chartPlot->xMaximum() );
413 mSpinMinYAxis->setValue( chartPlot->yMinimum() );
414 mSpinMaxYAxis->setValue( chartPlot->yMaximum() );
415
416 if ( chartPlot->xAxis().gridMajorSymbol() )
417 mXAxisMajorLinesSymbolButton->setSymbol( chartPlot->xAxis().gridMajorSymbol()->clone() );
418 if ( chartPlot->xAxis().gridMinorSymbol() )
419 mXAxisMinorLinesSymbolButton->setSymbol( chartPlot->xAxis().gridMinorSymbol()->clone() );
420 if ( chartPlot->yAxis().gridMajorSymbol() )
421 mYAxisMajorLinesSymbolButton->setSymbol( chartPlot->yAxis().gridMajorSymbol()->clone() );
422 if ( chartPlot->yAxis().gridMinorSymbol() )
423 mYAxisMinorLinesSymbolButton->setSymbol( chartPlot->yAxis().gridMinorSymbol()->clone() );
424
425 mXAxisLabelFontButton->setTextFormat( chartPlot->xAxis().textFormat() );
426 mXAxisNumericFormat.reset( chartPlot->xAxis().numericFormat()->clone() );
427 mYAxisLabelFontButton->setTextFormat( chartPlot->yAxis().textFormat() );
428 mYAxisNumericFormat.reset( chartPlot->yAxis().numericFormat()->clone() );
429
430 mXAxisTypeCombo->setCurrentIndex( mXAxisTypeCombo->findData( QVariant::fromValue( chartPlot->xAxis().type() ) ) );
431 mXAxisLabelsCombo->setCurrentIndex( mXAxisLabelsCombo->findData( QVariant::fromValue( chartPlot->xAxis().labelSuffixPlacement() ) ) );
432
433 mXAxisMajorIntervalSpin->setValue( chartPlot->xAxis().gridIntervalMajor() );
434 mXAxisMinorIntervalSpin->setValue( chartPlot->xAxis().gridIntervalMinor() );
435 mXAxisLabelIntervalSpin->setValue( chartPlot->xAxis().labelInterval() );
436
437 mYAxisMajorIntervalSpin->setValue( chartPlot->yAxis().gridIntervalMajor() );
438 mYAxisMinorIntervalSpin->setValue( chartPlot->yAxis().gridIntervalMinor() );
439 mYAxisLabelIntervalSpin->setValue( chartPlot->yAxis().labelInterval() );
440
441 if ( chartPlot->chartBackgroundSymbol() )
442 mChartBackgroundSymbolButton->setSymbol( chartPlot->chartBackgroundSymbol()->clone() );
443 if ( chartPlot->chartBorderSymbol() )
444 mChartBorderSymbolButton->setSymbol( chartPlot->chartBorderSymbol()->clone() );
445
446 mSpinLeftMargin->setValue( chartPlot->margins().left() );
447 mSpinRightMargin->setValue( chartPlot->margins().right() );
448 mSpinTopMargin->setValue( chartPlot->margins().top() );
449 mSpinBottomMargin->setValue( chartPlot->margins().bottom() );
450
452
453 updateDataDefinedButton( mDDBtnMinXAxis );
454 updateDataDefinedButton( mDDBtnMaxXAxis );
455 updateDataDefinedButton( mDDBtnMinYAxis );
456 updateDataDefinedButton( mDDBtnMaxYAxis );
457
458 updateDataDefinedButton( mDDBtnXAxisMajorInterval );
459 updateDataDefinedButton( mDDBtnXAxisMinorInterval );
460 updateDataDefinedButton( mDDBtnXAxisLabelInterval );
461 updateDataDefinedButton( mDDBtnYAxisMajorInterval );
462 updateDataDefinedButton( mDDBtnYAxisMinorInterval );
463 updateDataDefinedButton( mDDBtnYAxisLabelInterval );
464
465 updateDataDefinedButton( mDDBtnLeftMargin );
466 updateDataDefinedButton( mDDBtnRightMargin );
467 updateDataDefinedButton( mDDBtnTopMargin );
468 updateDataDefinedButton( mDDBtnBottomMargin );
469
470 mBlockChanges--;
471}
472
473
475{
476 QgsPlot *plot = QgsApplication::plotRegistry()->createPlot( QStringLiteral( "bar" ) );
477 QgsBarChartPlot *chartPlot = dynamic_cast<QgsBarChartPlot *>( plot );
478 if ( !chartPlot )
479 {
480 return nullptr;
481 }
482
483 const int rowCount = mSymbolsList->rowCount();
484 for ( int i = 0; i < rowCount; i++ )
485 {
486 QgsSymbolButton *symbolButton = dynamic_cast<QgsSymbolButton *>( mSymbolsList->cellWidget( i, 1 ) );
487 if ( symbolButton )
488 {
489 chartPlot->setFillSymbolAt( i, symbolButton->clonedSymbol<QgsFillSymbol>() );
490 }
491 }
492
493 chartPlot->setXMinimum( mSpinMinXAxis->value() );
494 chartPlot->setXMaximum( mSpinMaxXAxis->value() );
495 chartPlot->setYMinimum( mSpinMinYAxis->value() );
496 chartPlot->setYMaximum( mSpinMaxYAxis->value() );
497
498 chartPlot->xAxis().setGridMajorSymbol( mXAxisMajorLinesSymbolButton->clonedSymbol<QgsLineSymbol>() );
499 chartPlot->xAxis().setGridMinorSymbol( mXAxisMinorLinesSymbolButton->clonedSymbol<QgsLineSymbol>() );
500 chartPlot->yAxis().setGridMajorSymbol( mYAxisMajorLinesSymbolButton->clonedSymbol<QgsLineSymbol>() );
501 chartPlot->yAxis().setGridMinorSymbol( mYAxisMinorLinesSymbolButton->clonedSymbol<QgsLineSymbol>() );
502
503 chartPlot->xAxis().setTextFormat( mXAxisLabelFontButton->textFormat() );
504 chartPlot->xAxis().setNumericFormat( mXAxisNumericFormat.get()->clone() );
505 chartPlot->yAxis().setTextFormat( mYAxisLabelFontButton->textFormat() );
506 chartPlot->yAxis().setNumericFormat( mYAxisNumericFormat.get()->clone() );
507
508 chartPlot->xAxis().setType( mXAxisTypeCombo->currentData().value<Qgis::PlotAxisType>() );
509 chartPlot->xAxis().setLabelSuffixPlacement( mXAxisLabelsCombo->currentData().value<Qgis::PlotAxisSuffixPlacement>() );
510
511 chartPlot->xAxis().setGridIntervalMajor( mXAxisMajorIntervalSpin->value() );
512 chartPlot->xAxis().setGridIntervalMinor( mXAxisMinorIntervalSpin->value() );
513 chartPlot->xAxis().setLabelInterval( mXAxisLabelIntervalSpin->value() );
514
515 chartPlot->yAxis().setGridIntervalMajor( mYAxisMajorIntervalSpin->value() );
516 chartPlot->yAxis().setGridIntervalMinor( mYAxisMinorIntervalSpin->value() );
517 chartPlot->yAxis().setLabelInterval( mYAxisLabelIntervalSpin->value() );
518
519 chartPlot->setChartBackgroundSymbol( mChartBackgroundSymbolButton->clonedSymbol<QgsFillSymbol>() );
520 chartPlot->setChartBorderSymbol( mChartBorderSymbolButton->clonedSymbol<QgsFillSymbol>() );
521
522 QgsMargins margins;
523 margins.setLeft( mSpinLeftMargin->value() );
524 margins.setRight( mSpinRightMargin->value() );
525 margins.setTop( mSpinTopMargin->value() );
526 margins.setBottom( mSpinBottomMargin->value() );
527 chartPlot->setMargins( margins );
528
530
531 return plot;
532}
533
534
536 : QgsPlotWidget( parent )
537{
538 setupUi( this );
539
540 setPanelTitle( tr( "Line Chart Plot Properties" ) );
541
542 mSymbolsList->setColumnCount( 3 );
543 mSymbolsList->setSelectionBehavior( QAbstractItemView::SelectRows );
544 mSymbolsList->setSelectionMode( QAbstractItemView::ExtendedSelection );
545 mSymbolsList->setSortingEnabled( false );
546 mSymbolsList->horizontalHeader()->setSectionResizeMode( 0, QHeaderView::Stretch );
547 mSymbolsList->horizontalHeader()->setSectionResizeMode( 1, QHeaderView::Stretch );
548 mSymbolsList->horizontalHeader()->setSectionResizeMode( 2, QHeaderView::Stretch );
549 mSymbolsList->horizontalHeader()->hide();
550 mSymbolsList->verticalHeader()->hide();
551
552 connect( mAddSymbolPushButton, &QPushButton::clicked, this, &QgsLineChartPlotWidget::mAddSymbolPushButton_clicked );
553 connect( mRemoveSymbolPushButton, &QPushButton::clicked, this, &QgsLineChartPlotWidget::mRemoveSymbolPushButton_clicked );
554
555 mSpinMinXAxis->setClearValue( 0 );
556 connect( mSpinMinXAxis, qOverload<double>( &QDoubleSpinBox::valueChanged ), this, [this]( double ) {
557 if ( mBlockChanges )
558 return;
559 emit widgetChanged();
560 } );
561
562 connect( mSpinMaxXAxis, qOverload<double>( &QDoubleSpinBox::valueChanged ), this, [this]( double ) {
563 if ( mBlockChanges )
564 return;
565 emit widgetChanged();
566 } );
567
568 mSpinMinYAxis->setClearValue( 0 );
569 connect( mSpinMinYAxis, qOverload<double>( &QDoubleSpinBox::valueChanged ), this, [this]( double ) {
570 if ( mBlockChanges )
571 return;
572 emit widgetChanged();
573 } );
574
575 mSpinMaxYAxis->setClearValue( 0 );
576 connect( mSpinMaxYAxis, qOverload<double>( &QDoubleSpinBox::valueChanged ), this, [this]( double ) {
577 if ( mBlockChanges )
578 return;
579 emit widgetChanged();
580 } );
581
582 mXAxisMajorLinesSymbolButton->setSymbolType( Qgis::SymbolType::Line );
583 connect( mXAxisMajorLinesSymbolButton, &QgsSymbolButton::changed, this, [this] {
584 if ( mBlockChanges )
585 return;
586 emit widgetChanged();
587 } );
588 mXAxisMajorLinesSymbolButton->setDefaultSymbol( QgsPlotDefaultSettings::axisGridMajorSymbol() );
589
590 mXAxisMinorLinesSymbolButton->setSymbolType( Qgis::SymbolType::Line );
591 connect( mXAxisMinorLinesSymbolButton, &QgsSymbolButton::changed, this, [this] {
592 if ( mBlockChanges )
593 return;
594 emit widgetChanged();
595 } );
596 mXAxisMinorLinesSymbolButton->setDefaultSymbol( QgsPlotDefaultSettings::axisGridMinorSymbol() );
597
598 connect( mXAxisMajorIntervalSpin, qOverload<double>( &QDoubleSpinBox::valueChanged ), this, [this]( double ) {
599 if ( mBlockChanges )
600 return;
601 emit widgetChanged();
602 } );
603
604 connect( mXAxisMinorIntervalSpin, qOverload<double>( &QDoubleSpinBox::valueChanged ), this, [this]( double ) {
605 if ( mBlockChanges )
606 return;
607 emit widgetChanged();
608 } );
609
610 connect( mXAxisLabelIntervalSpin, qOverload<double>( &QDoubleSpinBox::valueChanged ), this, [this]( double ) {
611 if ( mBlockChanges )
612 return;
613 emit widgetChanged();
614 } );
615
616 mYAxisMajorLinesSymbolButton->setSymbolType( Qgis::SymbolType::Line );
617 connect( mYAxisMajorLinesSymbolButton, &QgsSymbolButton::changed, this, [this] {
618 if ( mBlockChanges )
619 return;
620 emit widgetChanged();
621 } );
622 mYAxisMajorLinesSymbolButton->setDefaultSymbol( QgsPlotDefaultSettings::axisGridMajorSymbol() );
623
624 mYAxisMinorLinesSymbolButton->setSymbolType( Qgis::SymbolType::Line );
625 connect( mYAxisMinorLinesSymbolButton, &QgsSymbolButton::changed, this, [this] {
626 if ( mBlockChanges )
627 return;
628 emit widgetChanged();
629 } );
630 mYAxisMinorLinesSymbolButton->setDefaultSymbol( QgsPlotDefaultSettings::axisGridMinorSymbol() );
631
632 connect( mYAxisLabelIntervalSpin, qOverload<double>( &QDoubleSpinBox::valueChanged ), this, [this]( double ) {
633 if ( mBlockChanges )
634 return;
635 emit widgetChanged();
636 } );
637
638 connect( mYAxisMajorIntervalSpin, qOverload<double>( &QDoubleSpinBox::valueChanged ), this, [this]( double ) {
639 if ( mBlockChanges )
640 return;
641 emit widgetChanged();
642 } );
643
644 connect( mYAxisMinorIntervalSpin, qOverload<double>( &QDoubleSpinBox::valueChanged ), this, [this]( double ) {
645 if ( mBlockChanges )
646 return;
647 emit widgetChanged();
648 } );
649
650 mChartBackgroundSymbolButton->setSymbolType( Qgis::SymbolType::Fill );
651 connect( mChartBackgroundSymbolButton, &QgsSymbolButton::changed, this, [this] {
652 if ( mBlockChanges )
653 return;
654 emit widgetChanged();
655 } );
656 mChartBackgroundSymbolButton->setDefaultSymbol( QgsPlotDefaultSettings::chartBackgroundSymbol() );
657
658 mChartBorderSymbolButton->setSymbolType( Qgis::SymbolType::Fill );
659 connect( mChartBorderSymbolButton, &QgsSymbolButton::changed, this, [this] {
660 if ( mBlockChanges )
661 return;
662 emit widgetChanged();
663 } );
664 mChartBorderSymbolButton->setDefaultSymbol( QgsPlotDefaultSettings::chartBorderSymbol() );
665
666 connect( mXAxisLabelFormatButton, &QPushButton::clicked, this, [this] {
668 widget->setPanelTitle( tr( "X Axis Number Format" ) );
669 widget->setFormat( mXAxisNumericFormat.get() );
670 connect( widget, &QgsNumericFormatSelectorWidget::changed, this, [this, widget] {
671 mXAxisNumericFormat.reset( widget->format() );
672 emit widgetChanged();
673 } );
674 openPanel( widget );
675 } );
676
677 connect( mYAxisLabelFormatButton, &QPushButton::clicked, this, [this] {
679 widget->setPanelTitle( tr( "Y Axis Number Format" ) );
680 widget->setFormat( mYAxisNumericFormat.get() );
681 connect( widget, &QgsNumericFormatSelectorWidget::changed, this, [this, widget] {
682 mYAxisNumericFormat.reset( widget->format() );
683 emit widgetChanged();
684 } );
685 openPanel( widget );
686 } );
687
688 mXAxisLabelFontButton->setDialogTitle( tr( "X Axis Label Font" ) );
689 mYAxisLabelFontButton->setDialogTitle( tr( "Y Axis Label Font" ) );
690 mXAxisLabelFontButton->setMode( QgsFontButton::ModeTextRenderer );
691 mYAxisLabelFontButton->setMode( QgsFontButton::ModeTextRenderer );
692
693 connect( mXAxisLabelFontButton, &QgsFontButton::changed, this, [this] {
694 if ( mBlockChanges )
695 return;
696 emit widgetChanged();
697 } );
698
699 connect( mYAxisLabelFontButton, &QgsFontButton::changed, this, [this] {
700 if ( mBlockChanges )
701 return;
702 emit widgetChanged();
703 } );
704
705 mSpinLeftMargin->setClearValue( 0 );
706 connect( mSpinLeftMargin, qOverload<double>( &QDoubleSpinBox::valueChanged ), this, [this]( double ) {
707 if ( mBlockChanges )
708 return;
709 emit widgetChanged();
710 } );
711
712 mSpinRightMargin->setClearValue( 0 );
713 connect( mSpinRightMargin, qOverload<double>( &QDoubleSpinBox::valueChanged ), this, [this]( double ) {
714 if ( mBlockChanges )
715 return;
716 emit widgetChanged();
717 } );
718
719 mSpinTopMargin->setClearValue( 0 );
720 connect( mSpinTopMargin, qOverload<double>( &QDoubleSpinBox::valueChanged ), this, [this]( double ) {
721 if ( mBlockChanges )
722 return;
723 emit widgetChanged();
724 } );
725
726 mSpinBottomMargin->setClearValue( 0 );
727 connect( mSpinBottomMargin, qOverload<double>( &QDoubleSpinBox::valueChanged ), this, [this]( double ) {
728 if ( mBlockChanges )
729 return;
730 emit widgetChanged();
731 } );
732
733 mXAxisTypeCombo->addItem( tr( "Interval" ), QVariant::fromValue( Qgis::PlotAxisType::Interval ) );
734 mXAxisTypeCombo->addItem( tr( "Categorical" ), QVariant::fromValue( Qgis::PlotAxisType::Categorical ) );
735 connect( mXAxisTypeCombo, qOverload<int>( &QComboBox::currentIndexChanged ), this, [this]( int ) {
736 if ( mBlockChanges )
737 return;
738 emit widgetChanged();
739 } );
740
741 mXAxisLabelsCombo->addItem( tr( "None" ), QVariant::fromValue( Qgis::PlotAxisSuffixPlacement::NoLabels ) );
742 mXAxisLabelsCombo->addItem( tr( "Every Value" ), QVariant::fromValue( Qgis::PlotAxisSuffixPlacement::EveryLabel ) );
743 mXAxisLabelsCombo->addItem( tr( "First Value" ), QVariant::fromValue( Qgis::PlotAxisSuffixPlacement::FirstLabel ) );
744 mXAxisLabelsCombo->addItem( tr( "Last Value" ), QVariant::fromValue( Qgis::PlotAxisSuffixPlacement::LastLabel ) );
745 mXAxisLabelsCombo->addItem( tr( "First and Last Values" ), QVariant::fromValue( Qgis::PlotAxisSuffixPlacement::FirstAndLastLabels ) );
746 connect( mXAxisLabelsCombo, qOverload<int>( &QComboBox::currentIndexChanged ), this, [this]( int ) {
747 if ( mBlockChanges )
748 return;
749 emit widgetChanged();
750 } );
751
752 mXAxisMajorLinesSymbolButton->registerExpressionContextGenerator( this );
753 mXAxisMinorLinesSymbolButton->registerExpressionContextGenerator( this );
754 mXAxisLabelFontButton->registerExpressionContextGenerator( this );
755 mYAxisMajorLinesSymbolButton->registerExpressionContextGenerator( this );
756 mYAxisMinorLinesSymbolButton->registerExpressionContextGenerator( this );
757 mYAxisLabelFontButton->registerExpressionContextGenerator( this );
758 mChartBackgroundSymbolButton->registerExpressionContextGenerator( this );
759 mChartBorderSymbolButton->registerExpressionContextGenerator( this );
760
765
772
777}
778
779void QgsLineChartPlotWidget::mAddSymbolPushButton_clicked()
780{
781 const int row = mSymbolsList->rowCount();
782 mSymbolsList->insertRow( row );
783
784 QTableWidgetItem *item = new QTableWidgetItem();
785 item->setData( Qt::DisplayRole, tr( "Symbol" ) );
786 mSymbolsList->setItem( row, 0, item );
787
788 // Line
789 QgsSymbolButton *symbolButton = new QgsSymbolButton( this );
790 symbolButton->setSymbolType( Qgis::SymbolType::Line );
791 symbolButton->setShowNull( true );
793 symbolButton->registerExpressionContextGenerator( this );
794 connect( symbolButton, &QgsSymbolButton::changed, this, [this] {
795 if ( mBlockChanges )
796 return;
797 emit widgetChanged();
798 } );
799 mSymbolsList->setCellWidget( row, 1, symbolButton );
800
801 // Marker
802 symbolButton = new QgsSymbolButton( this );
803 symbolButton->setFixedSizeConstraints( false );
805 symbolButton->setShowNull( true );
807 symbolButton->registerExpressionContextGenerator( this );
808 connect( symbolButton, &QgsSymbolButton::changed, this, [this] {
809 if ( mBlockChanges )
810 return;
811 emit widgetChanged();
812 } );
813 mSymbolsList->setCellWidget( row, 2, symbolButton );
814
815 emit widgetChanged();
816}
817
818void QgsLineChartPlotWidget::mRemoveSymbolPushButton_clicked()
819{
820 QTableWidgetItem *item = mSymbolsList->currentItem();
821 if ( !item )
822 {
823 return;
824 }
825
826 mSymbolsList->removeRow( mSymbolsList->row( item ) );
827
828 emit widgetChanged();
829}
830
832{
833 QgsLineChartPlot *chartPlot = dynamic_cast<QgsLineChartPlot *>( plot );
834 if ( !chartPlot )
835 {
836 return;
837 }
838
839 mBlockChanges++;
840
841 mSymbolsList->clear();
842 const int symbolCount = std::max( chartPlot->markerSymbolCount(), chartPlot->lineSymbolCount() );
843 for ( int i = 0; i < symbolCount; i++ )
844 {
845 const int row = mSymbolsList->rowCount();
846 mSymbolsList->insertRow( row );
847
848 QTableWidgetItem *item = new QTableWidgetItem();
849 item->setData( Qt::DisplayRole, tr( "Symbol" ) );
850 mSymbolsList->setItem( row, 0, item );
851
852 // Line
853 QgsSymbolButton *symbolButton = new QgsSymbolButton( this );
854 symbolButton->setSymbolType( Qgis::SymbolType::Line );
855 symbolButton->setShowNull( true );
856 symbolButton->setSymbol( i < chartPlot->lineSymbolCount() ? chartPlot->lineSymbolAt( i )->clone() : nullptr );
857 symbolButton->registerExpressionContextGenerator( this );
858 connect( symbolButton, &QgsSymbolButton::changed, this, [this] {
859 if ( mBlockChanges )
860 return;
861 emit widgetChanged();
862 } );
863 mSymbolsList->setCellWidget( row, 1, symbolButton );
864
865 // Marker
866 symbolButton = new QgsSymbolButton( this );
867 symbolButton->setFixedSizeConstraints( false );
869 symbolButton->setShowNull( true );
870 symbolButton->setSymbol( i < chartPlot->markerSymbolCount() ? chartPlot->markerSymbolAt( i )->clone() : nullptr );
871 symbolButton->registerExpressionContextGenerator( this );
872 connect( symbolButton, &QgsSymbolButton::changed, this, [this] {
873 if ( mBlockChanges )
874 return;
875 emit widgetChanged();
876 } );
877 mSymbolsList->setCellWidget( row, 2, symbolButton );
878 }
879
880 mSpinMinXAxis->setValue( chartPlot->xMinimum() );
881 mSpinMaxXAxis->setValue( chartPlot->xMaximum() );
882 mSpinMinYAxis->setValue( chartPlot->yMinimum() );
883 mSpinMaxYAxis->setValue( chartPlot->yMaximum() );
884
885 if ( chartPlot->xAxis().gridMajorSymbol() )
886 mXAxisMajorLinesSymbolButton->setSymbol( chartPlot->xAxis().gridMajorSymbol()->clone() );
887 if ( chartPlot->xAxis().gridMinorSymbol() )
888 mXAxisMinorLinesSymbolButton->setSymbol( chartPlot->xAxis().gridMinorSymbol()->clone() );
889 if ( chartPlot->yAxis().gridMajorSymbol() )
890 mYAxisMajorLinesSymbolButton->setSymbol( chartPlot->yAxis().gridMajorSymbol()->clone() );
891 if ( chartPlot->yAxis().gridMinorSymbol() )
892 mYAxisMinorLinesSymbolButton->setSymbol( chartPlot->yAxis().gridMinorSymbol()->clone() );
893
894 mXAxisLabelFontButton->setTextFormat( chartPlot->xAxis().textFormat() );
895 mYAxisLabelFontButton->setTextFormat( chartPlot->yAxis().textFormat() );
896
897 mXAxisTypeCombo->setCurrentIndex( mXAxisTypeCombo->findData( QVariant::fromValue( chartPlot->xAxis().type() ) ) );
898 mXAxisLabelsCombo->setCurrentIndex( mXAxisLabelsCombo->findData( QVariant::fromValue( chartPlot->xAxis().labelSuffixPlacement() ) ) );
899
900 mXAxisMajorIntervalSpin->setValue( chartPlot->xAxis().gridIntervalMajor() );
901 mXAxisMinorIntervalSpin->setValue( chartPlot->xAxis().gridIntervalMinor() );
902 mXAxisLabelIntervalSpin->setValue( chartPlot->xAxis().labelInterval() );
903
904 mYAxisMajorIntervalSpin->setValue( chartPlot->yAxis().gridIntervalMajor() );
905 mYAxisMinorIntervalSpin->setValue( chartPlot->yAxis().gridIntervalMinor() );
906 mYAxisLabelIntervalSpin->setValue( chartPlot->yAxis().labelInterval() );
907
908 if ( chartPlot->chartBackgroundSymbol() )
909 mChartBackgroundSymbolButton->setSymbol( chartPlot->chartBackgroundSymbol()->clone() );
910 if ( chartPlot->chartBorderSymbol() )
911 mChartBorderSymbolButton->setSymbol( chartPlot->chartBorderSymbol()->clone() );
912
913 mSpinLeftMargin->setValue( chartPlot->margins().left() );
914 mSpinRightMargin->setValue( chartPlot->margins().right() );
915 mSpinTopMargin->setValue( chartPlot->margins().top() );
916 mSpinBottomMargin->setValue( chartPlot->margins().bottom() );
917
919
920 updateDataDefinedButton( mDDBtnMinXAxis );
921 updateDataDefinedButton( mDDBtnMaxXAxis );
922 updateDataDefinedButton( mDDBtnMinYAxis );
923 updateDataDefinedButton( mDDBtnMaxYAxis );
924
925 updateDataDefinedButton( mDDBtnXAxisMajorInterval );
926 updateDataDefinedButton( mDDBtnXAxisMinorInterval );
927 updateDataDefinedButton( mDDBtnXAxisLabelInterval );
928 updateDataDefinedButton( mDDBtnYAxisMajorInterval );
929 updateDataDefinedButton( mDDBtnYAxisMinorInterval );
930 updateDataDefinedButton( mDDBtnYAxisLabelInterval );
931
932 updateDataDefinedButton( mDDBtnLeftMargin );
933 updateDataDefinedButton( mDDBtnRightMargin );
934 updateDataDefinedButton( mDDBtnTopMargin );
935 updateDataDefinedButton( mDDBtnBottomMargin );
936
937 mBlockChanges--;
938}
939
940
942{
943 QgsPlot *plot = QgsApplication::plotRegistry()->createPlot( QStringLiteral( "line" ) );
944 QgsLineChartPlot *chartPlot = dynamic_cast<QgsLineChartPlot *>( plot );
945 if ( !chartPlot )
946 {
947 return nullptr;
948 }
949
950 const int rowCount = mSymbolsList->rowCount();
951 for ( int i = 0; i < rowCount; i++ )
952 {
953 QgsSymbolButton *symbolButton = dynamic_cast<QgsSymbolButton *>( mSymbolsList->cellWidget( i, 1 ) );
954 if ( symbolButton )
955 {
956 chartPlot->setLineSymbolAt( i, symbolButton->clonedSymbol<QgsLineSymbol>() );
957 }
958
959 symbolButton = dynamic_cast<QgsSymbolButton *>( mSymbolsList->cellWidget( i, 2 ) );
960 if ( symbolButton )
961 {
962 chartPlot->setMarkerSymbolAt( i, symbolButton->clonedSymbol<QgsMarkerSymbol>() );
963 }
964 }
965
966 chartPlot->setXMinimum( mSpinMinXAxis->value() );
967 chartPlot->setXMaximum( mSpinMaxXAxis->value() );
968 chartPlot->setYMinimum( mSpinMinYAxis->value() );
969 chartPlot->setYMaximum( mSpinMaxYAxis->value() );
970
971 chartPlot->xAxis().setGridMajorSymbol( mXAxisMajorLinesSymbolButton->clonedSymbol<QgsLineSymbol>() );
972 chartPlot->xAxis().setGridMinorSymbol( mXAxisMinorLinesSymbolButton->clonedSymbol<QgsLineSymbol>() );
973 chartPlot->yAxis().setGridMajorSymbol( mYAxisMajorLinesSymbolButton->clonedSymbol<QgsLineSymbol>() );
974 chartPlot->yAxis().setGridMinorSymbol( mYAxisMinorLinesSymbolButton->clonedSymbol<QgsLineSymbol>() );
975
976 chartPlot->xAxis().setTextFormat( mXAxisLabelFontButton->textFormat() );
977 chartPlot->yAxis().setTextFormat( mYAxisLabelFontButton->textFormat() );
978
979 chartPlot->xAxis().setType( mXAxisTypeCombo->currentData().value<Qgis::PlotAxisType>() );
980 chartPlot->xAxis().setLabelSuffixPlacement( mXAxisLabelsCombo->currentData().value<Qgis::PlotAxisSuffixPlacement>() );
981
982 chartPlot->xAxis().setGridIntervalMajor( mXAxisMajorIntervalSpin->value() );
983 chartPlot->xAxis().setGridIntervalMinor( mXAxisMinorIntervalSpin->value() );
984 chartPlot->xAxis().setLabelInterval( mXAxisLabelIntervalSpin->value() );
985
986 chartPlot->yAxis().setGridIntervalMajor( mYAxisMajorIntervalSpin->value() );
987 chartPlot->yAxis().setGridIntervalMinor( mYAxisMinorIntervalSpin->value() );
988 chartPlot->yAxis().setLabelInterval( mYAxisLabelIntervalSpin->value() );
989
990 chartPlot->setChartBackgroundSymbol( mChartBackgroundSymbolButton->clonedSymbol<QgsFillSymbol>() );
991 chartPlot->setChartBorderSymbol( mChartBorderSymbolButton->clonedSymbol<QgsFillSymbol>() );
992
993 QgsMargins margins;
994 margins.setLeft( mSpinLeftMargin->value() );
995 margins.setRight( mSpinRightMargin->value() );
996 margins.setTop( mSpinTopMargin->value() );
997 margins.setBottom( mSpinBottomMargin->value() );
998 chartPlot->setMargins( margins );
999
1001
1002 return plot;
1003}
1004
1005
1007 : QgsPlotWidget( parent )
1008{
1009 setupUi( this );
1010
1011 setPanelTitle( tr( "Pie Chart Plot Properties" ) );
1012
1013 mSymbolsList->setColumnCount( 3 );
1014 mSymbolsList->setSelectionBehavior( QAbstractItemView::SelectRows );
1015 mSymbolsList->setSelectionMode( QAbstractItemView::ExtendedSelection );
1016 mSymbolsList->setSortingEnabled( false );
1017 mSymbolsList->horizontalHeader()->setSectionResizeMode( 0, QHeaderView::Stretch );
1018 mSymbolsList->horizontalHeader()->setSectionResizeMode( 1, QHeaderView::Stretch );
1019 mSymbolsList->horizontalHeader()->setSectionResizeMode( 2, QHeaderView::Stretch );
1020 mSymbolsList->horizontalHeader()->hide();
1021 mSymbolsList->verticalHeader()->hide();
1022
1023 mLabelCombo->addItem( tr( "None" ), QVariant::fromValue( Qgis::PieChartLabelType::NoLabels ) );
1024 mLabelCombo->addItem( tr( "Category Labels" ), QVariant::fromValue( Qgis::PieChartLabelType::Categories ) );
1025 mLabelCombo->addItem( tr( "Value Labels" ), QVariant::fromValue( Qgis::PieChartLabelType::Values ) );
1026 connect( mLabelCombo, qOverload<int>( &QComboBox::currentIndexChanged ), this, [this]( int ) {
1027 if ( mBlockChanges )
1028 return;
1029 emit widgetChanged();
1030 } );
1031
1032 mLabelFontButton->setDialogTitle( tr( "Chart Label Font" ) );
1033 mLabelFontButton->setMode( QgsFontButton::ModeTextRenderer );
1034 connect( mLabelFontButton, &QgsFontButton::changed, this, [this] {
1035 if ( mBlockChanges )
1036 return;
1037 emit widgetChanged();
1038 } );
1039
1040 connect( mLabelFormatButton, &QPushButton::clicked, this, [this] {
1042 widget->setPanelTitle( tr( "Chart Number Format" ) );
1043 widget->setFormat( mNumericFormat.get() );
1044 connect( widget, &QgsNumericFormatSelectorWidget::changed, this, [this, widget] {
1045 mNumericFormat.reset( widget->format() );
1046 emit widgetChanged();
1047 } );
1048 openPanel( widget );
1049 } );
1050
1051 mSpinLeftMargin->setClearValue( 0 );
1052 connect( mSpinLeftMargin, qOverload<double>( &QDoubleSpinBox::valueChanged ), this, [this]( double ) {
1053 if ( mBlockChanges )
1054 return;
1055 emit widgetChanged();
1056 } );
1057
1058 mSpinRightMargin->setClearValue( 0 );
1059 connect( mSpinRightMargin, qOverload<double>( &QDoubleSpinBox::valueChanged ), this, [this]( double ) {
1060 if ( mBlockChanges )
1061 return;
1062 emit widgetChanged();
1063 } );
1064
1065 mSpinTopMargin->setClearValue( 0 );
1066 connect( mSpinTopMargin, qOverload<double>( &QDoubleSpinBox::valueChanged ), this, [this]( double ) {
1067 if ( mBlockChanges )
1068 return;
1069 emit widgetChanged();
1070 } );
1071
1072 mSpinBottomMargin->setClearValue( 0 );
1073 connect( mSpinBottomMargin, qOverload<double>( &QDoubleSpinBox::valueChanged ), this, [this]( double ) {
1074 if ( mBlockChanges )
1075 return;
1076 emit widgetChanged();
1077 } );
1078
1079 connect( mAddSymbolPushButton, &QPushButton::clicked, this, &QgsPieChartPlotWidget::mAddSymbolPushButton_clicked );
1080 connect( mRemoveSymbolPushButton, &QPushButton::clicked, this, &QgsPieChartPlotWidget::mRemoveSymbolPushButton_clicked );
1081
1082 mLabelFontButton->registerExpressionContextGenerator( this );
1083
1088}
1089
1090void QgsPieChartPlotWidget::mAddSymbolPushButton_clicked()
1091{
1092 const int row = mSymbolsList->rowCount();
1093 mSymbolsList->insertRow( row );
1094
1095 QTableWidgetItem *item = new QTableWidgetItem();
1096 item->setData( Qt::DisplayRole, tr( "Symbol" ) );
1097 mSymbolsList->setItem( row, 0, item );
1098
1099 // Fill
1100 QgsSymbolButton *symbolButton = new QgsSymbolButton( this );
1101 symbolButton->setSymbolType( Qgis::SymbolType::Fill );
1102 symbolButton->setShowNull( true );
1104 symbolButton->registerExpressionContextGenerator( this );
1105 connect( symbolButton, &QgsSymbolButton::changed, this, [this] {
1106 if ( mBlockChanges )
1107 return;
1108 emit widgetChanged();
1109 } );
1110 mSymbolsList->setCellWidget( row, 1, symbolButton );
1111
1112 // Color ramp
1113 QgsColorRampButton *colorRampButton = new QgsColorRampButton( this );
1114 colorRampButton->setShowNull( true );
1116 connect( colorRampButton, &QgsColorRampButton::colorRampChanged, this, [this] {
1117 if ( mBlockChanges )
1118 return;
1119 emit widgetChanged();
1120 } );
1121 mSymbolsList->setCellWidget( row, 2, colorRampButton );
1122
1123 emit widgetChanged();
1124}
1125
1126void QgsPieChartPlotWidget::mRemoveSymbolPushButton_clicked()
1127{
1128 QTableWidgetItem *item = mSymbolsList->currentItem();
1129 if ( !item )
1130 {
1131 return;
1132 }
1133
1134 mSymbolsList->removeRow( mSymbolsList->row( item ) );
1135
1136 emit widgetChanged();
1137}
1138
1140{
1141 QgsPieChartPlot *chartPlot = dynamic_cast<QgsPieChartPlot *>( plot );
1142 if ( !chartPlot )
1143 {
1144 return;
1145 }
1146
1147 mBlockChanges++;
1148
1149 mSymbolsList->clear();
1150 const int symbolCount = std::max( chartPlot->fillSymbolCount(), chartPlot->colorRampCount() );
1151 for ( int i = 0; i < symbolCount; i++ )
1152 {
1153 const int row = mSymbolsList->rowCount();
1154 mSymbolsList->insertRow( row );
1155
1156 QTableWidgetItem *item = new QTableWidgetItem();
1157 item->setData( Qt::DisplayRole, tr( "Symbol" ) );
1158 mSymbolsList->setItem( row, 0, item );
1159
1160 // Fill
1161 QgsSymbolButton *symbolButton = new QgsSymbolButton( this );
1162 symbolButton->setSymbolType( Qgis::SymbolType::Fill );
1163 symbolButton->setShowNull( true );
1164 symbolButton->setSymbol( i < chartPlot->fillSymbolCount() ? chartPlot->fillSymbolAt( i )->clone() : nullptr );
1165 symbolButton->registerExpressionContextGenerator( this );
1166 connect( symbolButton, &QgsSymbolButton::changed, this, [this] {
1167 if ( mBlockChanges )
1168 return;
1169 emit widgetChanged();
1170 } );
1171 mSymbolsList->setCellWidget( row, 1, symbolButton );
1172
1173 // Color ramp
1174 QgsColorRampButton *colorRampButton = new QgsColorRampButton( this );
1175 colorRampButton->setShowNull( true );
1176 colorRampButton->setColorRamp( i < chartPlot->colorRampCount() ? chartPlot->colorRampAt( i )->clone() : nullptr );
1177 connect( colorRampButton, &QgsColorRampButton::colorRampChanged, this, [this] {
1178 if ( mBlockChanges )
1179 return;
1180 emit widgetChanged();
1181 } );
1182 mSymbolsList->setCellWidget( row, 2, colorRampButton );
1183 }
1184
1185 mNumericFormat.reset( chartPlot->numericFormat()->clone() );
1186 mLabelFontButton->setTextFormat( chartPlot->textFormat() );
1187
1188 mLabelCombo->setCurrentIndex( mLabelCombo->findData( QVariant::fromValue( chartPlot->labelType() ) ) );
1189
1191
1192 updateDataDefinedButton( mDDBtnLeftMargin );
1193 updateDataDefinedButton( mDDBtnRightMargin );
1194 updateDataDefinedButton( mDDBtnTopMargin );
1195 updateDataDefinedButton( mDDBtnBottomMargin );
1196
1197 mBlockChanges--;
1198}
1199
1201{
1202 QgsPlot *plot = QgsApplication::plotRegistry()->createPlot( QStringLiteral( "pie" ) );
1203 QgsPieChartPlot *chartPlot = dynamic_cast<QgsPieChartPlot *>( plot );
1204 if ( !chartPlot )
1205 {
1206 return nullptr;
1207 }
1208
1209 const int rowCount = mSymbolsList->rowCount();
1210 for ( int i = 0; i < rowCount; i++ )
1211 {
1212 QgsSymbolButton *symbolButton = dynamic_cast<QgsSymbolButton *>( mSymbolsList->cellWidget( i, 1 ) );
1213 if ( symbolButton )
1214 {
1215 chartPlot->setFillSymbolAt( i, symbolButton->clonedSymbol<QgsFillSymbol>() );
1216 }
1217
1218 QgsColorRampButton *colorRampButton = dynamic_cast<QgsColorRampButton *>( mSymbolsList->cellWidget( i, 2 ) );
1219 if ( colorRampButton )
1220 {
1221 chartPlot->setColorRampAt( i, colorRampButton->colorRamp()->clone() );
1222 }
1223 }
1224
1225 chartPlot->setNumericFormat( mNumericFormat.get()->clone() );
1226 chartPlot->setTextFormat( mLabelFontButton->textFormat() );
1227 chartPlot->setLabelType( mLabelCombo->currentData().value<Qgis::PieChartLabelType>() );
1228
1229 QgsMargins margins;
1230 margins.setLeft( mSpinLeftMargin->value() );
1231 margins.setRight( mSpinRightMargin->value() );
1232 margins.setTop( mSpinTopMargin->value() );
1233 margins.setBottom( mSpinBottomMargin->value() );
1234 chartPlot->setMargins( margins );
1235
1237
1238 return plot;
1239}
PieChartLabelType
Pie chart label types.
Definition qgis.h:3346
@ Categories
Category labels are drawn.
Definition qgis.h:3348
@ Values
Value labels are drawn.
Definition qgis.h:3349
@ NoLabels
Labels are not drawn.
Definition qgis.h:3347
PlotAxisSuffixPlacement
Placement options for suffixes in the labels for axis of plots.
Definition qgis.h:3318
@ FirstAndLastLabels
Place suffix after the first and last label values only.
Definition qgis.h:3323
@ EveryLabel
Place suffix after every value label.
Definition qgis.h:3320
@ FirstLabel
Place suffix after the first label value only.
Definition qgis.h:3321
@ LastLabel
Place suffix after the last label value only.
Definition qgis.h:3322
@ NoLabels
Do not place suffixes.
Definition qgis.h:3319
PlotAxisType
Plots axis types.
Definition qgis.h:3334
@ Categorical
The axis represents categories.
Definition qgis.h:3336
@ Interval
The axis represents a range of values.
Definition qgis.h:3335
@ Marker
Marker symbol.
Definition qgis.h:611
@ Line
Line symbol.
Definition qgis.h:612
@ Fill
Fill symbol.
Definition qgis.h:613
const QgsMargins & margins() const
Returns the margins of the plot area (in millimeters).
Definition qgsplot.cpp:292
void setMargins(const QgsMargins &margins)
Sets the margins of the plot area (in millimeters).
Definition qgsplot.cpp:297
void setXMaximum(double maximum)
Sets the maximum value of the x axis.
Definition qgsplot.h:735
double yMaximum() const
Returns the maximum value of the y axis.
Definition qgsplot.h:742
void setYMinimum(double minimum)
Sets the minimum value of the y axis.
Definition qgsplot.h:721
double xMinimum() const
Returns the minimum value of the x axis.
Definition qgsplot.h:700
void setChartBackgroundSymbol(QgsFillSymbol *symbol)
Sets the fill symbol used to render the background of the chart.
Definition qgsplot.cpp:1037
QgsPlotAxis & yAxis()
Returns a reference to the plot's y axis.
Definition qgsplot.h:770
void setChartBorderSymbol(QgsFillSymbol *symbol)
Sets the symbol used to render the border of the chart.
Definition qgsplot.cpp:1047
QgsFillSymbol * chartBackgroundSymbol()
Returns the fill symbol used to render the background of the chart.
Definition qgsplot.cpp:1032
void setXMinimum(double minimum)
Sets the minimum value of the x axis.
Definition qgsplot.h:707
QgsPlotAxis & xAxis()
Returns a reference to the plot's x axis.
Definition qgsplot.h:756
QgsFillSymbol * chartBorderSymbol()
Returns the symbol used to render the border of the chart.
Definition qgsplot.cpp:1042
double yMinimum() const
Returns the minimum value of the y axis.
Definition qgsplot.h:714
void setYMaximum(double maximum)
Sets the maximum value of the y axis.
Definition qgsplot.h:749
double xMaximum() const
Returns the maximum value of the x axis.
Definition qgsplot.h:728
static QgsPlotRegistry * plotRegistry()
Returns the application's plot registry, used for plot types.
void setPlot(QgsPlot *plot) override
Sets the widget to match the settings of the plot.
QgsBarChartPlotWidget(QWidget *parent=nullptr)
Constructor for QgsBarChartPlotWidget.
QgsPlot * createPlot() override
Creates a plot defined by the current settings in the widget.
A simple bar chart class.
void setFillSymbolAt(int index, QgsFillSymbol *symbol)
Sets the fill symbol to use for the series with matching index.
int fillSymbolCount() const
Returns the fill symbols list count.
QgsFillSymbol * fillSymbolAt(int index) const
Returns the fill symbol for the series with matching index.
A cross platform button subclass for selecting color ramps.
void setColorRamp(QgsColorRamp *colorramp)
Sets the current color ramp for the button.
QgsColorRamp * colorRamp() const
Returns a copy of the current color ramp.
void setShowNull(bool showNull)
Sets whether a set to null (clear) option is shown in the button's drop-down menu.
void colorRampChanged()
Emitted whenever a new color ramp is set for the button.
virtual QgsColorRamp * clone() const =0
Creates a clone of the color ramp.
Abstract interface for generating an expression context.
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 appendScope(QgsExpressionContextScope *scope)
Appends a scope to the end of the context.
void setHighlightedVariables(const QStringList &variableNames)
Sets the list of variable names within the context intended to be highlighted to the user.
A fill symbol type, for rendering Polygon and MultiPolygon geometries.
QgsFillSymbol * clone() const override
Returns a deep copy of this symbol.
@ ModeTextRenderer
Configure font settings for use with QgsTextRenderer.
void changed()
Emitted when the widget's text format settings are changed.
QgsLineChartPlotWidget(QWidget *parent=nullptr)
Constructor for QgsLineChartPlotWidget.
void setPlot(QgsPlot *plot) override
Sets the widget to match the settings of the plot.
QgsPlot * createPlot() override
Creates a plot defined by the current settings in the widget.
A simple line chart class.
QgsMarkerSymbol * markerSymbolAt(int index) const
Returns the marker symbol for the series with matching index.
QgsLineSymbol * lineSymbolAt(int index) const
Returns the line symbol for the series with matching index.
void setLineSymbolAt(int index, QgsLineSymbol *symbol)
Sets the line symbol to use for the series with matching index.
int lineSymbolCount() const
Returns the line symbols list count.
void setMarkerSymbolAt(int index, QgsMarkerSymbol *symbol)
Sets the fill symbol to use for the series with matching index.
int markerSymbolCount() const
Returns the line symbols list count.
A line symbol type, for rendering LineString and MultiLineString geometries.
QgsLineSymbol * clone() const override
Returns a deep copy of this symbol.
Defines the four margins of a rectangle.
Definition qgsmargins.h:38
void setBottom(double bottom)
Sets the bottom margin to bottom.
Definition qgsmargins.h:114
double top() const
Returns the top margin.
Definition qgsmargins.h:78
void setLeft(double left)
Sets the left margin to left.
Definition qgsmargins.h:96
double right() const
Returns the right margin.
Definition qgsmargins.h:84
double bottom() const
Returns the bottom margin.
Definition qgsmargins.h:90
void setRight(double right)
Sets the right margin to right.
Definition qgsmargins.h:108
void setTop(double top)
Sets the top margin to top.
Definition qgsmargins.h:102
double left() const
Returns the left margin.
Definition qgsmargins.h:72
A marker symbol type, for rendering Point and MultiPoint geometries.
QgsMarkerSymbol * clone() const override
Returns a deep copy of this symbol.
A widget which allows choice of numeric formats and the properties of them.
QgsNumericFormat * format() const
Returns a new format object representing the settings currently configured in the widget.
void changed()
Emitted whenever the format configured55 in the widget is changed.
void setFormat(const QgsNumericFormat *format)
Sets the format to show in the widget.
virtual QgsNumericFormat * clone() const =0
Clones the format, returning a new object.
void openPanel(QgsPanelWidget *panel)
Open a panel or dialog depending on dock mode setting If dock mode is true this method will emit the ...
void widgetChanged()
Emitted when the widget state changes.
void setPanelTitle(const QString &panelTitle)
Set the title of the panel when shown in the interface.
QgsPlot * createPlot() override
Creates a plot defined by the current settings in the widget.
void setPlot(QgsPlot *plot) override
Sets the widget to match the settings of the plot.
QgsPieChartPlotWidget(QWidget *parent=nullptr)
Constructor for QgsLineChartPlotWidget.
A simple pie chart class.
void setTextFormat(const QgsTextFormat &format)
Sets the text format used for the pie chart labels.
QgsTextFormat textFormat() const
Returns the text format used for the pie chart labels.
QgsFillSymbol * fillSymbolAt(int index) const
Returns the fill symbol for the series with matching index.
void setNumericFormat(QgsNumericFormat *format)
Sets the numeric format used for the pie chart labels.
QgsColorRamp * colorRampAt(int index) const
Returns the color ramp for the series with matching index.
QgsNumericFormat * numericFormat() const
Returns the numeric format used for the pie chart labels.
void setLabelType(Qgis::PieChartLabelType type)
Sets the pie chart label type.
Qgis::PieChartLabelType labelType() const
Returns the pie chart label type.
int fillSymbolCount() const
Returns the fill symbols list count.
void setColorRampAt(int index, QgsColorRamp *ramp)
Sets the color ramp for the series with matching index.
void setFillSymbolAt(int index, QgsFillSymbol *symbol)
Sets the fill symbol to use for the series with matching index.
int colorRampCount() const
Returns the color ramps list count.
QgsLineSymbol * gridMinorSymbol()
Returns the line symbol used to render the minor lines in the axis grid.
Definition qgsplot.cpp:204
void setGridMajorSymbol(QgsLineSymbol *symbol)
Sets the symbol used to render the major lines in the axis grid.
Definition qgsplot.cpp:199
double gridIntervalMinor() const
Returns the interval of minor grid lines for the axis.
Definition qgsplot.h:389
double gridIntervalMajor() const
Returns the interval of major grid lines for the axis.
Definition qgsplot.h:403
void setType(Qgis::PlotAxisType type)
Sets the axis type.
Definition qgsplot.cpp:108
void setNumericFormat(QgsNumericFormat *format)
Sets the numeric format used for the axis labels.
Definition qgsplot.cpp:169
QgsTextFormat textFormat() const
Returns the text format used for the axis labels.
Definition qgsplot.cpp:214
void setGridIntervalMajor(double interval)
Sets the interval of major grid lines for the axis.
Definition qgsplot.h:410
void setLabelSuffixPlacement(Qgis::PlotAxisSuffixPlacement placement)
Sets the placement for the axis label suffixes.
Definition qgsplot.cpp:189
void setGridIntervalMinor(double interval)
Sets the interval of minor grid lines for the axis.
Definition qgsplot.h:396
void setLabelInterval(double interval)
Sets the interval of labels for the axis.
Definition qgsplot.h:424
Qgis::PlotAxisType type() const
Returns the axis type.
Definition qgsplot.cpp:103
double labelInterval() const
Returns the interval of labels for the axis.
Definition qgsplot.h:417
QgsLineSymbol * gridMajorSymbol()
Returns the line symbol used to render the major lines in the axis grid.
Definition qgsplot.cpp:194
void setTextFormat(const QgsTextFormat &format)
Sets the text format used for the axis labels.
Definition qgsplot.cpp:219
void setGridMinorSymbol(QgsLineSymbol *symbol)
Sets the symbol used to render the minor lines in the axis grid.
Definition qgsplot.cpp:209
QgsNumericFormat * numericFormat() const
Returns the numeric format used for the axis labels.
Definition qgsplot.cpp:164
Qgis::PlotAxisSuffixPlacement labelSuffixPlacement() const
Returns the placement for the axis label suffixes.
Definition qgsplot.cpp:184
static QgsFillSymbol * chartBorderSymbol()
Returns the default fill symbol to use for the chart area border.
Definition qgsplot.cpp:1190
static QgsColorRamp * pieChartColorRamp()
Returns the default color ramp to use for pie charts.
Definition qgsplot.cpp:1220
static QgsFillSymbol * barChartFillSymbol()
Returns the default fill symbol to use for bar charts.
Definition qgsplot.cpp:1208
static QgsLineSymbol * lineChartLineSymbol()
Returns the default line symbol to use for line charts.
Definition qgsplot.cpp:1202
static QgsLineSymbol * axisGridMinorSymbol()
Returns the default line symbol to use for axis minor grid lines.
Definition qgsplot.cpp:1177
static QgsFillSymbol * pieChartFillSymbol()
Returns the default fill symbol to use for pie charts.
Definition qgsplot.cpp:1214
static QgsMarkerSymbol * lineChartMarkerSymbol()
Returns the default marker symbol to use for line charts.
Definition qgsplot.cpp:1196
static QgsFillSymbol * chartBackgroundSymbol()
Returns the default fill symbol to use for the chart area background fill.
Definition qgsplot.cpp:1184
static QgsLineSymbol * axisGridMajorSymbol()
Returns the default line symbol to use for axis major grid lines.
Definition qgsplot.cpp:1170
QgsPlot * createPlot(const QString &type) const
Creates a new instance of a plot given the type.
void registerExpressionContextGenerator(QgsExpressionContextGenerator *generator)
Register an expression context generator class that will be used to retrieve an expression context fo...
QgsPropertyCollection mPropertyCollection
QgsExpressionContext createExpressionContext() const override
This method needs to be reimplemented in all classes which implement this interface and return an exp...
void updateDataDefinedButton(QgsPropertyOverrideButton *button)
Initiate a data-defined property button tied to a plot widget.
QgsPlotWidget(QWidget *parent=nullptr)
Constructor for QgsPlotWidget.
void initializeDataDefinedButton(QgsPropertyOverrideButton *button, QgsPlot::DataDefinedProperty key)
Initiate a data-defined property button tied to a plot widget.
Base class for plot/chart/graphs.
Definition qgsplot.h:48
void setDataDefinedProperties(const QgsPropertyCollection &collection)
Sets the plot's property collection, used for data defined overrides.
Definition qgsplot.h:151
static const QgsPropertiesDefinition & propertyDefinitions()
Returns the plot property definitions.
Definition qgsplot.cpp:84
QgsPropertyCollection & dataDefinedProperties()
Returns a reference to the plot's property collection, used for data defined overrides.
Definition qgsplot.h:136
DataDefinedProperty
Data defined properties for different plot types.
Definition qgsplot.h:96
@ YAxisMinorInterval
Minor grid line interval for Y axis.
Definition qgsplot.h:105
@ YAxisLabelInterval
Label interval for Y axis.
Definition qgsplot.h:106
@ XAxisMajorInterval
Major grid line interval for X axis.
Definition qgsplot.h:101
@ XAxisMaximum
Maximum X axis value.
Definition qgsplot.h:108
@ XAxisMinimum
Minimum X axis value.
Definition qgsplot.h:107
@ XAxisLabelInterval
Label interval for X axis.
Definition qgsplot.h:103
@ MarginBottom
Bottom margin.
Definition qgsplot.h:100
@ XAxisMinorInterval
Minor grid line interval for X axis.
Definition qgsplot.h:102
@ YAxisMajorInterval
Major grid line interval for Y axis.
Definition qgsplot.h:104
@ YAxisMaximum
Maximum Y axis value.
Definition qgsplot.h:110
@ MarginLeft
Left margin.
Definition qgsplot.h:97
@ MarginRight
Right margin.
Definition qgsplot.h:99
@ YAxisMinimum
Minimum Y axis value.
Definition qgsplot.h:109
void setProperty(int key, const QgsProperty &property)
Adds a property to the collection and takes ownership of it.
A button for controlling property overrides which may apply to a widget.
QgsProperty toProperty() const
Returns a QgsProperty object encapsulating the current state of the widget.
void changed()
Emitted when property definition changes.
void init(int propertyKey, const QgsProperty &property, const QgsPropertiesDefinition &definitions, const QgsVectorLayer *layer=nullptr, bool auxiliaryStorageEnabled=false)
Initialize a newly constructed property button (useful if button was included in a UI layout).
void registerExpressionContextGenerator(QgsExpressionContextGenerator *generator)
Register an expression context generator class that will be used to retrieve an expression context fo...
int propertyKey() const
Returns the property key linked to the button.
A button for creating and modifying QgsSymbol settings.
void setFixedSizeConstraints(bool fixedSizeConstraints)
Sets whether the widget adopts fixed size constraints.
void setSymbol(QgsSymbol *symbol)
Sets the symbol for the button.
void setSymbolType(Qgis::SymbolType type)
Sets the symbol type which the button requires.
void registerExpressionContextGenerator(QgsExpressionContextGenerator *generator)
Register an expression context generator class that will be used to retrieve an expression context fo...
void changed()
Emitted when the symbol's settings are changed.
void setShowNull(bool showNull)
Sets whether a set to null (clear) option is shown in the button's drop-down menu.
SymbolType * clonedSymbol()
Returns a clone of the current symbol (as the specified template type) defined by the button.
QgsSignalBlocker< Object > whileBlocking(Object *object)
Temporarily blocks signals from a QObject while calling a single method from the object.
Definition qgis.h:6511
Single variable definition for use within a QgsExpressionContextScope.