summaryrefslogtreecommitdiff
Side-by-side diff
Diffstat (more/less context) (show whitespace changes)
-rw-r--r--noncore/apps/checkbook/checkbook.cpp122
-rw-r--r--noncore/apps/checkbook/checkbook.h7
-rw-r--r--noncore/apps/checkbook/graph.cpp85
-rw-r--r--noncore/apps/checkbook/graph.h7
-rw-r--r--noncore/apps/checkbook/graphinfo.cpp45
-rw-r--r--noncore/apps/checkbook/graphinfo.h8
6 files changed, 238 insertions, 36 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
@@ -231,35 +231,32 @@ QWidget *Checkbook::initTransactions()
}
QWidget *Checkbook::initCharts()
{
+ graphInfo = 0x0;
+
QWidget *control = new QWidget( mainWidget );
QGridLayout *layout = new QGridLayout( control );
layout->setSpacing( 2 );
layout->setMargin( 4 );
-/*
- QLabel *label = new QLabel( control );
- label->setText( tr( "Graph type:" ) );
- layout->addWidget( label, 0, 0 );
+ graphWidget = new Graph( control );
+ QWhatsThis::add( graphWidget, tr( "Select the desired chart below and then click on the Draw button." ) );
+ layout->addMultiCellWidget( graphWidget, 0, 0, 0, 2 );
+
graphList = new QComboBox( control );
- graphList->insertItem( tr( "By category" ) );
- graphList->insertItem( tr( "..." ) );
- graphList->insertItem( tr( "..." ) );
- layout->addWidget( graphList, 0, 1 );
-*/
+ QWhatsThis::add( graphList, tr( "Click here to select the desired chart type." ) );
+ graphList->insertItem( tr( "Account balance" ) );
+ graphList->insertItem( tr( "Withdrawals by category" ) );
+ graphList->insertItem( tr( "Deposits by category" ) );
- GraphInfo* info = new GraphInfo( GraphInfo::BarChart, 0x0, tr( "Graph Title" ),
- tr( "X-Axis" ), tr( "Y-Axis" ) );
- graphWidget = new Graph( control, info );
- QWhatsThis::add( graphWidget, tr( "Charting is not implemented yet." ) );
- layout->addMultiCellWidget( graphWidget, 0, 0, 0, 1 );
+ layout->addMultiCellWidget( graphList, 1, 1, 0, 1 );
QPushButton *btn = new QPushButton( Resource::loadPixmap( "checkbook/drawbtn" ), tr( "Draw" ), control );
- QWhatsThis::add( btn, tr( "Click here to draw the chart." ) );
+ QWhatsThis::add( btn, tr( "Click here to draw the selected chart." ) );
connect( btn, SIGNAL( clicked() ), this, SLOT( slotDrawGraph() ) );
- layout->addWidget( btn, 1, 1 );
+ layout->addWidget( btn, 1, 2 );
return control;
}
@@ -366,14 +363,12 @@ void Checkbook::accept()
config->writeEntry( "Balance", balanceEdit->text() );
config->writeEntry( "Notes", notesEdit->text() );
// Save transactions
- TranInfo *tran = transactions.first();
int i = 1;
- while ( tran )
+ for ( TranInfo *tran = transactions.first(); tran; tran = transactions.next() )
{
tran->write( config, i );
- tran = transactions.next();
i++;
}
config->write();
@@ -508,5 +503,94 @@ void Checkbook::slotDeleteTran()
}
void Checkbook::slotDrawGraph()
{
+ if ( graphInfo )
+ {
+ delete graphInfo;
+ }
+
+ switch ( graphList->currentItem() )
+ {
+ case 0 : drawBalanceChart();
+ break;
+ case 1 : drawCategoryChart( TRUE );
+ break;
+ case 2 : drawCategoryChart( FALSE );
+ break;
+ };
+
+ graphWidget->setGraphInfo( graphInfo );
+ graphWidget->drawGraph( TRUE );
+}
+
+void Checkbook::drawBalanceChart()
+{
+ DataPointList *list = new DataPointList();
+
+ float balance = startBalance;
+ float amount;
+ QString label;
+ int i = 0;
+ int count = transactions.count();
+
+ for ( TranInfo *tran = transactions.first(); tran; tran = transactions.next() )
+ {
+ i++;
+ balance -= tran->fee();
+ amount = tran->amount();
+ if ( tran->withdrawal() )
+ {
+ amount *= -1;
+ }
+ balance += amount;
+ if ( i == 1 || i == count / 2 || i == count )
+ {
+ label = tran->datestr();
+ }
+ else
+ {
+ label = "";
+ }
+ list->append( new DataPointInfo( label, balance ) );
+ }
+
+ graphInfo = new GraphInfo( GraphInfo::BarChart, list );
+}
+
+void Checkbook::drawCategoryChart( bool withdrawals )
+{
+ DataPointList *list = new DataPointList();
+
+ TranInfo *tran = transactions.first();
+ if ( tran->withdrawal() == withdrawals )
+ {
+ list->append( new DataPointInfo( tran->category(), tran->amount() ) );
+ }
+ tran = transactions.next();
+
+ DataPointInfo *cat;
+ for ( ; tran; tran = transactions.next() )
+ {
+ if ( tran->withdrawal() == withdrawals )
+ {
+ // Find category in list
+ for ( cat = list->first(); cat; cat = list->next() )
+ {
+ if ( cat->label() == tran->category() )
+ {
+ break;
+ }
+ }
+ if ( cat && cat->label() == tran->category() )
+ { // Found category, add to transaction to category total
+ cat->addToValue( tran->amount() );
+ }
+ else
+ { // Didn't find category, add category to list
+ list->append( new DataPointInfo( tran->category(), tran->amount() ) );
+ }
+ }
+ }
+
+ graphInfo = new GraphInfo( GraphInfo::PieChart, list );
}
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
@@ -35,8 +35,9 @@
class OTabWidget;
class Graph;
+class GraphInfo;
class QComboBox;
class QLabel;
class QLineEdit;
class QListView;
@@ -84,11 +85,15 @@ class Checkbook : public QDialog
float currBalance;
// Charts tab
QWidget *initCharts();
- //QComboBox *graphList;
+ GraphInfo *graphInfo;
+ QComboBox *graphList;
Graph *graphWidget;
+ void drawBalanceChart();
+ void drawCategoryChart( bool = TRUE );
+
protected slots:
void accept();
private slots:
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
@@ -28,15 +28,15 @@
#include "graph.h"
#include "graphinfo.h"
+#include <qcolor.h>
+#include <qfontmetrics.h>
#include <qpainter.h>
Graph::Graph( QWidget *parent, GraphInfo *d, const QString &name, int flags )
: QWidget( parent, name, flags )
{
- setBackgroundMode( QWidget::PaletteBase );
-
data = d;
graph.setOptimization( QPixmap::BestOptim );
}
@@ -81,32 +81,99 @@ void Graph::initGraph()
switch ( data->graphType() )
{
case GraphInfo::BarChart :
{
- drawBarChart();
+ drawBarChart( width(), height(), data->maxValue() );
}
break;
case GraphInfo::LineChart :
{
- drawLineChart();
+ //drawLineChart( p, s, min, max );
}
break;
case GraphInfo::PieChart :
{
- drawPieChart();
+ drawPieChart( width(), height(), data->totalValue() );
}
};
}
-void Graph::drawBarChart()
+void Graph::drawBarChart( int width, int height, float max )
+{
+ QPainter p( &graph );
+
+ // Try to set the font size smaller for text
+ QFont f = font();
+ f.setPointSize( 8 );
+ p.setFont( f );
+
+ int x = 0;
+ int i = 0;
+ int n = data->numberDataPoints();
+ QFontMetrics fm=fontMetrics();
+ int fh = fm.height();
+ int fw;
+
+ QColor c( 0, 0, 255);
+ p.setBrush( c );
+
+ for (DataPointInfo *dp = data->firstDataPoint(); dp; dp = data->nextDataPoint() )
+ {
+ int bw = ( width - width / 4 - x ) / ( n - i );
+ int bh = int( ( height - height / 4 - 1 ) * dp->value() / max );
+ p.drawRect( width / 8 + x, height - height / 8 - 1 - bh, bw, bh );
+ fw = fm.width( dp->label() );
+ p.drawText( width / 8 + x - fw / 2 + bw / 2, height - height / 8, fw,
+ fh + height / 8, AlignTop | AlignHCenter, dp->label() );
+// WordBreak | AlignTop | AlignHCenter, dp->label() );
+ i++;
+ x += bw;
+ }
+}
+
+void Graph::drawLineChart( int width, int height, float max )
{
- //Find max value in GraphInfo->dataPoints() - make function in GraphInfo!!!
}
-void Graph::drawLineChart()
+void Graph::drawPieChart( int width, int height, float sum )
{
+ QPainter p( &graph );
+
+ // Try to set the font size smaller for text
+ QFont f = font();
+ f.setPointSize( 8 );
+ p.setFont( f );
+
+ int n = data->numberDataPoints();
+
+ int apos = -90 * 16;
+
+ int xd = width - width / 5;
+ int yd = height - height / 5;
+
+ int i = 0;
+
+ QColor c;
+
+ for (DataPointInfo *dp = data->firstDataPoint(); dp; dp = data->nextDataPoint() )
+ {
+ c.setHsv( ( i *255) / n, 255, 255 );
+ p.setBrush( c );
+
+ int a = int( ( dp->value() * 360.0 ) / sum * 16.0 + 0.5 );
+ p.drawPie( width/10, height/10, xd, yd, -apos, -a );
+ apos += a;
+ i++;
}
-void Graph::drawPieChart()
+ double apos2 = -90 * 3.14159 / 180;
+ for (DataPointInfo *dp = data->firstDataPoint(); dp; dp = data->nextDataPoint() )
{
+ double a = dp->value() *360 / sum * 3.14159 / 180;
+ int x = int( cos( apos2 + a/2 ) * width * 5/16 + width/2 + 0.5 );
+ int y = int( sin( apos2 + a/2 ) * height * 5/16 + height/2 + 0.5 );
+ p.drawText( x - width/8, y - height/8, width/4, height/4, WordBreak | AlignCenter,
+ dp->label() );
+ apos2 += a;
+ }
}
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
@@ -32,8 +32,9 @@
#include <qpixmap.h>
#include <qwidget.h>
class GraphInfo;
+class QPainter;
class Graph : public QWidget
{
Q_OBJECT
@@ -54,10 +55,10 @@ class Graph : public QWidget
QPixmap graph;
void initGraph();
- void drawBarChart();
- void drawLineChart();
- void drawPieChart();
+ void drawBarChart( int, int, float );
+ void drawLineChart( int, int, float );
+ void drawPieChart( int, int, float );
};
#endif
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
@@ -37,8 +37,19 @@ GraphInfo::GraphInfo( GraphType type, DataPointList *data, const QString &title,
xt = xtitle;
yt = ytitle;
}
+GraphInfo::~GraphInfo()
+{
+ if ( d )
+ {
+ for ( DataPointInfo *data = d->first(); data; data = d->next() )
+ {
+ delete data;
+ }
+ }
+}
+
GraphInfo::GraphType GraphInfo::graphType()
{
return t;
}
@@ -57,16 +68,44 @@ void GraphInfo::setDataPoints( DataPointList *data )
{
d = data;
}
-float GraphInfo::maxValue()
+DataPointInfo *GraphInfo::firstDataPoint()
{
- float max;
+ return( d->first() );
+}
+DataPointInfo *GraphInfo::nextDataPoint()
+{
+ return( d->next() );
}
-float GraphInfo::minValue()
+int GraphInfo::numberDataPoints()
{
+ return( d->count() );
+}
+
+float GraphInfo::maxValue()
+{
+ float max = 0.0;
+ for ( DataPointInfo *data = d->first(); data; data = d->next() )
+ {
+ if ( data->value() > max )
+ {
+ max = data->value();
+ }
+ }
+ return max;
+}
+
+float GraphInfo::totalValue()
+{
+ float sum = 0.0;
+ for ( DataPointInfo *data = d->first(); data; data = d->next() )
+ {
+ sum += data->value();
+ }
+ return sum;
}
void GraphInfo::setGraphTitle( const QString &title )
{
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
@@ -42,8 +42,10 @@ class DataPointInfo
const QString &label() { return l; }
float value() { return v; }
+ void addToValue( float value ) { v += value; }
+
private:
QString l;
float v;
};
@@ -56,17 +58,21 @@ class GraphInfo
enum GraphType { BarChart, LineChart, PieChart };
GraphInfo( GraphType = BarChart, DataPointList * = 0x0,
const QString & = 0x0, const QString & = 0x0, const QString & = 0x0 );
+ ~GraphInfo();
GraphInfo::GraphType graphType();
void setGraphType( GraphType );
DataPointList *dataPoints();
void setDataPoints( DataPointList * );
+ DataPointInfo *firstDataPoint();
+ DataPointInfo *nextDataPoint();
+ int numberDataPoints();
float maxValue();
- float minValue();
+ float totalValue();
void setGraphTitle( const QString & );
void setXAxisTitle( const QString & );
void setYAxisTitle( const QString & );