##// END OF EJS Templates
Handles rendering properties for spectrograms...
Handles rendering properties for spectrograms Spectrogram's colormap uses gradient and is associated to the color scale of the plot

File last commit:

r920:bea8fb891633
r921:76b9deb45018
Show More
AxisRenderingUtils.cpp
163 lines | 5.1 KiB | text/x-c | CppLexer
/ gui / src / Visualization / AxisRenderingUtils.cpp
Alexandre Leroux
Refactoring handling of axes properties (1)...
r915 #include "Visualization/AxisRenderingUtils.h"
#include <Data/ScalarSeries.h>
Alexandre Leroux
Handles axes properties for spectrograms...
r920 #include <Data/SpectrogramSeries.h>
Alexandre Leroux
Refactoring handling of axes properties (1)...
r915 #include <Data/VectorSeries.h>
#include <Visualization/qcustomplot.h>
namespace {
Alexandre Leroux
Refactoring handling of axes properties (2)...
r916 const auto DATETIME_FORMAT = QStringLiteral("yyyy/MM/dd hh:mm:ss:zzz");
/// 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);
dateTicker->setDateTimeSpec(Qt::UTC);
return dateTicker;
}
else {
// default ticker
return QSharedPointer<QCPAxisTicker>::create();
}
}
/**
* Sets properties of the axis passed as parameter
* @param axis the axis to set
* @param unit the unit to set for the axis
* @param scaleType the scale type to set for the axis
*/
void setAxisProperties(QCPAxis &axis, const Unit &unit,
QCPAxis::ScaleType scaleType = QCPAxis::stLinear)
{
// label (unit name)
axis.setLabel(unit.m_Name);
// scale type
axis.setScaleType(scaleType);
// ticker (depending on the type of unit)
axis.setTicker(axisTicker(unit.m_TimeUnit));
}
Alexandre Leroux
Refactoring handling of axes properties (1)...
r915 /**
* Delegate used to set axes properties
*/
template <typename T, typename Enabled = void>
struct AxisSetter {
static void setProperties(T &, QCustomPlot &, QCPColorScale &)
{
// Default implementation does nothing
}
};
/**
* Specialization of AxisSetter for scalars and vectors
* @sa ScalarSeries
* @sa VectorSeries
*/
template <typename T>
struct AxisSetter<T, typename std::enable_if_t<std::is_base_of<ScalarSeries, T>::value
or std::is_base_of<VectorSeries, T>::value> > {
static void setProperties(T &dataSeries, QCustomPlot &plot, QCPColorScale &)
{
Alexandre Leroux
Refactoring handling of axes properties (2)...
r916 dataSeries.lockRead();
auto xAxisUnit = dataSeries.xAxisUnit();
auto valuesUnit = dataSeries.valuesUnit();
dataSeries.unlock();
setAxisProperties(*plot.xAxis, xAxisUnit);
setAxisProperties(*plot.yAxis, valuesUnit);
Alexandre Leroux
Refactoring handling of axes properties (1)...
r915 }
};
Alexandre Leroux
Handles axes properties for spectrograms...
r920 /**
* Specialization of AxisSetter for spectrograms
* @sa SpectrogramSeries
*/
template <typename T>
struct AxisSetter<T, typename std::enable_if_t<std::is_base_of<SpectrogramSeries, T>::value> > {
static void setProperties(T &dataSeries, QCustomPlot &plot, QCPColorScale &colorScale)
{
dataSeries.lockRead();
auto xAxisUnit = dataSeries.xAxisUnit();
/// @todo ALX: use iterators here
auto yAxisUnit = dataSeries.yAxis().unit();
auto valuesUnit = dataSeries.valuesUnit();
dataSeries.unlock();
setAxisProperties(*plot.xAxis, xAxisUnit);
setAxisProperties(*plot.yAxis, yAxisUnit);
// Displays color scale in plot
plot.plotLayout()->insertRow(0);
plot.plotLayout()->addElement(0, 0, &colorScale);
colorScale.setType(QCPAxis::atTop);
colorScale.setMinimumMargins(QMargins{0, 0, 0, 0});
// Aligns color scale with axes
auto marginGroups = plot.axisRect()->marginGroups();
for (auto it = marginGroups.begin(), end = marginGroups.end(); it != end; ++it) {
colorScale.setMarginGroup(it.key(), it.value());
}
// Set color scale properties
colorScale.setLabel(valuesUnit.m_Name);
colorScale.setDataScaleType(QCPAxis::stLogarithmic); // Logarithmic scale
}
};
Alexandre Leroux
Refactoring handling of axes properties (1)...
r915 /**
* Default implementation of IAxisHelper, which takes data series to set axes properties
* @tparam T the data series' type
*/
template <typename T>
struct AxisHelper : public IAxisHelper {
explicit AxisHelper(T &dataSeries) : m_DataSeries{dataSeries} {}
void setProperties(QCustomPlot &plot, QCPColorScale &colorScale) override
{
AxisSetter<T>::setProperties(m_DataSeries, plot, colorScale);
}
T &m_DataSeries;
};
} // namespace
Alexandre Leroux
Refactoring handling of axes properties (2)...
r916 QString formatValue(double value, const QCPAxis &axis)
{
// If the axis is a time axis, formats the value as a date
if (auto axisTicker = qSharedPointerDynamicCast<QCPAxisTickerDateTime>(axis.ticker())) {
return DateUtils::dateTime(value, axisTicker->dateTimeSpec()).toString(DATETIME_FORMAT);
}
else {
return QString::number(value);
}
}
Alexandre Leroux
Refactoring handling of axes properties (1)...
r915 std::unique_ptr<IAxisHelper>
IAxisHelperFactory::create(std::shared_ptr<IDataSeries> dataSeries) noexcept
{
if (auto scalarSeries = std::dynamic_pointer_cast<ScalarSeries>(dataSeries)) {
return std::make_unique<AxisHelper<ScalarSeries> >(*scalarSeries);
}
Alexandre Leroux
Handles axes properties for spectrograms...
r920 else if (auto spectrogramSeries = std::dynamic_pointer_cast<SpectrogramSeries>(dataSeries)) {
return std::make_unique<AxisHelper<SpectrogramSeries> >(*spectrogramSeries);
}
Alexandre Leroux
Refactoring handling of axes properties (1)...
r915 else if (auto vectorSeries = std::dynamic_pointer_cast<VectorSeries>(dataSeries)) {
return std::make_unique<AxisHelper<VectorSeries> >(*vectorSeries);
}
else {
return std::make_unique<AxisHelper<IDataSeries> >(*dataSeries);
}
}