PlottablesRenderingUtils.cpp
136 lines
| 4.2 KiB
| text/x-c
|
CppLexer
Alexandre Leroux
|
r917 | #include "Visualization/PlottablesRenderingUtils.h" | ||
Alexandre Leroux
|
r918 | #include <Common/ColorUtils.h> | ||
r1420 | #include <Variable/Variable2.h> | |||
Alexandre Leroux
|
r1282 | |||
Alexandre Leroux
|
r917 | #include <Visualization/qcustomplot.h> | ||
Alexandre Leroux
|
r928 | Q_LOGGING_CATEGORY(LOG_PlottablesRenderingUtils, "PlottablesRenderingUtils") | ||
r1420 | namespace | |||
{ | ||||
Alexandre Leroux
|
r917 | |||
/** | ||||
* Delegate used to set plottables properties | ||||
*/ | ||||
template <typename T, typename Enabled = void> | ||||
r1420 | struct PlottablesSetter | |||
{ | ||||
static void setProperties(PlottablesMap&) | ||||
Alexandre Leroux
|
r917 | { | ||
// Default implementation does nothing | ||||
Alexandre Leroux
|
r928 | qCCritical(LOG_PlottablesRenderingUtils()) | ||
<< "Can't set plottables properties: unmanaged type of data"; | ||||
Alexandre Leroux
|
r917 | } | ||
}; | ||||
/** | ||||
* Specialization of PlottablesSetter for scalars and vectors | ||||
* @sa ScalarSeries | ||||
* @sa VectorSeries | ||||
*/ | ||||
template <typename T> | ||||
r1420 | struct PlottablesSetter<T, | |||
typename std::enable_if_t<std::is_base_of<ScalarTimeSerie, T>::value | ||||
r1432 | or std::is_base_of<VectorTimeSerie, T>::value | |||
or std::is_base_of<MultiComponentTimeSerie, T>::value>> | ||||
r1420 | { | |||
static void setProperties(PlottablesMap& plottables) | ||||
Alexandre Leroux
|
r917 | { | ||
Alexandre Leroux
|
r1282 | // Finds the plottable with the highest index to determine the number of colors to generate | ||
auto end = plottables.cend(); | ||||
r1420 | auto maxPlottableIndexIt = std::max_element(plottables.cbegin(), end, | |||
[](const auto& it1, const auto& it2) { return it1.first < it2.first; }); | ||||
Alexandre Leroux
|
r1282 | auto componentCount = maxPlottableIndexIt != end ? maxPlottableIndexIt->first + 1 : 0; | ||
Alexandre Leroux
|
r918 | |||
// Generates colors for each component | ||||
auto colors = ColorUtils::colors(Qt::blue, Qt::red, componentCount); | ||||
// For each component of the data series, creates a QCPGraph to add to the plot | ||||
r1420 | for (auto i = 0; i < componentCount; ++i) | |||
{ | ||||
Alexandre Leroux
|
r1282 | auto graphIt = plottables.find(i); | ||
r1420 | if (graphIt != end) | |||
{ | ||||
graphIt->second->setPen(QPen { colors.at(i) }); | ||||
Alexandre Leroux
|
r1282 | } | ||
Alexandre Leroux
|
r918 | } | ||
Alexandre Leroux
|
r917 | } | ||
}; | ||||
Alexandre Leroux
|
r921 | /** | ||
* Specialization of PlottablesSetter for spectrograms | ||||
* @sa SpectrogramSeries | ||||
*/ | ||||
template <typename T> | ||||
struct PlottablesSetter<T, | ||||
r1420 | typename std::enable_if_t<std::is_base_of<SpectrogramTimeSerie, T>::value>> | |||
{ | ||||
static void setProperties(PlottablesMap& plottables) | ||||
Alexandre Leroux
|
r921 | { | ||
// Checks that for a spectrogram there is only one plottable, that is a colormap | ||||
r1420 | if (plottables.size() != 1) | |||
{ | ||||
Alexandre Leroux
|
r921 | return; | ||
} | ||||
r1420 | if (auto colormap = dynamic_cast<QCPColorMap*>(plottables.begin()->second)) | |||
{ | ||||
Alexandre Leroux
|
r921 | colormap->setInterpolate(false); // No value interpolation | ||
colormap->setTightBoundary(true); | ||||
// Finds color scale in the colormap's plot to associate with it | ||||
auto plot = colormap->parentPlot(); | ||||
auto plotElements = plot->plotLayout()->elements(false); | ||||
r1420 | for (auto plotElement : plotElements) | |||
{ | ||||
if (auto colorScale = dynamic_cast<QCPColorScale*>(plotElement)) | ||||
{ | ||||
Alexandre Leroux
|
r921 | colormap->setColorScale(colorScale); | ||
} | ||||
} | ||||
colormap->rescaleDataRange(); | ||||
} | ||||
r1420 | else | |||
{ | ||||
Alexandre Leroux
|
r928 | qCCritical(LOG_PlottablesRenderingUtils()) << "Can't get colormap of the spectrogram"; | ||
} | ||||
Alexandre Leroux
|
r921 | } | ||
}; | ||||
Alexandre Leroux
|
r917 | /** | ||
* Default implementation of IPlottablesHelper, which takes data series to set plottables properties | ||||
* @tparam T the data series' type | ||||
*/ | ||||
template <typename T> | ||||
r1420 | struct PlottablesHelper : public IPlottablesHelper | |||
{ | ||||
void setProperties(PlottablesMap& plottables) override | ||||
Alexandre Leroux
|
r917 | { | ||
Alexandre Leroux
|
r1282 | PlottablesSetter<T>::setProperties(plottables); | ||
Alexandre Leroux
|
r917 | } | ||
}; | ||||
} // namespace | ||||
r1420 | std::unique_ptr<IPlottablesHelper> IPlottablesHelperFactory::create(Variable2& variable) noexcept | |||
Alexandre Leroux
|
r917 | { | ||
r1420 | switch (variable.type()) | |||
{ | ||||
Alexandre Leroux
|
r1282 | case DataSeriesType::SCALAR: | ||
r1420 | return std::make_unique<PlottablesHelper<ScalarTimeSerie>>(); | |||
Alexandre Leroux
|
r1282 | case DataSeriesType::SPECTROGRAM: | ||
r1420 | return std::make_unique<PlottablesHelper<SpectrogramTimeSerie>>(); | |||
Alexandre Leroux
|
r1282 | case DataSeriesType::VECTOR: | ||
r1420 | return std::make_unique<PlottablesHelper<VectorTimeSerie>>(); | |||
r1432 | case DataSeriesType::MULTICOMPONENT: | |||
return std::make_unique<PlottablesHelper<MultiComponentTimeSerie>>(); | ||||
Alexandre Leroux
|
r1282 | default: | ||
// Returns default helper | ||||
break; | ||||
Alexandre Leroux
|
r917 | } | ||
Alexandre Leroux
|
r1282 | |||
r1422 | return std::make_unique<PlottablesHelper<TimeSeries::ITimeSerie>>(); | |||
Alexandre Leroux
|
r917 | } | ||