##// END OF EJS Templates
Handles axes properties for spectrograms...
Alexandre Leroux -
r921:bea8fb891633
parent child
Show More
@@ -1,123 +1,163
1 #include "Visualization/AxisRenderingUtils.h"
1 #include "Visualization/AxisRenderingUtils.h"
2
2
3 #include <Data/ScalarSeries.h>
3 #include <Data/ScalarSeries.h>
4 #include <Data/SpectrogramSeries.h>
4 #include <Data/VectorSeries.h>
5 #include <Data/VectorSeries.h>
5
6
6 #include <Visualization/qcustomplot.h>
7 #include <Visualization/qcustomplot.h>
7
8
8 namespace {
9 namespace {
9
10
10 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");
11
12
12 /// Format for datetimes on a axis
13 /// Format for datetimes on a axis
13 const auto DATETIME_TICKER_FORMAT = QStringLiteral("yyyy/MM/dd \nhh:mm:ss");
14 const auto DATETIME_TICKER_FORMAT = QStringLiteral("yyyy/MM/dd \nhh:mm:ss");
14
15
15 /// Generates the appropriate ticker for an axis, depending on whether the axis displays time or
16 /// Generates the appropriate ticker for an axis, depending on whether the axis displays time or
16 /// non-time data
17 /// non-time data
17 QSharedPointer<QCPAxisTicker> axisTicker(bool isTimeAxis)
18 QSharedPointer<QCPAxisTicker> axisTicker(bool isTimeAxis)
18 {
19 {
19 if (isTimeAxis) {
20 if (isTimeAxis) {
20 auto dateTicker = QSharedPointer<QCPAxisTickerDateTime>::create();
21 auto dateTicker = QSharedPointer<QCPAxisTickerDateTime>::create();
21 dateTicker->setDateTimeFormat(DATETIME_TICKER_FORMAT);
22 dateTicker->setDateTimeFormat(DATETIME_TICKER_FORMAT);
22 dateTicker->setDateTimeSpec(Qt::UTC);
23 dateTicker->setDateTimeSpec(Qt::UTC);
23
24
24 return dateTicker;
25 return dateTicker;
25 }
26 }
26 else {
27 else {
27 // default ticker
28 // default ticker
28 return QSharedPointer<QCPAxisTicker>::create();
29 return QSharedPointer<QCPAxisTicker>::create();
29 }
30 }
30 }
31 }
31
32
32 /**
33 /**
33 * Sets properties of the axis passed as parameter
34 * Sets properties of the axis passed as parameter
34 * @param axis the axis to set
35 * @param axis the axis to set
35 * @param unit the unit to set for the axis
36 * @param unit the unit to set for the axis
36 * @param scaleType the scale type to set for the axis
37 * @param scaleType the scale type to set for the axis
37 */
38 */
38 void setAxisProperties(QCPAxis &axis, const Unit &unit,
39 void setAxisProperties(QCPAxis &axis, const Unit &unit,
39 QCPAxis::ScaleType scaleType = QCPAxis::stLinear)
40 QCPAxis::ScaleType scaleType = QCPAxis::stLinear)
40 {
41 {
41 // label (unit name)
42 // label (unit name)
42 axis.setLabel(unit.m_Name);
43 axis.setLabel(unit.m_Name);
43
44
44 // scale type
45 // scale type
45 axis.setScaleType(scaleType);
46 axis.setScaleType(scaleType);
46
47
47 // ticker (depending on the type of unit)
48 // ticker (depending on the type of unit)
48 axis.setTicker(axisTicker(unit.m_TimeUnit));
49 axis.setTicker(axisTicker(unit.m_TimeUnit));
49 }
50 }
50
51
51 /**
52 /**
52 * Delegate used to set axes properties
53 * Delegate used to set axes properties
53 */
54 */
54 template <typename T, typename Enabled = void>
55 template <typename T, typename Enabled = void>
55 struct AxisSetter {
56 struct AxisSetter {
56 static void setProperties(T &, QCustomPlot &, QCPColorScale &)
57 static void setProperties(T &, QCustomPlot &, QCPColorScale &)
57 {
58 {
58 // Default implementation does nothing
59 // Default implementation does nothing
59 }
60 }
60 };
61 };
61
62
62 /**
63 /**
63 * Specialization of AxisSetter for scalars and vectors
64 * Specialization of AxisSetter for scalars and vectors
64 * @sa ScalarSeries
65 * @sa ScalarSeries
65 * @sa VectorSeries
66 * @sa VectorSeries
66 */
67 */
67 template <typename T>
68 template <typename T>
68 struct AxisSetter<T, typename std::enable_if_t<std::is_base_of<ScalarSeries, T>::value
69 struct AxisSetter<T, typename std::enable_if_t<std::is_base_of<ScalarSeries, T>::value
69 or std::is_base_of<VectorSeries, T>::value> > {
70 or std::is_base_of<VectorSeries, T>::value> > {
70 static void setProperties(T &dataSeries, QCustomPlot &plot, QCPColorScale &)
71 static void setProperties(T &dataSeries, QCustomPlot &plot, QCPColorScale &)
71 {
72 {
72 dataSeries.lockRead();
73 dataSeries.lockRead();
73 auto xAxisUnit = dataSeries.xAxisUnit();
74 auto xAxisUnit = dataSeries.xAxisUnit();
74 auto valuesUnit = dataSeries.valuesUnit();
75 auto valuesUnit = dataSeries.valuesUnit();
75 dataSeries.unlock();
76 dataSeries.unlock();
76
77
77 setAxisProperties(*plot.xAxis, xAxisUnit);
78 setAxisProperties(*plot.xAxis, xAxisUnit);
78 setAxisProperties(*plot.yAxis, valuesUnit);
79 setAxisProperties(*plot.yAxis, valuesUnit);
79 }
80 }
80 };
81 };
81
82
82 /**
83 /**
84 * Specialization of AxisSetter for spectrograms
85 * @sa SpectrogramSeries
86 */
87 template <typename T>
88 struct AxisSetter<T, typename std::enable_if_t<std::is_base_of<SpectrogramSeries, T>::value> > {
89 static void setProperties(T &dataSeries, QCustomPlot &plot, QCPColorScale &colorScale)
90 {
91 dataSeries.lockRead();
92 auto xAxisUnit = dataSeries.xAxisUnit();
93 /// @todo ALX: use iterators here
94 auto yAxisUnit = dataSeries.yAxis().unit();
95 auto valuesUnit = dataSeries.valuesUnit();
96 dataSeries.unlock();
97
98 setAxisProperties(*plot.xAxis, xAxisUnit);
99 setAxisProperties(*plot.yAxis, yAxisUnit);
100
101 // Displays color scale in plot
102 plot.plotLayout()->insertRow(0);
103 plot.plotLayout()->addElement(0, 0, &colorScale);
104 colorScale.setType(QCPAxis::atTop);
105 colorScale.setMinimumMargins(QMargins{0, 0, 0, 0});
106
107 // Aligns color scale with axes
108 auto marginGroups = plot.axisRect()->marginGroups();
109 for (auto it = marginGroups.begin(), end = marginGroups.end(); it != end; ++it) {
110 colorScale.setMarginGroup(it.key(), it.value());
111 }
112
113 // Set color scale properties
114 colorScale.setLabel(valuesUnit.m_Name);
115 colorScale.setDataScaleType(QCPAxis::stLogarithmic); // Logarithmic scale
116 }
117 };
118
119 /**
83 * Default implementation of IAxisHelper, which takes data series to set axes properties
120 * Default implementation of IAxisHelper, which takes data series to set axes properties
84 * @tparam T the data series' type
121 * @tparam T the data series' type
85 */
122 */
86 template <typename T>
123 template <typename T>
87 struct AxisHelper : public IAxisHelper {
124 struct AxisHelper : public IAxisHelper {
88 explicit AxisHelper(T &dataSeries) : m_DataSeries{dataSeries} {}
125 explicit AxisHelper(T &dataSeries) : m_DataSeries{dataSeries} {}
89
126
90 void setProperties(QCustomPlot &plot, QCPColorScale &colorScale) override
127 void setProperties(QCustomPlot &plot, QCPColorScale &colorScale) override
91 {
128 {
92 AxisSetter<T>::setProperties(m_DataSeries, plot, colorScale);
129 AxisSetter<T>::setProperties(m_DataSeries, plot, colorScale);
93 }
130 }
94
131
95 T &m_DataSeries;
132 T &m_DataSeries;
96 };
133 };
97
134
98 } // namespace
135 } // namespace
99
136
100 QString formatValue(double value, const QCPAxis &axis)
137 QString formatValue(double value, const QCPAxis &axis)
101 {
138 {
102 // If the axis is a time axis, formats the value as a date
139 // If the axis is a time axis, formats the value as a date
103 if (auto axisTicker = qSharedPointerDynamicCast<QCPAxisTickerDateTime>(axis.ticker())) {
140 if (auto axisTicker = qSharedPointerDynamicCast<QCPAxisTickerDateTime>(axis.ticker())) {
104 return DateUtils::dateTime(value, axisTicker->dateTimeSpec()).toString(DATETIME_FORMAT);
141 return DateUtils::dateTime(value, axisTicker->dateTimeSpec()).toString(DATETIME_FORMAT);
105 }
142 }
106 else {
143 else {
107 return QString::number(value);
144 return QString::number(value);
108 }
145 }
109 }
146 }
110
147
111 std::unique_ptr<IAxisHelper>
148 std::unique_ptr<IAxisHelper>
112 IAxisHelperFactory::create(std::shared_ptr<IDataSeries> dataSeries) noexcept
149 IAxisHelperFactory::create(std::shared_ptr<IDataSeries> dataSeries) noexcept
113 {
150 {
114 if (auto scalarSeries = std::dynamic_pointer_cast<ScalarSeries>(dataSeries)) {
151 if (auto scalarSeries = std::dynamic_pointer_cast<ScalarSeries>(dataSeries)) {
115 return std::make_unique<AxisHelper<ScalarSeries> >(*scalarSeries);
152 return std::make_unique<AxisHelper<ScalarSeries> >(*scalarSeries);
116 }
153 }
154 else if (auto spectrogramSeries = std::dynamic_pointer_cast<SpectrogramSeries>(dataSeries)) {
155 return std::make_unique<AxisHelper<SpectrogramSeries> >(*spectrogramSeries);
156 }
117 else if (auto vectorSeries = std::dynamic_pointer_cast<VectorSeries>(dataSeries)) {
157 else if (auto vectorSeries = std::dynamic_pointer_cast<VectorSeries>(dataSeries)) {
118 return std::make_unique<AxisHelper<VectorSeries> >(*vectorSeries);
158 return std::make_unique<AxisHelper<VectorSeries> >(*vectorSeries);
119 }
159 }
120 else {
160 else {
121 return std::make_unique<AxisHelper<IDataSeries> >(*dataSeries);
161 return std::make_unique<AxisHelper<IDataSeries> >(*dataSeries);
122 }
162 }
123 }
163 }
@@ -1,243 +1,245
1 #include "Visualization/VisualizationGraphRenderingDelegate.h"
1 #include "Visualization/VisualizationGraphRenderingDelegate.h"
2 #include "Visualization/AxisRenderingUtils.h"
2 #include "Visualization/AxisRenderingUtils.h"
3 #include "Visualization/PlottablesRenderingUtils.h"
3 #include "Visualization/PlottablesRenderingUtils.h"
4 #include "Visualization/VisualizationGraphWidget.h"
4 #include "Visualization/VisualizationGraphWidget.h"
5 #include "Visualization/qcustomplot.h"
5 #include "Visualization/qcustomplot.h"
6
6
7 #include <Common/DateUtils.h>
7 #include <Common/DateUtils.h>
8
8
9 #include <Data/IDataSeries.h>
9 #include <Data/IDataSeries.h>
10
10
11 #include <SqpApplication.h>
11 #include <SqpApplication.h>
12
12
13 namespace {
13 namespace {
14
14
15 /// Name of the axes layer in QCustomPlot
15 /// Name of the axes layer in QCustomPlot
16 const auto AXES_LAYER = QStringLiteral("axes");
16 const auto AXES_LAYER = QStringLiteral("axes");
17
17
18 /// Icon used to show x-axis properties
18 /// Icon used to show x-axis properties
19 const auto HIDE_AXIS_ICON_PATH = QStringLiteral(":/icones/down.png");
19 const auto HIDE_AXIS_ICON_PATH = QStringLiteral(":/icones/down.png");
20
20
21 /// Name of the overlay layer in QCustomPlot
21 /// Name of the overlay layer in QCustomPlot
22 const auto OVERLAY_LAYER = QStringLiteral("overlay");
22 const auto OVERLAY_LAYER = QStringLiteral("overlay");
23
23
24 /// Pixmap used to show x-axis properties
24 /// Pixmap used to show x-axis properties
25 const auto SHOW_AXIS_ICON_PATH = QStringLiteral(":/icones/up.png");
25 const auto SHOW_AXIS_ICON_PATH = QStringLiteral(":/icones/up.png");
26
26
27 const auto TOOLTIP_FORMAT = QStringLiteral("key: %1\nvalue: %2");
27 const auto TOOLTIP_FORMAT = QStringLiteral("key: %1\nvalue: %2");
28
28
29 /// Offset used to shift the tooltip of the mouse
29 /// Offset used to shift the tooltip of the mouse
30 const auto TOOLTIP_OFFSET = QPoint{20, 20};
30 const auto TOOLTIP_OFFSET = QPoint{20, 20};
31
31
32 /// Tooltip display rectangle (the tooltip is hidden when the mouse leaves this rectangle)
32 /// Tooltip display rectangle (the tooltip is hidden when the mouse leaves this rectangle)
33 const auto TOOLTIP_RECT = QRect{10, 10, 10, 10};
33 const auto TOOLTIP_RECT = QRect{10, 10, 10, 10};
34
34
35 /// Timeout after which the tooltip is displayed
35 /// Timeout after which the tooltip is displayed
36 const auto TOOLTIP_TIMEOUT = 500;
36 const auto TOOLTIP_TIMEOUT = 500;
37
37
38 void initPointTracerStyle(QCPItemTracer &tracer) noexcept
38 void initPointTracerStyle(QCPItemTracer &tracer) noexcept
39 {
39 {
40 tracer.setInterpolating(false);
40 tracer.setInterpolating(false);
41 tracer.setStyle(QCPItemTracer::tsCircle);
41 tracer.setStyle(QCPItemTracer::tsCircle);
42 tracer.setSize(3);
42 tracer.setSize(3);
43 tracer.setPen(QPen(Qt::black));
43 tracer.setPen(QPen(Qt::black));
44 tracer.setBrush(Qt::black);
44 tracer.setBrush(Qt::black);
45 }
45 }
46
46
47 QPixmap pixmap(const QString &iconPath) noexcept
47 QPixmap pixmap(const QString &iconPath) noexcept
48 {
48 {
49 return QIcon{iconPath}.pixmap(QSize{16, 16});
49 return QIcon{iconPath}.pixmap(QSize{16, 16});
50 }
50 }
51
51
52 void initClosePixmapStyle(QCPItemPixmap &pixmap) noexcept
52 void initClosePixmapStyle(QCPItemPixmap &pixmap) noexcept
53 {
53 {
54 // Icon
54 // Icon
55 pixmap.setPixmap(
55 pixmap.setPixmap(
56 sqpApp->style()->standardIcon(QStyle::SP_TitleBarCloseButton).pixmap(QSize{16, 16}));
56 sqpApp->style()->standardIcon(QStyle::SP_TitleBarCloseButton).pixmap(QSize{16, 16}));
57
57
58 // Position
58 // Position
59 pixmap.topLeft->setType(QCPItemPosition::ptAxisRectRatio);
59 pixmap.topLeft->setType(QCPItemPosition::ptAxisRectRatio);
60 pixmap.topLeft->setCoords(1, 0);
60 pixmap.topLeft->setCoords(1, 0);
61 pixmap.setClipToAxisRect(false);
61 pixmap.setClipToAxisRect(false);
62
62
63 // Can be selected
63 // Can be selected
64 pixmap.setSelectable(true);
64 pixmap.setSelectable(true);
65 }
65 }
66
66
67 void initXAxisPixmapStyle(QCPItemPixmap &itemPixmap) noexcept
67 void initXAxisPixmapStyle(QCPItemPixmap &itemPixmap) noexcept
68 {
68 {
69 // Icon
69 // Icon
70 itemPixmap.setPixmap(pixmap(HIDE_AXIS_ICON_PATH));
70 itemPixmap.setPixmap(pixmap(HIDE_AXIS_ICON_PATH));
71
71
72 // Position
72 // Position
73 itemPixmap.topLeft->setType(QCPItemPosition::ptAxisRectRatio);
73 itemPixmap.topLeft->setType(QCPItemPosition::ptAxisRectRatio);
74 itemPixmap.topLeft->setCoords(0, 1);
74 itemPixmap.topLeft->setCoords(0, 1);
75 itemPixmap.setClipToAxisRect(false);
75 itemPixmap.setClipToAxisRect(false);
76
76
77 // Can be selected
77 // Can be selected
78 itemPixmap.setSelectable(true);
78 itemPixmap.setSelectable(true);
79 }
79 }
80
80
81 void initTitleTextStyle(QCPItemText &text) noexcept
81 void initTitleTextStyle(QCPItemText &text) noexcept
82 {
82 {
83 // Font and background styles
83 // Font and background styles
84 text.setColor(Qt::gray);
84 text.setColor(Qt::gray);
85 text.setBrush(Qt::white);
85 text.setBrush(Qt::white);
86
86
87 // Position
87 // Position
88 text.setPositionAlignment(Qt::AlignTop | Qt::AlignLeft);
88 text.setPositionAlignment(Qt::AlignTop | Qt::AlignLeft);
89 text.position->setType(QCPItemPosition::ptAxisRectRatio);
89 text.position->setType(QCPItemPosition::ptAxisRectRatio);
90 text.position->setCoords(0.5, 0);
90 text.position->setCoords(0.5, 0);
91 }
91 }
92
92
93 } // namespace
93 } // namespace
94
94
95 struct VisualizationGraphRenderingDelegate::VisualizationGraphRenderingDelegatePrivate {
95 struct VisualizationGraphRenderingDelegate::VisualizationGraphRenderingDelegatePrivate {
96 explicit VisualizationGraphRenderingDelegatePrivate(VisualizationGraphWidget &graphWidget)
96 explicit VisualizationGraphRenderingDelegatePrivate(VisualizationGraphWidget &graphWidget)
97 : m_Plot{graphWidget.plot()},
97 : m_Plot{graphWidget.plot()},
98 m_PointTracer{new QCPItemTracer{&m_Plot}},
98 m_PointTracer{new QCPItemTracer{&m_Plot}},
99 m_TracerTimer{},
99 m_TracerTimer{},
100 m_ClosePixmap{new QCPItemPixmap{&m_Plot}},
100 m_ClosePixmap{new QCPItemPixmap{&m_Plot}},
101 m_TitleText{new QCPItemText{&m_Plot}},
101 m_TitleText{new QCPItemText{&m_Plot}},
102 m_XAxisPixmap{new QCPItemPixmap{&m_Plot}},
102 m_XAxisPixmap{new QCPItemPixmap{&m_Plot}},
103 m_ShowXAxis{true},
103 m_ShowXAxis{true},
104 m_XAxisLabel{}
104 m_XAxisLabel{},
105 m_ColorScale{new QCPColorScale{&m_Plot}}
note

Who manage the delete of the color scale ?

105 {
106 {
106 initPointTracerStyle(*m_PointTracer);
107 initPointTracerStyle(*m_PointTracer);
107
108
108 m_TracerTimer.setInterval(TOOLTIP_TIMEOUT);
109 m_TracerTimer.setInterval(TOOLTIP_TIMEOUT);
109 m_TracerTimer.setSingleShot(true);
110 m_TracerTimer.setSingleShot(true);
110
111
111 // Inits "close button" in plot overlay
112 // Inits "close button" in plot overlay
112 m_ClosePixmap->setLayer(OVERLAY_LAYER);
113 m_ClosePixmap->setLayer(OVERLAY_LAYER);
113 initClosePixmapStyle(*m_ClosePixmap);
114 initClosePixmapStyle(*m_ClosePixmap);
114
115
115 // Connects pixmap selection to graph widget closing
116 // Connects pixmap selection to graph widget closing
116 QObject::connect(m_ClosePixmap, &QCPItemPixmap::selectionChanged,
117 QObject::connect(m_ClosePixmap, &QCPItemPixmap::selectionChanged,
117 [&graphWidget](bool selected) {
118 [&graphWidget](bool selected) {
118 if (selected) {
119 if (selected) {
119 graphWidget.close();
120 graphWidget.close();
120 }
121 }
121 });
122 });
122
123
123 // Inits graph name in plot overlay
124 // Inits graph name in plot overlay
124 m_TitleText->setLayer(OVERLAY_LAYER);
125 m_TitleText->setLayer(OVERLAY_LAYER);
125 m_TitleText->setText(graphWidget.name());
126 m_TitleText->setText(graphWidget.name());
126 initTitleTextStyle(*m_TitleText);
127 initTitleTextStyle(*m_TitleText);
127
128
128 // Inits "show x-axis button" in plot overlay
129 // Inits "show x-axis button" in plot overlay
129 m_XAxisPixmap->setLayer(OVERLAY_LAYER);
130 m_XAxisPixmap->setLayer(OVERLAY_LAYER);
130 initXAxisPixmapStyle(*m_XAxisPixmap);
131 initXAxisPixmapStyle(*m_XAxisPixmap);
131
132
132 // Connects pixmap selection to graph x-axis showing/hiding
133 // Connects pixmap selection to graph x-axis showing/hiding
133 QObject::connect(m_XAxisPixmap, &QCPItemPixmap::selectionChanged, [this]() {
134 QObject::connect(m_XAxisPixmap, &QCPItemPixmap::selectionChanged, [this]() {
134 if (m_XAxisPixmap->selected()) {
135 if (m_XAxisPixmap->selected()) {
135 // Changes the selection state and refreshes the x-axis
136 // Changes the selection state and refreshes the x-axis
136 m_ShowXAxis = !m_ShowXAxis;
137 m_ShowXAxis = !m_ShowXAxis;
137 updateXAxisState();
138 updateXAxisState();
138 m_Plot.layer(AXES_LAYER)->replot();
139 m_Plot.layer(AXES_LAYER)->replot();
139
140
140 // Deselects the x-axis pixmap and updates icon
141 // Deselects the x-axis pixmap and updates icon
141 m_XAxisPixmap->setSelected(false);
142 m_XAxisPixmap->setSelected(false);
142 m_XAxisPixmap->setPixmap(
143 m_XAxisPixmap->setPixmap(
143 pixmap(m_ShowXAxis ? HIDE_AXIS_ICON_PATH : SHOW_AXIS_ICON_PATH));
144 pixmap(m_ShowXAxis ? HIDE_AXIS_ICON_PATH : SHOW_AXIS_ICON_PATH));
144 m_Plot.layer(OVERLAY_LAYER)->replot();
145 m_Plot.layer(OVERLAY_LAYER)->replot();
145 }
146 }
146 });
147 });
147 }
148 }
148
149
149 /// Updates state of x-axis according to the current selection of x-axis pixmap
150 /// Updates state of x-axis according to the current selection of x-axis pixmap
150 /// @remarks the method doesn't call plot refresh
151 /// @remarks the method doesn't call plot refresh
151 void updateXAxisState() noexcept
152 void updateXAxisState() noexcept
152 {
153 {
153 m_Plot.xAxis->setTickLabels(m_ShowXAxis);
154 m_Plot.xAxis->setTickLabels(m_ShowXAxis);
154 m_Plot.xAxis->setLabel(m_ShowXAxis ? m_XAxisLabel : QString{});
155 m_Plot.xAxis->setLabel(m_ShowXAxis ? m_XAxisLabel : QString{});
155 }
156 }
156
157
157 QCustomPlot &m_Plot;
158 QCustomPlot &m_Plot;
158 QCPItemTracer *m_PointTracer;
159 QCPItemTracer *m_PointTracer;
159 QTimer m_TracerTimer;
160 QTimer m_TracerTimer;
160 QCPItemPixmap *m_ClosePixmap; /// Graph's close button
161 QCPItemPixmap *m_ClosePixmap; /// Graph's close button
161 QCPItemText *m_TitleText; /// Graph's title
162 QCPItemText *m_TitleText; /// Graph's title
162 QCPItemPixmap *m_XAxisPixmap;
163 QCPItemPixmap *m_XAxisPixmap;
163 bool m_ShowXAxis; /// X-axis properties are shown or hidden
164 bool m_ShowXAxis; /// X-axis properties are shown or hidden
164 QString m_XAxisLabel;
165 QString m_XAxisLabel;
166 QCPColorScale *m_ColorScale; /// Color scale used for some types of graphs (as spectrograms)
165 };
167 };
166
168
167 VisualizationGraphRenderingDelegate::VisualizationGraphRenderingDelegate(
169 VisualizationGraphRenderingDelegate::VisualizationGraphRenderingDelegate(
168 VisualizationGraphWidget &graphWidget)
170 VisualizationGraphWidget &graphWidget)
169 : impl{spimpl::make_unique_impl<VisualizationGraphRenderingDelegatePrivate>(graphWidget)}
171 : impl{spimpl::make_unique_impl<VisualizationGraphRenderingDelegatePrivate>(graphWidget)}
170 {
172 {
171 }
173 }
172
174
173 void VisualizationGraphRenderingDelegate::onMouseMove(QMouseEvent *event) noexcept
175 void VisualizationGraphRenderingDelegate::onMouseMove(QMouseEvent *event) noexcept
174 {
176 {
175 // Cancels pending refresh
177 // Cancels pending refresh
176 impl->m_TracerTimer.disconnect();
178 impl->m_TracerTimer.disconnect();
177
179
178 // Reinits tracers
180 // Reinits tracers
179 impl->m_PointTracer->setGraph(nullptr);
181 impl->m_PointTracer->setGraph(nullptr);
180 impl->m_PointTracer->setVisible(false);
182 impl->m_PointTracer->setVisible(false);
181 impl->m_Plot.replot();
183 impl->m_Plot.replot();
182
184
183 // Gets the graph under the mouse position
185 // Gets the graph under the mouse position
184 auto eventPos = event->pos();
186 auto eventPos = event->pos();
185 if (auto graph = qobject_cast<QCPGraph *>(impl->m_Plot.plottableAt(eventPos))) {
187 if (auto graph = qobject_cast<QCPGraph *>(impl->m_Plot.plottableAt(eventPos))) {
186 auto mouseKey = graph->keyAxis()->pixelToCoord(eventPos.x());
188 auto mouseKey = graph->keyAxis()->pixelToCoord(eventPos.x());
187 auto graphData = graph->data();
189 auto graphData = graph->data();
188
190
189 // Gets the closest data point to the mouse
191 // Gets the closest data point to the mouse
190 auto graphDataIt = graphData->findBegin(mouseKey);
192 auto graphDataIt = graphData->findBegin(mouseKey);
191 if (graphDataIt != graphData->constEnd()) {
193 if (graphDataIt != graphData->constEnd()) {
192 auto key = formatValue(graphDataIt->key, *graph->keyAxis());
194 auto key = formatValue(graphDataIt->key, *graph->keyAxis());
193 auto value = formatValue(graphDataIt->value, *graph->valueAxis());
195 auto value = formatValue(graphDataIt->value, *graph->valueAxis());
194
196
195 // Displays point tracer
197 // Displays point tracer
196 impl->m_PointTracer->setGraph(graph);
198 impl->m_PointTracer->setGraph(graph);
197 impl->m_PointTracer->setGraphKey(graphDataIt->key);
199 impl->m_PointTracer->setGraphKey(graphDataIt->key);
198 impl->m_PointTracer->setLayer(
200 impl->m_PointTracer->setLayer(
199 impl->m_Plot.layer("main")); // Tracer is set on top of the plot's main layer
201 impl->m_Plot.layer("main")); // Tracer is set on top of the plot's main layer
200 impl->m_PointTracer->setVisible(true);
202 impl->m_PointTracer->setVisible(true);
201 impl->m_Plot.replot();
203 impl->m_Plot.replot();
202
204
203 // Starts timer to show tooltip after timeout
205 // Starts timer to show tooltip after timeout
204 auto showTooltip = [ tooltip = TOOLTIP_FORMAT.arg(key, value), eventPos, this ]()
206 auto showTooltip = [ tooltip = TOOLTIP_FORMAT.arg(key, value), eventPos, this ]()
205 {
207 {
206 QToolTip::showText(impl->m_Plot.mapToGlobal(eventPos) + TOOLTIP_OFFSET, tooltip,
208 QToolTip::showText(impl->m_Plot.mapToGlobal(eventPos) + TOOLTIP_OFFSET, tooltip,
207 &impl->m_Plot, TOOLTIP_RECT);
209 &impl->m_Plot, TOOLTIP_RECT);
208 };
210 };
209
211
210 QObject::connect(&impl->m_TracerTimer, &QTimer::timeout, showTooltip);
212 QObject::connect(&impl->m_TracerTimer, &QTimer::timeout, showTooltip);
211 impl->m_TracerTimer.start();
213 impl->m_TracerTimer.start();
212 }
214 }
213 }
215 }
214 }
216 }
215
217
216 void VisualizationGraphRenderingDelegate::setAxesProperties(
218 void VisualizationGraphRenderingDelegate::setAxesProperties(
217 std::shared_ptr<IDataSeries> dataSeries) noexcept
219 std::shared_ptr<IDataSeries> dataSeries) noexcept
218 {
220 {
219 // Stores x-axis label to be able to retrieve it when x-axis pixmap is unselected
221 // Stores x-axis label to be able to retrieve it when x-axis pixmap is unselected
220 impl->m_XAxisLabel = dataSeries->xAxisUnit().m_Name;
222 impl->m_XAxisLabel = dataSeries->xAxisUnit().m_Name;
221
223
222 auto axisHelper = IAxisHelperFactory::create(dataSeries);
224 auto axisHelper = IAxisHelperFactory::create(dataSeries);
223 axisHelper->setProperties(impl->m_Plot, *impl->m_ColorScale);
225 axisHelper->setProperties(impl->m_Plot, *impl->m_ColorScale);
224
226
225 // Updates x-axis state
227 // Updates x-axis state
226 impl->updateXAxisState();
228 impl->updateXAxisState();
227
229
228 impl->m_Plot.layer(AXES_LAYER)->replot();
230 impl->m_Plot.layer(AXES_LAYER)->replot();
229 }
231 }
230
232
231 void VisualizationGraphRenderingDelegate::setPlottablesProperties(
233 void VisualizationGraphRenderingDelegate::setPlottablesProperties(
232 std::shared_ptr<IDataSeries> dataSeries, PlottablesMap &plottables) noexcept
234 std::shared_ptr<IDataSeries> dataSeries, PlottablesMap &plottables) noexcept
233 {
235 {
234 auto plottablesHelper = IPlottablesHelperFactory::create(dataSeries);
236 auto plottablesHelper = IPlottablesHelperFactory::create(dataSeries);
235 plottablesHelper->setProperties(plottables);
237 plottablesHelper->setProperties(plottables);
236 }
238 }
237
239
238 void VisualizationGraphRenderingDelegate::showGraphOverlay(bool show) noexcept
240 void VisualizationGraphRenderingDelegate::showGraphOverlay(bool show) noexcept
239 {
241 {
240 auto overlay = impl->m_Plot.layer(OVERLAY_LAYER);
242 auto overlay = impl->m_Plot.layer(OVERLAY_LAYER);
241 overlay->setVisible(show);
243 overlay->setVisible(show);
242 overlay->replot();
244 overlay->replot();
243 }
245 }
General Comments 0
You need to be logged in to leave comments. Login now