387 lines
16 KiB
C++
387 lines
16 KiB
C++
#include "scountdlg.h"
|
|
#include "mainwindow.h"
|
|
#include <QVBoxLayout>
|
|
#include <QHBoxLayout>
|
|
#include <QPushButton>
|
|
#include <QDateTime>
|
|
#include <QTimer>
|
|
#include <QFile>
|
|
#include <QApplication>
|
|
#include <QMessageBox>
|
|
#include <QFileDialog>
|
|
|
|
const int C_COMBO_MAX = 2;
|
|
|
|
SCountDlg::SCountDlg()
|
|
{
|
|
setWidgets();
|
|
}
|
|
|
|
SCountDlg::~SCountDlg()
|
|
{
|
|
}
|
|
|
|
void SCountDlg::setWidgets()
|
|
{
|
|
setWindowTitle("Count");
|
|
QVBoxLayout *vlayout = new QVBoxLayout;
|
|
{
|
|
QHBoxLayout *hlayout = new QHBoxLayout;
|
|
m_pCombo = new QComboBox[C_COMBO_MAX];
|
|
for (int i = 0; i < C_COMBO_MAX ; i++)
|
|
hlayout->addWidget(&m_pCombo[i]);
|
|
|
|
QPushButton *ppbRun = new QPushButton("Run");
|
|
connect(ppbRun, SIGNAL(released()),this, SLOT(run()));
|
|
hlayout->addWidget(ppbRun);
|
|
QPushButton *ppbGraph = new QPushButton("Graph");
|
|
connect(ppbGraph, SIGNAL(released()),this, SLOT(graph()));
|
|
hlayout->addWidget(ppbGraph);
|
|
QPushButton *ppbSave = new QPushButton("Save");
|
|
connect(ppbSave, SIGNAL(released()),this, SLOT(save()));
|
|
hlayout->addWidget(ppbSave);
|
|
|
|
vlayout->addLayout(hlayout);
|
|
}
|
|
m_pTable = new STable;
|
|
m_pTable->SetHeaderList(QStringList() << "Item" << "Count");
|
|
vlayout->addWidget(m_pTable);
|
|
|
|
setLayout(vlayout);
|
|
|
|
for (int i = 0; i < C_COMBO_MAX ; i++)
|
|
{
|
|
m_pCombo[i].clear();
|
|
foreach(QStringList strList,GetColumn().data())
|
|
m_pCombo[i].addItem(strList.at(SColumn::E_NAME));
|
|
}
|
|
|
|
for (int i = 0; i < C_COMBO_MAX ; i++)
|
|
{
|
|
m_pCombo[i].addItem("[--------]");
|
|
m_pCombo[i].setCurrentIndex(GetColumn().data().size());
|
|
}
|
|
}
|
|
|
|
void SCountDlg::choose_1()
|
|
{
|
|
int nCatalog = D_NOT_SELECT;
|
|
for (int i = 0; i < C_COMBO_MAX ; i++)
|
|
{
|
|
if (m_pCombo[i].currentIndex() != GetColumn().data().size())
|
|
{
|
|
nCatalog = m_pCombo[i].currentIndex();
|
|
break;
|
|
}
|
|
}
|
|
if (nCatalog == D_NOT_SELECT) return;
|
|
m_pTable->SetHeaderList(QStringList() << GetColumn().data().at(nCatalog).at(SColumn::E_NAME) << "Count");
|
|
QTableWidget *pCurrent = (QTableWidget *)GetMainWindow()->m_pDataDlg->GetCurrentWidget();
|
|
GetMainWindow()->m_progress.setRange(0,pCurrent->rowCount());
|
|
if (GetColumn().isDateColumn(nCatalog))
|
|
{
|
|
QMap <QDate,int> mapCount;
|
|
QDate dateStart(2055,12,31),dateEnd(1900,1,1);
|
|
for (int nCount = 0 ; nCount < pCurrent->rowCount(); nCount++ )
|
|
{
|
|
//if(pCurrent->item(nCount,nCatalog)->text().trimmed().isEmpty()) continue;
|
|
QDateTime date;
|
|
QDate day = date.fromString(pCurrent->item(nCount,nCatalog)->text().trimmed(),"yyyy-MM-dd hh:mm:ss").date();
|
|
if (day.year() < 1901) continue;
|
|
if (day < dateStart) dateStart=day;
|
|
if (day > dateEnd) dateEnd=day;
|
|
if (mapCount.contains(day))
|
|
mapCount[day]++;
|
|
else
|
|
mapCount.insert(day,1);
|
|
GetMainWindow()->m_progress.setValue(nCount);
|
|
GetMainWindow()->m_progress.repaint();
|
|
}
|
|
int nCount = 0;
|
|
m_pTable->setRowCount(dateStart.daysTo(dateEnd));
|
|
for (QDate now = dateStart; now < dateEnd ; now=now.addDays(1) )
|
|
{
|
|
int nCol = 0;
|
|
QString str = now.toString("yyyy-MM-dd").trimmed();
|
|
m_pTable->setItem(nCount,nCol++,new QTableWidgetItem(str));
|
|
if (mapCount.contains(now))
|
|
m_pTable->setItem(nCount,nCol,new STableNumberItem(QString::number(mapCount[now])));
|
|
else
|
|
m_pTable->setItem(nCount,nCol,new STableNumberItem(QString::number(0)));
|
|
nCount++;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
QMap <QString,int> mapCount;
|
|
for (int nCount = 0 ; nCount < pCurrent->rowCount() ; nCount++ )
|
|
{
|
|
QString str = pCurrent->item(nCount,nCatalog)->text().trimmed();
|
|
if(str.isEmpty()) continue;
|
|
if (mapCount.contains(str))
|
|
mapCount[str]++;
|
|
else
|
|
mapCount.insert(str,1);
|
|
GetMainWindow()->m_progress.setValue(nCount);
|
|
GetMainWindow()->m_progress.repaint();
|
|
}
|
|
m_pTable->setRowCount(mapCount.size());
|
|
int nCount = 0;
|
|
for (QMap<QString,int> ::iterator i = mapCount.begin(); i != mapCount.end(); ++i)
|
|
{
|
|
int nCol = 0;
|
|
m_pTable->setItem(nCount,nCol++,new QTableWidgetItem(i.key()));
|
|
m_pTable->setItem(nCount,nCol++,new STableNumberItem(QString::number(i.value())));
|
|
nCount++;
|
|
}
|
|
}
|
|
}
|
|
|
|
void SCountDlg::choose_2()
|
|
{
|
|
QTableWidget *pCurrent = (QTableWidget *)GetMainWindow()->m_pDataDlg->GetCurrentWidget();
|
|
int anCatalog[C_COMBO_MAX];
|
|
|
|
for (int i = 0; i < C_COMBO_MAX ; i++)
|
|
anCatalog[i] = m_pCombo[i].currentIndex();
|
|
|
|
QMap <QString,QMap<QString,int> > mapCount;
|
|
QSet <QString> setList;
|
|
QDate dateStart(2055,12,31),dateEnd(1900,1,1);
|
|
GetMainWindow()->m_progress.setRange(0,pCurrent->rowCount());
|
|
for (int nCount = 0 ; nCount < pCurrent->rowCount(); nCount++ )
|
|
{
|
|
QString astr[C_COMBO_MAX];
|
|
bool bFlag=true;
|
|
for (int i = 0; i < C_COMBO_MAX ; i++)
|
|
{
|
|
if (GetColumn().isDateColumn(anCatalog[i]))
|
|
{
|
|
QDateTime date;
|
|
QDate day = date.fromString(pCurrent->item(nCount,anCatalog[i])->text().trimmed(),"yyyy-MM-dd hh:mm:ss").date();
|
|
astr[i] = day.toString("yyyy-MM-dd").trimmed();
|
|
if(astr[i].isEmpty()) continue;
|
|
if (day.year() == 0) continue;
|
|
if (day < dateStart) dateStart=day;
|
|
if (day > dateEnd) dateEnd=day;
|
|
}
|
|
else
|
|
astr[i] = pCurrent->item(nCount,anCatalog[i])->text().trimmed();
|
|
if (astr[i].isEmpty()) bFlag = false;
|
|
}
|
|
if (bFlag == false) continue;
|
|
if (mapCount.contains(astr[0]) == false)
|
|
{
|
|
QMap <QString,int> mapSec;
|
|
mapCount.insert(astr[0],mapSec);
|
|
}
|
|
if (mapCount[astr[0]].contains(astr[1]) == false)
|
|
mapCount[astr[0]].insert(astr[1],0);
|
|
if (setList.contains(astr[1]) == false)
|
|
setList.insert(astr[1]);
|
|
mapCount[astr[0]][astr[1]]++;
|
|
GetMainWindow()->m_progress.setValue(nCount);
|
|
GetMainWindow()->m_progress.repaint();
|
|
}
|
|
m_pTable->clear();
|
|
QStringList strList;
|
|
strList.push_back(m_pCombo[0].currentText());
|
|
for (QSet<QString>::iterator i = setList.begin(); i != setList.end(); ++i)
|
|
strList.push_back(*i);
|
|
m_pTable->SetHeaderList(strList);
|
|
int nCount = 0;
|
|
m_dTotal = 0.0;
|
|
if (GetColumn().isDateColumn(anCatalog[0]))
|
|
{
|
|
//qDebug() << dateStart.daysTo(dateEnd);
|
|
m_pTable->setRowCount(dateStart.daysTo(dateEnd));
|
|
for (QDate now = dateStart; now < dateEnd ; now=now.addDays(1) )
|
|
{
|
|
int nCol = 0;
|
|
QString str = now.toString("yyyy-MM-dd").trimmed();
|
|
m_pTable->setItem(nCount,nCol++,new QTableWidgetItem(str));
|
|
if (mapCount.contains(str))
|
|
{
|
|
for (QSet<QString>::iterator j = setList.begin(); j != setList.end(); ++j)
|
|
{
|
|
if (mapCount[str].contains(*j))
|
|
m_pTable->setItem(nCount,nCol++,new STableNumberItem(QString::number(mapCount[str].value(*j))));
|
|
else
|
|
m_pTable->setItem(nCount,nCol++,new STableNumberItem(QString::number(0)));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
for (;nCol < strList.size();nCol++)
|
|
m_pTable->setItem(nCount,nCol,new STableNumberItem(QString::number(0)));
|
|
}
|
|
nCount++;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
m_pTable->setRowCount(mapCount.size());
|
|
for (QMap<QString,QMap<QString,int> >::iterator i = mapCount.begin(); i != mapCount.end(); ++i)
|
|
{
|
|
int nCol = 0;
|
|
m_pTable->setItem(nCount,nCol++,new QTableWidgetItem(i.key()));
|
|
for (QSet<QString>::iterator j = setList.begin(); j != setList.end(); ++j)
|
|
{
|
|
if (i->contains(*j))
|
|
m_pTable->setItem(nCount,nCol++,new STableNumberItem(QString::number(i->value(*j))));
|
|
else
|
|
m_pTable->setItem(nCount,nCol++,new STableNumberItem(QString::number(0)));
|
|
}
|
|
nCount++;
|
|
}
|
|
}
|
|
|
|
m_strGraph = "<html>\r\n<meta charset=\"utf8\">\r\n<style>\r\nbody {\r\n font: 10px sans-serif;\r\n}\r\n\r\n.axis path,\r\n.axis line {\r\n fill: none;"
|
|
"\r\n stroke: #000;\r\n shape-rendering: crispEdges;\r\n}\r\n\r\n.x.axis path {\r\n display: none;\r\n}\r\n\r\n.line {\r\n fill: none;\r\n stroke: steelblue;"
|
|
"\r\n stroke-width: 1.5px;\r\n}\r\n\r\n</style>\r\n<body>\r\n<script src=\"http://d3js.org/d3.v3.min.js\"></script>\r\n<script>\r\n"
|
|
"\r\nvar margin = {top: 20, right: 80, bottom: 30, left: 50},\r\n width = 960 - margin.left - margin.right,\r\n height = 500 - margin.top - margin.bottom;"
|
|
"\r\n\r\nvar parseDate = d3.time.format(\"%Y-%m-%d\").parse;\r\n\r\nvar x = d3.time.scale()\r\n .range([0, width]);\r\n\r\nvar y = d3.scale.linear()\r\n .range([height, 0]);"
|
|
"\r\n\r\nvar color = d3.scale.category10();\r\n\r\nvar xAxis = d3.svg.axis()\r\n .scale(x)\r\n .orient(\"bottom\");\r\n\r\nvar yAxis = d3.svg.axis()\r\n .scale(y)"
|
|
"\r\n .orient(\"left\");"
|
|
"\r\n"
|
|
"\r\nvar line = d3.svg.line()"
|
|
"\r\n .interpolate(\"basis\")"
|
|
"\r\n .x(function(d) { return x(d.date); })"
|
|
"\r\n .y(function(d) { return y(d.temperature); });"
|
|
"\r\n"
|
|
"\r\nvar svg = d3.select(\"body\").append(\"svg\")"
|
|
"\r\n .attr(\"width\", width + margin.left + margin.right)"
|
|
"\r\n .attr(\"height\", height + margin.top + margin.bottom)"
|
|
"\r\n .append(\"g\")"
|
|
"\r\n .attr(\"transform\", \"translate(\" + margin.left + \",\" + margin.top + \")\");"
|
|
"\r\n"
|
|
"\r\nd3.tsv(\"file:///[!F*i!l*e!]\", function(error, data) {"
|
|
"\r\n if (error) throw error;"
|
|
"\r\n"
|
|
"\r\n color.domain(d3.keys(data[0]).filter(function(key) { return key !== \"date\"; }));"
|
|
"\r\n"
|
|
"\r\n data.forEach(function(d) {"
|
|
"\r\n d.date = parseDate(d.date);"
|
|
"\r\n });"
|
|
"\r\n"
|
|
"\r\n var cities = color.domain().map(function(name) {"
|
|
"\r\n return {"
|
|
"\r\n name: name,"
|
|
"\r\n values: data.map(function(d) {"
|
|
"\r\n return {date: d.date, temperature: +d[name]};"
|
|
"\r\n })"
|
|
"\r\n };"
|
|
"\r\n });"
|
|
"\r\n"
|
|
"\r\n x.domain(d3.extent(data, function(d) { return d.date; }));"
|
|
"\r\n"
|
|
"\r\n y.domain(["
|
|
"\r\n d3.min(cities, function(c) { return d3.min(c.values, function(v) { return v.temperature; }); }),"
|
|
"\r\n d3.max(cities, function(c) { return d3.max(c.values, function(v) { return v.temperature; }); })"
|
|
"\r\n ]);"
|
|
"\r\n"
|
|
"\r\n svg.append(\"g\")"
|
|
"\r\n .attr(\"class\", \"x axis\")"
|
|
"\r\n .attr(\"transform\", \"translate(0,\" + height + \")\")"
|
|
"\r\n .call(xAxis);"
|
|
"\r\n"
|
|
"\r\n svg.append(\"g\")"
|
|
"\r\n .attr(\"class\", \"y axis\")"
|
|
"\r\n .call(yAxis)"
|
|
"\r\n .append(\"text\")"
|
|
"\r\n .attr(\"transform\", \"rotate(-90)\")"
|
|
"\r\n .attr(\"y\", 6)"
|
|
"\r\n .attr(\"dy\", \".71em\")"
|
|
"\r\n .style(\"text-anchor\", \"end\")"
|
|
"\r\n .text(\"Count\");"
|
|
"\r\n"
|
|
"\r\n var city = svg.selectAll(\".city\")"
|
|
"\r\n .data(cities)"
|
|
"\r\n .enter().append(\"g\")"
|
|
"\r\n .attr(\"class\", \"city\");"
|
|
"\r\n"
|
|
"\r\n city.append(\"path\")"
|
|
"\r\n .attr(\"class\", \"line\")"
|
|
"\r\n .attr(\"d\", function(d) { return line(d.values); })"
|
|
"\r\n .style(\"stroke\", function(d) { return color(d.name); });"
|
|
"\r\n"
|
|
"\r\n city.append(\"text\")"
|
|
"\r\n .datum(function(d) { return {name: d.name, value: d.values[d.values.length - 1]}; })"
|
|
"\r\n .attr(\"transform\", function(d) { return \"translate(\" + x(d.value.date) + \",\" + y(d.value.temperature) + \")\"; })"
|
|
"\r\n .attr(\"x\", 3)"
|
|
"\r\n .attr(\"dy\", \".35em\")"
|
|
"\r\n .text(function(d) { return d.name; });"
|
|
"\r\n});"
|
|
"\r\n"
|
|
"\r\n</script>"
|
|
"\r\n";
|
|
QRegExp re("\\s{2,}");
|
|
m_strGraph = m_strGraph.replace(re,"");
|
|
m_strGraph = m_strGraph.replace("[!F*i!l*e!]",QApplication::applicationDirPath()+"/graph.tsv");
|
|
}
|
|
|
|
void SCountDlg::run()
|
|
{
|
|
int nNone=0;
|
|
for (int i = 0; i < C_COMBO_MAX ; i++)
|
|
{
|
|
if (m_pCombo[i].currentIndex() == GetColumn().data().size())
|
|
nNone++;
|
|
}
|
|
switch(nNone)
|
|
{
|
|
case 0:choose_2();break;
|
|
case 1:choose_1();break;
|
|
}
|
|
}
|
|
|
|
void SCountDlg::graph()
|
|
{
|
|
QFile file(QApplication::applicationDirPath()+"/graph.tsv");
|
|
if (!file.open(QIODevice::WriteOnly)) return;
|
|
QTextStream out(&file);
|
|
out << QString("date\t").toUtf8();
|
|
for (int i = 1; i < m_pTable->columnCount();i++)
|
|
out << m_pTable->horizontalHeaderItem(i)->text().toUtf8() << QString("\t").toUtf8();
|
|
out << QString("\n").toUtf8();
|
|
GetMainWindow()->m_progress.setRange(0,m_pTable->rowCount());
|
|
for (int i = 0 ; i < m_pTable->rowCount() ; i++ )
|
|
{
|
|
for (int j = 0; j < m_pTable->columnCount();j++)
|
|
{
|
|
out << m_pTable->item(i,j)->text().trimmed().toUtf8() << QString("\t").toUtf8();
|
|
}
|
|
out << QString("\n").toUtf8();
|
|
GetMainWindow()->m_progress.setValue(i);
|
|
GetMainWindow()->m_progress.repaint();
|
|
}
|
|
file.close();
|
|
|
|
GetMainWindow()->m_graph.setHtml(m_strGraph.toUtf8(),QUrl("file:///"));
|
|
GetMainWindow()->m_graph.settings()->setObjectCacheCapacities(0,0,0);
|
|
GetMainWindow()->m_graph.repaint();
|
|
GetMainWindow()->m_graph.show();
|
|
}
|
|
|
|
void SCountDlg::save()
|
|
{
|
|
QFile file(QFileDialog::getSaveFileName(this,tr("Save Csv"), "", tr("Csv Files (*.csv)")));
|
|
if (!file.open(QIODevice::WriteOnly)) return;
|
|
QTextStream out(&file);
|
|
for (int i = 0; i < m_pTable->columnCount();i++)
|
|
out << m_pTable->horizontalHeaderItem(i)->text().toUtf8() << QString(",").toUtf8();
|
|
out << QString("\r\n").toUtf8();
|
|
GetMainWindow()->m_progress.setRange(0,m_pTable->rowCount());
|
|
for (int i = 0 ; i < m_pTable->rowCount() ; i++ )
|
|
{
|
|
for (int j = 0; j < m_pTable->columnCount();j++)
|
|
{
|
|
out << m_pTable->item(i,j)->text().trimmed().toUtf8() << QString(",").toUtf8();
|
|
}
|
|
out << QString("\r\n").toUtf8();
|
|
GetMainWindow()->m_progress.setValue(i);
|
|
GetMainWindow()->m_progress.repaint();
|
|
}
|
|
file.close();
|
|
}
|