[Companion][logsDialog]Fixes for #1863 in next.

This commit is contained in:
Grieb
2015-04-11 00:49:26 -03:00
parent ae26f4c4d5
commit e150310715
2 changed files with 308 additions and 256 deletions
+273 -248
View File
@@ -1,7 +1,6 @@
#include "logsdialog.h"
#include "appdata.h"
#include "ui_logsdialog.h"
#include "qcustomplot.h"
#include "helpers.h"
#if defined WIN32 || !defined __GNUC__
#include <windows.h>
@@ -14,25 +13,43 @@ logsDialog::logsDialog(QWidget *parent) :
ui(new Ui::logsDialog)
{
csvlog.clear();
srand(QDateTime::currentDateTime().toTime_t());
ui->setupUi(this);
this->setWindowIcon(CompanionIcon("logs.png"));
palette.clear();
plotLock=false;
for (int i=0; i< 60; i++)
palette << QColor(rand()%245+10, rand()%245+10, rand()%245+10);
colors.append(Qt::green);
colors.append(Qt::red);
colors.append(Qt::yellow);
colors.append(Qt::magenta);
colors.append(Qt::cyan);
colors.append(Qt::darkBlue);
colors.append(Qt::darkGreen);
colors.append(Qt::darkRed);
colors.append(Qt::darkYellow);
colors.append(Qt::darkMagenta);
colors.append(Qt::darkCyan);
colors.append(Qt::blue);
pen.setWidthF(1.5);
ui->customPlot->setInteractions(QCustomPlot::iRangeDrag | QCustomPlot::iRangeZoom | QCustomPlot::iSelectAxes |
QCustomPlot::iSelectLegend | QCustomPlot::iSelectPlottables | QCustomPlot::iSelectTitle | QCustomPlot::iSelectItems);
ui->customPlot->setRangeDrag(Qt::Horizontal|Qt::Vertical);
ui->customPlot->setRangeZoom(Qt::Horizontal|Qt::Vertical);
ui->customPlot->yAxis->setRange(-1100, 1100);
ui->customPlot->setupFullAxesBox();
ui->customPlot->setTitle(tr("Telemetry logs"));
ui->customPlot->xAxis->setLabel(tr("Time"));
ui->customPlot->xAxis->setLabel(tr("Time (hh:mm:ss)"));
ui->customPlot->xAxis->setTickLabelType(QCPAxis::ltDateTime);
ui->customPlot->xAxis->setDateTimeFormat("hh:mm:ss");
QDateTime now = QDateTime::currentDateTime();
ui->customPlot->xAxis->setRange(now.addSecs(-60*60*2).toTime_t(),
now.toTime_t());
ui->customPlot->legend->setVisible(true);
ui->customPlot->yAxis->setTickLabels(false);
ui->customPlot->yAxis->setAutoTickCount(10);
ui->customPlot->xAxis2->setTicks(false);
ui->customPlot->yAxis2->setTicks(false);
ui->customPlot->setRangeZoomFactor(2, 2);
QFont legendFont = font();
@@ -44,23 +61,22 @@ logsDialog::logsDialog(QWidget *parent) :
QString Path=g.gePath();
if (Path.isEmpty() || !QFile(Path).exists()) {
ui->mapsButton->hide();
}
}
// connect slot that ties some axis selections together (especially opposite axes):
connect(ui->customPlot, SIGNAL(selectionChangedByUser()), this, SLOT(selectionChanged()));
// connect slots that takes care that when an axis is selected, only that direction can be dragged and zoomed:
connect(ui->customPlot, SIGNAL(mousePress(QMouseEvent*)), this, SLOT(mousePress()));
connect(ui->customPlot, SIGNAL(mouseWheel(QWheelEvent*)), this, SLOT(mouseWheel()));
// make bottom and left axes transfer their ranges to top and right axes:
connect(ui->customPlot->xAxis, SIGNAL(rangeChanged(QCPRange)), ui->customPlot->xAxis2, SLOT(setRange(QCPRange)));
connect(ui->customPlot->yAxis, SIGNAL(rangeChanged(QCPRange)), ui->customPlot->yAxis2, SLOT(setRange(QCPRange)));
// make left axes transfer its ranges to right axes:
connect(ui->customPlot->yAxis, SIGNAL(rangeChanged(QCPRange)), this, SLOT(setRangeyAxis2(QCPRange)));
// connect some interaction slots:
connect(ui->customPlot, SIGNAL(titleDoubleClick(QMouseEvent*)), this, SLOT(titleDoubleClick()));
connect(ui->customPlot, SIGNAL(axisDoubleClick(QCPAxis*,QCPAxis::SelectablePart,QMouseEvent*)), this, SLOT(axisLabelDoubleClick(QCPAxis*,QCPAxis::SelectablePart)));
connect(ui->customPlot, SIGNAL(legendDoubleClick(QCPLegend*,QCPAbstractLegendItem*,QMouseEvent*)), this, SLOT(legendDoubleClick(QCPLegend*,QCPAbstractLegendItem*)));
connect(ui->customPlot, SIGNAL(plottableDoubleClick(QCPAbstractPlottable *, QMouseEvent *)), this, SLOT(plottableItemDoubleClick(QCPAbstractPlottable *, QMouseEvent *)));
// connect(ui->customPlot, SIGNAL(plottableDoubleClick(QCPAbstractPlottable *, QMouseEvent *)), this, SLOT(plottableItemDoubleClick(QCPAbstractPlottable *, QMouseEvent *)));
connect(ui->FieldsTW, SIGNAL(itemSelectionChanged()), this, SLOT(plotLogs()));
connect(ui->logTable, SIGNAL(itemSelectionChanged()), this, SLOT(plotLogs()));
connect(ui->Reset_PB, SIGNAL(clicked()), this, SLOT(plotLogs()));
@@ -71,24 +87,12 @@ logsDialog::~logsDialog()
delete ui;
}
double logsDialog::GetScale(QString channel) {
QString Analog="Rud,Ele,Thr,Ail,P1,P2,P3";
QString Switches="THR,RUD,ELE,ID0,ID1,ID2,AIL,GEA,TRN";
if (Analog.contains(channel)) {
return 1.0;
}
if (Switches.contains(channel)) {
return 0.001;
}
return -1;
}
void logsDialog::titleDoubleClick()
{
// Set the plot title by double clicking on it
bool ok;
QString newTitle = QInputDialog::getText(this, "QCustomPlot example", "New plot title:", QLineEdit::Normal, ui->customPlot->title(), &ok);
QString newTitle = QInputDialog::getText(this, "Plot Title Change", "New plot title:", QLineEdit::Normal, ui->customPlot->title(), &ok);
if (ok)
{
ui->customPlot->setTitle(newTitle);
@@ -99,11 +103,11 @@ void logsDialog::titleDoubleClick()
void logsDialog::axisLabelDoubleClick(QCPAxis *axis, QCPAxis::SelectablePart part)
{
// Set an axis label by double clicking on it
if (part == QCPAxis::spAxisLabel) // only react when the actual axis label is clicked, not tick label or axis backbone
{
bool ok;
QString newLabel = QInputDialog::getText(this, "QCustomPlot example", "New axis label:", QLineEdit::Normal, axis->label(), &ok);
QString newLabel = QInputDialog::getText(this, "Axis Label Change", "New axis label:", QLineEdit::Normal, axis->label(), &ok);
if (ok)
{
axis->setLabel(newLabel);
@@ -115,13 +119,11 @@ void logsDialog::axisLabelDoubleClick(QCPAxis *axis, QCPAxis::SelectablePart par
void logsDialog::legendDoubleClick(QCPLegend *legend, QCPAbstractLegendItem *item)
{
// Rename a graph by double clicking on its legend item
Q_UNUSED(legend)
if (item) // only react if item was clicked (user could have clicked on border padding of legend where there is no item, then item is 0)
{
QCPPlottableLegendItem *plItem = qobject_cast<QCPPlottableLegendItem*>(item);
bool ok;
QString newName = QInputDialog::getText(this, "QCustomPlot example", "New graph name:", QLineEdit::Normal, plItem->plottable()->name(), &ok);
QString newName = QInputDialog::getText(this, "Graph Name Change", "New graph name:", QLineEdit::Normal, plItem->plottable()->name(), &ok);
if (ok)
{
plItem->plottable()->setName(newName);
@@ -129,10 +131,11 @@ void logsDialog::legendDoubleClick(QCPLegend *legend, QCPAbstractLegendItem *ite
}
}
}
void logsDialog::plottableItemDoubleClick(QCPAbstractPlottable * plottable, QMouseEvent * event)
{
// void logsDialog::plottableItemDoubleClick(QCPAbstractPlottable * plottable, QMouseEvent * event)
// {
// qDebug() << plottable->
}
// }
void logsDialog::selectionChanged()
{
@@ -140,31 +143,33 @@ void logsDialog::selectionChanged()
normally, axis base line, axis tick labels and axis labels are selectable separately, but we want
the user only to be able to select the axis as a whole, so we tie the selected states of the tick labels
and the axis base line together. However, the axis label shall be selectable individually.
The selection state of the left and right axes shall be synchronized as well as the state of the
bottom and top axes.
Further, we want to synchronize the selection of the graphs with the selection state of the respective
legend item belonging to that graph. So the user can select a graph by either clicking on the graph itself
or on its legend item.
*/
if (plotLock)
return;
// make top and bottom axes be selected synchronously, and handle axis and tick labels as one selectable object:
if (ui->customPlot->xAxis->selected().testFlag(QCPAxis::spAxis) || ui->customPlot->xAxis->selected().testFlag(QCPAxis::spTickLabels) ||
ui->customPlot->xAxis2->selected().testFlag(QCPAxis::spAxis) || ui->customPlot->xAxis2->selected().testFlag(QCPAxis::spTickLabels))
if (plotLock) return;
// handle bottom axis and tick labels as one selectable object:
if (ui->customPlot->xAxis->selected().testFlag(QCPAxis::spAxis) || ui->customPlot->xAxis->selected().testFlag(QCPAxis::spTickLabels))
{
ui->customPlot->xAxis2->setSelected(QCPAxis::spAxis|QCPAxis::spTickLabels);
ui->customPlot->xAxis->setSelected(QCPAxis::spAxis|QCPAxis::spTickLabels);
}
// make left and right axes be selected synchronously, and handle axis and tick labels as one selectable object:
// make left and right axes be selected synchronously,
// and handle axis and tick labels as one selectable object:
if (ui->customPlot->yAxis->selected().testFlag(QCPAxis::spAxis) || ui->customPlot->yAxis->selected().testFlag(QCPAxis::spTickLabels) ||
ui->customPlot->yAxis2->selected().testFlag(QCPAxis::spAxis) || ui->customPlot->yAxis2->selected().testFlag(QCPAxis::spTickLabels))
{
ui->customPlot->yAxis2->setSelected(QCPAxis::spAxis|QCPAxis::spTickLabels);
ui->customPlot->yAxis->setSelected(QCPAxis::spAxis|QCPAxis::spTickLabels);
if (hasyAxis2) {
ui->customPlot->yAxis2->setSelected(QCPAxis::spAxis|QCPAxis::spTickLabels);
}
}
// synchronize selection of graphs with selection of corresponding legend items:
for (int i=0; i<ui->customPlot->graphCount(); ++i)
{
@@ -178,7 +183,8 @@ void logsDialog::selectionChanged()
}
}
void logsDialog::on_mapsButton_clicked() {
void logsDialog::on_mapsButton_clicked()
{
int n = csvlog.count(); // number of points in graph
if (n==0) return;
int latcol=0, longcol=0, altcol=0, speedcol=0;
@@ -186,13 +192,13 @@ void logsDialog::on_mapsButton_clicked() {
bool rangeSelected=false;
ui->FieldsTW->setDisabled(true);
ui->logTable->setDisabled(true);
QString gePath=g.gePath();
if (gePath.isEmpty() || !QFile(gePath).exists()) {
ui->FieldsTW->setDisabled(false);
ui->logTable->setDisabled(false);
return;
}
}
QSet<int> nondataCols;
for (int i=1; i<csvlog.at(0).count(); i++) {
//Long,Lat,Course,GPS Speed,GPS Alt
@@ -225,7 +231,7 @@ void logsDialog::on_mapsButton_clicked() {
if (itemSelected==0) {
itemSelected=n-1;
}
QString geIconFilename = generateProcessUniqueTempFileName("track0.png");
if (QFile::exists(geIconFilename)) {
QFile::remove(geIconFilename);
@@ -247,7 +253,7 @@ void logsDialog::on_mapsButton_clicked() {
return;
}
QString latitude,longitude;
double flatitude, flongitude,temp;
double flatitude, flongitude,temp;
QTextStream outputStream(&geFile);
outputStream << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<kml xmlns=\"http://www.opengis.net/kml/2.2\" xmlns:gx=\"http://www.google.com/kml/ext/2.2\">\n";
outputStream << "\t<Document>\n\t\t<name>" << logFilename << "</name>\n";
@@ -269,7 +275,7 @@ void logsDialog::on_mapsButton_clicked() {
}
}
outputStream << "\t\t</Schema>\n";
QString planeName;
if (logFilename.indexOf("-")>0) {
planeName=logFilename.left(logFilename.indexOf("-"));
@@ -286,7 +292,7 @@ void logsDialog::on_mapsButton_clicked() {
outputStream << "\t\t\t\t\t<when>"<< tstamp <<"</when>\n";
}
}
for (int i=1; i<n; i++) {
if ((ui->logTable->item(i-1,1)->isSelected() &&rangeSelected) || !rangeSelected) {
latitude=csvlog.at(i).at(latcol).trimmed();
@@ -348,7 +354,7 @@ void logsDialog::mousePress()
{
// if an axis is selected, only allow the direction of that axis to be dragged
// if no axis is selected, both directions may be dragged
if (ui->customPlot->xAxis->selected().testFlag(QCPAxis::spAxis))
ui->customPlot->setRangeDrag(ui->customPlot->xAxis->orientation());
else if (ui->customPlot->yAxis->selected().testFlag(QCPAxis::spAxis))
@@ -370,173 +376,8 @@ void logsDialog::mouseWheel()
}
if (orientation) {
ui->customPlot->setRangeZoom((Qt::Orientation)orientation);
}
}
void logsDialog::plotValue(int index, int plot, int numplots)
{
if (plotLock)
return;
int n = csvlog.count(); // number of points in graph
bool rangeSelected=false;
uint minx;
uint maxx;
uint itemSelected=0;
uint itemCount=0;
double miny=9999;
double maxy=-9999;
minx=-1;
maxx=0;
double tmpval,yscale;
for (int i=1; i<n; i++) {
if (ui->logTable->item(i-1,1)->isSelected()) {
rangeSelected=true;
itemSelected++;
}
}
if (itemSelected==0) {
itemSelected=n-1;
}
QVector<double> x(itemSelected), y(itemSelected);
if (numplots<3) {
for (int i=1; i<n; i++) {
if ((ui->logTable->item(i-1,1)->isSelected() &&rangeSelected) || !rangeSelected) {
double tmp;
QString tstamp=csvlog.at(i).at(0)+QString(" ")+csvlog.at(i).at(1);
if (csvlog.at(i).at(1).contains(".")) {
tmp=QDateTime::fromString(tstamp, "yyyy-MM-dd HH:mm:ss.zzz").toTime_t();
tmp+=csvlog.at(i).at(1).mid(csvlog.at(i).at(1).indexOf(".")).toDouble();
} else {
tmp=QDateTime::fromString(tstamp, "yyyy-MM-dd HH:mm:ss").toTime_t();
}
if (minx>tmp) {
minx=tmp;
}
if (maxx<tmp) {
maxx=tmp;
}
tmpval = csvlog.at(i).at(index).toDouble();
if (tmpval>maxy) {
maxy=tmpval;
}
if (tmpval<miny) {
miny=tmpval;
}
}
}
yscale=1;
} else {
yscale=GetScale(csvlog.at(0).at(index));
for (int i=1; i<n; i++)
{
if ((ui->logTable->item(i-1,1)->isSelected() &&rangeSelected) || !rangeSelected) {
double tmp;
QString tstamp=csvlog.at(i).at(0)+QString(" ")+csvlog.at(i).at(1);
if (csvlog.at(i).at(1).contains(".")) {
tmp=QDateTime::fromString(tstamp, "yyyy-MM-dd HH:mm:ss.zzz").toTime_t();
tmp+=csvlog.at(i).at(1).mid(csvlog.at(i).at(1).indexOf(".")).toDouble();
} else {
tmp=QDateTime::fromString(tstamp, "yyyy-MM-dd HH:mm:ss").toTime_t();
}
if (minx>tmp) {
minx=tmp;
}
if (maxx<tmp) {
maxx=tmp;
}
if (yscale<0) {
tmpval = csvlog.at(i).at(index).toDouble();
if (tmpval>maxy) {
maxy=tmpval;
}
if (tmpval<miny) {
miny=tmpval;
}
}
}
}
if (yscale<0) {
if (miny<0) {
miny=-miny;
}
if (maxy<0) {
maxy=-maxy;
}
if (miny>maxy) {
yscale=miny/1000.0;
} else {
yscale=maxy/1000.0;
}
if (yscale==0) {
yscale=1;
}
}
}
for (int i=1; i<n; i++) {
if ((ui->logTable->item(i-1,1)->isSelected() &&rangeSelected) || !rangeSelected) {
double tmp;
QString tstamp=csvlog.at(i).at(0)+QString(" ")+csvlog.at(i).at(1);
if (csvlog.at(i).at(1).contains(".")) {
tmp=QDateTime::fromString(tstamp, "yyyy-MM-dd HH:mm:ss.zzz").toTime_t();
tmp+=csvlog.at(i).at(1).mid(csvlog.at(i).at(1).indexOf(".")).toDouble();
} else {
tmp=QDateTime::fromString(tstamp, "yyyy-MM-dd HH:mm:ss").toTime_t();
}
x[itemCount] = tmp-minx;
y[itemCount] = csvlog.at(i).at(index).toDouble()/yscale;
itemCount++;
}
}
QPen graphPen;
QColor color=palette.at(index % 60);
graphPen.setColor(color);
graphPen.setWidthF(1.5);
if (numplots<3) {
if (plot==1) {
ui->customPlot->xAxis->setRange(0, maxx-minx);
ui->customPlot->yAxis->setRange(miny,maxy);
ui->customPlot->yAxis->setLabelColor(color);
ui->customPlot->yAxis->setLabel(csvlog.at(0).at(index));
ui->customPlot->yAxis->setTickLabels(true);
ui->customPlot->yAxis->setVisible(true);
ui->customPlot->yAxis2->setVisible(false);
ui->customPlot->addGraph(ui->customPlot->xAxis, ui->customPlot->yAxis);
ui->customPlot->graph(0)->setName(csvlog.at(0).at(index));
ui->customPlot->graph(0)->setData(x, y);
ui->customPlot->graph(0)->setLineStyle(QCPGraph::lsLine);
ui->customPlot->graph(0)->setScatterStyle(QCP::ssNone);
//ui->customPlot->graph()->setLineStyle((QCPGraph::LineStyle)(rand()%5+1));
ui->customPlot->graph(0)->setPen(graphPen);
}
else {
ui->customPlot->xAxis2->setRange(0, maxx-minx);
ui->customPlot->yAxis2->setTickLabels(true);
ui->customPlot->yAxis2->setRange(miny,maxy);
ui->customPlot->yAxis2->setVisible(true);
ui->customPlot->yAxis2->setLabelColor(color);
ui->customPlot->yAxis2->setLabel(csvlog.at(0).at(index));
ui->customPlot->addGraph(ui->customPlot->xAxis2, ui->customPlot->yAxis2);
ui->customPlot->graph(1)->setName(csvlog.at(0).at(index));
ui->customPlot->graph(1)->setData(x, y);
ui->customPlot->graph(1)->setLineStyle(QCPGraph::lsLine);
ui->customPlot->graph(1)->setScatterStyle(QCP::ssNone);
//ui->customPlot->graph()->setLineStyle((QCPGraph::LineStyle)(rand()%5+1));
ui->customPlot->graph(1)->setPen(graphPen);
}
}
else {
ui->customPlot->yAxis->setTickLabels(false);
ui->customPlot->yAxis2->setTickLabels(false);
ui->customPlot->yAxis->setRange(-1100, 1100);
ui->customPlot->yAxis->setVisible(false);
ui->customPlot->yAxis2->setVisible(false);
ui->customPlot->addGraph();
ui->customPlot->graph()->setName(csvlog.at(0).at(index));
ui->customPlot->graph()->setData(x, y);
ui->customPlot->graph()->setLineStyle(QCPGraph::lsLine);
ui->customPlot->graph()->setScatterStyle(QCP::ssNone);
//ui->customPlot->graph()->setLineStyle((QCPGraph::LineStyle)(rand()%5+1));
ui->customPlot->graph()->setPen(graphPen);
ui->customPlot->setRangeZoom(Qt::Horizontal|Qt::Vertical);
}
}
@@ -552,6 +393,9 @@ void logsDialog::removeSelectedGraph()
void logsDialog::removeAllGraphs()
{
ui->customPlot->clearGraphs();
ui->customPlot->legend->setVisible(false);
ui->customPlot->yAxis2->setVisible(false);
ui->customPlot->yAxis->setTickLabels(false);
ui->customPlot->replot();
}
@@ -602,7 +446,7 @@ void logsDialog::on_fileOpen_BT_clicked()
}
ui->logTable->setItem(i-1,j,item );
}
}
}
ui->logTable->resizeColumnsToContents();
ui->logTable->resizeRowsToContents();
// Hack - add some pixel of space to columns as Qt resize them too small
@@ -614,7 +458,7 @@ void logsDialog::on_fileOpen_BT_clicked()
}
}
bool logsDialog::cvsFileParse()
bool logsDialog::cvsFileParse()
{
QFile file(ui->FileName_LE->text());
int errors=0;
@@ -676,7 +520,7 @@ bool logsDialog::cvsFileParse()
}
logFilename=QFileInfo(file.fileName()).baseName();
}
file.close();
if (errors>1) {
QMessageBox::warning(this, "Companion", tr("The selected logfile contains %1 invalid lines out of %2 total lines").arg(errors).arg(lines));
@@ -687,8 +531,8 @@ bool logsDialog::cvsFileParse()
csvlog.clear();
return false;
}
int lastvalue=0;
int tmp;
double lastvalue=0;
double tmp;
ui->sessions_CB->addItem("---");
for (int i=1; i<n; i++) {
QString tstamp=csvlog.at(i).at(0)+QString(" ")+csvlog.at(i).at(1);
@@ -715,19 +559,19 @@ void logsDialog::on_sessions_CB_currentIndexChanged(int index)
if (plotLock)
return;
plotLock=true;
int start=0;
int stop=-1;
double start=0;
double stop=-1;
if (index!=0) {
start=ui->sessions_CB->itemData(index,Qt::UserRole).toInt();
start=ui->sessions_CB->itemData(index,Qt::UserRole).toDouble();
if (index<(ui->sessions_CB->count()-1)) {
stop=ui->sessions_CB->itemData(index+1,Qt::UserRole).toInt();
stop=ui->sessions_CB->itemData(index+1,Qt::UserRole).toDouble();
}
}
// if (ui->logTable->item(i-1,1)->isSelected()) {
ui->logTable->clearSelection();
if (start>0) {
int n=csvlog.count();
int tmp;
double tmp;
ui->logTable->setSelectionBehavior(QAbstractItemView::SelectRows);
for (int i=1; i<n; i++) {
QString tstamp=csvlog.at(i).at(0)+QString(" ")+csvlog.at(i).at(1);
@@ -750,7 +594,7 @@ void logsDialog::on_sessions_CB_currentIndexChanged(int index)
ui->logTable->selectionModel()->select(ui->logTable->model()->index(i-1,0), QItemSelectionModel::Select|QItemSelectionModel::Rows);
}
}
}
}
}
plotLock=false;
plotLogs();
@@ -758,24 +602,205 @@ void logsDialog::on_sessions_CB_currentIndexChanged(int index)
void logsDialog::plotLogs()
{
if (plotLock)
if (plotLock) return;
if (!ui->FieldsTW->selectedItems().length()) {
removeAllGraphs();
return;
int n = csvlog.at(0).count(); // number of points in graph
}
plotsCollection plots;
QList<QTableWidgetSelectionRange> selections = ui->logTable->selectedRanges();
int rowCount = selections.length();
bool hasLogSelection;
QVarLengthArray<int> selectedRows;
if (rowCount) {
hasLogSelection = true;
foreach (QTableWidgetSelectionRange range, selections) {
for (int i = range.topRow(); i <= range.bottomRow(); i++) {
selectedRows.append(i);
}
}
} else {
hasLogSelection = false;
rowCount = ui->logTable->rowCount();
}
plots.min_x = QDateTime::currentDateTime().toTime_t();
plots.max_x = 0;
foreach (QTableWidgetItem *plot, ui->FieldsTW->selectedItems()) {
coords plotCoords;
int plotColumn = plot->row() + 2; // Date and Time first
plotCoords.min_y = 999999;
plotCoords.max_y = -999999;
plotCoords.secondRange = false;
plotCoords.name = plot->text();
for (int row = 0; row < rowCount; row++) {
QTableWidgetItem *logValue;
if (hasLogSelection) {
logValue = ui->logTable->item(selectedRows.at(row), plotColumn);
} else {
logValue = ui->logTable->item(row, plotColumn);
}
double y;
double time;
QString time_str;
y = logValue->text().toDouble();
plotCoords.y.push_back(y);
if (plotCoords.min_y > y) {
plotCoords.min_y = y;
} else if (plotCoords.max_y < y) {
plotCoords.max_y = y;
}
time_str = ui->logTable->item(row, 0)->text() + QString(" ")
+ ui->logTable->item(row, 1)->text();
if (time_str.contains('.')) {
time = QDateTime::fromString(time_str, "yyyy-MM-dd HH:mm:ss.zzz")
.toTime_t();
time += time_str.mid(time_str.indexOf('.')).toDouble();
} else {
time = QDateTime::fromString(time_str, "yyyy-MM-dd HH:mm:ss")
.toTime_t();
}
plotCoords.x.push_back(time);
if (plots.min_x > time) {
plots.min_x = time;
} else if (plots.max_x < time) {
plots.max_x = time;
}
}
plots.coords.append(plotCoords);
}
plots.rangeOneMin = plots.coords.at(0).min_y;
plots.rangeOneMax = plots.coords.at(0).max_y;
plots.twoRanges = false;
plots.tooManyRanges = false;
for (int i = 1; i < plots.coords.size(); i++) {
if (plots.tooManyRanges) {
if (plots.coords.at(i).min_y < plots.rangeOneMin) {
plots.rangeOneMin = plots.coords.at(i).min_y;
}
if (plots.coords.at(i).max_y > plots.rangeOneMax) {
plots.rangeOneMax = plots.coords.at(i).max_y;
}
continue;
}
double actualRange = plots.rangeOneMax - plots.rangeOneMin;
double thisRange = plots.coords.at(i).max_y - plots.coords.at(i).min_y;
if (thisRange > actualRange * 1.3 || thisRange * 1.3 < actualRange ||
plots.coords.at(i).min_y > plots.rangeOneMax ||
plots.coords.at(i).max_y < plots.rangeOneMin) {
plots.coords[i].secondRange = true;
if (plots.twoRanges) {
actualRange = plots.rangeTwoMax - plots.rangeTwoMin;
if (thisRange > actualRange * 1.3 || thisRange * 1.3 < actualRange ||
plots.coords.at(i).min_y > plots.rangeTwoMax ||
plots.coords.at(i).max_y < plots.rangeTwoMin) {
plots.tooManyRanges = true;
plots.twoRanges = false;
if (plots.rangeTwoMin < plots.rangeOneMin) {
plots.rangeOneMin = plots.rangeTwoMin;
}
if (plots.rangeTwoMax > plots.rangeOneMax) {
plots.rangeOneMax = plots.rangeTwoMax;
}
if (plots.coords.at(i).min_y < plots.rangeOneMin) {
plots.rangeOneMin = plots.coords.at(i).min_y;
}
if (plots.coords.at(i).max_y > plots.rangeOneMax) {
plots.rangeOneMax = plots.coords.at(i).max_y;
}
} else {
if (plots.coords.at(i).min_y < plots.rangeTwoMin) {
plots.rangeTwoMin = plots.coords.at(i).min_y;
}
if (plots.coords.at(i).max_y > plots.rangeTwoMax) {
plots.rangeTwoMax = plots.coords.at(i).max_y;
}
}
} else {
plots.twoRanges = true;
plots.rangeTwoMax = plots.coords.at(i).max_y;
plots.rangeTwoMin = plots.coords.at(i).min_y;
}
} else {
if (plots.coords.at(i).min_y < plots.rangeOneMin) {
plots.rangeOneMin = plots.coords.at(i).min_y;
}
if (plots.coords.at(i).max_y > plots.rangeOneMax) {
plots.rangeOneMax = plots.coords.at(i).max_y;
}
}
}
if (plots.twoRanges) {
rangeRatio = (plots.rangeTwoMax - plots.rangeTwoMin) /
(plots.rangeOneMax - plots.rangeOneMin);
rangeyAxisMin = plots.rangeOneMin;
rangeyAxisMax = plots.rangeOneMax;
rangeyAxis2Min = plots.rangeTwoMin;
rangeyAxis2Max = plots.rangeTwoMax;
hasyAxis2 = true;
} else {
hasyAxis2 = false;
}
removeAllGraphs();
int numplots=0;
int plots=0;
for (int i=0; i<n-2; i++) {
if (ui->FieldsTW->item(0,i)->isSelected()) {
numplots++;
}
ui->customPlot->xAxis->setRange(plots.min_x, plots.max_x);
ui->customPlot->yAxis->setRange(plots.rangeOneMin, plots.rangeOneMax);
ui->customPlot->yAxis->setTickLabels(true);
if (plots.twoRanges) {
ui->customPlot->yAxis2->setRange(plots.rangeTwoMin, plots.rangeTwoMax);
ui->customPlot->yAxis2->setVisible(true);
}
for (int i=0; i<n-2; i++) {
if (ui->FieldsTW->item(0,i)->isSelected()) {
plots++;
plotValue(i+2,plots, numplots);
for (int i = 0; i < plots.coords.size(); i++) {
if (plots.coords.at(i).secondRange && plots.twoRanges) {
ui->customPlot->addGraph(ui->customPlot->xAxis, ui->customPlot->yAxis2);
} else {
ui->customPlot->addGraph();
}
ui->customPlot->graph(i)->setData(plots.coords.at(i).x,
plots.coords.at(i).y);
pen.setColor(colors.at(i % colors.size()));
ui->customPlot->graph(i)->setPen(pen);
ui->customPlot->graph(i)->setName(plots.coords.at(i).name);
}
ui->customPlot->legend->setVisible((numplots>2));
ui->customPlot->replot();
ui->customPlot->legend->setVisible(true);
ui->customPlot->replot();
}
void logsDialog::setRangeyAxis2(QCPRange range)
{
if (hasyAxis2) {
double lowerChange = (range.lower - rangeyAxisMin) * rangeRatio;
double upperChange = (range.upper - rangeyAxisMax) * rangeRatio;
rangeyAxisMin = range.lower;
rangeyAxisMax = range.upper;
rangeyAxis2Min += lowerChange;
rangeyAxis2Max += upperChange;
ui->customPlot->yAxis2->setRange(rangeyAxis2Min, rangeyAxis2Max);
}
}
+35 -8
View File
@@ -5,6 +5,26 @@
#include <QtGui>
#include "qcustomplot.h"
struct coords {
QVector<double> x, y;
double min_y;
double max_y;
bool secondRange;
QString name;
};
struct plotsCollection {
QVarLengthArray<struct coords> coords;
double min_x;
double max_x;
bool twoRanges;
bool tooManyRanges;
double rangeOneMin;
double rangeOneMax;
double rangeTwoMin;
double rangeTwoMax;
};
namespace Ui {
class logsDialog;
}
@@ -12,12 +32,11 @@ namespace Ui {
class logsDialog : public QDialog
{
Q_OBJECT
public:
explicit logsDialog(QWidget *parent = 0);
~logsDialog();
private slots:
void titleDoubleClick();
void axisLabelDoubleClick(QCPAxis* axis, QCPAxis::SelectablePart part);
@@ -29,21 +48,29 @@ private slots:
void removeAllGraphs();
void moveLegend();
void plotLogs();
void plotValue(int index, int plot, int numplots);
void plottableItemDoubleClick(QCPAbstractPlottable * plottable, QMouseEvent * event);
// void plottableItemDoubleClick(QCPAbstractPlottable * plottable, QMouseEvent * event);
// void graphClicked(QCPAbstractPlottable *plottable);
void on_fileOpen_BT_clicked();
void on_sessions_CB_currentIndexChanged(int index);
void on_mapsButton_clicked();
void setRangeyAxis2(QCPRange range);
private:
QList<QStringList> csvlog;
Ui::logsDialog *ui;
bool cvsFileParse();
double GetScale(QString channel);
QList<QColor> palette;
bool plotLock;
QString logFilename;
QVarLengthArray<Qt::GlobalColor> colors;
QPen pen;
bool hasyAxis2;
double rangeRatio;
double rangeyAxisMin;
double rangeyAxisMax;
double rangeyAxis2Min;
double rangeyAxis2Max;
};
#endif // LOGSDIALOG_H