diff --git a/companion/src/logsdialog.cpp b/companion/src/logsdialog.cpp index 9195812b4..54f5f0790 100644 --- a/companion/src/logsdialog.cpp +++ b/companion/src/logsdialog.cpp @@ -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 @@ -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(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; icustomPlot->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 nondataCols; for (int i=1; i\n\n"; outputStream << "\t\n\t\t" << logFilename << "\n"; @@ -269,7 +275,7 @@ void logsDialog::on_mapsButton_clicked() { } } outputStream << "\t\t\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"<< tstamp <<"\n"; } } - + for (int i=1; ilogTable->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; ilogTable->item(i-1,1)->isSelected()) { - rangeSelected=true; - itemSelected++; - } - } - if (itemSelected==0) { - itemSelected=n-1; - } - QVector x(itemSelected), y(itemSelected); - if (numplots<3) { - for (int i=1; ilogTable->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 (maxxmaxy) { - maxy=tmpval; - } - if (tmpvallogTable->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 (maxxmaxy) { - maxy=tmpval; - } - if (tmpvalmaxy) { - yscale=miny/1000.0; - } else { - yscale=maxy/1000.0; - } - if (yscale==0) { - yscale=1; - } - } - } - for (int i=1; ilogTable->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; isessions_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; ilogTable->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 selections = ui->logTable->selectedRanges(); + int rowCount = selections.length(); + bool hasLogSelection; + QVarLengthArray 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; iFieldsTW->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; iFieldsTW->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); + } +} diff --git a/companion/src/logsdialog.h b/companion/src/logsdialog.h index e78fa6c51..5eb174c95 100644 --- a/companion/src/logsdialog.h +++ b/companion/src/logsdialog.h @@ -5,6 +5,26 @@ #include #include "qcustomplot.h" +struct coords { + QVector x, y; + double min_y; + double max_y; + bool secondRange; + QString name; +}; + +struct plotsCollection { + QVarLengthArray 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 csvlog; Ui::logsDialog *ui; bool cvsFileParse(); - double GetScale(QString channel); - QList palette; bool plotLock; QString logFilename; + + QVarLengthArray colors; + QPen pen; + + bool hasyAxis2; + double rangeRatio; + double rangeyAxisMin; + double rangeyAxisMax; + double rangeyAxis2Min; + double rangeyAxis2Max; }; #endif // LOGSDIALOG_H