00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "elementdataviewer.h"
00016
00017 #include <element.h>
00018 #include <kplotaxis.h>
00019 #include <kplotobject.h>
00020
00021 #include <klocale.h>
00022 #include <kdebug.h>
00023 #include <kactioncollection.h>
00024 #include <kstandardaction.h>
00025 #include <ktoolinvocation.h>
00026
00027
00028 #include <QKeyEvent>
00029 #include <QPen>
00030 #include <QTimer>
00031
00032 AxisData::AxisData( AXISTYPE type) : currentDataType(-1)
00033 {
00034 m_type = type;
00035 }
00036
00037 double AxisData::value( int element ) const
00038 {
00039 if ( ( element < 1 ) || ( element > dataList.count() ) )
00040 return 0.0;
00041
00042 return dataList[ element-1 ];
00043 }
00044
00045
00046 ElementDataViewer::ElementDataViewer( QWidget *parent )
00047 : KDialog( parent ),
00048 m_yData( new AxisData( AxisData::Y ) ) ,
00049 m_xData( new AxisData( AxisData::X ) )
00050 {
00051 setCaption( i18n( "Plot Data" ) );
00052 setButtons( Help | Close );
00053 setDefaultButton( Close );
00054
00055 KalziumDataObject *kdo = KalziumDataObject::instance();
00056
00057 ui.setupUi( mainWidget() );
00058
00059 m_timer = new QTimer( this );
00060 m_timer->setSingleShot( true );
00061
00062
00063 foreach (Element * e, kdo->ElementList) {
00064 names << e->dataAsString( ChemicalDataObject::name );
00065 symbols << e->dataAsString( ChemicalDataObject::symbol );
00066 }
00067
00068 m_actionCollection = new KActionCollection (this );
00069 KStandardAction::quit( this, SLOT( close() ), m_actionCollection );
00070
00071 connect( m_timer, SIGNAL( timeout() ),
00072 this, SLOT( drawPlot() ) );
00073 connect( ui.KCB_y, SIGNAL( activated(int) ),
00074 this, SLOT( rangeChanged()) );
00075 connect( ui.KCB_x, SIGNAL( activated(int) ),
00076 this, SLOT( rangeChanged()) );
00077 connect( ui.comboElementLabels, SIGNAL( activated( int ) ),
00078 this, SLOT( rangeChanged()) );
00079 connect( ui.from, SIGNAL( valueChanged( int ) ),
00080 this, SLOT( rangeChanged() ) );
00081 connect( ui.to, SIGNAL( valueChanged( int ) ),
00082 this, SLOT( rangeChanged() ) );
00083 connect( this, SIGNAL( helpClicked() ), this, SLOT( slotHelp() ) );
00084 drawPlot();
00085
00086 resize( 650, 500 );
00087 }
00088
00089 ElementDataViewer::~ElementDataViewer()
00090 {
00091 delete m_yData;
00092 delete m_xData;
00093 }
00094
00095 void ElementDataViewer::slotHelp()
00096 {
00097 KToolInvocation::invokeHelp( "plot_data", "kalzium" );
00098 }
00099
00100 void ElementDataViewer::rangeChanged()
00101 {
00102 m_timer->stop();
00103 m_timer->start( 500 );
00104 }
00105
00106
00107 void ElementDataViewer::setLimits()
00108 {
00109 kDebug() << "ElementDataViewer::setLimits()";
00110
00111 double x1 = 0.0, x2 = 0.0, y1 = 0.0, y2 = 0.0;
00112
00113 getMinMax(x1, x2, m_xData);
00114 getMinMax(y1, y2, m_yData);
00115
00116 kDebug() << x1 << " :: " << x2 << " ----- " << y1 << " :: " << y2;
00117
00118
00119 double dx = 0.05*(x2-x1);
00120 double dy = 0.05*(y2-y1);
00121 x1 -= dx;
00122 x2 += dx;
00123 y1 -= dy;
00124 y2 += dy;
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135 ui.plotwidget->setLimits( x1, x2, y1, y2 );
00136 }
00137
00138 void ElementDataViewer::getMinMax(double& min, double& max, AxisData * data)
00139 {
00140 int firstElement = ui.from->value();
00141 int lastElement = ui.to->value();
00142
00143 double minValue = data->value(firstElement);
00144 double maxValue = data->value(firstElement);
00145
00146 kDebug() << "Taking elements from " << firstElement << " to " << lastElement;
00147
00148 for ( int _currentVal = firstElement; _currentVal <= lastElement; _currentVal++ )
00149 {
00150 double v = data->value( _currentVal );
00151
00152 if( minValue > v )
00153 minValue = v;
00154 if( maxValue < v)
00155 maxValue = v;
00156 }
00157
00158 kDebug() << "The value are ]"<< minValue << " , " << maxValue << "[.";
00159
00160 min = minValue;
00161 max = maxValue;
00162 }
00163
00164 void ElementDataViewer::keyPressEvent(QKeyEvent *e)
00165 {
00166 switch ( e->key() )
00167 {
00168 case Qt::Key_Plus:
00169 case Qt::Key_Equal:
00170 slotZoomIn();
00171 break;
00172 case Qt::Key_Minus:
00173 case Qt::Key_Underscore:
00174 slotZoomOut();
00175 break;
00176 case Qt::Key_Escape:
00177 close();
00178 break;
00179 }
00180 }
00181
00182 void ElementDataViewer::slotZoomIn(){}
00183 void ElementDataViewer::slotZoomOut(){}
00184
00185 void ElementDataViewer::setupAxisData( AxisData * data )
00186 {
00187 DoubleList l;
00188
00189 int selectedData = 0;
00190 if ( data->type() == AxisData::X )
00191 selectedData = ui.KCB_x->currentIndex();
00192 else
00193 selectedData = ui.KCB_y->currentIndex();
00194
00195 data->currentDataType = selectedData;
00196
00197
00198 ChemicalDataObject::BlueObelisk kind = ChemicalDataObject::mass;
00199 QString caption = QString();
00200 switch(selectedData)
00201 {
00202 case AxisData::NUMBER:
00203 {
00204 kind = ChemicalDataObject::atomicNumber;
00205 caption = i18n( "Atomic Mass [u]" );
00206 break;
00207 }
00208 case AxisData::MASS:
00209 {
00210 kind = ChemicalDataObject::mass;
00211 caption = i18n( "Atomic Mass [u]" );
00212 break;
00213 }
00214 case AxisData::MEANWEIGHT:
00215 {
00216 kind = ChemicalDataObject::mass;
00217 caption = i18n( "Mean Mass [u]" );
00218 break;
00219 }
00220 case AxisData::DENSITY:
00221 {
00222 kind = ChemicalDataObject::density;
00223 caption = i18n( "Density" );
00224 break;
00225 }
00226 case AxisData::EN:
00227 {
00228 kind = ChemicalDataObject::electronegativityPauling;
00229 caption = i18n( "Electronegativity" );
00230 break;
00231 }
00232 case AxisData::MELTINGPOINT:
00233 {
00234 kind = ChemicalDataObject::meltingpoint;
00235 caption = i18n( "Melting Point [K]" );
00236 break;
00237 }
00238 case AxisData::BOILINGPOINT:
00239 {
00240 kind = ChemicalDataObject::boilingpoint;
00241 caption = i18n( "Boiling Point [K]" );
00242 break;
00243 }
00244 case AxisData::ATOMICRADIUS:
00245 {
00246 kind = ChemicalDataObject::radiusVDW;
00247 caption = i18n( "Atomic Radius [pm]" );
00248 break;
00249 }
00250 case AxisData::COVALENTRADIUS:
00251 {
00252 kind = ChemicalDataObject::radiusCovalent;
00253 caption = i18n( "Covalent Radius [pm]" );
00254 break;
00255 }
00256 }
00257 KalziumDataObject *kdo = KalziumDataObject::instance();
00258
00259 foreach (Element * element, kdo->ElementList) {
00260 double value = element->dataAsVariant( kind ).toDouble();
00261 l << ( value > 0.0 ? value : 0.0 );
00262 }
00263
00264 data->dataList.clear();
00265 data->dataList << l;
00266 data->kind = kind;
00267
00268 if ( data->type() == AxisData::X )
00269 {
00270 ui.plotwidget->axis(KPlotWidget::BottomAxis)->setLabel( caption );
00271 }
00272 else
00273 {
00274 ui.plotwidget->axis(KPlotWidget::LeftAxis)->setLabel( caption );
00275 ui.plotwidget->axis(KPlotWidget::RightAxis)->setLabel( caption );
00276 }
00277 }
00278
00279 void ElementDataViewer::drawPlot()
00280 {
00281
00282
00283
00284 ui.plotwidget->removeAllPlotObjects();
00285
00286
00287
00288
00289 if( m_yData->currentDataType != ui.KCB_y->currentIndex() )
00290 initData();
00291
00292 if( m_xData->currentDataType != ui.KCB_x->currentIndex() )
00293 initData();
00294
00295
00296
00297
00298 const int tmpfrom = ui.from->value();
00299 const int tmpto = ui.to->value();
00300 const int from = qMin( tmpfrom, tmpto );
00301 const int to = qMax( tmpfrom, tmpto );
00302
00303
00304
00305
00306 const int num = to-from+1;
00307
00308 setLimits();
00309
00310
00311
00312
00313 int whatShow = ui.comboElementLabels->currentIndex();
00314
00315 KPlotObject* dataPoint = 0;
00316
00317 double av_x = 0.0;
00318 double max_x = m_xData->value(from);
00319 double min_x = m_xData->value(from);
00320 double av_y = 0.0;
00321 double max_y = m_yData->value(from);
00322 double min_y = m_yData->value(from);
00323
00324
00325
00326
00327
00328 dataPoint = new KPlotObject(
00329 Qt::blue,
00330 KPlotObject::Points,
00331 4,
00332 KPlotObject::Star );
00333 dataPoint->setLabelPen( QPen( Qt::red ) );
00334
00335 for( int i = from; i < to+1 ; i++ )
00336 {
00337 double value_y = m_yData->value( i );
00338 double value_x = m_xData->value( i );
00339
00340 av_x += value_x;
00341 av_y += value_y;
00342
00343 if (value_x > max_x) {
00344 max_x = value_x;
00345 }
00346 if (value_y > max_y) {
00347 max_y = value_y;
00348 }
00349 if (value_x < min_x) {
00350 min_x = value_x;
00351 }
00352 if (value_y < min_y) {
00353 min_y = value_y;
00354 }
00355
00356 QString lbl = QString();
00357 if ( whatShow > 0 )
00358 {
00359 lbl = whatShow == 1 ? names[i-1] : symbols[i-1];
00360 }
00361
00362 dataPoint->addPoint( value_x, value_y, lbl );
00363
00364 }
00365
00366 ui.plotwidget->addPlotObject( dataPoint );
00367
00368
00369 ui.av_x->setText( QString::number( av_x / num ) );
00370 ui.minimum_x->setText( QString::number( min_x ) );
00371 ui.maximum_x->setText( QString::number( max_x ) );
00372 ui.av_y->setText( QString::number( av_y / num ) );
00373 ui.minimum_y->setText( QString::number( min_y ) );
00374 ui.maximum_y->setText( QString::number( max_y ) );
00375 }
00376
00377 void ElementDataViewer::initData()
00378 {
00379 setupAxisData(m_xData);
00380 setupAxisData(m_yData);
00381 }
00382
00383 #include "elementdataviewer.moc"