707 lines
22 KiB
C++
707 lines
22 KiB
C++
#include "result.h"
|
|
#include "gnuplot-iostream.h"
|
|
#include "ui_result.h"
|
|
#include <QTableWidgetItem>
|
|
#include <algorithm>
|
|
#include <boost/format.hpp>
|
|
#include <boost/lexical_cast.hpp>
|
|
#include <cmath>
|
|
#include <iomanip> // setprecision
|
|
#include <iostream>
|
|
#include <map>
|
|
#include <math.h>
|
|
#include <qcolor.h>
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
#define SHELL 1
|
|
#define DEA 2
|
|
|
|
using std::cout;
|
|
using std::endl;
|
|
using std::string;
|
|
using std::vector;
|
|
|
|
Result::Result(DataBase * db, int rennid, QWidget * parent)
|
|
: QWidget(parent), ui(new Ui::Result) {
|
|
ui->setupUi(this);
|
|
this->db = db;
|
|
|
|
// prepare dummy data
|
|
vector<string> header;
|
|
// dummy for now
|
|
// this->rennid = 39;
|
|
this->rennid = rennid;
|
|
|
|
// test data
|
|
header.push_back("Spalte 1");
|
|
header.push_back("Spalte 2");
|
|
vector<vector<int>> data;
|
|
vector<int> subData;
|
|
subData.push_back(1);
|
|
subData.push_back(2);
|
|
data.push_back(subData);
|
|
data.push_back(subData);
|
|
|
|
this->ui->tWResult->resizeColumnsToContents();
|
|
this->ui->tWResult->horizontalHeader()->setStretchLastSection(true);
|
|
this->ui->tWResult->verticalHeader()->setVisible(true);
|
|
// this->model->setHeaderData(0, Qt::Horizontal, "Test");
|
|
|
|
// connects
|
|
// this->ui->pbClose->clicked()
|
|
|
|
std::stringstream statement;
|
|
statement << "select date from rennen where id like "
|
|
<< boost::lexical_cast<string>(rennid);
|
|
|
|
try {
|
|
this->renndatum = this->db->getData2(statement.str(), 1).at(0).at(0);
|
|
this->setWindowTitle(renndatum);
|
|
} catch (std::exception & e) {
|
|
Q_UNUSED(e);
|
|
cout << "Renndatum konnt aus Datenbank nicht gelesen werden" << endl;
|
|
}
|
|
// clear stringstream
|
|
statement.str(std::string());
|
|
statement << "select minimumroundtime from rennen where id like "
|
|
<< boost::lexical_cast<string>(rennid);
|
|
|
|
try {
|
|
this->minimumTime =
|
|
this->db->getData2(statement.str(), 1).at(0).at(0).toInt();
|
|
|
|
} catch (std::exception & e) {
|
|
Q_UNUSED(e);
|
|
cout << "Minimalzeit pro Runde konnte aus Datenbank nicht gelesen "
|
|
"werden."
|
|
<< endl;
|
|
}
|
|
|
|
vector<string> Fahrernamen;
|
|
for (size_t i = 0; i < this->getFahrerIds(this->rennid).size(); i++) {
|
|
Fahrernamen.push_back(
|
|
this->getFahrerName(this->getFahrerIds(this->rennid).at(i)));
|
|
}
|
|
|
|
vector<int> AutoIds = this->getAutoIds(this->rennid);
|
|
|
|
this->ui->tWResult->setRowCount(static_cast<int>(AutoIds.size()) * 2 + 4);
|
|
this->ui->tWResult->setColumnCount(static_cast<int>(Fahrernamen.size()) +
|
|
4);
|
|
|
|
int row = 0;
|
|
int col = 0;
|
|
this->ui->tWResult->setItem(row, col, new QTableWidgetItem("Auto"));
|
|
row += 0;
|
|
col += 1;
|
|
|
|
this->ui->tWResult->setItem(row, col, new QTableWidgetItem("Bahn"));
|
|
col += 1;
|
|
for (string fahrername : Fahrernamen) {
|
|
this->ui->tWResult->setItem(
|
|
row, col, new QTableWidgetItem(QString::fromStdString(fahrername)));
|
|
col += 1;
|
|
}
|
|
this->ui->tWResult->setItem(row, col,
|
|
new QTableWidgetItem("Durchschnitt Auto"));
|
|
col += 1;
|
|
this->ui->tWResult->setItem(
|
|
row, col, new QTableWidgetItem("Durchschnitt Auto gesamt"));
|
|
this->ui->tWResult->resizeColumnsToContents();
|
|
row = 1;
|
|
col = 1;
|
|
|
|
for (size_t i = 0; i <= AutoIds.size(); i++) {
|
|
this->ui->tWResult->setItem(row, col, new QTableWidgetItem("Shell"));
|
|
row += 1;
|
|
this->ui->tWResult->setItem(row, col, new QTableWidgetItem("Dea"));
|
|
row += 1;
|
|
}
|
|
|
|
vector<string> AutoNamen;
|
|
for (size_t i = 0; i < AutoIds.size(); i++) {
|
|
AutoNamen.push_back(this->getAutoName(AutoIds.at(i)));
|
|
}
|
|
col = 0;
|
|
row = 1;
|
|
|
|
for (string autoname : AutoNamen) {
|
|
this->ui->tWResult->setItem(
|
|
row, col, new QTableWidgetItem(QString::fromStdString(autoname)));
|
|
row += 2;
|
|
}
|
|
this->ui->tWResult->setItem(row, col,
|
|
new QTableWidgetItem("Durchschnitt Person"));
|
|
row += 2;
|
|
this->ui->tWResult->setItem(
|
|
row, col, new QTableWidgetItem("Durchschnitt Person ges"));
|
|
|
|
row = 1;
|
|
col = 2;
|
|
vector<vector<float>> zeiten;
|
|
vector<float> subZeiten;
|
|
|
|
for (int fahrer : this->getFahrerIds(this->rennid)) {
|
|
|
|
for (int car : this->getAutoIds(this->rennid)) {
|
|
int shellmin = this->getMinimum(fahrer, SHELL, this->rennid, car,
|
|
this->minimumTime);
|
|
int deamin = this->getMinimum(fahrer, DEA, this->rennid, car,
|
|
this->minimumTime);
|
|
|
|
subZeiten.push_back(static_cast<float>(shellmin) / 1000);
|
|
subZeiten.push_back(static_cast<float>(deamin) / 1000);
|
|
|
|
this->ui->tWResult->setItem(
|
|
row, col,
|
|
new QTableWidgetItem(QString::fromStdString(
|
|
this->myRound(static_cast<double>(shellmin) / 1000, 3))));
|
|
row += 1;
|
|
this->ui->tWResult->setItem(
|
|
row, col,
|
|
new QTableWidgetItem(QString::fromStdString(
|
|
this->myRound(static_cast<double>(deamin) / 1000, 3))));
|
|
row += 1;
|
|
}
|
|
zeiten.push_back(subZeiten);
|
|
subZeiten.clear();
|
|
|
|
col += 1;
|
|
row = 1;
|
|
}
|
|
|
|
// Durchschnitt Fahrer Shell und Dea
|
|
row = static_cast<int>(AutoNamen.size()) * 2 + 1;
|
|
col = 2;
|
|
for (size_t i = 0; i < Fahrernamen.size(); i++) {
|
|
vector<float> shellListe;
|
|
vector<float> dealiste;
|
|
for (size_t k = 0; k < zeiten.at(i).size(); k++) {
|
|
if (k % 2 == 0) {
|
|
shellListe.push_back(zeiten.at(i).at(k));
|
|
}
|
|
else {
|
|
dealiste.push_back(zeiten.at(i).at(k));
|
|
}
|
|
}
|
|
this->ui->tWResult->setItem(
|
|
row, col,
|
|
new QTableWidgetItem(QString::fromStdString(
|
|
this->myRound(this->meanVal(shellListe), 3))));
|
|
row += 1;
|
|
this->ui->tWResult->setItem(
|
|
row, col,
|
|
new QTableWidgetItem(QString::fromStdString(
|
|
this->myRound(this->meanVal(dealiste), 3))));
|
|
row -= 1;
|
|
col += 1;
|
|
shellListe.clear();
|
|
dealiste.clear();
|
|
}
|
|
|
|
// Durchschnitt Auto Shell und Dea
|
|
col = static_cast<int>(Fahrernamen.size()) + 2;
|
|
row = 1;
|
|
vector<float> durschnittAuto;
|
|
for (size_t i = 0; i < AutoIds.size() * 2; i++) { //*2 weil 2 Bahnen
|
|
|
|
for (size_t k = 0; k < Fahrernamen.size(); k++) {
|
|
durschnittAuto.push_back(zeiten.at(k).at(i));
|
|
}
|
|
this->ui->tWResult->setItem(
|
|
row, col,
|
|
new QTableWidgetItem(QString::fromStdString(
|
|
this->myRound(this->meanVal(durschnittAuto), 3))));
|
|
row += 1;
|
|
durschnittAuto.clear();
|
|
}
|
|
|
|
// Durchschnitt Fahrer ges
|
|
row = static_cast<int>(AutoIds.size()) * 2 + 3;
|
|
col = 2;
|
|
for (size_t i = 0; i < Fahrernamen.size(); i++) {
|
|
this->ui->tWResult->setItem(
|
|
row, col,
|
|
new QTableWidgetItem(QString::fromStdString(
|
|
this->myRound(this->meanVal(zeiten.at(i)), 3))));
|
|
col += 1;
|
|
}
|
|
|
|
// Durchschnitt Auto ges
|
|
col = static_cast<int>(Fahrernamen.size()) + 3;
|
|
row = 1;
|
|
for (size_t i = 0; i < AutoIds.size() * 2; i++) { //*2 weil 2 Bahnen
|
|
if (i % 2 == 0) {
|
|
vector<float> durschnittAuto;
|
|
for (size_t k = 0; k < Fahrernamen.size(); k++) {
|
|
durschnittAuto.push_back(zeiten.at(k).at(i));
|
|
durschnittAuto.push_back(zeiten.at(k).at(i + 1));
|
|
}
|
|
this->ui->tWResult->setItem(
|
|
row, col,
|
|
new QTableWidgetItem(QString::fromStdString(
|
|
this->myRound(this->meanVal(durschnittAuto), 3))));
|
|
row += 2;
|
|
durschnittAuto.clear();
|
|
}
|
|
}
|
|
|
|
// Minimum durchschnitt markieren
|
|
row = static_cast<int>(AutoIds.size()) * 2 + 3;
|
|
col = 2;
|
|
vector<float> avgList;
|
|
for (size_t i = 0; i < Fahrernamen.size(); i++) {
|
|
QString value = this->ui->tWResult->item(row, col)->text();
|
|
avgList.push_back(value.toFloat());
|
|
|
|
col += 1;
|
|
}
|
|
row = static_cast<int>(AutoIds.size()) * 2 + 3;
|
|
col = 2;
|
|
for (size_t i = 0; i < Fahrernamen.size(); i++) {
|
|
|
|
if (this->myMin(avgList) ==
|
|
this->ui->tWResult->item(row, col)->text().toFloat()) {
|
|
this->ui->tWResult->item(row, col)->setBackground(
|
|
QColor(118, 238, 0));
|
|
}
|
|
col += 1;
|
|
}
|
|
|
|
// minimum abs markieren
|
|
// minimum finden
|
|
vector<float> temp;
|
|
for (size_t i = 0; i < zeiten.size(); i++) {
|
|
temp.push_back(this->myMin(zeiten.at(i)));
|
|
}
|
|
float minimum = this->myMin(temp);
|
|
col = 2;
|
|
row = 1;
|
|
for (size_t i = 0; i < Fahrernamen.size(); i++) {
|
|
for (size_t k = 0; k < AutoIds.size() * 2; k++) {
|
|
|
|
// self.tWRennergebnis.item(row + k, col +
|
|
// i).setBackground(QtGui.QColor(255, 215, 0))
|
|
if (this->ui->tWResult->item(row + k, col + i)->text().toFloat() ==
|
|
minimum) {
|
|
this->ui->tWResult
|
|
->item(row + static_cast<int>(k), col + static_cast<int>(i))
|
|
->setBackground(QColor(255, 215, 0));
|
|
}
|
|
}
|
|
}
|
|
this->ui->tWResult->resizeColumnsToContents();
|
|
this->ui->tWResult->horizontalHeader()->setStretchLastSection(true);
|
|
|
|
this->drawPlots(rennid);
|
|
}
|
|
|
|
void Result::drawPlots(int rennid) {
|
|
|
|
// get drivers
|
|
vector<int> driverIds = this->getFahrerIds(rennid);
|
|
vector<string> drivers;
|
|
for_each(driverIds.begin(), driverIds.end(), [&drivers, this](int id) {
|
|
drivers.push_back(this->getFahrerName(id));
|
|
});
|
|
|
|
vector<int> carIds = this->getAutoIds(rennid);
|
|
|
|
// get minimal time from race
|
|
std::stringstream statement;
|
|
statement << "select rennen.minimumRoundtime from Rennen where id like "
|
|
<< boost::lexical_cast<string>(rennid);
|
|
int minTimeRace = 2950;
|
|
|
|
try {
|
|
minTimeRace =
|
|
this->db->getData2(statement.str(), 1).at(0).at(0).toInt();
|
|
} catch (std::exception & e) {
|
|
Q_UNUSED(e);
|
|
cout << "minimal race time not readable from database" << endl;
|
|
cout << "min time set to: " << minTimeRace;
|
|
}
|
|
|
|
vector<struct Times> times;
|
|
struct Times tempTimes;
|
|
int sumShell = 0;
|
|
int sumDea = 0;
|
|
for (int driverid : driverIds) {
|
|
sumShell = 0;
|
|
sumDea = 0;
|
|
for (int car : carIds) {
|
|
// shell
|
|
sumShell +=
|
|
this->getMinimum(driverid, SHELL, rennid, car, minTimeRace);
|
|
|
|
// dea
|
|
sumDea += this->getMinimum(driverid, DEA, rennid, car, minTimeRace);
|
|
}
|
|
tempTimes.shell = sumShell / static_cast<int>(carIds.size());
|
|
tempTimes.dea = sumDea / static_cast<int>(carIds.size());
|
|
|
|
times.push_back(tempTimes);
|
|
}
|
|
|
|
this->plotDrivers(drivers, times);
|
|
|
|
// clean up
|
|
times.clear();
|
|
|
|
// calc cars
|
|
for (int carId : carIds) {
|
|
sumShell = 0;
|
|
sumDea = 0;
|
|
for (int driverId : driverIds) {
|
|
// shell
|
|
sumShell +=
|
|
this->getMinimum(driverId, SHELL, rennid, carId, minTimeRace);
|
|
|
|
// dea
|
|
sumDea +=
|
|
this->getMinimum(driverId, DEA, rennid, carId, minTimeRace);
|
|
}
|
|
tempTimes.shell = sumShell / static_cast<int>(driverIds.size());
|
|
tempTimes.dea = sumDea / static_cast<int>(driverIds.size());
|
|
|
|
times.push_back(tempTimes);
|
|
}
|
|
|
|
// calc car names
|
|
vector<string> carNames;
|
|
for_each(carIds.begin(), carIds.end(), [&carNames, this](int id) {
|
|
carNames.push_back(this->getAutoName(id));
|
|
});
|
|
|
|
plotCars(carNames, times);
|
|
}
|
|
|
|
Result::~Result() {
|
|
cout << "result closed" << endl;
|
|
}
|
|
|
|
template <typename T> T Result::myMin(vector<T> vec) {
|
|
T min;
|
|
if (vec.size() > 0) {
|
|
min = vec.at(0);
|
|
}
|
|
else {
|
|
return 9999;
|
|
}
|
|
for (T minItr : vec) {
|
|
if (min > minItr) {
|
|
min = minItr;
|
|
}
|
|
}
|
|
return min;
|
|
}
|
|
|
|
template <typename T> double Result::meanVal(vector<T> vec) {
|
|
T sum = std::accumulate(vec.begin(), vec.end(), static_cast<float>(0.0));
|
|
double mean = static_cast<double>(sum) / vec.size();
|
|
return mean;
|
|
}
|
|
|
|
string Result::myRound(double x, int d = 0) {
|
|
std::stringstream stream;
|
|
stream << std::fixed << std::setprecision(d) << x;
|
|
return stream.str();
|
|
}
|
|
void Result::closeWindow() {
|
|
this->close();
|
|
}
|
|
|
|
vector<int> Result::getFahrerIds(int rennid) {
|
|
std::stringstream statement;
|
|
statement << "select id_fahrer from zeiten where id_rennen like "
|
|
<< boost::lexical_cast<string>(rennid) << " group by id_fahrer";
|
|
|
|
vector<int> vecToRet;
|
|
try {
|
|
vector<vector<QString>> ret = this->db->getData2(statement.str(), 1);
|
|
for (size_t i = 0; i < ret.size(); i++) {
|
|
string strValue = ret.at(i).at(0).toStdString();
|
|
vecToRet.push_back(boost::lexical_cast<int>(strValue));
|
|
}
|
|
return vecToRet;
|
|
} catch (std::exception & e) {
|
|
Q_UNUSED(e);
|
|
cout << "FahrerIds konnten nicht aus Datenbank gelesen "
|
|
"werden."
|
|
<< endl;
|
|
}
|
|
return vecToRet;
|
|
}
|
|
|
|
vector<int> Result::getAutoIds(int rennid) {
|
|
std::stringstream statement;
|
|
statement << "select id_auto from zeiten where id_rennen like "
|
|
<< boost::lexical_cast<string>(rennid) << " group by id_auto";
|
|
vector<vector<QString>> ret = this->db->getData2(statement.str(), 1);
|
|
|
|
vector<int> vecToRet;
|
|
try {
|
|
vector<vector<QString>> ret = this->db->getData2(statement.str(), 1);
|
|
for (size_t i = 0; i < ret.size(); i++) {
|
|
string strValue = ret.at(i).at(0).toStdString();
|
|
vecToRet.push_back(boost::lexical_cast<int>(strValue));
|
|
}
|
|
return vecToRet;
|
|
} catch (std::exception & e) {
|
|
Q_UNUSED(e);
|
|
cout << "AutoIds konnten nicht aus Datenbank gelesen werden." << endl;
|
|
}
|
|
return vecToRet;
|
|
}
|
|
|
|
// returns valid minimal time in milliseconds
|
|
int Result::getMinimum(int fahrerId, int bahnId, int rennId, int autoid,
|
|
int minTime) {
|
|
std::stringstream statement;
|
|
statement << "select zeit from Zeiten where id_rennen like "
|
|
<< boost::lexical_cast<string>(rennId) << " and id_fahrer like "
|
|
<< boost::lexical_cast<string>(fahrerId) << " and id_auto like "
|
|
<< boost::lexical_cast<string>(autoid) << " and id_bahn like "
|
|
<< boost::lexical_cast<string>(bahnId);
|
|
|
|
try {
|
|
vector<vector<QString>> res = this->db->getData2(statement.str(), 1);
|
|
// filter impossible values
|
|
vector<int> validTimes;
|
|
for (size_t i = 0; i < res.size(); i++) {
|
|
int timeToCompare = res.at(i).at(0).toInt();
|
|
if (timeToCompare >= minTime) {
|
|
validTimes.push_back(timeToCompare);
|
|
}
|
|
}
|
|
if (validTimes.size() > 0) {
|
|
std::vector<int>::iterator result =
|
|
std::min_element(validTimes.begin(), validTimes.end());
|
|
return *result;
|
|
}
|
|
else {
|
|
cout << "no valid time found" << endl;
|
|
return 9999;
|
|
}
|
|
|
|
} catch (std::exception & e) {
|
|
Q_UNUSED(e);
|
|
cout << "Minimalzeit konnte aus Datenbank nicht gelesen "
|
|
"werden."
|
|
<< endl;
|
|
}
|
|
return 9999;
|
|
}
|
|
|
|
float Result::getMean(int fahrerid, int bahnid, int rennid) {
|
|
vector<int> autoids = this->getAutoIds(rennid);
|
|
vector<int> avg;
|
|
|
|
for (int car : autoids) {
|
|
avg.push_back(
|
|
this->getMinimum(fahrerid, bahnid, rennid, car, this->minimumTime));
|
|
}
|
|
int sum = std::accumulate(avg.begin(), avg.end(), 0);
|
|
float floatAvg = 9999;
|
|
if (avg.size() > 0) {
|
|
floatAvg = static_cast<float>(sum) / static_cast<int>(avg.size());
|
|
cout << "avg:" << floatAvg << endl;
|
|
return floatAvg;
|
|
}
|
|
return 9999;
|
|
}
|
|
|
|
// returns name of driver with id
|
|
string Result::getFahrerName(int id) {
|
|
std::stringstream statement;
|
|
statement << "select name from fahrer where id like "
|
|
<< boost::lexical_cast<string>(id);
|
|
vector<vector<QString>> result = this->db->getData2(statement.str(), 1);
|
|
if (result.size() > 0) {
|
|
try {
|
|
return result.at(0).at(0).toStdString();
|
|
|
|
} catch (std::exception & e) {
|
|
Q_UNUSED(e);
|
|
cout << "Fehler beim Lesen vom Fahrernamen." << endl;
|
|
return "Leer";
|
|
}
|
|
}
|
|
return "Leer";
|
|
}
|
|
|
|
string Result::getAutoName(int id) {
|
|
std::stringstream statement;
|
|
statement << "select date from Rennen where id like "
|
|
<< boost::lexical_cast<string>(this->rennid);
|
|
string renndatum;
|
|
try {
|
|
QString qstrRenndatum =
|
|
this->db->getData2(statement.str(), 1).at(0).at(0);
|
|
renndatum = qstrRenndatum.toStdString();
|
|
|
|
} catch (std::exception & e) {
|
|
Q_UNUSED(e);
|
|
cout << "Renndatum konnte nicht gelesen werden." << endl;
|
|
return "nix";
|
|
}
|
|
|
|
try {
|
|
// clear stringstream
|
|
statement.str(std::string());
|
|
statement << "select name from Autokonfiguration where "
|
|
"id_auto like "
|
|
<< boost::lexical_cast<string>(id) << " and seit < '"
|
|
<< renndatum << "' order by seit DESC limit 1";
|
|
|
|
QString name = this->db->getData2(statement.str(), 1).at(0).at(0);
|
|
return name.toStdString();
|
|
} catch (std::exception & e) {
|
|
Q_UNUSED(e);
|
|
}
|
|
|
|
return "name";
|
|
}
|
|
|
|
double Result::getMinRangeTime(vector<struct Times> times) {
|
|
double min = 9999;
|
|
for (struct Times time : times) {
|
|
if (time.shell < min) {
|
|
min = time.shell;
|
|
}
|
|
if (time.dea < min) {
|
|
min = time.dea;
|
|
}
|
|
}
|
|
min -= 100;
|
|
cout << min << endl;
|
|
return min / 1000;
|
|
}
|
|
|
|
double Result::getMaxRangeTime(vector<struct Times> times) {
|
|
double max = 0;
|
|
for (struct Times time : times) {
|
|
if (time.shell > max) {
|
|
max = time.shell;
|
|
}
|
|
if (time.dea > max) {
|
|
max = time.dea;
|
|
}
|
|
}
|
|
max += 200;
|
|
return max / 1000;
|
|
}
|
|
|
|
void Result::plotCars(vector<string> carNames, vector<struct Times> times) {
|
|
// structure of times:
|
|
Gnuplot gp;
|
|
std::stringstream xlabels;
|
|
xlabels << "set xtics(";
|
|
for (size_t i = 0; i < carNames.size(); i++) {
|
|
xlabels << "'" << carNames[i] << "' "
|
|
<< boost::lexical_cast<string>(i + 0.15);
|
|
if (i + 1 != carNames.size()) {
|
|
xlabels << ", ";
|
|
}
|
|
else {
|
|
xlabels << ")\n";
|
|
}
|
|
}
|
|
cout << xlabels.str();
|
|
gp << xlabels.str();
|
|
|
|
std::vector<std::pair<double, double>> xy_pts;
|
|
for (size_t i = 0; i < carNames.size(); i++) {
|
|
xy_pts.push_back(std::make_pair(i, (times.at(i).shell) / 1000.0));
|
|
|
|
// xy_pts.push_back(std::make_pair(i + 0.3, times.at(i).dea));
|
|
}
|
|
double minRange = getMinRangeTime(times);
|
|
double maxRange = getMaxRangeTime(times);
|
|
|
|
string strMinRange = boost::str(boost::format("%.2f") % minRange);
|
|
string strMaxRange = boost::str(boost::format("%.2f") % maxRange);
|
|
|
|
double distance = (maxRange - minRange) / 35;
|
|
cout << "renndatum: " << this->renndatum.toStdString() << endl;
|
|
gp << "set yrange [" << strMinRange << ":" << strMaxRange << "]\n";
|
|
gp << "set term wxt title '" << this->renndatum.toStdString() << "'\n";
|
|
gp << "set boxwidth 0.3\nset style fill solid\n";
|
|
gp << "set title 'Vergleich der Autos'\n";
|
|
gp << "set ylabel 'Zeit in Sekunden'\n";
|
|
gp << "set xlabel 'Autos'\n";
|
|
gp << "show grid\nset grid ytics lc rgb '#bbbbbb' lw 1 lt 0\n";
|
|
gp << "plot" << gp.file1d(xy_pts)
|
|
<< "with boxes title 'Shell' lt rgb '#FF0000', '' u 1:($2 + " << distance
|
|
<< "):($2) with labels notitle" << std::endl;
|
|
|
|
xy_pts.clear();
|
|
for (size_t i = 0; i < carNames.size(); i++) {
|
|
// xy_pts.push_back(std::make_pair(i, times.at(i).shell));
|
|
xy_pts.push_back(std::make_pair(i + 0.3, (times.at(i).dea) / 1000.0));
|
|
}
|
|
|
|
gp << "replot" << gp.file1d(xy_pts)
|
|
<< "with boxes title 'Dea' lt rgb '#00FF00', ''u 1:($2 + " << distance
|
|
<< "):($2) "
|
|
"with labels notitle"
|
|
<< std::endl;
|
|
}
|
|
|
|
void Result::plotDrivers(vector<string> driverNames,
|
|
vector<struct Times> times) {
|
|
// structure of times:
|
|
Gnuplot gp;
|
|
std::stringstream xlabels;
|
|
xlabels << "set xtics(";
|
|
for (size_t i = 0; i < driverNames.size(); i++) {
|
|
xlabels << "'" << driverNames[i] << "' "
|
|
<< boost::lexical_cast<string>(i + 0.15);
|
|
if (i + 1 != driverNames.size()) {
|
|
xlabels << ", ";
|
|
}
|
|
else {
|
|
xlabels << ")\n";
|
|
}
|
|
}
|
|
|
|
gp << xlabels.str();
|
|
|
|
std::vector<std::pair<double, double>> xy_pts;
|
|
for (size_t i = 0; i < driverNames.size(); i++) {
|
|
xy_pts.push_back(std::make_pair(i, (times.at(i).shell) / 1000.0));
|
|
// xy_pts.push_back(std::make_pair(i + 0.3, times.at(i).dea));
|
|
}
|
|
double minRange = getMinRangeTime(times);
|
|
double maxRange = getMaxRangeTime(times);
|
|
|
|
string strMinRange = boost::str(boost::format("%.2f") % minRange);
|
|
string strMaxRange = boost::str(boost::format("%.2f") % maxRange);
|
|
|
|
double distance = (maxRange - minRange) / 35;
|
|
|
|
gp << "set yrange [" << strMinRange << ":" << strMaxRange << "]\n";
|
|
gp << "set term wxt title '" << this->renndatum.toStdString() << "'\n";
|
|
gp << "set boxwidth 0.3\nset style fill solid\n";
|
|
gp << "set title 'Vergleich der Fahrer'\n";
|
|
gp << "set ylabel 'Zeit in Sekunden'\n";
|
|
gp << "set xlabel 'Fahrer'\n";
|
|
gp << "show grid\nset grid ytics lc rgb '#bbbbbb' lw 1 lt 0\n";
|
|
gp << "plot" << gp.file1d(xy_pts)
|
|
<< "with boxes title 'Shell' lt rgb '#FF0000', '' u 1:($2 + " << distance
|
|
<< "):($2) with labels notitle" << std::endl;
|
|
|
|
xy_pts.clear();
|
|
for (size_t i = 0; i < driverNames.size(); i++) {
|
|
// xy_pts.push_back(std::make_pair(i, times.at(i).shell));
|
|
xy_pts.push_back(std::make_pair(i + 0.3, (times.at(i).dea) / 1000.0));
|
|
}
|
|
|
|
gp << "replot" << gp.file1d(xy_pts)
|
|
<< "with boxes title 'Dea' lt rgb '#00FF00', ''u 1:($2 +" << distance
|
|
<< "):($2) "
|
|
"with labels notitle"
|
|
<< std::endl;
|
|
}
|