PlottablesRenderingUtils.cpp
126 lines
| 4.1 KiB
| text/x-c
|
CppLexer
Alexandre Leroux
|
r918 | #include "Visualization/PlottablesRenderingUtils.h" | ||
Alexandre Leroux
|
r919 | #include <Common/ColorUtils.h> | ||
Alexandre Leroux
|
r918 | #include <Data/ScalarSeries.h> | ||
Alexandre Leroux
|
r922 | #include <Data/SpectrogramSeries.h> | ||
Alexandre Leroux
|
r918 | #include <Data/VectorSeries.h> | ||
Alexandre Leroux
|
r1336 | #include <Variable/Variable.h> | ||
Alexandre Leroux
|
r918 | #include <Visualization/qcustomplot.h> | ||
Alexandre Leroux
|
r927 | Q_LOGGING_CATEGORY(LOG_PlottablesRenderingUtils, "PlottablesRenderingUtils") | ||
Alexandre Leroux
|
r918 | namespace { | ||
/** | ||||
* Delegate used to set plottables properties | ||||
*/ | ||||
template <typename T, typename Enabled = void> | ||||
struct PlottablesSetter { | ||||
Alexandre Leroux
|
r1336 | static void setProperties(PlottablesMap &) | ||
Alexandre Leroux
|
r918 | { | ||
// Default implementation does nothing | ||||
Alexandre Leroux
|
r927 | qCCritical(LOG_PlottablesRenderingUtils()) | ||
<< "Can't set plottables properties: unmanaged type of data"; | ||||
Alexandre Leroux
|
r918 | } | ||
}; | ||||
/** | ||||
* Specialization of PlottablesSetter for scalars and vectors | ||||
* @sa ScalarSeries | ||||
* @sa VectorSeries | ||||
*/ | ||||
template <typename T> | ||||
struct PlottablesSetter<T, typename std::enable_if_t<std::is_base_of<ScalarSeries, T>::value | ||||
or std::is_base_of<VectorSeries, T>::value> > { | ||||
Alexandre Leroux
|
r1336 | static void setProperties(PlottablesMap &plottables) | ||
Alexandre Leroux
|
r918 | { | ||
Alexandre Leroux
|
r1336 | // Finds the plottable with the highest index to determine the number of colors to generate | ||
auto end = plottables.cend(); | ||||
auto maxPlottableIndexIt | ||||
= std::max_element(plottables.cbegin(), end, [](const auto &it1, const auto &it2) { | ||||
return it1.first < it2.first; | ||||
}); | ||||
auto componentCount = maxPlottableIndexIt != end ? maxPlottableIndexIt->first + 1 : 0; | ||||
Alexandre Leroux
|
r919 | |||
// 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 | ||||
for (auto i = 0; i < componentCount; ++i) { | ||||
Alexandre Leroux
|
r1336 | auto graphIt = plottables.find(i); | ||
if (graphIt != end) { | ||||
graphIt->second->setPen(QPen{colors.at(i)}); | ||||
} | ||||
Alexandre Leroux
|
r919 | } | ||
Alexandre Leroux
|
r918 | } | ||
}; | ||||
Alexandre Leroux
|
r922 | /** | ||
* Specialization of PlottablesSetter for spectrograms | ||||
* @sa SpectrogramSeries | ||||
*/ | ||||
template <typename T> | ||||
struct PlottablesSetter<T, | ||||
typename std::enable_if_t<std::is_base_of<SpectrogramSeries, T>::value> > { | ||||
Alexandre Leroux
|
r1336 | static void setProperties(PlottablesMap &plottables) | ||
Alexandre Leroux
|
r922 | { | ||
// Checks that for a spectrogram there is only one plottable, that is a colormap | ||||
if (plottables.size() != 1) { | ||||
return; | ||||
} | ||||
if (auto colormap = dynamic_cast<QCPColorMap *>(plottables.begin()->second)) { | ||||
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); | ||||
for (auto plotElement : plotElements) { | ||||
if (auto colorScale = dynamic_cast<QCPColorScale *>(plotElement)) { | ||||
colormap->setColorScale(colorScale); | ||||
} | ||||
} | ||||
colormap->rescaleDataRange(); | ||||
} | ||||
Alexandre Leroux
|
r927 | else { | ||
qCCritical(LOG_PlottablesRenderingUtils()) << "Can't get colormap of the spectrogram"; | ||||
} | ||||
Alexandre Leroux
|
r922 | } | ||
}; | ||||
Alexandre Leroux
|
r918 | /** | ||
* Default implementation of IPlottablesHelper, which takes data series to set plottables properties | ||||
* @tparam T the data series' type | ||||
*/ | ||||
template <typename T> | ||||
struct PlottablesHelper : public IPlottablesHelper { | ||||
void setProperties(PlottablesMap &plottables) override | ||||
{ | ||||
Alexandre Leroux
|
r1336 | PlottablesSetter<T>::setProperties(plottables); | ||
Alexandre Leroux
|
r918 | } | ||
}; | ||||
} // namespace | ||||
std::unique_ptr<IPlottablesHelper> | ||||
Alexandre Leroux
|
r1336 | IPlottablesHelperFactory::create(const Variable &variable) noexcept | ||
Alexandre Leroux
|
r918 | { | ||
Alexandre Leroux
|
r1336 | switch (variable.type()) { | ||
case DataSeriesType::SCALAR: | ||||
return std::make_unique<PlottablesHelper<ScalarSeries> >(); | ||||
case DataSeriesType::SPECTROGRAM: | ||||
return std::make_unique<PlottablesHelper<SpectrogramSeries> >(); | ||||
case DataSeriesType::VECTOR: | ||||
return std::make_unique<PlottablesHelper<VectorSeries> >(); | ||||
default: | ||||
// Returns default helper | ||||
break; | ||||
Alexandre Leroux
|
r918 | } | ||
Alexandre Leroux
|
r1336 | |||
return std::make_unique<PlottablesHelper<IDataSeries> >(); | ||||
Alexandre Leroux
|
r918 | } | ||