diff --git a/gui/src/Visualization/VisualizationGraphRenderingDelegate.cpp b/gui/src/Visualization/VisualizationGraphRenderingDelegate.cpp index 6e6e3ea..a5ef319 100644 --- a/gui/src/Visualization/VisualizationGraphRenderingDelegate.cpp +++ b/gui/src/Visualization/VisualizationGraphRenderingDelegate.cpp @@ -7,10 +7,13 @@ namespace { const auto DATETIME_FORMAT = QStringLiteral("yyyy/MM/dd hh:mm:ss:zzz"); -const auto TEXT_TRACER_FORMAT = QStringLiteral("key: %1\nvalue: %2"); +const auto TOOLTIP_FORMAT = QStringLiteral("key: %1\nvalue: %2"); -/// Timeout after which a tracer is displayed -const auto TRACER_TIMEOUT = 500; +/// 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; /// Formats a data value according to the axis on which it is present QString formatValue(double value, const QCPAxis &axis) @@ -33,34 +36,20 @@ void initPointTracerStyle(QCPItemTracer &tracer) noexcept tracer.setSize(10); } -void initTextTracerStyle(QCPItemText &tracer) noexcept -{ - tracer.setPen(QPen{Qt::gray}); - tracer.setBrush(Qt::white); - tracer.setPadding(QMargins{6, 6, 6, 6}); - tracer.setPositionAlignment(Qt::AlignTop | Qt::AlignLeft); - tracer.setTextAlignment(Qt::AlignLeft); -} - } // namespace struct VisualizationGraphRenderingDelegate::VisualizationGraphRenderingDelegatePrivate { explicit VisualizationGraphRenderingDelegatePrivate(QCustomPlot &plot) - : m_Plot{plot}, - m_PointTracer{new QCPItemTracer{&plot}}, - m_TextTracer{new QCPItemText{&plot}}, - m_TracerTimer{} + : m_Plot{plot}, m_PointTracer{new QCPItemTracer{&plot}}, m_TracerTimer{} { initPointTracerStyle(*m_PointTracer); - initTextTracerStyle(*m_TextTracer); - m_TracerTimer.setInterval(TRACER_TIMEOUT); + m_TracerTimer.setInterval(TOOLTIP_TIMEOUT); m_TracerTimer.setSingleShot(true); } QCustomPlot &m_Plot; QCPItemTracer *m_PointTracer; - QCPItemText *m_TextTracer; QTimer m_TracerTimer; }; @@ -74,50 +63,40 @@ void VisualizationGraphRenderingDelegate::onMouseMove(QMouseEvent *event) noexce // Cancels pending refresh impl->m_TracerTimer.disconnect(); - auto showTracers = [ eventPos = event->pos(), this ]() - { - // Lambda function to display a tracer - auto displayTracer = [this](auto &tracer) { - // Tracer is set on top of the plot's main layer - tracer.setLayer(impl->m_Plot.layer("main")); - tracer.setVisible(true); + // 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(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); impl->m_Plot.replot(); - }; - - // Reinits tracers - impl->m_PointTracer->setGraph(nullptr); - impl->m_PointTracer->setVisible(false); - impl->m_TextTracer->setVisible(false); - impl->m_Plot.replot(); - - // Gets the graph under the mouse position - if (auto graph = qobject_cast(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()); - impl->m_TextTracer->setText(TEXT_TRACER_FORMAT.arg(key, value)); - - // Displays point tracer - impl->m_PointTracer->setGraph(graph); - impl->m_PointTracer->setGraphKey(graphDataIt->key); - displayTracer(*impl->m_PointTracer); - - // Displays text tracer - auto tracerPosition = impl->m_TextTracer->position; - tracerPosition->setAxes(graph->keyAxis(), graph->valueAxis()); - tracerPosition->setCoords(impl->m_PointTracer->position->key(), - impl->m_PointTracer->position->value()); - displayTracer(*impl->m_TextTracer); - } - } - }; - // Starts the timer to display tracers at timeout - QObject::connect(&impl->m_TracerTimer, &QTimer::timeout, showTracers); - impl->m_TracerTimer.start(); + // Starts timer to show tooltip after timeout + auto showTooltip = [ tooltip = TOOLTIP_FORMAT.arg(key, value), eventPos, this ]() + { + QToolTip::showText(impl->m_Plot.mapToGlobal(eventPos), tooltip, &impl->m_Plot, + TOOLTIP_RECT); + }; + + QObject::connect(&impl->m_TracerTimer, &QTimer::timeout, showTooltip); + impl->m_TracerTimer.start(); + } + } }