kchart

KDChartTableBase.cpp
1/*
2 KDChart - a multi-platform charting engine
3*/
4
5/****************************************************************************
6 ** Copyright (C) 2001-2003 Klarälvdalens Datakonsult AB. All rights reserved.
7 **
8 ** This file is part of the KDChart library.
9 **
10 ** This file may be distributed and/or modified under the terms of the
11 ** GNU General Public License version 2 as published by the Free Software
12 ** Foundation and appearing in the file LICENSE.GPL included in the
13 ** packaging of this file.
14 **
15 ** Licensees holding valid commercial KDChart licenses may use this file in
16 ** accordance with the KDChart Commercial License Agreement provided with
17 ** the Software.
18 **
19 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
20 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
21 **
22 ** See http://www.klaralvdalens-datakonsult.se/?page=products for
23 ** information about KDChart Commercial License Agreements.
24 **
25 ** Contact info@klaralvdalens-datakonsult.se if any conditions of this
26 ** licensing are not clear to you.
27 **
28 **********************************************************************/
29#include <math.h>
30#include <limits.h>
31#include <tqtable.h>
32
33#include <KDChartTableBase.h>
34
35
91
92
94 _usedRows = _rows;
95 _useUsedRows = true;
96}
98 return _useUsedRows ? _usedRows : rows();
99}
101 _usedCols = _cols;
102 _useUsedCols = true;
103}
105 return _useUsedCols ? _usedCols : cols();
106}
107
108
109bool KDChartTableDataBase::cellsHaveSeveralCoordinates(
110 TQVariant::Type* type2Ref ) const
111{
112 return cellsHaveSeveralCoordinates( 0, UINT_MAX, type2Ref );
113}
114
115
116bool KDChartTableDataBase::cellsHaveSeveralCoordinates(
117 uint row1,
118 uint row2,
119 TQVariant::Type* type2Ref ) const
120{
121 // return true if all wanted datasets have at least two coordinates
122 // stored in all of their cells - BUT only if these coordinates are
123 // of equal type for each of the cells
124 // note: We skip cells that are empty, this means having
125 // set neither coordinate #1 nor coordinate #2.
126 bool severalCoordinates = row1 < usedRows();
127 if( severalCoordinates ) {
128 severalCoordinates = false;
129 TQVariant::Type testType = TQVariant::Invalid;
130 const uint r2 = (UINT_MAX == row2)
131 ? usedRows()
132 : TQMIN( row2+1, usedRows() );
133 TQVariant value1;
134 TQVariant value2;
135 for ( uint row = row1; row < r2; ++row ){
136 for ( uint col = 0; col < usedCols(); ++col ){
137 if( cellCoords( row, col, value1, value2 ) ){
138 if( TQVariant::Invalid != value2.type() ){
139 if( (TQVariant::Invalid != testType) &&
140 (value2.type() != testType) ){
141 severalCoordinates = false;
142 break;
143 }else{
144 testType = value2.type();
145 if( NULL != type2Ref )
146 *type2Ref = testType;
147 severalCoordinates = true;
148 }
149 }else if( TQVariant::Invalid != value1.type() ){
150 severalCoordinates = false;
151 break;
152 }
153 }
154 }
155 }
156 }
157 return severalCoordinates;
158}
159
160
161TQVariant::Type KDChartTableDataBase::cellsValueType(
162 uint row1,
163 uint row2,
164 int coordinate ) const
165{
166 TQVariant::Type res = TQVariant::Invalid;
167 const uint r2 = (UINT_MAX == row2)
168 ? usedRows()
169 : TQMIN( row2+1, usedRows() );
170
171 TQVariant value;
172 for ( uint row = row1; row < r2; ++row )
173 for ( uint col = 0; col < usedCols(); ++col )
174 if( cellCoord( row, col, value, coordinate ) )
175 if( TQVariant::Invalid != value.type() )
176 res = value.type();
177 return res;
178}
179
180
181TQVariant::Type KDChartTableDataBase::cellsValueType(
182 int coordinate ) const
183{
184 return cellsValueType( 0, UINT_MAX, coordinate );
185}
186
187
188double KDChartTableDataBase::maxValue( int coordinate ) const
189{
190 double maxValue = 0.0;
191 bool bStart = true;
192 TQVariant value;
193 double dVal;
194 for ( uint row = 0; row < usedRows(); row++ ) {
195 for ( uint col = 0; col < usedCols(); col++ ) {
196 if( cellCoord( row, col, value, coordinate ) &&
197 TQVariant::Double == value.type() ) {
198 dVal = value.toDouble();
199 if( isNormalDouble( dVal ) ){
200 if ( bStart ) {
201 maxValue = dVal;
202 bStart = false;
203 } else
204 maxValue = TQMAX( maxValue, dVal );
205 }
206 }
207 }
208 }
209 return maxValue;
210}
211
212
213
214double KDChartTableDataBase::minValue( int coordinate, bool bOnlyGTZero ) const
215{
216 double minValue = 0.0;
217 bool bStart = true;
218 TQVariant value;
219 double dVal;
220 for ( uint row = 0; row < usedRows(); row++ ) {
221 for ( uint col = 0; col < usedCols(); col++ ) {
222 if( cellCoord( row, col, value, coordinate ) &&
223 TQVariant::Double == value.type() ) {
224 dVal = value.toDouble();
225 if( !bOnlyGTZero || 0.0 < dVal ){
226 if ( bStart ) {
227 minValue = dVal;
228 bStart = false;
229 }else{
230 minValue = TQMIN( minValue, dVal );
231 }
232 }
233 }
234 }
235 }
236 return minValue;
237}
238
239
240TQDateTime KDChartTableDataBase::maxDtValue( int coordinate ) const
241{
242 TQDateTime maxValue = TQDateTime( TQDate(1970,1,1) );
243 bool bStart = true;
244 TQVariant value;
245 TQDateTime dtVal;
246 for ( uint row = 0; row < usedRows(); row++ ) {
247 for ( uint col = 0; col < usedCols(); col++ ) {
248 if( cellCoord( row, col, value, coordinate ) &&
249 TQVariant::DateTime == value.type() ) {
250 dtVal = value.toDateTime();
251 if ( bStart ) {
252 maxValue = dtVal;
253 bStart = false;
254 } else
255 maxValue = TQMAX(maxValue, dtVal);
256 }
257 }
258 }
259 return maxValue;
260}
261
262
263
264TQDateTime KDChartTableDataBase::minDtValue( int coordinate ) const
265{
266 TQDateTime minValue = TQDateTime( TQDate(1970,1,1) );
267 bool bStart = true;
268 TQVariant value;
269 TQDateTime dtVal;
270 for ( uint row = 0; row < usedRows(); row++ ) {
271 for ( uint col = 0; col < usedCols(); col++ ) {
272 if( cellCoord( row, col, value, coordinate ) &&
273 TQVariant::DateTime == value.type() ) {
274 dtVal = value.toDateTime();
275 if ( bStart ) {
276 minValue = dtVal;
277 bStart = false;
278 } else
279 minValue = TQMIN(minValue, dtVal);
280 }
281 }
282 }
283 return minValue;
284}
285
286
287double KDChartTableDataBase::maxColSum( int coordinate ) const
288{
289 double maxValue = 0.0;
290 bool bStart = true;
291 for ( uint col = 0; col < usedCols(); col++ ) {
292 double colValue = colSum( col, coordinate );
293 if ( bStart ) {
294 maxValue = colValue;
295 bStart = false;
296 } else
297 maxValue = TQMAX( maxValue, colValue );
298 }
299 return maxValue;
300}
301
302
303double KDChartTableDataBase::minColSum( int coordinate ) const
304{
305 double minValue = 0.0;
306 bool bStart = true;
307 for ( uint col = 0; col < usedCols(); col++ ) {
308 double colValue = colSum( col, coordinate );
309 if ( bStart ) {
310 minValue = colValue;
311 bStart = false;
312 } else
313 minValue = TQMIN( minValue, colValue );
314 }
315
316 return minValue;
317}
318
319
320double KDChartTableDataBase::maxColSum( uint row, uint row2, int coordinate ) const
321{
322 double maxValue = 0;
323 bool bStart = true;
324 if ( 0 < usedRows() ) {
325 uint a = row;
326 uint z = row2;
327 if ( usedRows() <= a )
328 a = usedRows() - 1;
329 if ( usedRows() <= z )
330 z = usedRows() - 1;
331 for ( uint col = 0; col < usedCols(); col++ ) {
332 double valueValue = 0.0;
333 TQVariant value;
334 double dVal;
335 for ( uint row = a; row <= z; row++ ) {
336 if( cellCoord( row, col, value, coordinate ) &&
337 TQVariant::Double == value.type() ) {
338 dVal = value.toDouble();
339 if( isNormalDouble( dVal ) )
340 valueValue += dVal;
341 }
342 }
343 if ( bStart ) {
344 maxValue = valueValue;
345 bStart = false;
346 } else
347 maxValue = TQMAX( maxValue, valueValue );
348 }
349 }
350 return maxValue;
351}
352
353
354double KDChartTableDataBase::minColSum( uint row, uint row2, int coordinate ) const
355{
356 double minValue = 0;
357 bool bStart = true;
358 if ( 0 < usedRows() ) {
359 uint a = row;
360 uint z = row2;
361 if ( usedRows() <= a )
362 a = usedRows() - 1;
363 if ( usedRows() <= z )
364 z = usedRows() - 1;
365 for ( uint col = 0; col < usedCols(); col++ ) {
366 double valueValue = 0.0;
367 TQVariant value;
368 double dVal;
369 for ( uint row = a; row <= z; row++ ) {
370 if( cellCoord( row, col, value, coordinate ) &&
371 TQVariant::Double == value.type() ) {
372 dVal = value.toDouble();
373 if( isNormalDouble( dVal ) )
374 valueValue += dVal;
375 }
376 }
377 if ( bStart ) {
378 minValue = valueValue;
379 bStart = false;
380 } else
381 minValue = TQMIN( minValue, valueValue );
382 }
383 }
384 return minValue;
385}
386
387
388double KDChartTableDataBase::colSum( uint col, int coordinate ) const
389{
390 double sum = 0.0;
391 TQVariant value;
392 double dVal;
393 for ( uint row = 0; row < usedRows(); row++ ) {
394 if( cellCoord( row, col, value, coordinate ) &&
395 TQVariant::Double == value.type() ) {
396 dVal = value.toDouble();
397 if( isNormalDouble( dVal ) )
398 sum += dVal;
399 }
400 }
401
402 return sum;
403}
404
405
406double KDChartTableDataBase::colAbsSum( uint col, int coordinate ) const
407{
408 double sum = 0.0;
409 TQVariant value;
410 double dVal;
411 for ( uint row = 0; row < usedRows(); row++ ) {
412 if( cellCoord( row, col, value, coordinate ) &&
413 TQVariant::Double == value.type() ) {
414 dVal = value.toDouble();
415 if( isNormalDouble( dVal ) )
416 sum += fabs( dVal );
417 }
418 }
419
420 return sum;
421}
422
423
424double KDChartTableDataBase::maxRowSum( int coordinate ) const
425{
426 double maxValue = 0.0;
427 bool bStart = true;
428 for ( uint row = 0; row < usedRows(); row++ ) {
429 double rowValue = rowSum( row, coordinate );
430 if ( bStart ) {
431 maxValue = rowValue;
432 bStart = false;
433 } else
434 maxValue = TQMAX( maxValue, rowValue );
435 }
436 return maxValue;
437}
438
439
440double KDChartTableDataBase::minRowSum( int coordinate ) const
441{
442 double minValue = 0.0;
443 bool bStart = true;
444 for ( uint row = 0; row < usedRows(); row++ ) {
445 double rowValue = rowSum( row, coordinate );
446 if ( bStart ) {
447 minValue = rowValue;
448 bStart = false;
449 } else
450 minValue = TQMIN( minValue, rowValue );
451 }
452
453 return minValue;
454}
455
456
457double KDChartTableDataBase::rowSum( uint row, int coordinate ) const
458{
459 double sum = 0.0;
460 TQVariant value;
461 double dVal;
462 for ( uint col = 0; col < usedCols(); col++ ) {
463 if( cellCoord( row, col, value, coordinate ) &&
464 TQVariant::Double == value.type() ) {
465 dVal = value.toDouble();
466 if( isNormalDouble( dVal ) )
467 sum += dVal;
468 }
469 }
470 return sum;
471}
472
473
474double KDChartTableDataBase::rowAbsSum( uint row, int coordinate ) const
475{
476 double sum = 0.0;
477 TQVariant value;
478 double dVal;
479 for ( uint col = 0; col < usedCols(); col++ ) {
480 if( cellCoord( row, col, value, coordinate ) &&
481 TQVariant::Double == value.type() ) {
482 dVal = value.toDouble();
483 if( isNormalDouble( dVal ) )
484 sum += fabs( dVal );
485 }
486 }
487 return sum;
488}
489
490
491double KDChartTableDataBase::maxInColumn( uint col, int coordinate ) const
492{
493 double maxValue = 0.0;
494 bool bStart = true;
495 TQVariant value;
496 double dVal;
497 for ( uint row = 0; row < usedRows(); row++ ) {
498 if( cellCoord( row, col, value, coordinate ) &&
499 TQVariant::Double == value.type() ) {
500 dVal = value.toDouble();
501 if( isNormalDouble( dVal ) ){
502 if ( bStart ) {
503 maxValue = dVal;
504 bStart = false;
505 } else
506 maxValue = TQMAX( maxValue, dVal );
507 }
508 }
509 }
510
511 return maxValue;
512}
513
514
515double KDChartTableDataBase::minInColumn( uint col, int coordinate ) const
516{
517 double minValue = 0.0;
518 bool bStart = true;
519 TQVariant value;
520 double dVal;
521 for ( uint row = 0; row < usedRows(); row++ ) {
522 if( cellCoord( row, col, value, coordinate ) &&
523 TQVariant::Double == value.type() ) {
524 dVal = value.toDouble();
525 if( isNormalDouble( dVal ) ){
526 if ( bStart ) {
527 minValue = dVal;
528 bStart = false;
529 } else
530 minValue = TQMIN( minValue, dVal );
531 }
532 }
533 }
534
535 return minValue;
536}
537
538
539double KDChartTableDataBase::maxInRow( uint row, int coordinate ) const
540{
541 double maxValue = DBL_MIN;
542 bool bStart = true;
543 TQVariant value;
544 double dVal;
545 if ( UINT_MAX > row ) {
546 for ( uint col = 0; col < usedCols(); col++ ) {
547 if( cellCoord( row, col, value, coordinate ) &&
548 TQVariant::Double == value.type() ) {
549 dVal = value.toDouble();
550 if( isNormalDouble( dVal ) ){
551 if ( bStart ) {
552 maxValue = dVal;
553 bStart = false;
554 } else
555 maxValue = TQMAX( maxValue, dVal );
556 }
557 }
558 }
559 }
560 return maxValue;
561}
562
563
564double KDChartTableDataBase::minInRow( uint row, int coordinate ) const
565{
566 double minValue = DBL_MAX;
567 bool bStart = true;
568 TQVariant value;
569 double dVal;
570 if ( UINT_MAX > row ) {
571 for ( uint col = 0; col < usedCols(); col++ ) {
572 if( cellCoord( row, col, value, coordinate ) &&
573 TQVariant::Double == value.type() ) {
574 dVal = value.toDouble();
575 if( isNormalDouble( dVal ) ){
576 if ( bStart ) {
577 minValue = dVal;
578 bStart = false;
579 } else
580 minValue = TQMIN( minValue, dVal );
581 }
582 }
583 }
584 }
585 return minValue;
586}
587
588
589double KDChartTableDataBase::maxInRows( uint row, uint row2, int coordinate ) const
590{
591 double maxValue = 0.0;
592 bool bStart = true;
593 if ( 0 < usedRows() ) {
594 uint a = row;
595 uint z = row2;
596 // tqDebug("KDChartTableDataBase::maxInRows() (1) a: %u z: %u", a, z);
597 if ( usedRows() <= a )
598 a = usedRows() - 1;
599 if ( usedRows() <= z )
600 z = usedRows() - 1;
601 // tqDebug("KDChartTableDataBase::maxInRows() (2) a: %u z: %u", a, z);
602 for ( uint row = a; row <= z; ++row ) {
603 TQVariant value;
604 double dVal;
605 for ( uint col = 0; col < usedCols(); ++col ) {
606 if( cellCoord( row, col, value, coordinate ) &&
607 TQVariant::Double == value.type() ) {
608 dVal = value.toDouble();
609 if( isNormalDouble( dVal ) ){
610 if ( bStart ) {
611 maxValue = dVal;
612 bStart = false;
613 } else
614 maxValue = TQMAX( maxValue, dVal );
615 }
616 }
617 }
618 }
619 }
620 return maxValue;
621}
622
623
624double KDChartTableDataBase::minInRows( uint row, uint row2, int coordinate, bool bOnlyGTZero ) const
625{
626 double minValue = 0.0;
627 bool bStart = true;
628 if ( 0 < usedRows() ) {
629 uint a = row;
630 uint z = row2;
631 // tqDebug("KDChartTableDataBase::minInRows() (1) a: %u z: %u", a, z);
632 if ( usedRows() <= a )
633 a = usedRows() - 1;
634 if ( usedRows() <= z )
635 z = usedRows() - 1;
636 //tqDebug("KDChartTableDataBase::minInRows() (2) a: %u z: %u", a, z);
637 for ( uint row = a; row <= z; ++row ) {
638 TQVariant value;
639 double dVal;
640 for ( uint col = 0; col < usedCols(); ++col ) {
641 if( cellCoord( row, col, value, coordinate ) &&
642 TQVariant::Double == value.type() ) {
643 dVal = value.toDouble();
644 if( isNormalDouble( dVal ) ){
645 if( !bOnlyGTZero || 0.0 < dVal ){
646 if ( bStart ) {
647 minValue = dVal;
648 bStart = false;
649 }else{
650 minValue = TQMIN( minValue, dVal );
651 }
652 }
653 }
654 }
655 }
656 }
657 }
658 return minValue;
659}
660
661
662TQDateTime KDChartTableDataBase::maxDtInRows( uint row, uint row2,
663 int coordinate ) const
664{
665 TQDateTime maxValue = TQDateTime( TQDate(1970,1,1) );
666 bool bStart = true;
667 if ( 0 < usedRows() ) {
668 uint a = row;
669 uint z = row2;
670 if ( usedRows() <= a )
671 a = usedRows() - 1;
672 if ( usedRows() <= z )
673 z = usedRows() - 1;
674 for ( uint row = a; row <= z; ++row ) {
675 TQVariant value;
676 TQDateTime dtVal;
677 for ( uint col = 0; col < usedCols(); ++col ) {
678 if( cellCoord( row, col, value, coordinate ) &&
679 TQVariant::DateTime == value.type() ) {
680 dtVal = value.toDateTime();
681 if ( bStart ) {
682 maxValue = dtVal;
683 bStart = false;
684 } else
685 maxValue = TQMAX( maxValue, dtVal );
686 }
687 }
688 }
689 }
690 return maxValue;
691}
692
693
694TQDateTime KDChartTableDataBase::minDtInRows( uint row, uint row2,
695 int coordinate ) const
696{
697 TQDateTime minValue = TQDateTime( TQDate(1970,1,1) );
698 bool bStart = true;
699 if ( 0 < usedRows() ) {
700 uint a = row;
701 uint z = row2;
702 if ( usedRows() <= a )
703 a = usedRows() - 1;
704 if ( usedRows() <= z )
705 z = usedRows() - 1;
706 for ( uint row = a; row <= z; ++row ) {
707 TQVariant value;
708 TQDateTime dtVal;
709 for ( uint col = 0; col < usedCols(); ++col ) {
710 if( cellCoord( row, col, value, coordinate ) &&
711 TQVariant::DateTime == value.type() ) {
712 dtVal = value.toDateTime();
713 if ( bStart ) {
714 minValue = dtVal;
715 bStart = false;
716 } else
717 minValue = TQMIN( minValue, dtVal );
718 }
719 }
720 }
721 }
722 return minValue;
723}
724
725
726uint KDChartTableDataBase::lastPositiveCellInColumn( uint col, int coordinate ) const
727{
728 uint ret = UINT_MAX;
729 TQVariant value;
730 double dVal;
731 for ( uint row = 0; row < usedRows(); row++ ) {
732 if( cellCoord( row, col, value, coordinate ) &&
733 TQVariant::Double == value.type() ) {
734 dVal = value.toDouble();
735 if( isNormalDouble( dVal ) && 0 < dVal )
736 ret = row;
737 }
738 }
739 return ret;
740}
741
742
743void KDChartTableDataBase::importFromQTable( TQTable* table )
744{
745 if( table->numRows() > (int)rows() ||
746 table->numCols() > (int)cols() )
747 expand( table->numRows(), table->numCols() );
748 setUsedRows( table->numRows() );
749 setUsedCols( table->numCols() );
750 for( int row = 0; row < table->numRows(); row++ )
751 for( int col = 0; col < table->numCols(); col++ ) {
752 TQString cellContents = table->text( row, col );
753 if( !cellContents.isEmpty() ) {
754 // First try to parse a double
755 bool ok = false;
756 double value = cellContents.toDouble( &ok );
757 if( ok ) {
758 // there was a double
759 setCell( row, col, value );
760 } else {
761 // no double, but at least a string
762 setCell( row, col, cellContents );
763 }
764 } // don't do anything if no contents
765 }
766 setSorted( false );
767}
768
769
771{
772 _sorted = sorted;
773}
775{
776 return _sorted;
777}
778
779#include "KDChartTableBase.moc"
Provides a table class holding all data values that are to be used in a chart.
virtual uint usedCols() const
Returns the number of cols in the table that actually contain data.
virtual bool cellCoord(uint _row, uint _col, TQVariant &_value, int coordinate=1) const =0
Returns one of the coordinate data value(s) stored in a cell.
virtual bool isNormalDouble(double value) const
Returns true if the given value represents a normal double value.
virtual void setSorted(bool sorted)
Specified whether the table is sorted.
virtual void setUsedCols(uint _cols)
Sets the number of cols in the table that actually contain data.
virtual void expand(uint _rows, uint _cols)=0
Increases the number of rows (and/or columns, resp.) stored in this table.
virtual uint cols() const =0
Returns the number of cols in the table.
virtual uint rows() const =0
Returns the number of rows in the table.
virtual bool cellCoords(uint _row, uint _col, TQVariant &_value1, TQVariant &_value2) const
virtual uint usedRows() const
Returns the number of rows in the table that actually contain data.
virtual void setUsedRows(uint _rows)
Sets the number of rows in the table that actually contain data.
virtual bool sorted() const
Returns whether the table is sorted.
virtual void setCell(uint _row, uint _col, const TQVariant &_value1, const TQVariant &_value2=TQVariant())=0
Stores data in a cell.