diff --git a/flowviewwindow.cpp b/flowviewwindow.cpp index f7041e6..4c9b1b1 100644 --- a/flowviewwindow.cpp +++ b/flowviewwindow.cpp @@ -1,6 +1,10 @@ #include "flowviewwindow.h" #include "ui_flowviewwindow.h" +const QColor FlowViewWindow::graphColors[8] = {Qt::blue, Qt::green, Qt::black, Qt::red, + Qt::gray, Qt::yellow, Qt::cyan, Qt::darkMagenta}; + + FlowViewWindow::FlowViewWindow(QList *frames, QWidget *parent) : QDialog(parent), ui(new Ui::FlowViewWindow) @@ -22,6 +26,24 @@ FlowViewWindow::FlowViewWindow(QList *frames, QWidget *parent) : updateFrameLabel(); + //ui->graphView->setInteractions(); + + ui->graphView->xAxis->setRange(0, 8); + ui->graphView->yAxis->setRange(0, 255); + ui->graphView->axisRect()->setupFullAxesBox(); + + ui->graphView->xAxis->setLabel("Time Axis"); + ui->graphView->yAxis->setLabel("Value Axis"); + //ui->graphView->legend->setVisible(true); + QFont legendFont = font(); + legendFont.setPointSize(10); + QFont legendSelectedFont = font(); + legendSelectedFont.setPointSize(12); + legendSelectedFont.setBold(true); + ui->graphView->legend->setFont(legendFont); + ui->graphView->legend->setSelectedFont(legendSelectedFont); + ui->graphView->legend->setSelectableParts(QCPLegend::spItems); // legend box shall not be selectable, only legend items + connect(ui->btnBackOne, SIGNAL(clicked(bool)), this, SLOT(btnBackOneClick())); connect(ui->btnPause, SIGNAL(clicked(bool)), this, SLOT(btnPauseClick())); connect(ui->btnReverse, SIGNAL(clicked(bool)), this, SLOT(btnReverseClick())); @@ -45,6 +67,41 @@ FlowViewWindow::~FlowViewWindow() delete playbackTimer; } +void FlowViewWindow::removeAllGraphs() +{ + ui->graphView->clearGraphs(); + ui->graphView->replot(); +} + +void FlowViewWindow::createGraph(int byteNum) +{ + int tempVal; + float minval=1000000, maxval = -100000; + + int numEntries = frameCache.count(); + + QVector x(numEntries), y(numEntries); + + for (int j = 0; j < numEntries; j++) + { + tempVal = frameCache[j].data[byteNum]; + x[j] = j; + y[j] = tempVal; + if (y[j] < minval) minval = y[j]; + if (y[j] > maxval) maxval = y[j]; + } + + ui->graphView->addGraph(); + ui->graphView->graph()->setName(QString("Graph %1").arg(ui->graphView->graphCount()-1)); + ui->graphView->graph()->setData(x,y); + ui->graphView->graph()->setLineStyle(QCPGraph::lsLine); //connect points with lines + QPen graphPen; + graphPen.setColor(graphColors[byteNum]); + graphPen.setWidth(1); + ui->graphView->graph()->setPen(graphPen); + ui->graphView->axisRect()->setupFullAxesBox(); +} + void FlowViewWindow::refreshIDList() { int id; @@ -83,7 +140,14 @@ void FlowViewWindow::changeID(QString newID) } currentPosition = 0; - updateFrameLabel(); + removeAllGraphs(); + for (int c = 0; c < frameCache.at(0).len; c++) + { + createGraph(c); + } + ui->graphView->replot(); + + updateDataView(); } void FlowViewWindow::btnBackOneClick() @@ -190,6 +254,9 @@ void FlowViewWindow::updateDataView() ui->flowView->setReference(refBytes, false); ui->flowView->updateData(currBytes, true); + ui->graphView->xAxis->setRange(currentPosition - 5, currentPosition + 5); + ui->graphView->replot(); + updateFrameLabel(); } diff --git a/flowviewwindow.h b/flowviewwindow.h index 9705c23..8ad175e 100644 --- a/flowviewwindow.h +++ b/flowviewwindow.h @@ -39,11 +39,14 @@ private: QTimer *playbackTimer; bool playbackActive; bool playbackForward; + static const QColor graphColors[8]; void refreshIDList(); void updateFrameLabel(); void updatePosition(bool forward); void updateDataView(); + void removeAllGraphs(); + void createGraph(int); }; #endif // FLOWVIEWWINDOW_H diff --git a/mainwindow.cpp b/mainwindow.cpp index ffb9ef5..ef53f1a 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -13,9 +13,7 @@ This first order of business is to attempt to gain feature parity (roughly) with can replace it as a cross platform solution. Here are things yet to do -- Add flow view - ability to see bits change over time - Ability to use programmatic frame sending interface (only I use it and it's complicated but helpful) -- Continuous logging. But, I see no real reason why this is needed. It would only be helpful if the program were prone to crashing. SO, don't do that. Things that were planned for the GVRET-PC project but never completed. Single / Multi state - The goal is to find bits that change based on toggles or discrete state items (shifters, etc)