author | drw <drw> | 2002-11-02 21:45:56 (UTC) |
---|---|---|
committer | drw <drw> | 2002-11-02 21:45:56 (UTC) |
commit | 2dc81c48428222533e5479947d9ad318e464bafa (patch) (unidiff) | |
tree | 2e3570d18f3574c49ffc8aaf287bac4822ff3a11 /noncore/apps | |
parent | 5e1893923a9ddf1e2bd3e8f9c0dd264d86b8d98d (diff) | |
download | opie-2dc81c48428222533e5479947d9ad318e464bafa.zip opie-2dc81c48428222533e5479947d9ad318e464bafa.tar.gz opie-2dc81c48428222533e5479947d9ad318e464bafa.tar.bz2 |
Implementing charting...
-rw-r--r-- | noncore/apps/checkbook/checkbook.cpp | 122 | ||||
-rw-r--r-- | noncore/apps/checkbook/checkbook.h | 11 | ||||
-rw-r--r-- | noncore/apps/checkbook/graph.cpp | 85 | ||||
-rw-r--r-- | noncore/apps/checkbook/graph.h | 9 | ||||
-rw-r--r-- | noncore/apps/checkbook/graphinfo.cpp | 45 | ||||
-rw-r--r-- | noncore/apps/checkbook/graphinfo.h | 8 |
6 files changed, 241 insertions, 39 deletions
diff --git a/noncore/apps/checkbook/checkbook.cpp b/noncore/apps/checkbook/checkbook.cpp index 20b42b5..77c1f57 100644 --- a/noncore/apps/checkbook/checkbook.cpp +++ b/noncore/apps/checkbook/checkbook.cpp | |||
@@ -234,2 +234,4 @@ QWidget *Checkbook::initCharts() | |||
234 | { | 234 | { |
235 | graphInfo = 0x0; | ||
236 | |||
235 | QWidget *control = new QWidget( mainWidget ); | 237 | QWidget *control = new QWidget( mainWidget ); |
@@ -240,23 +242,18 @@ QWidget *Checkbook::initCharts() | |||
240 | 242 | ||
241 | /* | 243 | graphWidget = new Graph( control ); |
242 | QLabel *label = new QLabel( control ); | 244 | QWhatsThis::add( graphWidget, tr( "Select the desired chart below and then click on the Draw button." ) ); |
243 | label->setText( tr( "Graph type:" ) ); | 245 | layout->addMultiCellWidget( graphWidget, 0, 0, 0, 2 ); |
244 | layout->addWidget( label, 0, 0 ); | 246 | |
245 | graphList = new QComboBox( control ); | 247 | graphList = new QComboBox( control ); |
246 | graphList->insertItem( tr( "By category" ) ); | 248 | QWhatsThis::add( graphList, tr( "Click here to select the desired chart type." ) ); |
247 | graphList->insertItem( tr( "..." ) ); | 249 | graphList->insertItem( tr( "Account balance" ) ); |
248 | graphList->insertItem( tr( "..." ) ); | 250 | graphList->insertItem( tr( "Withdrawals by category" ) ); |
249 | layout->addWidget( graphList, 0, 1 ); | 251 | graphList->insertItem( tr( "Deposits by category" ) ); |
250 | */ | ||
251 | 252 | ||
252 | GraphInfo* info = new GraphInfo( GraphInfo::BarChart, 0x0, tr( "Graph Title" ), | 253 | layout->addMultiCellWidget( graphList, 1, 1, 0, 1 ); |
253 | tr( "X-Axis" ), tr( "Y-Axis" ) ); | ||
254 | graphWidget = new Graph( control, info ); | ||
255 | QWhatsThis::add( graphWidget, tr( "Charting is not implemented yet." ) ); | ||
256 | layout->addMultiCellWidget( graphWidget, 0, 0, 0, 1 ); | ||
257 | 254 | ||
258 | QPushButton *btn = new QPushButton( Resource::loadPixmap( "checkbook/drawbtn" ), tr( "Draw" ), control ); | 255 | QPushButton *btn = new QPushButton( Resource::loadPixmap( "checkbook/drawbtn" ), tr( "Draw" ), control ); |
259 | QWhatsThis::add( btn, tr( "Click here to draw the chart." ) ); | 256 | QWhatsThis::add( btn, tr( "Click here to draw the selected chart." ) ); |
260 | connect( btn, SIGNAL( clicked() ), this, SLOT( slotDrawGraph() ) ); | 257 | connect( btn, SIGNAL( clicked() ), this, SLOT( slotDrawGraph() ) ); |
261 | layout->addWidget( btn, 1, 1 ); | 258 | layout->addWidget( btn, 1, 2 ); |
262 | 259 | ||
@@ -369,8 +366,6 @@ void Checkbook::accept() | |||
369 | // Save transactions | 366 | // Save transactions |
370 | TranInfo *tran = transactions.first(); | ||
371 | int i = 1; | 367 | int i = 1; |
372 | while ( tran ) | 368 | for ( TranInfo *tran = transactions.first(); tran; tran = transactions.next() ) |
373 | { | 369 | { |
374 | tran->write( config, i ); | 370 | tran->write( config, i ); |
375 | tran = transactions.next(); | ||
376 | i++; | 371 | i++; |
@@ -511,2 +506,91 @@ void Checkbook::slotDrawGraph() | |||
511 | { | 506 | { |
507 | if ( graphInfo ) | ||
508 | { | ||
509 | delete graphInfo; | ||
510 | } | ||
511 | |||
512 | switch ( graphList->currentItem() ) | ||
513 | { | ||
514 | case 0 : drawBalanceChart(); | ||
515 | break; | ||
516 | case 1 : drawCategoryChart( TRUE ); | ||
517 | break; | ||
518 | case 2 : drawCategoryChart( FALSE ); | ||
519 | break; | ||
520 | }; | ||
521 | |||
522 | graphWidget->setGraphInfo( graphInfo ); | ||
523 | graphWidget->drawGraph( TRUE ); | ||
524 | } | ||
525 | |||
526 | void Checkbook::drawBalanceChart() | ||
527 | { | ||
528 | DataPointList *list = new DataPointList(); | ||
529 | |||
530 | float balance = startBalance; | ||
531 | float amount; | ||
532 | QString label; | ||
533 | int i = 0; | ||
534 | int count = transactions.count(); | ||
535 | |||
536 | for ( TranInfo *tran = transactions.first(); tran; tran = transactions.next() ) | ||
537 | { | ||
538 | i++; | ||
539 | balance -= tran->fee(); | ||
540 | amount = tran->amount(); | ||
541 | if ( tran->withdrawal() ) | ||
542 | { | ||
543 | amount *= -1; | ||
544 | } | ||
545 | balance += amount; | ||
546 | if ( i == 1 || i == count / 2 || i == count ) | ||
547 | { | ||
548 | label = tran->datestr(); | ||
549 | } | ||
550 | else | ||
551 | { | ||
552 | label = ""; | ||
553 | } | ||
554 | list->append( new DataPointInfo( label, balance ) ); | ||
555 | } | ||
556 | |||
557 | graphInfo = new GraphInfo( GraphInfo::BarChart, list ); | ||
558 | } | ||
559 | |||
560 | void Checkbook::drawCategoryChart( bool withdrawals ) | ||
561 | { | ||
562 | DataPointList *list = new DataPointList(); | ||
563 | |||
564 | TranInfo *tran = transactions.first(); | ||
565 | if ( tran->withdrawal() == withdrawals ) | ||
566 | { | ||
567 | list->append( new DataPointInfo( tran->category(), tran->amount() ) ); | ||
568 | } | ||
569 | tran = transactions.next(); | ||
570 | |||
571 | DataPointInfo *cat; | ||
572 | for ( ; tran; tran = transactions.next() ) | ||
573 | { | ||
574 | if ( tran->withdrawal() == withdrawals ) | ||
575 | { | ||
576 | // Find category in list | ||
577 | for ( cat = list->first(); cat; cat = list->next() ) | ||
578 | { | ||
579 | if ( cat->label() == tran->category() ) | ||
580 | { | ||
581 | break; | ||
582 | } | ||
583 | } | ||
584 | if ( cat && cat->label() == tran->category() ) | ||
585 | { // Found category, add to transaction to category total | ||
586 | cat->addToValue( tran->amount() ); | ||
587 | } | ||
588 | else | ||
589 | { // Didn't find category, add category to list | ||
590 | list->append( new DataPointInfo( tran->category(), tran->amount() ) ); | ||
591 | } | ||
592 | } | ||
593 | } | ||
594 | |||
595 | graphInfo = new GraphInfo( GraphInfo::PieChart, list ); | ||
512 | } | 596 | } |
diff --git a/noncore/apps/checkbook/checkbook.h b/noncore/apps/checkbook/checkbook.h index 01f1115..287788a 100644 --- a/noncore/apps/checkbook/checkbook.h +++ b/noncore/apps/checkbook/checkbook.h | |||
@@ -38,2 +38,3 @@ class OTabWidget; | |||
38 | class Graph; | 38 | class Graph; |
39 | class GraphInfo; | ||
39 | class QComboBox; | 40 | class QComboBox; |
@@ -86,5 +87,9 @@ class Checkbook : public QDialog | |||
86 | // Charts tab | 87 | // Charts tab |
87 | QWidget *initCharts(); | 88 | QWidget *initCharts(); |
88 | //QComboBox *graphList; | 89 | GraphInfo *graphInfo; |
89 | Graph *graphWidget; | 90 | QComboBox *graphList; |
91 | Graph *graphWidget; | ||
92 | |||
93 | void drawBalanceChart(); | ||
94 | void drawCategoryChart( bool = TRUE ); | ||
90 | 95 | ||
diff --git a/noncore/apps/checkbook/graph.cpp b/noncore/apps/checkbook/graph.cpp index bae92da..a0d8b78 100644 --- a/noncore/apps/checkbook/graph.cpp +++ b/noncore/apps/checkbook/graph.cpp | |||
@@ -31,2 +31,4 @@ | |||
31 | 31 | ||
32 | #include <qcolor.h> | ||
33 | #include <qfontmetrics.h> | ||
32 | #include <qpainter.h> | 34 | #include <qpainter.h> |
@@ -36,4 +38,2 @@ Graph::Graph( QWidget *parent, GraphInfo *d, const QString &name, int flags ) | |||
36 | { | 38 | { |
37 | setBackgroundMode( QWidget::PaletteBase ); | ||
38 | |||
39 | data = d; | 39 | data = d; |
@@ -84,3 +84,3 @@ void Graph::initGraph() | |||
84 | { | 84 | { |
85 | drawBarChart(); | 85 | drawBarChart( width(), height(), data->maxValue() ); |
86 | } | 86 | } |
@@ -89,3 +89,3 @@ void Graph::initGraph() | |||
89 | { | 89 | { |
90 | drawLineChart(); | 90 | //drawLineChart( p, s, min, max ); |
91 | } | 91 | } |
@@ -94,3 +94,3 @@ void Graph::initGraph() | |||
94 | { | 94 | { |
95 | drawPieChart(); | 95 | drawPieChart( width(), height(), data->totalValue() ); |
96 | } | 96 | } |
@@ -99,8 +99,36 @@ void Graph::initGraph() | |||
99 | 99 | ||
100 | void Graph::drawBarChart() | 100 | void Graph::drawBarChart( int width, int height, float max ) |
101 | { | 101 | { |
102 | //Find max value in GraphInfo->dataPoints() - make function in GraphInfo!!! | 102 | QPainter p( &graph ); |
103 | |||
104 | // Try to set the font size smaller for text | ||
105 | QFont f = font(); | ||
106 | f.setPointSize( 8 ); | ||
107 | p.setFont( f ); | ||
108 | |||
109 | int x = 0; | ||
110 | int i = 0; | ||
111 | int n = data->numberDataPoints(); | ||
112 | QFontMetrics fm=fontMetrics(); | ||
113 | int fh = fm.height(); | ||
114 | int fw; | ||
115 | |||
116 | QColor c( 0, 0, 255); | ||
117 | p.setBrush( c ); | ||
118 | |||
119 | for (DataPointInfo *dp = data->firstDataPoint(); dp; dp = data->nextDataPoint() ) | ||
120 | { | ||
121 | int bw = ( width - width / 4 - x ) / ( n - i ); | ||
122 | int bh = int( ( height - height / 4 - 1 ) * dp->value() / max ); | ||
123 | p.drawRect( width / 8 + x, height - height / 8 - 1 - bh, bw, bh ); | ||
124 | fw = fm.width( dp->label() ); | ||
125 | p.drawText( width / 8 + x - fw / 2 + bw / 2, height - height / 8, fw, | ||
126 | fh + height / 8, AlignTop | AlignHCenter, dp->label() ); | ||
127 | // WordBreak | AlignTop | AlignHCenter, dp->label() ); | ||
128 | i++; | ||
129 | x += bw; | ||
130 | } | ||
103 | } | 131 | } |
104 | 132 | ||
105 | void Graph::drawLineChart() | 133 | void Graph::drawLineChart( int width, int height, float max ) |
106 | { | 134 | { |
@@ -108,4 +136,43 @@ void Graph::drawLineChart() | |||
108 | 136 | ||
109 | void Graph::drawPieChart() | 137 | void Graph::drawPieChart( int width, int height, float sum ) |
110 | { | 138 | { |
139 | QPainter p( &graph ); | ||
140 | |||
141 | // Try to set the font size smaller for text | ||
142 | QFont f = font(); | ||
143 | f.setPointSize( 8 ); | ||
144 | p.setFont( f ); | ||
145 | |||
146 | int n = data->numberDataPoints(); | ||
147 | |||
148 | int apos = -90 * 16; | ||
149 | |||
150 | int xd = width - width / 5; | ||
151 | int yd = height - height / 5; | ||
152 | |||
153 | int i = 0; | ||
154 | |||
155 | QColor c; | ||
156 | |||
157 | for (DataPointInfo *dp = data->firstDataPoint(); dp; dp = data->nextDataPoint() ) | ||
158 | { | ||
159 | c.setHsv( ( i *255) / n, 255, 255 ); | ||
160 | p.setBrush( c ); | ||
161 | |||
162 | int a = int( ( dp->value() * 360.0 ) / sum * 16.0 + 0.5 ); | ||
163 | p.drawPie( width/10, height/10, xd, yd, -apos, -a ); | ||
164 | apos += a; | ||
165 | i++; | ||
166 | } | ||
167 | |||
168 | double apos2 = -90 * 3.14159 / 180; | ||
169 | for (DataPointInfo *dp = data->firstDataPoint(); dp; dp = data->nextDataPoint() ) | ||
170 | { | ||
171 | double a = dp->value() *360 / sum * 3.14159 / 180; | ||
172 | int x = int( cos( apos2 + a/2 ) * width * 5/16 + width/2 + 0.5 ); | ||
173 | int y = int( sin( apos2 + a/2 ) * height * 5/16 + height/2 + 0.5 ); | ||
174 | p.drawText( x - width/8, y - height/8, width/4, height/4, WordBreak | AlignCenter, | ||
175 | dp->label() ); | ||
176 | apos2 += a; | ||
177 | } | ||
111 | } | 178 | } |
diff --git a/noncore/apps/checkbook/graph.h b/noncore/apps/checkbook/graph.h index 7379be7..40b23cd 100644 --- a/noncore/apps/checkbook/graph.h +++ b/noncore/apps/checkbook/graph.h | |||
@@ -35,2 +35,3 @@ | |||
35 | class GraphInfo; | 35 | class GraphInfo; |
36 | class QPainter; | ||
36 | 37 | ||
@@ -46,3 +47,3 @@ class Graph : public QWidget | |||
46 | void drawGraph( bool = FALSE ); | 47 | void drawGraph( bool = FALSE ); |
47 | 48 | ||
48 | protected: | 49 | protected: |
@@ -57,5 +58,5 @@ class Graph : public QWidget | |||
57 | void initGraph(); | 58 | void initGraph(); |
58 | void drawBarChart(); | 59 | void drawBarChart( int, int, float ); |
59 | void drawLineChart(); | 60 | void drawLineChart( int, int, float ); |
60 | void drawPieChart(); | 61 | void drawPieChart( int, int, float ); |
61 | }; | 62 | }; |
diff --git a/noncore/apps/checkbook/graphinfo.cpp b/noncore/apps/checkbook/graphinfo.cpp index 7b06bdb..ec6a465 100644 --- a/noncore/apps/checkbook/graphinfo.cpp +++ b/noncore/apps/checkbook/graphinfo.cpp | |||
@@ -40,2 +40,13 @@ GraphInfo::GraphInfo( GraphType type, DataPointList *data, const QString &title, | |||
40 | 40 | ||
41 | GraphInfo::~GraphInfo() | ||
42 | { | ||
43 | if ( d ) | ||
44 | { | ||
45 | for ( DataPointInfo *data = d->first(); data; data = d->next() ) | ||
46 | { | ||
47 | delete data; | ||
48 | } | ||
49 | } | ||
50 | } | ||
51 | |||
41 | GraphInfo::GraphType GraphInfo::graphType() | 52 | GraphInfo::GraphType GraphInfo::graphType() |
@@ -60,10 +71,38 @@ void GraphInfo::setDataPoints( DataPointList *data ) | |||
60 | 71 | ||
61 | float GraphInfo::maxValue() | 72 | DataPointInfo *GraphInfo::firstDataPoint() |
62 | { | 73 | { |
63 | float max; | 74 | return( d->first() ); |
75 | } | ||
64 | 76 | ||
77 | DataPointInfo *GraphInfo::nextDataPoint() | ||
78 | { | ||
79 | return( d->next() ); | ||
80 | } | ||
81 | |||
82 | int GraphInfo::numberDataPoints() | ||
83 | { | ||
84 | return( d->count() ); | ||
85 | } | ||
86 | |||
87 | float GraphInfo::maxValue() | ||
88 | { | ||
89 | float max = 0.0; | ||
90 | for ( DataPointInfo *data = d->first(); data; data = d->next() ) | ||
91 | { | ||
92 | if ( data->value() > max ) | ||
93 | { | ||
94 | max = data->value(); | ||
95 | } | ||
96 | } | ||
97 | return max; | ||
65 | } | 98 | } |
66 | 99 | ||
67 | float GraphInfo::minValue() | 100 | float GraphInfo::totalValue() |
68 | { | 101 | { |
102 | float sum = 0.0; | ||
103 | for ( DataPointInfo *data = d->first(); data; data = d->next() ) | ||
104 | { | ||
105 | sum += data->value(); | ||
106 | } | ||
107 | return sum; | ||
69 | } | 108 | } |
diff --git a/noncore/apps/checkbook/graphinfo.h b/noncore/apps/checkbook/graphinfo.h index 4ad1dc9..620da74 100644 --- a/noncore/apps/checkbook/graphinfo.h +++ b/noncore/apps/checkbook/graphinfo.h | |||
@@ -44,2 +44,4 @@ class DataPointInfo | |||
44 | float value() { return v; } | 44 | float value() { return v; } |
45 | |||
46 | void addToValue( float value ) { v += value; } | ||
45 | 47 | ||
@@ -59,2 +61,3 @@ class GraphInfo | |||
59 | const QString & = 0x0, const QString & = 0x0, const QString & = 0x0 ); | 61 | const QString & = 0x0, const QString & = 0x0, const QString & = 0x0 ); |
62 | ~GraphInfo(); | ||
60 | 63 | ||
@@ -65,5 +68,8 @@ class GraphInfo | |||
65 | void setDataPoints( DataPointList * ); | 68 | void setDataPoints( DataPointList * ); |
69 | DataPointInfo *firstDataPoint(); | ||
70 | DataPointInfo *nextDataPoint(); | ||
71 | int numberDataPoints(); | ||
66 | 72 | ||
67 | float maxValue(); | 73 | float maxValue(); |
68 | float minValue(); | 74 | float totalValue(); |
69 | 75 | ||