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