Skip to content

Commit 5d93d4d

Browse files
committed
[feat] stat_analysis: add velocity plot
1 parent c9f5fad commit 5d93d4d

File tree

2 files changed

+54
-14
lines changed

2 files changed

+54
-14
lines changed

src/statanalysis.cpp

Lines changed: 49 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,13 @@ StatAnalysis::StatAnalysis(QWidget* parent, bool isStandalone) : QMainWindow(par
2424
trackingData(new Data()),
2525
settingsFile(new QSettings(QStringLiteral("FastTrack"), QStringLiteral("FastTrackOrg"), this)),
2626
ruler(1),
27+
timeScale(1),
2728
isData(false) {
2829
ui->setupUi(this);
2930

31+
scale = new QLabel(QStringLiteral("1px = 1m and 1 timestep = 1s"), this);
32+
ui->statusbar->addPermanentWidget(scale);
33+
3034
// Loads settings
3135
settingsFile->beginGroup(QStringLiteral("statanalysis"));
3236
restoreState(settingsFile->value(QStringLiteral("windowState")).toByteArray());
@@ -50,10 +54,18 @@ StatAnalysis::StatAnalysis(QWidget* parent, bool isStandalone) : QMainWindow(par
5054
Qt::WindowFlags(), 1);
5155
if (ok) {
5256
ruler = d;
53-
clearPlots();
54-
QList<int> objects = trackingData->getId(0, trackingData->maxFrameIndex);
55-
initPlots(objects);
56-
emit ui->objectAll->clicked(true);
57+
58+
d = QInputDialog::getDouble(this, QStringLiteral("Get convertion factor"),
59+
QStringLiteral("1 timestep equal ? (in seconds)"), timeScale, -10000000, 1000000, 9, &ok,
60+
Qt::WindowFlags(), 1);
61+
if (ok) {
62+
timeScale = d;
63+
clearPlots();
64+
QList<int> objects = trackingData->getId(0, trackingData->maxFrameIndex);
65+
initPlots(objects);
66+
emit ui->objectAll->clicked(true);
67+
scale->setText(QString("1px = %1m and 1 timestep = %2s").arg(QString::number(ruler), QString::number(timeScale)));
68+
}
5769
}
5870
});
5971
ui->toolBar->addAction(optionAction);
@@ -78,12 +90,16 @@ StatAnalysis::StatAnalysis(QWidget* parent, bool isStandalone) : QMainWindow(par
7890
if (!isStandalone) {
7991
openAction->setVisible(false);
8092
}
93+
8194
// Chart and ChartView are added there. Plots are defined in initPlots.
8295
// Then refresh and clear are automatically endled.
83-
plots.append(new QChart());
84-
ui->tabPlot->addTab(new QChartView(plots[0]), QStringLiteral("Trajectory"));
85-
plots.append(new QChart());
86-
ui->tabPlot->addTab(new QChartView(plots[1]), QStringLiteral("Displacement"));
96+
QList<QString> plotLabel{"Trajectory", "Displacement", "Velocity"};
97+
for (int i = 0; i < plotLabel.size(); i++) {
98+
plots.append(new QChart());
99+
QChartView* chartView = new QChartView(plots[i]);
100+
chartView->setRubberBand(QChartView::RectangleRubberBand);
101+
ui->tabPlot->addTab(chartView, plotLabel[i]);
102+
}
87103
}
88104

89105
/**
@@ -170,7 +186,6 @@ void StatAnalysis::clear() {
170186
trackingData->clear();
171187
ui->objectList->setRowCount(0); // Remove all rows
172188
clearPlots();
173-
ruler = 1;
174189
}
175190

176191
void StatAnalysis::initPlots(const QList<int>& objects) {
@@ -186,15 +201,14 @@ void StatAnalysis::initPlots(const QList<int>& objects) {
186201
traj->addSeries(series);
187202
}
188203
traj->createDefaultAxes();
189-
traj->setTitle(QStringLiteral("Trajectories"));
190204

191205
// Displacement plot
206+
QList<QList<double>> velocity;
207+
192208
QChart* dis = plots[1];
193209
for (auto const& object : objects) {
194210
QHash<QString, QList<double>> data = trackingData->getDataId(object);
195211
if (data.value(QStringLiteral("imageNumber")).size() > 4) { // Need at least 4 points in the trajectory
196-
QBoxPlotSeries* displacements = new QBoxPlotSeries();
197-
QBoxSet* set = new QBoxSet(QString::number(object));
198212
auto x = data.value(QStringLiteral("xBody"));
199213
std::adjacent_difference(x.begin(), x.end(), x.begin());
200214
auto y = data.value(QStringLiteral("yBody"));
@@ -204,20 +218,41 @@ void StatAnalysis::initPlots(const QList<int>& objects) {
204218
std::adjacent_difference(t.begin(), t.end(), t.begin());
205219
std::transform(x.begin(), x.end(), t.begin(), x.begin(), std::divides<double>());
206220
x.removeAt(0); // Remove first element that is keep unchanged with adjacent_difference to keep size.
221+
velocity.append(x);
207222
std::sort(x.begin(), x.end());
223+
QBoxPlotSeries* displacements = new QBoxPlotSeries();
224+
QBoxSet* set = new QBoxSet(" "); // " " Avoid number label on xaxis
208225
set->setValue(QBoxSet::LowerExtreme, x.first() * ruler);
209226
set->setValue(QBoxSet::UpperExtreme, x.last() * ruler);
210227
set->setValue(QBoxSet::Median, median(0, x.size(), x) * ruler);
211228
set->setValue(QBoxSet::LowerQuartile, median(0, x.size() / 2, x) * ruler);
212229
set->setValue(QBoxSet::UpperQuartile, median(x.size() / 2 + (x.size() / 2 % 2), x.size(), x) * ruler);
213-
displacements->setName(QString::number(object));
214230
displacements->append(set);
231+
displacements->setName(QString::number(object));
215232
dis->addSeries(displacements);
216233
}
217234
}
218235
dis->createDefaultAxes();
219236
dis->axes(Qt::Vertical).at(0)->setTitleText(QStringLiteral("Displacement (m)"));
220-
dis->setTitle(QStringLiteral("Displacement"));
237+
238+
// Time plot
239+
QChart* time = plots[2];
240+
for (auto const& object : objects) {
241+
QLineSeries* series = new QLineSeries(traj);
242+
QHash<QString, QList<double>> data = trackingData->getDataId(object);
243+
if (data.value(QStringLiteral("imageNumber")).size() > 4) { // Need at least 4 points in the trajectory
244+
int i = 0;
245+
for (auto const& a : velocity[object]) {
246+
series->append(data.value(QStringLiteral("imageNumber")).at(i) * timeScale, a / timeScale);
247+
i++;
248+
}
249+
series->setName(QString::number(object));
250+
time->addSeries(series);
251+
}
252+
}
253+
time->createDefaultAxes();
254+
time->axes(Qt::Vertical).at(0)->setTitleText(QStringLiteral("Velocity (m/s)"));
255+
time->axes(Qt::Horizontal).at(0)->setTitleText(QStringLiteral("Time (s)"));
221256
}
222257

223258
void StatAnalysis::refreshPlots(const QList<int>& objects) {

src/statanalysis.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ This file is part of Fast Track.
1919
#define STATANALYSIS_H
2020

2121
#include <QAction>
22+
#include <QBarCategoryAxis>
2223
#include <QBoxPlotSeries>
2324
#include <QBoxSet>
2425
#include <QChart>
@@ -32,11 +33,13 @@ This file is part of Fast Track.
3233
#include <QIcon>
3334
#include <QInputDialog>
3435
#include <QLineSeries>
36+
#include <QList>
3537
#include <QMainWindow>
3638
#include <QObject>
3739
#include <QSettings>
3840
#include <QString>
3941
#include <QTableWidgetItem>
42+
#include <QValueAxis>
4043
#include <algorithm>
4144
#include <cmath>
4245
#include <functional>
@@ -80,7 +83,9 @@ class StatAnalysis : public QMainWindow {
8083
QSettings *settingsFile;
8184
QString memoryDir;
8285
double ruler;
86+
double timeScale;
8387
bool isData;
88+
QLabel *scale;
8489
};
8590

8691
#endif // STATANALYSIS_H

0 commit comments

Comments
 (0)