##// END OF EJS Templates
updated Amda tree
updated Amda tree

File last commit:

r1346:d8cb4bff8c14
r1372:ad67227cef3c
Show More
VisualizationGraphHelper.cpp
361 lines | 12.5 KiB | text/x-c | CppLexer
/ gui / src / Visualization / VisualizationGraphHelper.cpp
Correction for pull request
r243 #include "Visualization/VisualizationGraphHelper.h"
Alexandre Leroux
Creates factory that is responsible of creation of QCustomPlot components relative to a variable
r181 #include "Visualization/qcustomplot.h"
Alexandre Leroux
Mesh generation for QColorMap (4)...
r995 #include <Data/DataSeriesUtils.h>
Alexandre Leroux
Handles creations for scalar series
r182 #include <Data/ScalarSeries.h>
Alexandre Leroux
Implements spectrograms display (1)...
r902 #include <Data/SpectrogramSeries.h>
Alexandre Leroux
Updates VisualizationGraphHelper to handle vectors
r583 #include <Data/VectorSeries.h>
Alexandre Leroux
Handles creations for scalar series
r182
Alexandre Leroux
Creates factory that is responsible of creation of QCustomPlot components relative to a variable
r181 #include <Variable/Variable.h>
Correction for pull request
r243 Q_LOGGING_CATEGORY(LOG_VisualizationGraphHelper, "VisualizationGraphHelper")
Alexandre Leroux
Creates factory that is responsible of creation of QCustomPlot components relative to a variable
r181
Alexandre Leroux
Handles creations for scalar series
r182 namespace {
Add current progression for thread fix
r364 class SqpDataContainer : public QCPGraphDataContainer {
public:
Alexandre Leroux
Updates UI to not call the sort method when update graphs, as data series are already sorted
r453 void appendGraphData(const QCPGraphData &data) { mData.append(data); }
Add current progression for thread fix
r364 };
Alexandre Leroux
Updates VisualizationGraphHelper to handle vectors
r583 /**
Add mofif for clang format
r591 * Struct used to create plottables, depending on the type of the data series from which to create
* them
Alexandre Leroux
Updates VisualizationGraphHelper to handle vectors
r583 * @tparam T the data series' type
* @remarks Default implementation can't create plottables
*/
template <typename T, typename Enabled = void>
struct PlottablesCreator {
Alexandre Leroux
Updates VisualizationGraphHelper to use variable's type instead of dataseries
r1280 static PlottablesMap createPlottables(QCustomPlot &)
Alexandre Leroux
Updates VisualizationGraphHelper to handle vectors
r583 {
qCCritical(LOG_DataSeries())
<< QObject::tr("Can't create plottables: unmanaged data series type");
return {};
The mock plugin can now create data with view operation
r235 }
Alexandre Leroux
Updates VisualizationGraphHelper to handle vectors
r583 };
The mock plugin can now create data with view operation
r235
Alexandre Leroux
Updates VisualizationGraphHelper to use variable's type instead of dataseries
r1280 PlottablesMap createGraphs(QCustomPlot &plot, int nbGraphs)
{
PlottablesMap result{};
// Creates {nbGraphs} QCPGraph to add to the plot
for (auto i = 0; i < nbGraphs; ++i) {
auto graph = plot.addGraph();
result.insert({i, graph});
}
plot.replot();
return result;
}
Alexandre Leroux
Updates VisualizationGraphHelper to handle vectors
r583 /**
Alexandre Leroux
Updates VisualizationGraphHelper to use variable's type instead of dataseries
r1280 * Specialization of PlottablesCreator for scalars
Alexandre Leroux
Updates VisualizationGraphHelper to handle vectors
r583 * @sa ScalarSeries
*/
template <typename T>
Alexandre Leroux
Updates VisualizationGraphHelper to use variable's type instead of dataseries
r1280 struct PlottablesCreator<T, typename std::enable_if_t<std::is_base_of<ScalarSeries, T>::value> > {
static PlottablesMap createPlottables(QCustomPlot &plot) { return createGraphs(plot, 1); }
};
Alexandre Leroux
Updates VisualizationGraphHelper to handle vectors
r583
Alexandre Leroux
Updates VisualizationGraphHelper to use variable's type instead of dataseries
r1280 /**
* Specialization of PlottablesCreator for vectors
* @sa VectorSeries
*/
template <typename T>
struct PlottablesCreator<T, typename std::enable_if_t<std::is_base_of<VectorSeries, T>::value> > {
static PlottablesMap createPlottables(QCustomPlot &plot) { return createGraphs(plot, 3); }
Alexandre Leroux
Updates VisualizationGraphHelper to handle vectors
r583 };
Initialisation of the graph range at creation in a new graphe, or inside...
r548
Alexandre Leroux
Implements spectrograms display (1)...
r902 /**
* Specialization of PlottablesCreator for spectrograms
* @sa SpectrogramSeries
*/
template <typename T>
struct PlottablesCreator<T,
typename std::enable_if_t<std::is_base_of<SpectrogramSeries, T>::value> > {
Alexandre Leroux
Updates VisualizationGraphHelper to use variable's type instead of dataseries
r1280 static PlottablesMap createPlottables(QCustomPlot &plot)
Alexandre Leroux
Implements spectrograms display (1)...
r902 {
PlottablesMap result{};
result.insert({0, new QCPColorMap{plot.xAxis, plot.yAxis}});
plot.replot();
return result;
}
};
Alexandre Leroux
Updates VisualizationGraphHelper to handle vectors
r583 /**
Add mofif for clang format
r591 * Struct used to update plottables, depending on the type of the data series from which to update
* them
Alexandre Leroux
Updates VisualizationGraphHelper to handle vectors
r583 * @tparam T the data series' type
* @remarks Default implementation can't update plottables
*/
template <typename T, typename Enabled = void>
struct PlottablesUpdater {
Renamed SqpRange to DateTimeRange, introduced VariableController2 to...
r1346 static void setPlotYAxisRange(T &, const DateTimeRange &, QCustomPlot &)
Alexandre Leroux
Refactors VisualizationGraphWidget::setYRange()...
r900 {
Alexandre Leroux
(Minor) Removes obsolete code
r905 qCCritical(LOG_VisualizationGraphHelper())
Alexandre Leroux
Refactors VisualizationGraphWidget::setYRange()...
r900 << QObject::tr("Can't set plot y-axis range: unmanaged data series type");
}
Renamed SqpRange to DateTimeRange, introduced VariableController2 to...
r1346 static void updatePlottables(T &, PlottablesMap &, const DateTimeRange &, bool)
Alexandre Leroux
Updates VisualizationGraphHelper to handle vectors
r583 {
Alexandre Leroux
(Minor) Removes obsolete code
r905 qCCritical(LOG_VisualizationGraphHelper())
Alexandre Leroux
Updates VisualizationGraphHelper to handle vectors
r583 << QObject::tr("Can't update plottables: unmanaged data series type");
}
};
Alexandre Leroux
Handles creations for scalar series
r182
Alexandre Leroux
Updates VisualizationGraphHelper to handle vectors
r583 /**
* Specialization of PlottablesUpdater for scalars and vectors
* @sa ScalarSeries
* @sa VectorSeries
*/
template <typename T>
struct PlottablesUpdater<T,
typename std::enable_if_t<std::is_base_of<ScalarSeries, T>::value
or std::is_base_of<VectorSeries, T>::value> > {
Renamed SqpRange to DateTimeRange, introduced VariableController2 to...
r1346 static void setPlotYAxisRange(T &dataSeries, const DateTimeRange &xAxisRange, QCustomPlot &plot)
Alexandre Leroux
Refactors VisualizationGraphWidget::setYRange()...
r900 {
auto minValue = 0., maxValue = 0.;
dataSeries.lockRead();
auto valuesBounds = dataSeries.valuesBounds(xAxisRange.m_TStart, xAxisRange.m_TEnd);
auto end = dataSeries.cend();
if (valuesBounds.first != end && valuesBounds.second != end) {
auto rangeValue = [](const auto &value) { return std::isnan(value) ? 0. : value; };
minValue = rangeValue(valuesBounds.first->minValue());
maxValue = rangeValue(valuesBounds.second->maxValue());
}
dataSeries.unlock();
plot.yAxis->setRange(QCPRange{minValue, maxValue});
}
Renamed SqpRange to DateTimeRange, introduced VariableController2 to...
r1346 static void updatePlottables(T &dataSeries, PlottablesMap &plottables, const DateTimeRange &range,
Alexandre Leroux
Updates VisualizationGraphHelper to handle vectors
r583 bool rescaleAxes)
{
// For each plottable to update, resets its data
std::map<int, QSharedPointer<SqpDataContainer> > dataContainers{};
for (const auto &plottable : plottables) {
if (auto graph = dynamic_cast<QCPGraph *>(plottable.second)) {
auto dataContainer = QSharedPointer<SqpDataContainer>::create();
graph->setData(dataContainer);
dataContainers.insert({plottable.first, dataContainer});
}
}
Add thread protection for DataSeries...
r636 dataSeries.lockRead();
Alexandre Leroux
Handles creations for scalar series
r182
Alexandre Leroux
Updates VisualizationGraphHelper to handle vectors
r583 // - Gets the data of the series included in the current range
Add mofif for clang format
r591 // - Updates each plottable by adding, for each data item, a point that takes x-axis data
// and value data. The correct value is retrieved according to the index of the component
Alexandre Leroux
(Refactoring) Renames IDataSeries::subData()
r605 auto subDataIts = dataSeries.xAxisRange(range.m_TStart, range.m_TEnd);
Alexandre Leroux
Updates VisualizationGraphHelper to handle vectors
r583 for (auto it = subDataIts.first; it != subDataIts.second; ++it) {
for (const auto &dataContainer : dataContainers) {
auto componentIndex = dataContainer.first;
dataContainer.second->appendGraphData(
QCPGraphData(it->x(), it->value(componentIndex)));
}
}
The mock plugin can now create data with view operation
r235
Alexandre Leroux
Updates VisualizationGraphHelper to handle vectors
r583 dataSeries.unlock();
Alexandre Leroux
Handles axes properties
r183
Alexandre Leroux
Updates VisualizationGraphHelper to handle vectors
r583 if (!plottables.empty()) {
auto plot = plottables.begin()->second->parentPlot();
Alexandre Leroux
Handles axes properties
r183
Alexandre Leroux
Updates VisualizationGraphHelper to handle vectors
r583 if (rescaleAxes) {
plot->rescaleAxes();
}
}
Alexandre Leroux
Handles creations for scalar series
r182 }
Alexandre Leroux
Updates VisualizationGraphHelper to handle vectors
r583 };
Alexandre Leroux
Implements spectrograms display (2)...
r903 /**
* Specialization of PlottablesUpdater for spectrograms
* @sa SpectrogramSeries
*/
template <typename T>
struct PlottablesUpdater<T,
typename std::enable_if_t<std::is_base_of<SpectrogramSeries, T>::value> > {
Renamed SqpRange to DateTimeRange, introduced VariableController2 to...
r1346 static void setPlotYAxisRange(T &dataSeries, const DateTimeRange &xAxisRange, QCustomPlot &plot)
Alexandre Leroux
Implements spectrograms display (3)...
r904 {
double min, max;
Alexandre Leroux
Updates access to y-axis properties of the data series (1)...
r988 std::tie(min, max) = dataSeries.yBounds();
Alexandre Leroux
Implements spectrograms display (3)...
r904
if (!std::isnan(min) && !std::isnan(max)) {
plot.yAxis->setRange(QCPRange{min, max});
}
}
Renamed SqpRange to DateTimeRange, introduced VariableController2 to...
r1346 static void updatePlottables(T &dataSeries, PlottablesMap &plottables, const DateTimeRange &range,
Alexandre Leroux
Implements spectrograms display (2)...
r903 bool rescaleAxes)
{
if (plottables.empty()) {
qCDebug(LOG_VisualizationGraphHelper())
<< QObject::tr("Can't update spectrogram: no colormap has been associated");
return;
}
// Gets the colormap to update (normally there is only one colormap)
Q_ASSERT(plottables.size() == 1);
auto colormap = dynamic_cast<QCPColorMap *>(plottables.at(0));
Q_ASSERT(colormap != nullptr);
dataSeries.lockRead();
Alexandre Leroux
Mesh generation for QColorMap (4)...
r995 // Processing spectrogram data for display in QCustomPlot
Alexandre Leroux
Implements spectrograms display (2)...
r903 auto its = dataSeries.xAxisRange(range.m_TStart, range.m_TEnd);
Alexandre Leroux
Mesh generation for QColorMap (4)...
r995 // Computes logarithmic y-axis resolution for the spectrogram
auto yData = its.first->y();
auto yResolution = DataSeriesUtils::resolution(yData.begin(), yData.end(), true);
// Generates mesh for colormap
auto mesh = DataSeriesUtils::regularMesh(
its.first, its.second, DataSeriesUtils::Resolution{dataSeries.xResolution()},
yResolution);
dataSeries.unlock();
Alexandre Leroux
Implements spectrograms display (2)...
r903
Alexandre Leroux
Mesh generation for QColorMap (4)...
r995 colormap->data()->setSize(mesh.m_NbX, mesh.m_NbY);
if (!mesh.isEmpty()) {
colormap->data()->setRange(
QCPRange{mesh.m_XMin, mesh.xMax()},
// y-axis range is converted to linear values
QCPRange{std::pow(10, mesh.m_YMin), std::pow(10, mesh.yMax())});
Alexandre Leroux
Introduces NaN and zero values in data of the mock spectrogram...
r922
Alexandre Leroux
Mesh generation for QColorMap (4)...
r995 // Sets values
auto index = 0;
for (auto it = mesh.m_Data.begin(), end = mesh.m_Data.end(); it != end; ++it, ++index) {
auto xIndex = index % mesh.m_NbX;
auto yIndex = index / mesh.m_NbX;
Alexandre Leroux
Introduces NaN and zero values in data of the mock spectrogram...
r922
Alexandre Leroux
Mesh generation for QColorMap (4)...
r995 colormap->data()->setCell(xIndex, yIndex, *it);
// Makes the NaN values to be transparent in the colormap
if (std::isnan(*it)) {
Alexandre Leroux
Introduces NaN and zero values in data of the mock spectrogram...
r922 colormap->data()->setAlpha(xIndex, yIndex, 0);
}
Alexandre Leroux
Implements spectrograms display (2)...
r903 }
}
// Rescales axes
auto plot = colormap->parentPlot();
if (rescaleAxes) {
plot->rescaleAxes();
}
}
};
Alexandre Leroux
Updates VisualizationGraphHelper to handle vectors
r583 /**
* Helper used to create/update plottables
*/
struct IPlottablesHelper {
virtual ~IPlottablesHelper() noexcept = default;
virtual PlottablesMap create(QCustomPlot &plot) const = 0;
Renamed SqpRange to DateTimeRange, introduced VariableController2 to...
r1346 virtual void setYAxisRange(const DateTimeRange &xAxisRange, QCustomPlot &plot) const = 0;
virtual void update(PlottablesMap &plottables, const DateTimeRange &range,
Alexandre Leroux
Updates VisualizationGraphHelper to handle vectors
r583 bool rescaleAxes = false) const = 0;
};
/**
* Default implementation of IPlottablesHelper, which takes data series to create/update plottables
* @tparam T the data series' type
*/
template <typename T>
struct PlottablesHelper : public IPlottablesHelper {
Alexandre Leroux
Updates VisualizationGraphHelper to use variable's type instead of dataseries
r1280 explicit PlottablesHelper(std::shared_ptr<T> dataSeries) : m_DataSeries{dataSeries} {}
Alexandre Leroux
Updates VisualizationGraphHelper to handle vectors
r583
PlottablesMap create(QCustomPlot &plot) const override
{
Alexandre Leroux
Updates VisualizationGraphHelper to use variable's type instead of dataseries
r1280 return PlottablesCreator<T>::createPlottables(plot);
Alexandre Leroux
Handles creations for scalar series
r182 }
Renamed SqpRange to DateTimeRange, introduced VariableController2 to...
r1346 void update(PlottablesMap &plottables, const DateTimeRange &range, bool rescaleAxes) const override
Alexandre Leroux
Updates VisualizationGraphHelper to handle vectors
r583 {
Alexandre Leroux
Updates VisualizationGraphHelper to use variable's type instead of dataseries
r1280 if (m_DataSeries) {
PlottablesUpdater<T>::updatePlottables(*m_DataSeries, plottables, range, rescaleAxes);
}
else {
qCCritical(LOG_VisualizationGraphHelper()) << "Can't update plottables: inconsistency "
"between the type of data series and the "
"type supposed";
}
Alexandre Leroux
Updates VisualizationGraphHelper to handle vectors
r583 }
Alexandre Leroux
Handles creations for scalar series
r182
Renamed SqpRange to DateTimeRange, introduced VariableController2 to...
r1346 void setYAxisRange(const DateTimeRange &xAxisRange, QCustomPlot &plot) const override
Alexandre Leroux
Refactors VisualizationGraphWidget::setYRange()...
r900 {
Alexandre Leroux
Updates VisualizationGraphHelper to use variable's type instead of dataseries
r1280 if (m_DataSeries) {
PlottablesUpdater<T>::setPlotYAxisRange(*m_DataSeries, xAxisRange, plot);
}
else {
qCCritical(LOG_VisualizationGraphHelper()) << "Can't update plottables: inconsistency "
"between the type of data series and the "
"type supposed";
}
Alexandre Leroux
Refactors VisualizationGraphWidget::setYRange()...
r900 }
Alexandre Leroux
Updates VisualizationGraphHelper to use variable's type instead of dataseries
r1280 std::shared_ptr<T> m_DataSeries;
Alexandre Leroux
Updates VisualizationGraphHelper to handle vectors
r583 };
Alexandre Leroux
Handles creations for scalar series
r182
Alexandre Leroux
Updates VisualizationGraphHelper to use variable's type instead of dataseries
r1280 /// Creates IPlottablesHelper according to the type of data series a variable holds
std::unique_ptr<IPlottablesHelper> createHelper(std::shared_ptr<Variable> variable) noexcept
Initialisation of the graph range at creation in a new graphe, or inside...
r548 {
Alexandre Leroux
Updates VisualizationGraphHelper to use variable's type instead of dataseries
r1280 switch (variable->type()) {
case DataSeriesType::SCALAR:
return std::make_unique<PlottablesHelper<ScalarSeries> >(
std::dynamic_pointer_cast<ScalarSeries>(variable->dataSeries()));
case DataSeriesType::SPECTROGRAM:
return std::make_unique<PlottablesHelper<SpectrogramSeries> >(
std::dynamic_pointer_cast<SpectrogramSeries>(variable->dataSeries()));
case DataSeriesType::VECTOR:
return std::make_unique<PlottablesHelper<VectorSeries> >(
std::dynamic_pointer_cast<VectorSeries>(variable->dataSeries()));
default:
// Creates default helper
break;
Initialisation of the graph range at creation in a new graphe, or inside...
r548 }
Alexandre Leroux
Updates VisualizationGraphHelper to use variable's type instead of dataseries
r1280
return std::make_unique<PlottablesHelper<IDataSeries> >(nullptr);
Initialisation of the graph range at creation in a new graphe, or inside...
r548 }
Alexandre Leroux
Updates VisualizationGraphHelper to handle vectors
r583 } // namespace
Alexandre Leroux
Creates factory that is responsible of creation of QCustomPlot components relative to a variable
r181
Alexandre Leroux
Updates VisualizationGraphHelper to handle vectors
r583 PlottablesMap VisualizationGraphHelper::create(std::shared_ptr<Variable> variable,
QCustomPlot &plot) noexcept
{
Alexandre Leroux
Creates factory that is responsible of creation of QCustomPlot components relative to a variable
r181 if (variable) {
Alexandre Leroux
Updates VisualizationGraphHelper to use variable's type instead of dataseries
r1280 auto helper = createHelper(variable);
Alexandre Leroux
Updates VisualizationGraphHelper to handle vectors
r583 auto plottables = helper->create(plot);
return plottables;
Alexandre Leroux
Creates factory that is responsible of creation of QCustomPlot components relative to a variable
r181 }
else {
Correction for pull request
r243 qCDebug(LOG_VisualizationGraphHelper())
Alexandre Leroux
Creates factory that is responsible of creation of QCustomPlot components relative to a variable
r181 << QObject::tr("Can't create graph plottables : the variable is null");
Alexandre Leroux
Updates VisualizationGraphHelper to handle vectors
r583 return PlottablesMap{};
Alexandre Leroux
Creates factory that is responsible of creation of QCustomPlot components relative to a variable
r181 }
}
The mock plugin can now create data with view operation
r235
Alexandre Leroux
Refactors VisualizationGraphWidget::setYRange()...
r900 void VisualizationGraphHelper::setYAxisRange(std::shared_ptr<Variable> variable,
QCustomPlot &plot) noexcept
{
if (variable) {
Alexandre Leroux
Updates VisualizationGraphHelper to use variable's type instead of dataseries
r1280 auto helper = createHelper(variable);
Alexandre Leroux
Refactors VisualizationGraphWidget::setYRange()...
r900 helper->setYAxisRange(variable->range(), plot);
}
else {
qCDebug(LOG_VisualizationGraphHelper())
<< QObject::tr("Can't set y-axis range of plot: the variable is null");
}
}
Alexandre Leroux
Uses std::shared_ptr
r587 void VisualizationGraphHelper::updateData(PlottablesMap &plottables,
Alexandre Leroux
Updates VisualizationGraphHelper to use variable's type instead of dataseries
r1280 std::shared_ptr<Variable> variable,
Renamed SqpRange to DateTimeRange, introduced VariableController2 to...
r1346 const DateTimeRange &dateTime)
The mock plugin can now create data with view operation
r235 {
Alexandre Leroux
Updates VisualizationGraphHelper to use variable's type instead of dataseries
r1280 auto helper = createHelper(variable);
Alexandre Leroux
Updates VisualizationGraphHelper to handle vectors
r583 helper->update(plottables, dateTime);
The mock plugin can now create data with view operation
r235 }