##// END OF EJS Templates
Parser refactoring (4)...
Parser refactoring (4) Implements results reading and data series creation Implementation takes some of the basic parser, which will be deleted at the end

File last commit:

r921:bea8fb891633
r988:6f8d3c2b5ba3
Show More
VisualizationGraphRenderingDelegate.cpp
245 lines | 8.4 KiB | text/x-c | CppLexer
/ gui / src / Visualization / VisualizationGraphRenderingDelegate.cpp
Alexandre Leroux
Creates a delegate offering methods for rendering a graph
r480 #include "Visualization/VisualizationGraphRenderingDelegate.h"
Alexandre Leroux
Refactoring handling of axes properties (2)...
r917 #include "Visualization/AxisRenderingUtils.h"
Alexandre Leroux
Handles rendering of plottables (3)...
r920 #include "Visualization/PlottablesRenderingUtils.h"
Alexandre Leroux
Passes directly GraphWidget in delegate...
r725 #include "Visualization/VisualizationGraphWidget.h"
Alexandre Leroux
Creates a delegate offering methods for rendering a graph
r480 #include "Visualization/qcustomplot.h"
Alexandre Leroux
Uses the same time spec (UTC) as axis for tooltips on graph
r490 #include <Common/DateUtils.h>
Alexandre Leroux
Adds button on plot overlay to show/hide x-axis properties
r729 #include <Data/IDataSeries.h>
Alexandre Leroux
Adds title and close items in plot overlay
r726 #include <SqpApplication.h>
Alexandre Leroux
Inits tracers and timer...
r482 namespace {
Alexandre Leroux
Adds button on plot overlay to show/hide x-axis properties
r729 /// Name of the axes layer in QCustomPlot
const auto AXES_LAYER = QStringLiteral("axes");
/// Icon used to show x-axis properties
const auto HIDE_AXIS_ICON_PATH = QStringLiteral(":/icones/down.png");
Alexandre Leroux
Adds title and close items in plot overlay
r726 /// Name of the overlay layer in QCustomPlot
const auto OVERLAY_LAYER = QStringLiteral("overlay");
Alexandre Leroux
Adds button on plot overlay to show/hide x-axis properties
r729 /// Pixmap used to show x-axis properties
const auto SHOW_AXIS_ICON_PATH = QStringLiteral(":/icones/up.png");
Alexandre Leroux
Uses Qt tooltips instead of QCPTextItem...
r576 const auto TOOLTIP_FORMAT = QStringLiteral("key: %1\nvalue: %2");
Alexandre Leroux
Show tracers method (1)...
r483
Alexandre Leroux
Shifts tooltip to mouse
r578 /// Offset used to shift the tooltip of the mouse
const auto TOOLTIP_OFFSET = QPoint{20, 20};
Alexandre Leroux
Uses Qt tooltips instead of QCPTextItem...
r576 /// Tooltip display rectangle (the tooltip is hidden when the mouse leaves this rectangle)
const auto TOOLTIP_RECT = QRect{10, 10, 10, 10};
/// Timeout after which the tooltip is displayed
const auto TOOLTIP_TIMEOUT = 500;
Alexandre Leroux
Inits tracers and timer...
r482
Alexandre Leroux
Sets tracers' styles
r485 void initPointTracerStyle(QCPItemTracer &tracer) noexcept
{
tracer.setInterpolating(false);
Alexandre Leroux
Replaces "Plus" cursor by "Circle" cursor
r577 tracer.setStyle(QCPItemTracer::tsCircle);
tracer.setSize(3);
Alexandre Leroux
Sets tracers' styles
r485 tracer.setPen(QPen(Qt::black));
tracer.setBrush(Qt::black);
}
Alexandre Leroux
Adds button on plot overlay to show/hide x-axis properties
r729 QPixmap pixmap(const QString &iconPath) noexcept
{
return QIcon{iconPath}.pixmap(QSize{16, 16});
}
Alexandre Leroux
Adds title and close items in plot overlay
r726 void initClosePixmapStyle(QCPItemPixmap &pixmap) noexcept
{
// Icon
pixmap.setPixmap(
sqpApp->style()->standardIcon(QStyle::SP_TitleBarCloseButton).pixmap(QSize{16, 16}));
// Position
pixmap.topLeft->setType(QCPItemPosition::ptAxisRectRatio);
pixmap.topLeft->setCoords(1, 0);
pixmap.setClipToAxisRect(false);
// Can be selected
pixmap.setSelectable(true);
}
Alexandre Leroux
Adds button on plot overlay to show/hide x-axis properties
r729 void initXAxisPixmapStyle(QCPItemPixmap &itemPixmap) noexcept
{
// Icon
itemPixmap.setPixmap(pixmap(HIDE_AXIS_ICON_PATH));
// Position
itemPixmap.topLeft->setType(QCPItemPosition::ptAxisRectRatio);
itemPixmap.topLeft->setCoords(0, 1);
itemPixmap.setClipToAxisRect(false);
// Can be selected
itemPixmap.setSelectable(true);
}
Alexandre Leroux
Adds title and close items in plot overlay
r726 void initTitleTextStyle(QCPItemText &text) noexcept
{
// Font and background styles
text.setColor(Qt::gray);
text.setBrush(Qt::white);
// Position
text.setPositionAlignment(Qt::AlignTop | Qt::AlignLeft);
text.position->setType(QCPItemPosition::ptAxisRectRatio);
text.position->setCoords(0.5, 0);
}
Alexandre Leroux
Inits tracers and timer...
r482 } // namespace
Alexandre Leroux
Creates a delegate offering methods for rendering a graph
r480 struct VisualizationGraphRenderingDelegate::VisualizationGraphRenderingDelegatePrivate {
Alexandre Leroux
Passes directly GraphWidget in delegate...
r725 explicit VisualizationGraphRenderingDelegatePrivate(VisualizationGraphWidget &graphWidget)
: m_Plot{graphWidget.plot()},
m_PointTracer{new QCPItemTracer{&m_Plot}},
m_TracerTimer{},
Alexandre Leroux
Adds title and close items in plot overlay
r726 m_ClosePixmap{new QCPItemPixmap{&m_Plot}},
Alexandre Leroux
Adds button on plot overlay to show/hide x-axis properties
r729 m_TitleText{new QCPItemText{&m_Plot}},
m_XAxisPixmap{new QCPItemPixmap{&m_Plot}},
m_ShowXAxis{true},
Alexandre Leroux
Handles axes properties for spectrograms...
r921 m_XAxisLabel{},
m_ColorScale{new QCPColorScale{&m_Plot}}
Alexandre Leroux
Inits tracers and timer...
r482 {
Alexandre Leroux
Sets tracers' styles
r485 initPointTracerStyle(*m_PointTracer);
Alexandre Leroux
Inits tracers and timer...
r482
Alexandre Leroux
Uses Qt tooltips instead of QCPTextItem...
r576 m_TracerTimer.setInterval(TOOLTIP_TIMEOUT);
Alexandre Leroux
Inits tracers and timer...
r482 m_TracerTimer.setSingleShot(true);
Alexandre Leroux
Adds title and close items in plot overlay
r726
// Inits "close button" in plot overlay
m_ClosePixmap->setLayer(OVERLAY_LAYER);
initClosePixmapStyle(*m_ClosePixmap);
Alexandre Leroux
Calls 'close graph' action when selecting close item in overlay
r727
// Connects pixmap selection to graph widget closing
QObject::connect(m_ClosePixmap, &QCPItemPixmap::selectionChanged,
[&graphWidget](bool selected) {
if (selected) {
graphWidget.close();
}
});
Alexandre Leroux
Adds title and close items in plot overlay
r726 // Inits graph name in plot overlay
m_TitleText->setLayer(OVERLAY_LAYER);
m_TitleText->setText(graphWidget.name());
initTitleTextStyle(*m_TitleText);
Alexandre Leroux
Adds button on plot overlay to show/hide x-axis properties
r729
// Inits "show x-axis button" in plot overlay
m_XAxisPixmap->setLayer(OVERLAY_LAYER);
initXAxisPixmapStyle(*m_XAxisPixmap);
// Connects pixmap selection to graph x-axis showing/hiding
QObject::connect(m_XAxisPixmap, &QCPItemPixmap::selectionChanged, [this]() {
if (m_XAxisPixmap->selected()) {
// Changes the selection state and refreshes the x-axis
m_ShowXAxis = !m_ShowXAxis;
updateXAxisState();
m_Plot.layer(AXES_LAYER)->replot();
// Deselects the x-axis pixmap and updates icon
m_XAxisPixmap->setSelected(false);
m_XAxisPixmap->setPixmap(
pixmap(m_ShowXAxis ? HIDE_AXIS_ICON_PATH : SHOW_AXIS_ICON_PATH));
m_Plot.layer(OVERLAY_LAYER)->replot();
}
});
}
/// Updates state of x-axis according to the current selection of x-axis pixmap
/// @remarks the method doesn't call plot refresh
void updateXAxisState() noexcept
{
m_Plot.xAxis->setTickLabels(m_ShowXAxis);
m_Plot.xAxis->setLabel(m_ShowXAxis ? m_XAxisLabel : QString{});
Alexandre Leroux
Inits tracers and timer...
r482 }
Alexandre Leroux
Creates a delegate offering methods for rendering a graph
r480
QCustomPlot &m_Plot;
Alexandre Leroux
Inits tracers and timer...
r482 QCPItemTracer *m_PointTracer;
QTimer m_TracerTimer;
Alexandre Leroux
Adds title and close items in plot overlay
r726 QCPItemPixmap *m_ClosePixmap; /// Graph's close button
QCPItemText *m_TitleText; /// Graph's title
Alexandre Leroux
Adds button on plot overlay to show/hide x-axis properties
r729 QCPItemPixmap *m_XAxisPixmap;
bool m_ShowXAxis; /// X-axis properties are shown or hidden
QString m_XAxisLabel;
Alexandre Leroux
Handles axes properties for spectrograms...
r921 QCPColorScale *m_ColorScale; /// Color scale used for some types of graphs (as spectrograms)
Alexandre Leroux
Creates a delegate offering methods for rendering a graph
r480 };
Alexandre Leroux
Passes directly GraphWidget in delegate...
r725 VisualizationGraphRenderingDelegate::VisualizationGraphRenderingDelegate(
VisualizationGraphWidget &graphWidget)
: impl{spimpl::make_unique_impl<VisualizationGraphRenderingDelegatePrivate>(graphWidget)}
Alexandre Leroux
Creates a delegate offering methods for rendering a graph
r480 {
}
Alexandre Leroux
Creates method that will display a tooltip and a tracer with data point information after a while
r481
void VisualizationGraphRenderingDelegate::onMouseMove(QMouseEvent *event) noexcept
{
Alexandre Leroux
Inits tracers and timer...
r482 // Cancels pending refresh
impl->m_TracerTimer.disconnect();
Alexandre Leroux
Uses Qt tooltips instead of QCPTextItem...
r576 // Reinits tracers
impl->m_PointTracer->setGraph(nullptr);
impl->m_PointTracer->setVisible(false);
impl->m_Plot.replot();
// Gets the graph under the mouse position
auto eventPos = event->pos();
if (auto graph = qobject_cast<QCPGraph *>(impl->m_Plot.plottableAt(eventPos))) {
auto mouseKey = graph->keyAxis()->pixelToCoord(eventPos.x());
auto graphData = graph->data();
// Gets the closest data point to the mouse
auto graphDataIt = graphData->findBegin(mouseKey);
if (graphDataIt != graphData->constEnd()) {
auto key = formatValue(graphDataIt->key, *graph->keyAxis());
auto value = formatValue(graphDataIt->value, *graph->valueAxis());
// Displays point tracer
impl->m_PointTracer->setGraph(graph);
impl->m_PointTracer->setGraphKey(graphDataIt->key);
impl->m_PointTracer->setLayer(
impl->m_Plot.layer("main")); // Tracer is set on top of the plot's main layer
impl->m_PointTracer->setVisible(true);
Alexandre Leroux
Show tracers method (2)...
r484 impl->m_Plot.replot();
Alexandre Leroux
Inits tracers and timer...
r482
Alexandre Leroux
Uses Qt tooltips instead of QCPTextItem...
r576 // Starts timer to show tooltip after timeout
auto showTooltip = [ tooltip = TOOLTIP_FORMAT.arg(key, value), eventPos, this ]()
{
Alexandre Leroux
Shifts tooltip to mouse
r578 QToolTip::showText(impl->m_Plot.mapToGlobal(eventPos) + TOOLTIP_OFFSET, tooltip,
&impl->m_Plot, TOOLTIP_RECT);
Alexandre Leroux
Uses Qt tooltips instead of QCPTextItem...
r576 };
QObject::connect(&impl->m_TracerTimer, &QTimer::timeout, showTooltip);
impl->m_TracerTimer.start();
}
}
Alexandre Leroux
Creates method that will display a tooltip and a tracer with data point information after a while
r481 }
Alexandre Leroux
Shows/hides plot overlay when entering/leaving graph
r728
Alexandre Leroux
Refactoring handling of axes properties (2)...
r917 void VisualizationGraphRenderingDelegate::setAxesProperties(
std::shared_ptr<IDataSeries> dataSeries) noexcept
Alexandre Leroux
Adds button on plot overlay to show/hide x-axis properties
r729 {
// Stores x-axis label to be able to retrieve it when x-axis pixmap is unselected
Alexandre Leroux
Refactoring handling of axes properties (2)...
r917 impl->m_XAxisLabel = dataSeries->xAxisUnit().m_Name;
Alexandre Leroux
Adds button on plot overlay to show/hide x-axis properties
r729
Alexandre Leroux
Refactoring handling of axes properties (2)...
r917 auto axisHelper = IAxisHelperFactory::create(dataSeries);
axisHelper->setProperties(impl->m_Plot, *impl->m_ColorScale);
Alexandre Leroux
Adds button on plot overlay to show/hide x-axis properties
r729
// Updates x-axis state
impl->updateXAxisState();
impl->m_Plot.layer(AXES_LAYER)->replot();
}
Alexandre Leroux
Handles rendering of plottables (3)...
r920 void VisualizationGraphRenderingDelegate::setPlottablesProperties(
std::shared_ptr<IDataSeries> dataSeries, PlottablesMap &plottables) noexcept
{
auto plottablesHelper = IPlottablesHelperFactory::create(dataSeries);
plottablesHelper->setProperties(plottables);
}
Alexandre Leroux
Shows/hides plot overlay when entering/leaving graph
r728 void VisualizationGraphRenderingDelegate::showGraphOverlay(bool show) noexcept
{
auto overlay = impl->m_Plot.layer(OVERLAY_LAYER);
overlay->setVisible(show);
overlay->replot();
}