/*************************************************************************** copyright : (C) 2004, 2005 by Carsten Niehaus email : cniehaus@kde.org ***************************************************************************/ /*************************************************************************** * * * 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. * * * ***************************************************************************/ #include "elementdataviewer.h" #include "element.h" #include "plotsetupwidget.h" #include "plotwidget.h" #include "kalziumdataobject.h" #include #include #include #include #include #include //QT-Includes #include #include #include ElementDataViewer::ElementDataViewer( TQWidget *parent, const char* name ) : KDialogBase( KDialogBase::Plain, i18n( "Plot Data") , Help | User1 | Close, User1, parent, name ) { d = KalziumDataObject::instance(); yData = new AxisData(); TQHBoxLayout *layout = new TQHBoxLayout(plainPage(), 0, KDialog::spacingHint() ); m_pPlotSetupWidget = new PlotSetupWidget( plainPage(), "plotsetup" ); m_pPlotSetupWidget->from->setMaxValue( d->numberOfElements() - 1 ); m_pPlotSetupWidget->to->setMaxValue( d->numberOfElements() ); m_pPlotWidget = new PlotWidget( 0.0, 12.0 ,0.0 ,22.0, plainPage(), "plotwidget" ); m_pPlotWidget->setYAxisLabel(" "); m_pPlotWidget->setMinimumWidth( 200 ); m_pPlotWidget->resize( 400, m_pPlotWidget->height() ); layout->addWidget( m_pPlotSetupWidget ); layout->addWidget( m_pPlotWidget ); layout->setStretchFactor( m_pPlotSetupWidget, 0 ); layout->setStretchFactor( m_pPlotWidget, 1 ); // setup the list of names EList::iterator it = d->ElementList.begin(); const EList::iterator itEnd = d->ElementList.end(); for( ; it != itEnd ; ++it ) { names.append( (*it)->elname() ); } resize(500, 500); setButtonText( User1, i18n("&Plot") ); m_actionCollection = new TDEActionCollection(this); KStdAction::quit(TQT_TQOBJECT(this), TQT_SLOT(slotClose()), m_actionCollection); connect ( m_pPlotSetupWidget->KCB_y, TQT_SIGNAL( activated(int) ), this, TQT_SLOT( drawPlot()) ); connect ( m_pPlotSetupWidget->connectPoints, TQT_SIGNAL( toggled(bool) ), this, TQT_SLOT( drawPlot()) ); connect ( m_pPlotSetupWidget->showNames, TQT_SIGNAL( toggled(bool) ), this, TQT_SLOT( drawPlot()) ); // Draw the plot so that the user doesn't have to press the "Plot" // button to seee anything. drawPlot(); } void ElementDataViewer::slotHelp() { emit helpClicked(); if ( kapp ) kapp->invokeHelp ( "plot_data", "kalzium" ); } // Reimplement slotUser1 from KDialogBase void ElementDataViewer::slotUser1() { kdDebug() << "slotUser1" << endl; drawPlot(); } void ElementDataViewer::setLimits(int f, int t) { kdDebug() << "setLimits()" << endl; double minY = yData->value(f); double maxY = yData->value(f); for ( int _currentVal = f; _currentVal <= t; _currentVal++ ) { double v = yData->value( _currentVal ); if( minY > v ) minY = v; if( maxY < v) maxY = v; } // try to put a small padding to make the points on the axis visible double dx = ( t - f + 1 ) / 25 + 1.0; double dy = ( maxY - minY ) / 10.0; // in case that dy is quite small (for example, when plotting a single // point) if ( dy < 1e-7 ) dy = maxY / 10.0; m_pPlotWidget->setLimits( f - dx, t + dx, minY - dy, maxY + dy ); } void ElementDataViewer::paintEvent(TQPaintEvent*) { m_pPlotWidget->update(); } void ElementDataViewer::keyPressEvent(TQKeyEvent *e) { switch ( e->key() ) { case Key_Plus: case Key_Equal: slotZoomIn(); break; case Key_Minus: case Key_Underscore: slotZoomOut(); break; case Key_Escape: close(); break; } } void ElementDataViewer::slotZoomIn(){} void ElementDataViewer::slotZoomOut(){} void ElementDataViewer::setupAxisData() { DoubleList l; const int selectedData = m_pPlotSetupWidget->KCB_y->currentItem(); //this should be somewhere else, eg in its own method yData->m_currentDataType = selectedData; EList::iterator it = d->ElementList.begin(); const EList::iterator itEnd = d->ElementList.end(); switch(selectedData) { case AxisData::MASS: for( ; it != itEnd ; ++it ) { double value = (*it)->mass(); if( value > 0.0 ) l.append( value ); else l.append( 0.0 ); } m_pPlotWidget->setYAxisLabel(i18n("Atomic Mass [u]")); break; case AxisData::MEANWEIGHT: for( ; it != itEnd ; ++it ) { double value =(*it)->meanmass(); if( value > 0.0 ) l.append( value ); else l.append( 0.0 ); } m_pPlotWidget->setYAxisLabel(i18n("Mean Mass [u]")); break; case AxisData::DENSITY: for( ; it != itEnd ; ++it ) { double value =(*it)->density(); if( value > 0.0 ) l.append( value ); else l.append( 0.0 ); } m_pPlotWidget->setYAxisLabel(i18n("Density")); break; case AxisData::EN: for( ; it != itEnd ; ++it ) { double value = (*it)->electroneg(); if( value > 0.0 ) l.append( value ); else l.append( 0.0 ); } m_pPlotWidget->setYAxisLabel(i18n("Electronegativity")); break; case AxisData::MELTINGPOINT: for( ; it != itEnd ; ++it ) { double value = (*it)->melting(); if( value > 0.0 ) l.append( value ); else l.append( 0.0 ); } m_pPlotWidget->setYAxisLabel(i18n("Melting Point [K]")); break; case AxisData::BOILINGPOINT: for( ; it != itEnd ; ++it ) { double value = (*it)->boiling(); if( value > 0.0 ) l.append( value ); else l.append( 0.0 ); } m_pPlotWidget->setYAxisLabel(i18n("Boiling Point [K]")); break; case AxisData::ATOMICRADIUS: for( ; it != itEnd ; ++it ) { double value = (*it)->radius( Element::ATOMIC ); if( value > 0.0 ) l.append( value ); else l.append( 0.0 ); } m_pPlotWidget->setYAxisLabel(i18n("Atomic Radius [pm]")); break; case AxisData::COVALENTRADIUS: for( ; it != itEnd ; ++it ) { double value = (*it)->radius( Element::COVALENT ); if( value > 0.0 ) l.append( value ); else l.append( 0.0 ); } m_pPlotWidget->setYAxisLabel(i18n("Covalent Radius [pm]")); break; } yData->setDataList( l ); } void ElementDataViewer::drawPlot() { kdDebug() << "drawPlot()" << endl; /* * to be 100% safe delete the old list */ m_pPlotWidget->clearObjectList(); /* * spare the next step in case everything is already set and done */ if( yData->currentDataType() != m_pPlotSetupWidget->KCB_y->currentItem() ) initData(); /* * if the user selected the elements 20 to 30 the list-values are 19 to 29!!! */ const int from = m_pPlotSetupWidget->from->value(); const int to = m_pPlotSetupWidget->to->value(); /* * The number of elements. #20 to 30 are 30-20+1=11 Elements */ const int num = to-from+1; setLimits(from,to); /* * check if the users wants to see the elementnames or not */ bool showNames = m_pPlotSetupWidget->showNames->isChecked(); bool connectPoints = m_pPlotSetupWidget->connectPoints->isChecked(); if ( connectPoints ) m_pPlotWidget->setConnection( true ); else m_pPlotWidget->setConnection( false ); /* * reserve the memory for the KPlotObjects */ //TODO QT4 replace TQMemArray with TQVector TQMemArray dataPoint(num); TQMemArray dataPointLabel(num); int number = 0; double max = 0.0, av = 0.0; double min = yData->value( 1 ); /* * iterate for example from element 20 to 30 and contruct * the KPlotObjects */ for( int i = from; i < to+1 ; i++ ) { double v = yData->value( i ); if ( v >= 0.0 ) { if ( v < min ) min = v; if ( v > max ) max = v; av += v; dataPoint[number] = new KPlotObject( "whocares", "Blue", KPlotObject::POINTS, 4, KPlotObject::CIRCLE ); dataPoint[number]->addPoint( new DPoint( (double)i , v ) ); m_pPlotWidget->addObject( dataPoint[ number ] ); if (showNames) { dataPointLabel[number] = new KPlotObject( *(names.at(i-1)), "Red", KPlotObject::LABEL ); dataPointLabel[number]->addPoint( new DPoint( (double)i , yData->value( i ) ) ); m_pPlotWidget->addObject( dataPointLabel[number] ); } } number++; } //now set the values for the min, max and avarage value m_pPlotSetupWidget->aValue->setText( TQString::number( av/number ) ); m_pPlotSetupWidget->minValue->setText( TQString::number( min ) ); m_pPlotSetupWidget->maxValue->setText( TQString::number( max ) ); } void ElementDataViewer::initData() { setupAxisData(); } /////////////////////////////////////////////// AxisData::AxisData() {} #include "elementdataviewer.moc"