File indexing completed on 2024-11-24 03:57:50
0001 /** 0002 * SPDX-FileCopyrightText: 2001-2015 Klaralvdalens Datakonsult AB. All rights reserved. 0003 * 0004 * This file is part of the KD Chart library. 0005 * 0006 * SPDX-License-Identifier: GPL-2.0-or-later 0007 */ 0008 0009 #include "mainwindow.h" 0010 0011 #include <KChartChart> 0012 #include <KChartLineDiagram> 0013 #include <KChartTextAttributes> 0014 #include <KChartDataValueAttributes> 0015 #include <KChartThreeDLineAttributes> 0016 0017 0018 #include <QTimer> 0019 #include <QMouseEvent> 0020 0021 using namespace KChart; 0022 0023 MainWindow::MainWindow( QWidget* parent ) : 0024 QWidget( parent ) 0025 { 0026 setupUi( this ); 0027 0028 m_curColumn = -1; 0029 m_curOpacity = 0; 0030 0031 QHBoxLayout* chartLayout = new QHBoxLayout( chartFrame ); 0032 m_chart = new Chart(); 0033 chartLayout->addWidget( m_chart ); 0034 0035 m_model.loadFromCSV( ":/data" ); 0036 0037 // Set up the diagram 0038 m_lines = new LineDiagram( this ); 0039 m_lines->setModel( &m_model ); 0040 0041 CartesianAxis* xAxis = new CartesianAxis( m_lines ); 0042 CartesianAxis* yAxis = new CartesianAxis( m_lines ); 0043 xAxis->setPosition( KChart::CartesianAxis::Bottom ); 0044 yAxis->setPosition( KChart::CartesianAxis::Left ); 0045 m_lines->addAxis( xAxis ); 0046 m_lines->addAxis( yAxis ); 0047 0048 m_chart->coordinatePlane()->replaceDiagram( m_lines ); 0049 m_chart->setGlobalLeading( 20, 20, 20, 20 ); 0050 // Instantiate the timer 0051 QTimer* timer = new QTimer( this ); 0052 connect( timer, SIGNAL(timeout()), this, SLOT(slot_timerFired()) ); 0053 timer->start( 30 ); 0054 0055 //Change the cursor to IBeamCursor inside Chart widget. 0056 m_chart->setCursor( Qt::IBeamCursor ); 0057 0058 //Install event filter on Chart to get the mouse position 0059 m_chart->installEventFilter( this ); 0060 } 0061 0062 /** 0063 Event filter for getting mouse position 0064 */ 0065 bool MainWindow::eventFilter(QObject* target, QEvent* event) 0066 { 0067 if (target == m_chart) { 0068 if (event->type() == QEvent::MouseMove) { 0069 // When the mouse is over a data-point then fetch that data-point 0070 // that belongs to the mouse-position and print the data value. 0071 QMouseEvent* mouseEvent = static_cast< QMouseEvent* >( event ); 0072 QPointF pos = mouseEvent->pos(); 0073 QModelIndex index = m_lines->indexAt(pos.toPoint()); 0074 if (index.isValid()) { 0075 qDebug() << "Mouse position" << pos << "Data:" << m_model.data(index).toDouble(); 0076 } 0077 } 0078 } 0079 return QWidget::eventFilter(target, event); 0080 } 0081 0082 void MainWindow::on_lineTypeCB_currentIndexChanged( const QString& text ) 0083 { 0084 if ( text == "Normal" ) 0085 m_lines->setType( LineDiagram::Normal ); 0086 else if ( text == "Stacked" ) 0087 m_lines->setType( LineDiagram::Stacked ); 0088 else if ( text == "Percent" ) 0089 m_lines->setType( LineDiagram::Percent ); 0090 else 0091 qWarning (" Does not match any type"); 0092 0093 m_chart->update(); 0094 } 0095 0096 void MainWindow::on_paintValuesCB_toggled( bool checked ) 0097 { 0098 const int colCount = m_lines->model()->columnCount( m_lines->rootIndex() ); 0099 for ( int iColumn = 0; iColumn<colCount; ++iColumn ) { 0100 DataValueAttributes a( m_lines->dataValueAttributes( iColumn ) ); 0101 QBrush brush( m_lines->brush( iColumn ) ); 0102 TextAttributes ta( a.textAttributes() ); 0103 ta.setRotation( 0 ); 0104 ta.setFont( QFont( "Comic", 10 ) ); 0105 ta.setPen( QPen( brush.color() ) ); 0106 0107 if ( checked ) 0108 ta.setVisible( true ); 0109 else 0110 ta.setVisible( false ); 0111 a.setVisible( true ); 0112 a.setTextAttributes( ta ); 0113 m_lines->setDataValueAttributes( iColumn, a ); 0114 } 0115 m_chart->update(); 0116 } 0117 0118 void MainWindow::on_centerDataPointsCB_toggled( bool checked ) 0119 { 0120 m_lines->setCenterDataPoints( checked ); 0121 m_chart->update(); 0122 } 0123 0124 void MainWindow::on_animateAreasCB_toggled( bool checked ) 0125 { 0126 if ( checked ) { 0127 highlightAreaCB->setCheckState( Qt::Unchecked ); 0128 m_curRow = 0; 0129 m_curColumn = 0; 0130 } else { 0131 m_curColumn = -1; 0132 } 0133 highlightAreaCB->setEnabled( !checked ); 0134 highlightAreaSB->setEnabled( !checked ); 0135 // un-highlight all previously highlighted columns 0136 const int rowCount = m_lines->model()->rowCount(); 0137 const int colCount = m_lines->model()->columnCount(); 0138 for ( int iColumn = 0; iColumn<colCount; ++iColumn ) { 0139 setHighlightArea( -1, iColumn, 127, false, false ); 0140 for ( int iRow = 0; iRow<rowCount; ++iRow ) 0141 setHighlightArea( iRow, iColumn, 127, false, false ); 0142 } 0143 m_chart->update(); 0144 m_curOpacity = 0; 0145 } 0146 0147 void MainWindow::slot_timerFired() 0148 { 0149 if ( m_curColumn < 0 ) { 0150 return; 0151 } 0152 m_curOpacity += 8; 0153 if ( m_curOpacity > 255 ) { 0154 setHighlightArea( m_curRow, m_curColumn, 127, false, false ); 0155 m_curOpacity = 5; 0156 ++m_curRow; 0157 if ( m_curRow >= m_lines->model()->rowCount( m_lines->rootIndex() ) ) { 0158 m_curRow = 0; 0159 ++m_curColumn; 0160 if ( m_curColumn >= m_lines->model()->columnCount( m_lines->rootIndex() ) ) 0161 m_curColumn = 0; 0162 } 0163 } 0164 setHighlightArea( m_curRow, m_curColumn, m_curOpacity, true, true ); 0165 } 0166 0167 void MainWindow::setHighlightArea( int row, int column, int opacity, 0168 bool checked, bool doUpdate ) 0169 { 0170 if ( row < 0 ) { 0171 // highlight a complete dataset 0172 LineAttributes la = m_lines->lineAttributes( column ); 0173 if ( checked ) { 0174 la.setDisplayArea( true ); 0175 la.setTransparency( opacity ); 0176 } else { 0177 la.setDisplayArea( false ); 0178 } 0179 m_lines->setLineAttributes( column, la ); 0180 } else { 0181 // highlight two segments only 0182 if ( row ) { 0183 QModelIndex cellIndex( m_lines->model()->index( row - 1, column, 0184 m_lines->rootIndex() ) ); 0185 if ( checked ) { 0186 LineAttributes la( m_lines->lineAttributes( cellIndex ) ); 0187 la.setDisplayArea( true ); 0188 la.setTransparency( 255 - opacity ); 0189 // set specific line attribute settings for this cell 0190 m_lines->setLineAttributes( cellIndex, la ); 0191 } else { 0192 // remove any cell-specific line attribute settings 0193 // from the indexed cell 0194 m_lines->resetLineAttributes( cellIndex ); 0195 } 0196 } 0197 if ( row < m_lines->model()->rowCount(m_lines->rootIndex() ) ) { 0198 QModelIndex cellIndex( m_lines->model()->index( row, column, m_lines->rootIndex() ) ); 0199 if ( checked ) { 0200 LineAttributes la( m_lines->lineAttributes( cellIndex ) ); 0201 la.setDisplayArea( true ); 0202 la.setTransparency( opacity ); 0203 // set specific line attribute settings for this cell 0204 m_lines->setLineAttributes( cellIndex, la ); 0205 } else { 0206 // remove any cell-specific line attribute settings 0207 // from the indexed cell 0208 m_lines->resetLineAttributes( cellIndex ); 0209 } 0210 } 0211 } 0212 if ( doUpdate ) 0213 m_chart->update(); 0214 } 0215 0216 void MainWindow::on_highlightAreaCB_toggled( bool checked ) 0217 { 0218 setHighlightArea( -1, highlightAreaSB->value(), 127, checked, true ); 0219 } 0220 0221 void MainWindow::on_highlightAreaSB_valueChanged( int i ) 0222 { 0223 Q_UNUSED( i ); 0224 if ( highlightAreaCB->isChecked() ) 0225 on_highlightAreaCB_toggled( true ); 0226 else 0227 on_highlightAreaCB_toggled( false ); 0228 } 0229 0230 void MainWindow::on_threeDModeCB_toggled( bool checked ) 0231 { 0232 ThreeDLineAttributes td( m_lines->threeDLineAttributes() ); 0233 td.setDepth( depthSB->value() ); 0234 if ( checked ) 0235 td.setEnabled( true ); 0236 else 0237 td.setEnabled( false ); 0238 0239 m_lines->setThreeDLineAttributes( td ); 0240 0241 m_chart->update(); 0242 } 0243 0244 void MainWindow::on_depthSB_valueChanged( int i ) 0245 { 0246 Q_UNUSED( i ); 0247 if ( threeDModeCB->isChecked() ) 0248 on_threeDModeCB_toggled( true ); 0249 } 0250 0251 void MainWindow::on_trackAreasCB_toggled( bool checked ) 0252 { 0253 setTrackedArea( trackAreasSB->value(), checked, true ); 0254 } 0255 0256 void MainWindow::on_trackAreasSB_valueChanged( int i ) 0257 { 0258 Q_UNUSED( i ); 0259 on_trackAreasCB_toggled( trackAreasCB->isChecked() ); 0260 } 0261 0262 void MainWindow::setTrackedArea( int column, bool checked, bool doUpdate ) 0263 { 0264 const int rowCount = m_model.rowCount( m_lines->rootIndex() ); 0265 const int columnCount = m_model.columnCount( m_lines->rootIndex() ); 0266 for ( int i = 0; i < rowCount; ++i ) { 0267 for ( int j = 0; j < columnCount; ++j ) { 0268 QModelIndex cellIndex( m_model.index( i, j, 0269 m_lines->rootIndex() ) ); 0270 ValueTrackerAttributes va( m_lines->valueTrackerAttributes( cellIndex ) ); 0271 va.setEnabled( checked && j == column ); 0272 va.setAreaBrush( QColor( 255, 255, 0, 50 ) ); 0273 va.setOrientations( Qt::Horizontal | Qt::Vertical ); 0274 QColor color = Qt::cyan; 0275 color.setAlphaF( 0.5 ); 0276 va.setAreaBrush( color ); 0277 m_lines->setValueTrackerAttributes( cellIndex, va ); 0278 } 0279 } 0280 if ( doUpdate ) 0281 m_chart->update(); 0282 } 0283 0284 void MainWindow::on_reverseHorizontalCB_toggled( bool checked ) 0285 { 0286 static_cast< KChart::CartesianCoordinatePlane* >( m_chart->coordinatePlane() ) 0287 ->setHorizontalRangeReversed( checked ); 0288 } 0289 0290 void MainWindow::on_reverseVerticalCB_toggled( bool checked ) 0291 { 0292 static_cast< KChart::CartesianCoordinatePlane* >( m_chart->coordinatePlane() ) 0293 ->setVerticalRangeReversed( checked ); 0294 }