diff --git a/qtests/DrawIntoPainter/mainwindow.cpp b/qtests/DrawIntoPainter/mainwindow.cpp index 396aead..2ae68cd 100644 --- a/qtests/DrawIntoPainter/mainwindow.cpp +++ b/qtests/DrawIntoPainter/mainwindow.cpp @@ -1,424 +1,432 @@ /** * Copyright (C) 2001-2015 Klaralvdalens Datakonsult AB. All rights reserved. * * This file is part of the KD Chart library. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "mainwindow.h" #include "framewidget.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace KChart; static QPixmap drawIntoPixmap( const QSize& size, KChart::Chart* chart ) { QPixmap pix( size ); pix.fill( Qt::white ); QPainter painter( &pix ); chart->paint( &painter, QRect( 0, 0, size.width(), size.height() ) ); return pix; } // When set, this example uses FrameWidget which uses Chart::paint to paint itself. // When not set, this example uses a Chart widget directly. #define USE_FRAME_WIDGET 1 MainWindow::MainWindow( QWidget* parent ) : QWidget( parent ) { setupUi( this ); + connect( lineTypeCB, SIGNAL(currentIndexChanged(QString)), this, SLOT(setLineType(QString)) ); + connect( paintLegendCB, SIGNAL(toggled(bool)), this, SLOT(setLegendVisible(bool)) ); + connect( paintValuesCB, SIGNAL(toggled(bool)), this, SLOT(setValuesVisible(bool)) ); + connect( paintMarkersCB, SIGNAL(toggled(bool)), this, SLOT(setMarkersVisible(bool)) ); + connect( markersStyleCB, SIGNAL(currentIndexChanged(int)), this, SLOT(updateMarkers()) ); + connect( markersWidthSB, SIGNAL(valueChanged(int)), this, SLOT(updateMarkersHeight()) ); + connect( markersHeightSB, SIGNAL(valueChanged(int)), this, SLOT(updateMarkersWidth()) ); + connect( displayAreasCB, SIGNAL(toggled(bool)), this, SLOT(updateAreas(bool)) ); + connect( transparencySB, SIGNAL(valueChanged(int)), this, SLOT(updateAreasTransparency()) ); + connect( zoomFactorSB, SIGNAL(valueChanged(double)), this, SLOT(setZoomFactor(qreal)) ); + connect( hSBar, SIGNAL(valueChanged(int)), this, SLOT(setHPos(int)) ); + connect( vSBar, SIGNAL(valueChanged(int)), this, SLOT(setVPos(int)) ); + connect( savePB, SIGNAL(clicked()), this, SLOT(saveChart()) ); + QHBoxLayout* chartLayout = new QHBoxLayout( chartFrame ); #ifdef USE_FRAME_WIDGET FrameWidget* chartFrameWidget = new FrameWidget(); chartLayout->addWidget( chartFrameWidget ); #endif hSBar->setVisible( false ); vSBar->setVisible( false ); m_model.loadFromCSV( ":/empty" ); // Set up the diagram m_lines = new LineDiagram(); m_lines->setModel( &m_model ); CartesianAxis *xAxis = new CartesianAxis( m_lines ); CartesianAxis *yAxis = new CartesianAxis ( m_lines ); CartesianAxis *axisTop = new CartesianAxis ( m_lines ); CartesianAxis *axisRight = new CartesianAxis ( m_lines ); xAxis->setPosition ( KChart::CartesianAxis::Bottom ); yAxis->setPosition ( KChart::CartesianAxis::Left ); axisTop->setPosition( KChart::CartesianAxis::Top ); axisRight->setPosition( KChart::CartesianAxis::Right ); m_lines->addAxis( xAxis ); m_lines->addAxis( yAxis ); m_lines->addAxis( axisTop ); m_lines->addAxis( axisRight ); m_chart = new Chart(); //m_chart->setGlobalLeading(10,10,10,10); // by default there is no leading #ifdef USE_FRAME_WIDGET chartFrameWidget->setChart( m_chart ); // make sure, we re-draw after changing one of the chart's properties connect( m_chart, SIGNAL(propertiesChanged()), chartFrameWidget, SLOT(update()) ) ; #else chartLayout->addWidget( m_chart ); #endif m_chart->coordinatePlane()->replaceDiagram( m_lines ); for ( int iColumn = 0; iColumnmodel()->columnCount(); ++iColumn ) { QPen pen(m_lines->pen( iColumn )); pen.setWidth(4); m_lines->setPen( iColumn, pen ); } FrameAttributes faChart( m_chart->frameAttributes() ); faChart.setVisible( true ); faChart.setPen( QPen(QColor(0x60,0x60,0xb0), 8) ); m_chart->setFrameAttributes( faChart ); BackgroundAttributes baChart( m_chart->backgroundAttributes() ); baChart.setVisible( true ); baChart.setBrush( QColor(0xd0,0xd0,0xff) ); m_chart->setBackgroundAttributes( baChart ); // Set up the legend m_legend = new Legend( m_lines, m_chart ); m_legend->setPosition( Position::South ); m_legend->setAlignment( Qt::AlignRight ); m_legend->setShowLines( false ); m_legend->setTitleText( tr( "Legend" ) ); m_legend->setOrientation( Qt::Horizontal ); // setting the legend frame and background to the same color: const QColor legendColor(0xff,0xe0,0x80); FrameAttributes faLegend( m_legend->frameAttributes() ); faLegend.setVisible( true ); faLegend.setPen( QPen(legendColor, 1) ); m_legend->setFrameAttributes( faLegend ); BackgroundAttributes baLegend( m_legend->backgroundAttributes() ); baLegend.setVisible( true ); baLegend.setBrush( legendColor ); m_legend->setBackgroundAttributes( baLegend ); m_chart->addLegend( m_legend ); // for illustration we paint the same chart at different sizes: QSize size1 = QSize( 200, 200 ); QSize size2 = QSize( 800, 800 ); m_pix1 = drawIntoPixmap( size1, m_chart ); m_pix2 = drawIntoPixmap( size2, m_chart ); m_pix2 = m_pix2.scaled( size1 ); m_smallChart1 = new QLabel( this ); m_smallChart1->setWindowTitle( "200x200" ); m_smallChart1->setPixmap( m_pix1 ); m_smallChart1->setFixedSize( m_pix1.size() ); m_smallChart1->move( width() - m_pix1.width()*2, height()/2 - m_pix1.height()-5 ); m_smallChart1->show(); m_smallChart2 = new QLabel( this ); m_smallChart2->setWindowTitle( "800x800 scaled down" ); m_smallChart2->setPixmap( m_pix2 ); m_smallChart2->setFixedSize( m_pix2.size() ); m_smallChart2->move( width() - m_pix2.width()*2, height()/2 + 5 ); m_smallChart2->show(); faChart.setPen( QPen(QColor(0xb0,0xb0,0xff), 8) ); m_chart->setFrameAttributes( faChart ); // initialize attributes; this is necessary because we need to enable data value attributes before // any of them (e.g. only markers) can be displayed. but if we enable data value attributs, a default // data value text is included, even if we only wanted to set markers. so we enable DVA and then // individually disable the parts we don't want. - on_paintValuesCB_toggled( false ); - on_paintMarkersCB_toggled( false ); + setValuesVisible( false ); + setMarkersVisible( false ); } void MainWindow::updateData(QString data) { QTime t; t.start(); m_model.loadFromCSV( data ); qDebug("Time for loading data %s: %d ms", data.toLatin1().constData(), t.elapsed()); t.restart(); QSize size1 = QSize( 200, 200 ); QSize size2 = QSize( 800, 800 ); m_pix1 = drawIntoPixmap( size1, m_chart ); m_pix2 = drawIntoPixmap( size2, m_chart ); qDebug("Time for drawing pixmap %s: %d ms", data.toLatin1().constData(), t.elapsed()); t.restart(); m_lines->setModel( &m_model ); qDebug("Time for setting model %s: %d ms", data.toLatin1().constData(), t.elapsed()); t.restart(); m_smallChart1->setPixmap( m_pix1 ); m_smallChart2->setPixmap( m_pix2 ); m_smallChart1->show(); m_smallChart2->show(); qDebug("Time for setting pixmap %s: %d ms", data.toLatin1().constData(), t.elapsed()); t.restart(); } -void MainWindow::on_lineTypeCB_currentIndexChanged( const QString & text ) +void MainWindow::setLineType( const QString & text ) { if ( text == "Normal" ) m_lines->setType( LineDiagram::Normal ); else if ( text == "Stacked" ) m_lines->setType( LineDiagram::Stacked ); else if ( text == "Percent" ) m_lines->setType( LineDiagram::Percent ); else qWarning (" Does not match any type"); } -void MainWindow::on_paintLegendCB_toggled( bool checked ) +void MainWindow::setLegendVisible(bool visible ) { KChart::Legend* legend = m_chart->legend(); - if ( checked != ( legend != nullptr ) ) { - if ( checked ) + if ( visible != ( legend != nullptr ) ) { + if ( visible ) m_chart->addLegend( m_legend ); else m_chart->takeLegend( legend ); } } -void MainWindow::on_paintValuesCB_toggled( bool checked ) +void MainWindow::setValuesVisible(bool visible ) { const int colCount = m_lines->model()->columnCount(); for ( int iColumn = 0; iColumndataValueAttributes( iColumn ); a.setVisible( true ); TextAttributes ta = a.textAttributes(); ta.setRotation( 0 ); ta.setFont( QFont( "Comic", 10 ) ); ta.setPen( m_lines->brush( iColumn ).color() ); - ta.setVisible( checked ); + ta.setVisible( visible ); a.setTextAttributes( ta ); m_lines->setDataValueAttributes( iColumn, a); } } -void MainWindow::on_paintMarkersCB_toggled( bool checked ) +void MainWindow::setMarkersVisible( bool visible ) { - paintMarkers( checked, QSize() ); + paintMarkers( visible, QSize() ); } -void MainWindow::on_markersStyleCB_currentIndexChanged( const QString & text ) +void MainWindow::updateMarkers() { - Q_UNUSED( text ); - on_paintMarkersCB_toggled( paintMarkersCB->isChecked() ); + setMarkersVisible( paintMarkersCB->isChecked() ); } - -void MainWindow::on_markersWidthSB_valueChanged( int i ) +void MainWindow::updateMarkersHeight() { - Q_UNUSED( i ); markersHeightSB->setValue( markersWidthSB->value() ); - on_paintMarkersCB_toggled( paintMarkersCB->isChecked() ); + updateMarkers(); } -void MainWindow::on_markersHeightSB_valueChanged( int i ) +void MainWindow::updateMarkersWidth() { - Q_UNUSED( i ); markersWidthSB->setValue( markersHeightSB->value() ); - on_paintMarkersCB_toggled( paintMarkersCB->isChecked() ); + updateMarkers(); } - -void MainWindow::on_displayAreasCB_toggled( bool checked ) +void MainWindow::updateAreas( bool visible ) { const int colCount = m_lines->model()->columnCount(); for ( int iColumn = 0; iColumnlineAttributes( iColumn ) ); - la.setDisplayArea( checked ); - if ( checked ) + la.setDisplayArea( visible ); + if ( visible ) la.setTransparency( transparencySB->value() ); m_lines->setLineAttributes( iColumn, la ); } } -void MainWindow::on_transparencySB_valueChanged( int alpha ) +void MainWindow::updateAreasTransparency() { - Q_UNUSED( alpha ); if ( !displayAreasCB->isChecked() ) displayAreasCB->setChecked( true ); else - on_displayAreasCB_toggled( true ); + updateAreas( true ); } -void MainWindow::on_zoomFactorSB_valueChanged( qreal factor ) +void MainWindow::setZoomFactor( qreal factor ) { const bool isZoomedIn = factor > 1.0f; hSBar->setVisible( isZoomedIn ); vSBar->setVisible( isZoomedIn ); if ( !isZoomedIn ) { hSBar->setValue( 500 ); vSBar->setValue( 500 ); } m_chart->coordinatePlane()->setZoomFactorX( factor ); m_chart->coordinatePlane()->setZoomFactorY( factor ); } -void MainWindow::on_hSBar_valueChanged( int hPos ) +void MainWindow::setHPos( int hPos ) { m_chart->coordinatePlane()->setZoomCenter( QPointF(hPos/1000.0, vSBar->value()/1000.0) ); m_chart->update(); } -void MainWindow::on_vSBar_valueChanged( int vPos ) +void MainWindow::setVPos( int vPos ) { m_chart->coordinatePlane()->setZoomCenter( QPointF( hSBar->value()/1000.0, vPos/1000.0) ); } // since DataValue markers have no relative sizing mode we need to scale them for printing void MainWindow::paintMarkers( bool checked, const QSize& printSize ) { MarkerAttributes::MarkerStylesMap map; map.insert( 0, MarkerAttributes::MarkerSquare ); map.insert( 1, MarkerAttributes::MarkerCircle ); map.insert( 2, MarkerAttributes::MarkerRing ); map.insert( 3, MarkerAttributes::MarkerCross ); map.insert( 4, MarkerAttributes::MarkerDiamond ); // next: Specify column- / cell-specific attributes! const int colCount = m_lines->model()->columnCount(); for ( int iColumn = 0; iColumndataValueAttributes( iColumn ); dva.setVisible( true ); MarkerAttributes ma( dva.markerAttributes() ); switch ( markersStyleCB->currentIndex() ) { case 0: ma.setMarkerStyle( MarkerAttributes::MarkerSquare ); break; case 1: // Column-specific attributes ma.setMarkerStyle( map.value( iColumn ) ); break; case 2: ma.setMarkerStyle( MarkerAttributes::MarkerCircle ); break; case 3: ma.setMarkerStyle( MarkerAttributes::MarkerDiamond ); break; case 4: ma.setMarkerStyle( MarkerAttributes::Marker1Pixel ); break; case 5: ma.setMarkerStyle( MarkerAttributes::Marker4Pixels ); break; case 6: ma.setMarkerStyle( MarkerAttributes::MarkerRing ); break; case 7: ma.setMarkerStyle( MarkerAttributes::MarkerCross ); break; case 8: ma.setMarkerStyle( MarkerAttributes::MarkerFastCross ); break; default: Q_ASSERT( false ); } ma.setVisible( checked ); qreal factorWidth = printSize.isValid() ? ( printSize.width() / m_chart->rect().width() ) : 1.0f; qreal factorHeight = printSize.isValid() ? ( printSize.height() / m_chart->rect().height() ) : 1.0f; ma.setMarkerSize( QSize( markersWidthSB->value() * factorWidth, markersHeightSB->value() * factorHeight ) ); dva.setMarkerAttributes( ma ); m_lines->setDataValueAttributes( iColumn, dva ); // make a special one for certain values DataValueAttributes yellowAttributes( dva ); MarkerAttributes yellowMarker( yellowAttributes.markerAttributes() ); yellowMarker.setMarkerColor( Qt::yellow ); yellowAttributes.setMarkerAttributes( yellowMarker ); const int rowCount = m_lines->model()->rowCount(); for ( int j=0; j< rowCount; ++j ) { QModelIndex index = m_lines->model()->index( j, iColumn, QModelIndex() ); QBrush brush = m_lines->model()->headerData( iColumn, Qt::Vertical, DatasetBrushRole ).value(); qreal value = m_lines->model()->data( index ).toReal(); /* Set a specific color - marker for a specific value */ if ( value == 13 ) { m_lines->setDataValueAttributes( index, yellowAttributes ); } } } } -void MainWindow::on_savePB_clicked() +void MainWindow::saveChart() { qDebug() << "Painting into PNG"; QPixmap qpix(600,600); QPainter painter(&qpix); painter.setBrush(Qt::white); painter.fillRect( 0, 0, 600, 600, Qt::white); m_chart->paint( &painter, QRect(100, 100, 400, 400) ); painter.end(); qpix.save("kchart-demo.png", "PNG"); qDebug() << "Painting into PNG - done"; } void MainWindow::resizeEvent ( QResizeEvent * ) { m_smallChart1->move( width() - m_pix1.width()*2, height()/2 - m_pix1.height()-5 ); m_smallChart2->move( width() - m_pix2.width()*2, height()/2 + 5 ); } diff --git a/qtests/DrawIntoPainter/mainwindow.h b/qtests/DrawIntoPainter/mainwindow.h index ee0ba33..919b29d 100644 --- a/qtests/DrawIntoPainter/mainwindow.h +++ b/qtests/DrawIntoPainter/mainwindow.h @@ -1,81 +1,81 @@ /** * Copyright (C) 2001-2015 Klaralvdalens Datakonsult AB. All rights reserved. * * This file is part of the KD Chart library. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef MAINWINDOW_H #define MAINWINDOW_H #include "ui_mainwindow.h" #include #include namespace KChart { class Chart; class DatasetProxyModel; class LineDiagram; class Legend; } class QLabel; class MainWindow : public QWidget, private Ui::MainWindow { Q_OBJECT public: MainWindow( QWidget* parent = nullptr ); void updateData(QString data); protected: /** * Adjusts the two small charts when the window is resized. */ /* reimp */ void resizeEvent ( QResizeEvent * ) Q_DECL_OVERRIDE; private slots: - void on_lineTypeCB_currentIndexChanged( const QString & text ); - void on_paintLegendCB_toggled( bool checked ); - void on_paintValuesCB_toggled( bool checked ); - void on_paintMarkersCB_toggled( bool checked ); - void on_markersStyleCB_currentIndexChanged( const QString & text ); - void on_markersWidthSB_valueChanged( int i ); - void on_markersHeightSB_valueChanged( int i); - void on_displayAreasCB_toggled( bool checked ); - void on_transparencySB_valueChanged( int i ); - void on_zoomFactorSB_valueChanged( qreal factor ); - void on_hSBar_valueChanged( int value ); - void on_vSBar_valueChanged( int value ); - void on_savePB_clicked(); + void setLineType( const QString & text ); + void setLegendVisible( bool visible ); + void setValuesVisible( bool visible ); + void setMarkersVisible( bool visible ); + void updateMarkers(); + void updateMarkersHeight(); + void updateMarkersWidth(); + void updateAreas( bool visible ); + void updateAreasTransparency(); + void setZoomFactor( qreal factor ); + void setHPos( int value ); + void setVPos( int value ); + void saveChart(); private: void paintMarkers( bool checked, const QSize& printSize ); private: KChart::Chart* m_chart; TableModel m_model; KChart::DatasetProxyModel* m_datasetProxy; KChart::LineDiagram* m_lines; KChart::Legend* m_legend; QPixmap m_pix1, m_pix2; QLabel* m_smallChart1; QLabel* m_smallChart2; }; #endif /* MAINWINDOW_H */