##// END OF EJS Templates
Adds title and close items in plot overlay
Alexandre Leroux -
r726:29f9f4126213
parent child
Show More
@@ -1,109 +1,153
1 1 #include "Visualization/VisualizationGraphRenderingDelegate.h"
2 2 #include "Visualization/VisualizationGraphWidget.h"
3 3 #include "Visualization/qcustomplot.h"
4 4
5 5 #include <Common/DateUtils.h>
6 6
7 #include <SqpApplication.h>
8
7 9 namespace {
8 10
9 11 const auto DATETIME_FORMAT = QStringLiteral("yyyy/MM/dd hh:mm:ss:zzz");
10 12
13 /// Name of the overlay layer in QCustomPlot
14 const auto OVERLAY_LAYER = QStringLiteral("overlay");
15
11 16 const auto TOOLTIP_FORMAT = QStringLiteral("key: %1\nvalue: %2");
12 17
13 18 /// Offset used to shift the tooltip of the mouse
14 19 const auto TOOLTIP_OFFSET = QPoint{20, 20};
15 20
16 21 /// Tooltip display rectangle (the tooltip is hidden when the mouse leaves this rectangle)
17 22 const auto TOOLTIP_RECT = QRect{10, 10, 10, 10};
18 23
19 24 /// Timeout after which the tooltip is displayed
20 25 const auto TOOLTIP_TIMEOUT = 500;
21 26
22 27 /// Formats a data value according to the axis on which it is present
23 28 QString formatValue(double value, const QCPAxis &axis)
24 29 {
25 30 // If the axis is a time axis, formats the value as a date
26 31 if (auto axisTicker = qSharedPointerDynamicCast<QCPAxisTickerDateTime>(axis.ticker())) {
27 32 return DateUtils::dateTime(value, axisTicker->dateTimeSpec()).toString(DATETIME_FORMAT);
28 33 }
29 34 else {
30 35 return QString::number(value);
31 36 }
32 37 }
33 38
34 39 void initPointTracerStyle(QCPItemTracer &tracer) noexcept
35 40 {
36 41 tracer.setInterpolating(false);
37 42 tracer.setStyle(QCPItemTracer::tsCircle);
38 43 tracer.setSize(3);
39 44 tracer.setPen(QPen(Qt::black));
40 45 tracer.setBrush(Qt::black);
41 46 }
42 47
48 void initClosePixmapStyle(QCPItemPixmap &pixmap) noexcept
49 {
50 // Icon
51 pixmap.setPixmap(
52 sqpApp->style()->standardIcon(QStyle::SP_TitleBarCloseButton).pixmap(QSize{16, 16}));
53
54 // Position
55 pixmap.topLeft->setType(QCPItemPosition::ptAxisRectRatio);
56 pixmap.topLeft->setCoords(1, 0);
57 pixmap.setClipToAxisRect(false);
58
59 // Can be selected
60 pixmap.setSelectable(true);
61 }
62
63 void initTitleTextStyle(QCPItemText &text) noexcept
64 {
65 // Font and background styles
66 text.setColor(Qt::gray);
67 text.setBrush(Qt::white);
68
69 // Position
70 text.setPositionAlignment(Qt::AlignTop | Qt::AlignLeft);
71 text.position->setType(QCPItemPosition::ptAxisRectRatio);
72 text.position->setCoords(0.5, 0);
73 }
74
43 75 } // namespace
44 76
45 77 struct VisualizationGraphRenderingDelegate::VisualizationGraphRenderingDelegatePrivate {
46 78 explicit VisualizationGraphRenderingDelegatePrivate(VisualizationGraphWidget &graphWidget)
47 79 : m_Plot{graphWidget.plot()},
48 80 m_PointTracer{new QCPItemTracer{&m_Plot}},
49 81 m_TracerTimer{},
82 m_ClosePixmap{new QCPItemPixmap{&m_Plot}},
83 m_TitleText{new QCPItemText{&m_Plot}}
50 84 {
51 85 initPointTracerStyle(*m_PointTracer);
52 86
53 87 m_TracerTimer.setInterval(TOOLTIP_TIMEOUT);
54 88 m_TracerTimer.setSingleShot(true);
89
90 // Inits "close button" in plot overlay
91 m_ClosePixmap->setLayer(OVERLAY_LAYER);
92 initClosePixmapStyle(*m_ClosePixmap);
93 // Inits graph name in plot overlay
94 m_TitleText->setLayer(OVERLAY_LAYER);
95 m_TitleText->setText(graphWidget.name());
96 initTitleTextStyle(*m_TitleText);
55 97 }
56 98
57 99 QCustomPlot &m_Plot;
58 100 QCPItemTracer *m_PointTracer;
59 101 QTimer m_TracerTimer;
102 QCPItemPixmap *m_ClosePixmap; /// Graph's close button
103 QCPItemText *m_TitleText; /// Graph's title
60 104 };
61 105
62 106 VisualizationGraphRenderingDelegate::VisualizationGraphRenderingDelegate(
63 107 VisualizationGraphWidget &graphWidget)
64 108 : impl{spimpl::make_unique_impl<VisualizationGraphRenderingDelegatePrivate>(graphWidget)}
65 109 {
66 110 }
67 111
68 112 void VisualizationGraphRenderingDelegate::onMouseMove(QMouseEvent *event) noexcept
69 113 {
70 114 // Cancels pending refresh
71 115 impl->m_TracerTimer.disconnect();
72 116
73 117 // Reinits tracers
74 118 impl->m_PointTracer->setGraph(nullptr);
75 119 impl->m_PointTracer->setVisible(false);
76 120 impl->m_Plot.replot();
77 121
78 122 // Gets the graph under the mouse position
79 123 auto eventPos = event->pos();
80 124 if (auto graph = qobject_cast<QCPGraph *>(impl->m_Plot.plottableAt(eventPos))) {
81 125 auto mouseKey = graph->keyAxis()->pixelToCoord(eventPos.x());
82 126 auto graphData = graph->data();
83 127
84 128 // Gets the closest data point to the mouse
85 129 auto graphDataIt = graphData->findBegin(mouseKey);
86 130 if (graphDataIt != graphData->constEnd()) {
87 131 auto key = formatValue(graphDataIt->key, *graph->keyAxis());
88 132 auto value = formatValue(graphDataIt->value, *graph->valueAxis());
89 133
90 134 // Displays point tracer
91 135 impl->m_PointTracer->setGraph(graph);
92 136 impl->m_PointTracer->setGraphKey(graphDataIt->key);
93 137 impl->m_PointTracer->setLayer(
94 138 impl->m_Plot.layer("main")); // Tracer is set on top of the plot's main layer
95 139 impl->m_PointTracer->setVisible(true);
96 140 impl->m_Plot.replot();
97 141
98 142 // Starts timer to show tooltip after timeout
99 143 auto showTooltip = [ tooltip = TOOLTIP_FORMAT.arg(key, value), eventPos, this ]()
100 144 {
101 145 QToolTip::showText(impl->m_Plot.mapToGlobal(eventPos) + TOOLTIP_OFFSET, tooltip,
102 146 &impl->m_Plot, TOOLTIP_RECT);
103 147 };
104 148
105 149 QObject::connect(&impl->m_TracerTimer, &QTimer::timeout, showTooltip);
106 150 impl->m_TracerTimer.start();
107 151 }
108 152 }
109 153 }
General Comments 0
You need to be logged in to leave comments. Login now