VisualizationGraphHelper.cpp
161 lines
| 5.6 KiB
| text/x-c
|
CppLexer
r243 | #include "Visualization/VisualizationGraphHelper.h" | |||
Alexandre Leroux
|
r181 | #include "Visualization/qcustomplot.h" | ||
Alexandre Leroux
|
r182 | #include <Data/ScalarSeries.h> | ||
Alexandre Leroux
|
r181 | #include <Variable/Variable.h> | ||
r243 | Q_LOGGING_CATEGORY(LOG_VisualizationGraphHelper, "VisualizationGraphHelper") | |||
Alexandre Leroux
|
r181 | |||
Alexandre Leroux
|
r182 | namespace { | ||
r364 | class SqpDataContainer : public QCPGraphDataContainer { | |||
public: | ||||
Alexandre Leroux
|
r453 | void appendGraphData(const QCPGraphData &data) { mData.append(data); } | ||
r364 | }; | |||
Alexandre Leroux
|
r183 | /// Format for datetimes on a axis | ||
const auto DATETIME_TICKER_FORMAT = QStringLiteral("yyyy/MM/dd \nhh:mm:ss"); | ||||
/// Generates the appropriate ticker for an axis, depending on whether the axis displays time or | ||||
/// non-time data | ||||
QSharedPointer<QCPAxisTicker> axisTicker(bool isTimeAxis) | ||||
{ | ||||
if (isTimeAxis) { | ||||
auto dateTicker = QSharedPointer<QCPAxisTickerDateTime>::create(); | ||||
dateTicker->setDateTimeFormat(DATETIME_TICKER_FORMAT); | ||||
return dateTicker; | ||||
} | ||||
else { | ||||
// default ticker | ||||
return QSharedPointer<QCPAxisTicker>::create(); | ||||
} | ||||
} | ||||
Alexandre Leroux
|
r182 | |||
r235 | void updateScalarData(QCPAbstractPlottable *component, ScalarSeries &scalarSeries, | |||
const SqpDateTime &dateTime) | ||||
{ | ||||
r367 | qCDebug(LOG_VisualizationGraphHelper()) << "TORM: updateScalarData" | |||
<< QThread::currentThread()->objectName(); | ||||
r235 | if (auto qcpGraph = dynamic_cast<QCPGraph *>(component)) { | |||
r364 | scalarSeries.lockRead(); | |||
{ | ||||
Alexandre Leroux
|
r453 | const auto &xData = scalarSeries.xAxisData()->cdata(); | ||
const auto &valuesData = scalarSeries.valuesData()->cdata(); | ||||
auto xDataBegin = xData.cbegin(); | ||||
auto xDataEnd = xData.cend(); | ||||
r471 | qCInfo(LOG_VisualizationGraphHelper()) << "TORM: Current points in cache" | |||
<< xData.count(); | ||||
Alexandre Leroux
|
r453 | |||
r364 | auto sqpDataContainer = QSharedPointer<SqpDataContainer>::create(); | |||
qcpGraph->setData(sqpDataContainer); | ||||
Alexandre Leroux
|
r453 | auto lowerIt = std::lower_bound(xDataBegin, xDataEnd, dateTime.m_TStart); | ||
auto upperIt = std::upper_bound(xDataBegin, xDataEnd, dateTime.m_TEnd); | ||||
auto distance = std::distance(xDataBegin, lowerIt); | ||||
auto valuesDataIt = valuesData.cbegin() + distance; | ||||
for (auto xAxisDataIt = lowerIt; xAxisDataIt != upperIt; | ||||
++xAxisDataIt, ++valuesDataIt) { | ||||
sqpDataContainer->appendGraphData(QCPGraphData(*xAxisDataIt, *valuesDataIt)); | ||||
r235 | } | |||
Alexandre Leroux
|
r453 | |||
r471 | qCInfo(LOG_VisualizationGraphHelper()) << "TORM: Current points displayed" | |||
<< sqpDataContainer->size(); | ||||
r235 | } | |||
r364 | scalarSeries.unlock(); | |||
r235 | ||||
r315 | ||||
// Display all data | ||||
component->parentPlot()->replot(); | ||||
r235 | } | |||
else { | ||||
/// @todo DEBUG | ||||
} | ||||
} | ||||
QCPAbstractPlottable *createScalarSeriesComponent(ScalarSeries &scalarSeries, QCustomPlot &plot, | ||||
const SqpDateTime &dateTime) | ||||
Alexandre Leroux
|
r182 | { | ||
auto component = plot.addGraph(); | ||||
if (component) { | ||||
r235 | // // Graph data | |||
Alexandre Leroux
|
r182 | component->setData(scalarSeries.xAxisData()->data(), scalarSeries.valuesData()->data(), | ||
true); | ||||
r235 | updateScalarData(component, scalarSeries, dateTime); | |||
Alexandre Leroux
|
r183 | // Axes properties | ||
/// @todo : for the moment, no control is performed on the axes: the units and the tickers | ||||
/// are fixed for the default x-axis and y-axis of the plot, and according to the new graph | ||||
auto setAxisProperties = [](auto axis, const auto &unit) { | ||||
// label (unit name) | ||||
axis->setLabel(unit.m_Name); | ||||
// ticker (depending on the type of unit) | ||||
axis->setTicker(axisTicker(unit.m_TimeUnit)); | ||||
}; | ||||
setAxisProperties(plot.xAxis, scalarSeries.xAxisUnit()); | ||||
setAxisProperties(plot.yAxis, scalarSeries.valuesUnit()); | ||||
Alexandre Leroux
|
r182 | // Display all data | ||
component->rescaleAxes(); | ||||
plot.replot(); | ||||
} | ||||
else { | ||||
r243 | qCDebug(LOG_VisualizationGraphHelper()) | |||
Alexandre Leroux
|
r182 | << QObject::tr("Can't create graph for the scalar series"); | ||
} | ||||
return component; | ||||
} | ||||
} // namespace | ||||
r243 | QVector<QCPAbstractPlottable *> VisualizationGraphHelper::create(std::shared_ptr<Variable> variable, | |||
QCustomPlot &plot) noexcept | ||||
Alexandre Leroux
|
r181 | { | ||
auto result = QVector<QCPAbstractPlottable *>{}; | ||||
if (variable) { | ||||
Alexandre Leroux
|
r182 | // Gets the data series of the variable to call the creation of the right components | ||
// according to its type | ||||
if (auto scalarSeries = dynamic_cast<ScalarSeries *>(variable->dataSeries())) { | ||||
r235 | result.append(createScalarSeriesComponent(*scalarSeries, plot, variable->dateTime())); | |||
Alexandre Leroux
|
r182 | } | ||
else { | ||||
r243 | qCDebug(LOG_VisualizationGraphHelper()) | |||
Alexandre Leroux
|
r182 | << QObject::tr("Can't create graph plottables : unmanaged data series type"); | ||
} | ||||
Alexandre Leroux
|
r181 | } | ||
else { | ||||
r243 | qCDebug(LOG_VisualizationGraphHelper()) | |||
Alexandre Leroux
|
r181 | << QObject::tr("Can't create graph plottables : the variable is null"); | ||
} | ||||
return result; | ||||
} | ||||
r235 | ||||
r243 | void VisualizationGraphHelper::updateData(QVector<QCPAbstractPlottable *> plotableVect, | |||
IDataSeries *dataSeries, const SqpDateTime &dateTime) | ||||
r235 | { | |||
if (auto scalarSeries = dynamic_cast<ScalarSeries *>(dataSeries)) { | ||||
if (plotableVect.size() == 1) { | ||||
updateScalarData(plotableVect.at(0), *scalarSeries, dateTime); | ||||
} | ||||
else { | ||||
r243 | qCCritical(LOG_VisualizationGraphHelper()) << QObject::tr( | |||
r235 | "Can't update Data of a scalarSeries because there is not only one component " | |||
"associated"); | ||||
} | ||||
} | ||||
else { | ||||
/// @todo DEBUG | ||||
} | ||||
} | ||||