Test change - can I push OK?
[kdeedu-porting.git] / kalzium / src / elementdataviewer.cpp
blobfa52e8824eafdd17afe208f884cde774fa2db165
1 /***************************************************************************
2 copyright : (C) 2004, 2005, 2006 by Carsten Niehaus
3 email : cniehaus@kde.org
4 ***************************************************************************/
6 /***************************************************************************
7 * *
8 * This program is free software; you can redistribute it and/or modify *
9 * it under the terms of the GNU General Public License as published by *
10 * the Free Software Foundation; either version 2 of the License, or *
11 * (at your option) any later version. *
12 * *
13 ***************************************************************************/
15 #include "elementdataviewer.h"
17 #include <element.h>
18 #include <kplotaxis.h>
19 #include <kplotobject.h>
21 #include <klocale.h>
22 #include <kdebug.h>
23 #include <kactioncollection.h>
24 #include <kstandardaction.h>
25 #include <ktoolinvocation.h>
27 //QT-Includes
28 #include <QKeyEvent>
29 #include <QPen>
30 #include <QTimer>
32 AxisData::AxisData( AXISTYPE type) : currentDataType(-1)
34 m_type = type;
37 double AxisData::value( int element ) const
39 if ( ( element < 1 ) || ( element > dataList.count() ) )
40 return 0.0;
42 return dataList[ element-1 ];
46 ElementDataViewer::ElementDataViewer( QWidget *parent )
47 : KDialog( parent ),
48 m_yData( new AxisData( AxisData::Y ) ) ,
49 m_xData( new AxisData( AxisData::X ) )
51 setCaption( i18n( "Plot Data" ) );
52 setButtons( Help | Close );
53 setDefaultButton( Close );
55 KalziumDataObject *kdo = KalziumDataObject::instance();
57 ui.setupUi( mainWidget() );
59 m_timer = new QTimer( this );
60 m_timer->setSingleShot( true );
62 // setup the list of names
63 foreach (Element * e, kdo->ElementList) {
64 names << e->dataAsString( ChemicalDataObject::name );
65 symbols << e->dataAsString( ChemicalDataObject::symbol );
68 m_actionCollection = new KActionCollection (this );
69 KStandardAction::quit( this, SLOT( close() ), m_actionCollection );
71 connect( m_timer, SIGNAL( timeout() ),
72 this, SLOT( drawPlot() ) );
73 connect( ui.KCB_y, SIGNAL( activated(int) ),
74 this, SLOT( rangeChanged()) );
75 connect( ui.KCB_x, SIGNAL( activated(int) ),
76 this, SLOT( rangeChanged()) );
77 connect( ui.comboElementLabels, SIGNAL( activated( int ) ),
78 this, SLOT( rangeChanged()) );
79 connect( ui.from, SIGNAL( valueChanged( int ) ),
80 this, SLOT( rangeChanged() ) );
81 connect( ui.to, SIGNAL( valueChanged( int ) ),
82 this, SLOT( rangeChanged() ) );
83 connect( this, SIGNAL( helpClicked() ), this, SLOT( slotHelp() ) );
84 drawPlot();
86 resize( 650, 500 );
89 ElementDataViewer::~ElementDataViewer()
91 delete m_yData;
92 delete m_xData;
95 void ElementDataViewer::slotHelp()
97 KToolInvocation::invokeHelp( "plot_data", "kalzium" );
100 void ElementDataViewer::rangeChanged()
102 m_timer->stop();
103 m_timer->start( 500 );
107 void ElementDataViewer::setLimits()
109 kDebug() << "ElementDataViewer::setLimits()";
111 double x1 = 0.0, x2 = 0.0, y1 = 0.0, y2 = 0.0;
113 getMinMax(x1, x2, m_xData);
114 getMinMax(y1, y2, m_yData);
116 kDebug() << x1 << " :: " << x2 << " ----- " << y1 << " :: " << y2;
118 //JH: add some padding to show all points
119 double dx = 0.05*(x2-x1);
120 double dy = 0.05*(y2-y1);
121 x1 -= dx;
122 x2 += dx;
123 y1 -= dy;
124 y2 += dy;
126 //X // try to put a small padding to make the points on the axis visible
127 //X double dx = ( to - from + 1 ) / 25 + 1.0;
128 //X double dy = ( maxY - minY ) / 10.0;
129 //X // in case that dy is quite small (for example, when plotting a single
130 //X // point)
131 //X if ( dy < 1e-7 )
132 //X dy = maxY / 10.0;
133 //X ui.plotwidget->setLimits( from - dx, to + dx, minY - dy, maxY + dy );
135 ui.plotwidget->setLimits( x1, x2, y1, y2 );
138 void ElementDataViewer::getMinMax(double& min, double& max, AxisData * data)
140 int firstElement = ui.from->value();
141 int lastElement = ui.to->value();
143 double minValue = data->value(firstElement);
144 double maxValue = data->value(firstElement);
146 kDebug() << "Taking elements from " << firstElement << " to " << lastElement;
148 for ( int _currentVal = firstElement; _currentVal <= lastElement; _currentVal++ )
149 {//go over all selected elements
150 double v = data->value( _currentVal );
152 if( minValue > v )
153 minValue = v;
154 if( maxValue < v)
155 maxValue = v;
158 kDebug() << "The value are ]"<< minValue << " , " << maxValue << "[.";
160 min = minValue;
161 max = maxValue;
164 void ElementDataViewer::keyPressEvent(QKeyEvent *e)
166 switch ( e->key() )
168 case Qt::Key_Plus:
169 case Qt::Key_Equal:
170 slotZoomIn();
171 break;
172 case Qt::Key_Minus:
173 case Qt::Key_Underscore:
174 slotZoomOut();
175 break;
176 case Qt::Key_Escape:
177 close();
178 break;
182 void ElementDataViewer::slotZoomIn(){}
183 void ElementDataViewer::slotZoomOut(){}
185 void ElementDataViewer::setupAxisData( AxisData * data )
187 DoubleList l;
189 int selectedData = 0;
190 if ( data->type() == AxisData::X )
191 selectedData = ui.KCB_x->currentIndex();
192 else
193 selectedData = ui.KCB_y->currentIndex();
195 data->currentDataType = selectedData;
197 // init to _something_
198 ChemicalDataObject::BlueObelisk kind = ChemicalDataObject::mass;
199 QString caption = QString();
200 switch(selectedData)
202 case AxisData::NUMBER:
204 kind = ChemicalDataObject::atomicNumber;
205 caption = i18n( "Atomic Mass [u]" );
206 break;
208 case AxisData::MASS:
210 kind = ChemicalDataObject::mass;
211 caption = i18n( "Atomic Mass [u]" );
212 break;
214 case AxisData::EN:
216 kind = ChemicalDataObject::electronegativityPauling;
217 caption = i18n( "Electronegativity" );
218 break;
220 case AxisData::MELTINGPOINT:
222 kind = ChemicalDataObject::meltingpoint;
223 caption = i18n( "Melting Point [K]" );
224 break;
226 case AxisData::BOILINGPOINT:
228 kind = ChemicalDataObject::boilingpoint;
229 caption = i18n( "Boiling Point [K]" );
230 break;
232 case AxisData::ATOMICRADIUS:
234 kind = ChemicalDataObject::radiusVDW;
235 caption = i18n( "Atomic Radius [pm]" );
236 break;
238 case AxisData::COVALENTRADIUS:
240 kind = ChemicalDataObject::radiusCovalent;
241 caption = i18n( "Covalent Radius [pm]" );
242 break;
245 KalziumDataObject *kdo = KalziumDataObject::instance();
247 foreach (Element * element, kdo->ElementList) {
248 double value = element->dataAsVariant( kind ).toDouble();
249 l << ( value > 0.0 ? value : 0.0 );
252 data->dataList.clear();
253 data->dataList << l;
254 data->kind = kind;
256 if ( data->type() == AxisData::X )
258 ui.plotwidget->axis(KPlotWidget::BottomAxis)->setLabel( caption );
260 else
262 ui.plotwidget->axis(KPlotWidget::LeftAxis)->setLabel( caption );
263 ui.plotwidget->axis(KPlotWidget::RightAxis)->setLabel( caption );
267 void ElementDataViewer::drawPlot()
270 * to be 100% safe delete the old list
272 ui.plotwidget->removeAllPlotObjects();
275 * spare the next step in case everything is already set and done
277 if( m_yData->currentDataType != ui.KCB_y->currentIndex() )
278 initData();
280 if( m_xData->currentDataType != ui.KCB_x->currentIndex() )
281 initData();
284 * if the user selected the elements 20 to 30 the list-values are 19 to 29!!!
286 const int tmpfrom = ui.from->value();
287 const int tmpto = ui.to->value();
288 const int from = qMin( tmpfrom, tmpto );
289 const int to = qMax( tmpfrom, tmpto );
292 * The number of elements. #20 to 30 are 30-20+1=11 Elements
294 const int num = to-from+1;
296 setLimits();
299 * check if the users wants to see the elementnames or not
301 int whatShow = ui.comboElementLabels->currentIndex();
303 KPlotObject* dataPoint = 0;
305 double av_x = 0.0;
306 double max_x = m_xData->value(from);
307 double min_x = m_xData->value(from);
308 double av_y = 0.0;
309 double max_y = m_yData->value(from);
310 double min_y = m_yData->value(from);
313 * iterate for example from element 20 to 30 and contruct
314 * the KPlotObjects
316 dataPoint = new KPlotObject(
317 Qt::blue,
318 KPlotObject::Points,
320 KPlotObject::Star );
321 dataPoint->setLabelPen( QPen( Qt::red ) );
323 for( int i = from; i < to+1 ; i++ )
325 double value_y = m_yData->value( i );
326 double value_x = m_xData->value( i );
328 av_x += value_x;
329 av_y += value_y;
331 if (value_x > max_x) {
332 max_x = value_x;
334 if (value_y > max_y) {
335 max_y = value_y;
337 if (value_x < min_x) {
338 min_x = value_x;
340 if (value_y < min_y) {
341 min_y = value_y;
344 QString lbl = QString();
345 if ( whatShow > 0 )//The users wants to see the labels
347 lbl = whatShow == 1 ? names[i-1] : symbols[i-1];
350 dataPoint->addPoint( value_x, value_y, lbl );
354 ui.plotwidget->addPlotObject( dataPoint );
356 //now set the values for the min, max and avarage value
357 ui.av_x->setText( QString::number( av_x / num ) );
358 ui.minimum_x->setText( QString::number( min_x ) );
359 ui.maximum_x->setText( QString::number( max_x ) );
360 ui.av_y->setText( QString::number( av_y / num ) );
361 ui.minimum_y->setText( QString::number( min_y ) );
362 ui.maximum_y->setText( QString::number( max_y ) );
365 void ElementDataViewer::initData()
367 setupAxisData(m_xData);
368 setupAxisData(m_yData);
371 #include "elementdataviewer.moc"