/*
Copyright 2010-2012 Grégory Soutadé
This file is part of KissCount.
KissCount is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
KissCount is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with KissCount. If not, see .
*/
#include
#include
#include
#include
#include
#include "StatsPanel.hpp"
using namespace QtCharts;
StatsPanel::StatsPanel(KissCount* kiss, wxUI *parent, bool lowResolution) :
KissPanel(kiss, parent, lowResolution), _chartView(0)
{
QHBoxLayout *hbox = new QHBoxLayout();
QHBoxLayout *hbox1 = new QHBoxLayout();
QVBoxLayout *vbox = new QVBoxLayout();
_hbox2 = new QHBoxLayout();
_vbox2 = new QVBoxLayout();
_vbox3 = new QVBoxLayout();
int i, nbCategories;
User* user = _kiss->GetUser();
std::vector::iterator accountIt;
std::vector::iterator categoryIt;
std::map > operations;
std::map >::iterator it;
_icons[KissPanel::LOW_RES_ICON] = STATS_LOW_ICON;
_icons[KissPanel::HIGH_RES_ICON] = STATS_ICON;
setLayout(vbox);
_monthFrom = new QComboBox(parent);
for(i=0; i<12; i++)
_monthFrom->addItem(wxUI::months[i]);
_yearFrom = new QComboBox(parent);
_monthTo = new QComboBox(parent);
for(i=0; i<12; i++)
_monthTo->addItem(wxUI::months[i]);
_yearTo = new QComboBox(parent);
operations = _kiss->GetAllOperations();
for(i=0, it = operations.begin(); it != operations.end(); it++, i++)
{
_yearFrom->addItem(QString::number(it->first));
_yearTo->addItem(QString::number(it->first));
}
if (i) i--;
_yearFrom->setCurrentIndex(i);
_yearTo->setCurrentIndex(i);
_monthFrom->setCurrentIndex(0);
_monthTo->setCurrentIndex(11);
QLabel* label = new QLabel(_("From"));
label->setAlignment(Qt::AlignRight);
hbox->addWidget(label, 1);
hbox->addWidget(_monthFrom, 2);
hbox->addWidget(_yearFrom, 2);
hbox->addStretch(1);
label = new QLabel(_("To"));
label->setAlignment(Qt::AlignRight);
hbox->addWidget(label, 1);
hbox->addWidget(_monthTo, 2);
hbox->addWidget(_yearTo, 2);
hbox->addStretch(1);
connect(_yearFrom, SIGNAL(currentIndexChanged(int)), this, SLOT(OnRangeChange(int)));
connect(_monthFrom, SIGNAL(currentIndexChanged(int)), this, SLOT(OnRangeChange(int)));
connect(_yearTo, SIGNAL(currentIndexChanged(int)), this, SLOT(OnRangeChange(int)));
connect(_monthTo, SIGNAL(currentIndexChanged(int)), this, SLOT(OnRangeChange(int)));
_account = new QListWidget(this);
for(i=0, accountIt = user->_accounts.begin(); accountIt != user->_accounts.end(); accountIt++, i++)
{
_account->addItem(accountIt->name);
}
_account->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
_account->setSizeAdjustPolicy(QAbstractScrollArea::AdjustToContents);
connect(_account, SIGNAL(itemClicked(QListWidgetItem*)), this, SLOT(OnAccountChange(QListWidgetItem*)));
_categories = new QString[user->GetCategoriesNumber()] ;
for(i=0, categoryIt = user->_categories.begin();
categoryIt != user->_categories.end();
categoryIt++, i++)
{
_categoriesIndexes[categoryIt->id] = i;
_categories[i] = _(categoryIt->name.toStdString().c_str()) ;
}
DEFAULT_FONT(font);
_costRepartitionBanner = new CostRepartitionBanner(_kiss, this, _categories);
hbox1->addStretch(1);
hbox1->addWidget(_account, 2);
hbox1->addStretch(1);
_vbox3->addLayout(hbox1, 1);
nbCategories = user->GetCategoriesNumber();
_categoriesValues = new int[nbCategories];
for(i=0; iaddWidget(_costRepartitionBanner, 3);
_vbox2->addLayout(hbox);
_hbox2->addLayout(_vbox2);
vbox->addLayout(_hbox2);
_hbox2->addLayout(_vbox3);
_hbox2->setStretch(0, 4);
_hbox2->setStretch(1, 1);
OnRangeChange(0);
layout();
}
KissPanel* StatsPanel::CreatePanel()
{
return new StatsPanel(_kiss, _wxUI, _lowResolution);
}
QString StatsPanel::GetToolTip()
{
return _("Statistics");
}
void StatsPanel::UpdateStats(int monthFrom, int yearFrom, int monthTo, int yearTo)
{
std::map > > accountAmounts;
std::map categories;
std::map tags;
std::map > operations;
std::vector::iterator accountIt;
std::map::iterator categoriesIt;
std::map >::iterator accountYearIt;
std::map::iterator accountMonthIt;
int total;
int account, i, nbDays, nbTicks = 0;
QString value, v;
User* user = _kiss->GetUser();
QDate date, start, end;
QLineSeries * series = new QLineSeries();
QLineSeries * series0 = series;
QDateTimeAxis *axisX = new QDateTimeAxis;
QDateTime xValue;
double previous;
if (_chartView)
{
_plot->removeAllSeries();
}
else
_plot = new QChart();
if (monthFrom == monthTo && yearFrom == yearTo)
{
date.setDate(yearFrom, monthFrom+1, 1);
nbDays = date.daysInMonth();
_kiss->GetMonthStats(monthFrom, yearFrom, nbDays, &operations, &categories, &tags);
// Line on 0 all over the years
for (i=0; i<=nbDays; i++)
{
date = QDate(yearFrom, monthFrom+1, i+1);
xValue.setDate(date);
series->append(xValue.toMSecsSinceEpoch(), 0.0);
nbTicks++;
}
series->setName(_("0 line"));
series->setColor(Qt::red);
axisX->setFormat("dd");
_plot->addSeries(series);
for (account = 0, accountIt = user->_accounts.begin(); accountIt != user->_accounts.end();
account++, accountIt++)
{
if (_account->item(account)->checkState() != Qt::Checked)
continue;
series = new QLineSeries();
for (i=0; iappend(xValue.toMSecsSinceEpoch(),
(double) operations[accountIt->id][i] / 100);
}
series->setName(user->GetAccountName(accountIt->id));
_plot->addSeries(series);
}
}
else
{
_kiss->GetStats(monthFrom, yearFrom, monthTo, yearTo, &accountAmounts, &categories, &tags);
// Line on 0 all over the years
start = QDate(yearFrom, monthFrom+1, 1);
end = QDate(yearTo, monthTo+1, 1);
end = end.addMonths(1);
date = start;
for (date = start; date <= end; date = date.addMonths(1))
{
xValue.setDate(date);
series->append(xValue.toMSecsSinceEpoch(), 0.0);
nbTicks++;
}
axisX->setLabelsAngle(-60);
axisX->setLineVisible(true);
axisX->setFormat("MM yyyy");
series->setName(_("0 line"));
series->setColor(Qt::red);
_plot->addSeries(series);
for (account = 0, i = 0, accountIt = user->_accounts.begin(); accountIt != user->_accounts.end();
account++, accountIt++, i++)
{
if (_account->item(account)->checkState() != Qt::Checked)
{
i-- ;
continue;
}
series = new QLineSeries();
previous = 0.0;
for(accountYearIt = accountAmounts[accountIt->id].begin();
accountYearIt != accountAmounts[accountIt->id].end();
accountYearIt++)
{
for(accountMonthIt = accountAmounts[accountIt->id][accountYearIt->first].begin();
accountMonthIt != accountAmounts[accountIt->id][accountYearIt->first].end();
accountMonthIt++)
{
date = QDate(accountYearIt->first, accountMonthIt->first+1, 1);
xValue.setDate(date);
previous = accountMonthIt->second / 100;
*series << QPointF(xValue.toMSecsSinceEpoch(), previous);
}
previous += _kiss->CalcAccountAmount(accountIt->id, date.month()-1, date.year(), 0)/100;
date = date.addMonths(1);
xValue.setDate(date);
*series << QPointF(xValue.toMSecsSinceEpoch(), previous) ;
}
series->setName(user->GetAccountName(accountIt->id));
_plot->addSeries(series);
}
}
// yAxis->setTitleText (_("Amount"));
QLegend* legend = _plot->legend();
legend->setAlignment(Qt::AlignRight);
_plot->addSeries(series0);
_plot->createDefaultAxes();
axisX->setTickCount(nbTicks);
_plot->setAxisX(axisX, series0);
// _plot->addAxis(axisX, Qt::AlignRight);
if (!_chartView)
{
_chartView = new QChartView(_plot);
_chartView->setRenderHint(QPainter::Antialiasing);
_vbox2->addWidget(_chartView);
}
total = 0.0;
for(i=0, categoriesIt = categories.begin(); categoriesIt != categories.end(); categoriesIt++, i++)
{
_categoriesValues[_categoriesIndexes[categoriesIt->first]] = categoriesIt->second;
total += categoriesIt->second;
}
_costRepartitionBanner->UpdateCosts(_categoriesValues, total);
layout();
}
void StatsPanel::OnShow()
{
_wxUI->setWindowTitle(_kiss->GetUser()->_name + _(" - ") + _("Statistics"));
}
void StatsPanel::OnRangeChange(int index)
{
int monthFrom, monthTo, yearFrom, yearTo;
QListWidgetItem* item;
std::vector::iterator accountIt;
int i;
User* user = _kiss->GetUser();
monthFrom = _monthFrom->currentIndex();
yearFrom = _yearFrom->currentText().toInt();
monthTo = _monthTo->currentIndex();
yearTo = _yearTo->currentText().toInt();
if (yearTo < yearFrom ||
(yearFrom == yearTo && monthFrom > monthTo))
{
QMessageBox::critical(0, _("Error"), _("Invalide date range"));
return;
}
if (index != -1)
{
for(i=0, accountIt = user->_accounts.begin(); accountIt != user->_accounts.end(); accountIt++, i++)
{
item = _account->item(i);
if (accountIt->hidden || !accountIt->validAt(monthFrom, yearFrom, monthTo, yearTo))
item->setCheckState (Qt::Unchecked);
else
item->setCheckState (Qt::Checked);
}
}
_costRepartitionBanner->Reset();
UpdateStats(monthFrom, yearFrom, monthTo, yearTo);
}
void StatsPanel::OnAccountChange(QListWidgetItem* item)
{
OnRangeChange(-1);
}