|
|
#include "Visualization/PlottablesRenderingUtils.h"
|
|
|
|
|
|
#include <Common/ColorUtils.h>
|
|
|
|
|
|
#include <Data/ScalarSeries.h>
|
|
|
#include <Data/SpectrogramSeries.h>
|
|
|
#include <Data/VectorSeries.h>
|
|
|
|
|
|
#include <Variable/Variable.h>
|
|
|
|
|
|
#include <Visualization/qcustomplot.h>
|
|
|
|
|
|
Q_LOGGING_CATEGORY(LOG_PlottablesRenderingUtils, "PlottablesRenderingUtils")
|
|
|
|
|
|
namespace {
|
|
|
|
|
|
/**
|
|
|
* Delegate used to set plottables properties
|
|
|
*/
|
|
|
template <typename T, typename Enabled = void>
|
|
|
struct PlottablesSetter {
|
|
|
static void setProperties(PlottablesMap &)
|
|
|
{
|
|
|
// Default implementation does nothing
|
|
|
qCCritical(LOG_PlottablesRenderingUtils())
|
|
|
<< "Can't set plottables properties: unmanaged type of data";
|
|
|
}
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
* 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> > {
|
|
|
static void setProperties(PlottablesMap &plottables)
|
|
|
{
|
|
|
// 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;
|
|
|
|
|
|
// 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) {
|
|
|
auto graphIt = plottables.find(i);
|
|
|
if (graphIt != end) {
|
|
|
graphIt->second->setPen(QPen{colors.at(i)});
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
* 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> > {
|
|
|
static void setProperties(PlottablesMap &plottables)
|
|
|
{
|
|
|
// 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();
|
|
|
}
|
|
|
else {
|
|
|
qCCritical(LOG_PlottablesRenderingUtils()) << "Can't get colormap of the spectrogram";
|
|
|
}
|
|
|
}
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
* 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
|
|
|
{
|
|
|
PlottablesSetter<T>::setProperties(plottables);
|
|
|
}
|
|
|
};
|
|
|
|
|
|
} // namespace
|
|
|
|
|
|
std::unique_ptr<IPlottablesHelper>
|
|
|
IPlottablesHelperFactory::create(const Variable &variable) noexcept
|
|
|
{
|
|
|
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;
|
|
|
}
|
|
|
|
|
|
return std::make_unique<PlottablesHelper<IDataSeries> >();
|
|
|
}
|
|
|
|