##// END OF EJS Templates
Adds button on plot overlay to show/hide x-axis properties
Alexandre Leroux -
r670:94000392d1e8
parent child
Show More
1 NO CONTENT: new file 100644, binary diff hidden
NO CONTENT: new file 100644, binary diff hidden
1 NO CONTENT: new file 100644, binary diff hidden
NO CONTENT: new file 100644, binary diff hidden
@@ -5,6 +5,7
5
5
6 class QCustomPlot;
6 class QCustomPlot;
7 class QMouseEvent;
7 class QMouseEvent;
8 class Unit;
8 class VisualizationGraphWidget;
9 class VisualizationGraphWidget;
9
10
10 class VisualizationGraphRenderingDelegate {
11 class VisualizationGraphRenderingDelegate {
@@ -16,6 +17,9 public:
16
17
17 void onMouseMove(QMouseEvent *event) noexcept;
18 void onMouseMove(QMouseEvent *event) noexcept;
18
19
20 /// Sets properties of the plot's axes
21 void setAxesProperties(const Unit &xAxisUnit, const Unit &valuesUnit) noexcept;
22
19 /// Shows or hides graph overlay (name, close button, etc.)
23 /// Shows or hides graph overlay (name, close button, etc.)
20 void showGraphOverlay(bool show) noexcept;
24 void showGraphOverlay(bool show) noexcept;
21
25
@@ -5,10 +5,12
5 <file>icones/dataSourceProduct.png</file>
5 <file>icones/dataSourceProduct.png</file>
6 <file>icones/dataSourceRoot.png</file>
6 <file>icones/dataSourceRoot.png</file>
7 <file>icones/delete.png</file>
7 <file>icones/delete.png</file>
8 <file>icones/down.png</file>
8 <file>icones/openInspector.png</file>
9 <file>icones/openInspector.png</file>
9 <file>icones/next.png</file>
10 <file>icones/next.png</file>
10 <file>icones/plot.png</file>
11 <file>icones/plot.png</file>
11 <file>icones/previous.png</file>
12 <file>icones/previous.png</file>
12 <file>icones/unplot.png</file>
13 <file>icones/unplot.png</file>
14 <file>icones/up.png</file>
13 </qresource>
15 </qresource>
14 </RCC>
16 </RCC>
@@ -17,44 +17,6 public:
17 void appendGraphData(const QCPGraphData &data) { mData.append(data); }
17 void appendGraphData(const QCPGraphData &data) { mData.append(data); }
18 };
18 };
19
19
20
21 /// Format for datetimes on a axis
22 const auto DATETIME_TICKER_FORMAT = QStringLiteral("yyyy/MM/dd \nhh:mm:ss");
23
24 /// Generates the appropriate ticker for an axis, depending on whether the axis displays time or
25 /// non-time data
26 QSharedPointer<QCPAxisTicker> axisTicker(bool isTimeAxis)
27 {
28 if (isTimeAxis) {
29 auto dateTicker = QSharedPointer<QCPAxisTickerDateTime>::create();
30 dateTicker->setDateTimeFormat(DATETIME_TICKER_FORMAT);
31 dateTicker->setDateTimeSpec(Qt::UTC);
32
33 return dateTicker;
34 }
35 else {
36 // default ticker
37 return QSharedPointer<QCPAxisTicker>::create();
38 }
39 }
40
41 /// Sets axes properties according to the properties of a data series. Not thread safe
42 template <int Dim>
43 void setAxesProperties(const DataSeries<Dim> &dataSeries, QCustomPlot &plot) noexcept
44 {
45 /// @todo : for the moment, no control is performed on the axes: the units and the tickers
46 /// are fixed for the default x-axis and y-axis of the plot, and according to the new graph
47 auto setAxisProperties = [](auto axis, const auto &unit) {
48 // label (unit name)
49 axis->setLabel(unit.m_Name);
50
51 // ticker (depending on the type of unit)
52 axis->setTicker(axisTicker(unit.m_TimeUnit));
53 };
54 setAxisProperties(plot.xAxis, dataSeries.xAxisUnit());
55 setAxisProperties(plot.yAxis, dataSeries.valuesUnit());
56 }
57
58 /**
20 /**
59 * Struct used to create plottables, depending on the type of the data series from which to create
21 * Struct used to create plottables, depending on the type of the data series from which to create
60 * them
22 * them
@@ -99,11 +61,6 struct PlottablesCreator<T,
99 result.insert({i, graph});
61 result.insert({i, graph});
100 }
62 }
101
63
102 // Axes properties
103 dataSeries.lockRead();
104 setAxesProperties(dataSeries, plot);
105 dataSeries.unlock();
106
107 plot.replot();
64 plot.replot();
108
65
109 return result;
66 return result;
@@ -4,15 +4,29
4
4
5 #include <Common/DateUtils.h>
5 #include <Common/DateUtils.h>
6
6
7 #include <Data/IDataSeries.h>
8
7 #include <SqpApplication.h>
9 #include <SqpApplication.h>
8
10
9 namespace {
11 namespace {
10
12
13 /// Name of the axes layer in QCustomPlot
14 const auto AXES_LAYER = QStringLiteral("axes");
15
11 const auto DATETIME_FORMAT = QStringLiteral("yyyy/MM/dd hh:mm:ss:zzz");
16 const auto DATETIME_FORMAT = QStringLiteral("yyyy/MM/dd hh:mm:ss:zzz");
12
17
18 /// Format for datetimes on a axis
19 const auto DATETIME_TICKER_FORMAT = QStringLiteral("yyyy/MM/dd \nhh:mm:ss");
20
21 /// Icon used to show x-axis properties
22 const auto HIDE_AXIS_ICON_PATH = QStringLiteral(":/icones/down.png");
23
13 /// Name of the overlay layer in QCustomPlot
24 /// Name of the overlay layer in QCustomPlot
14 const auto OVERLAY_LAYER = QStringLiteral("overlay");
25 const auto OVERLAY_LAYER = QStringLiteral("overlay");
15
26
27 /// Pixmap used to show x-axis properties
28 const auto SHOW_AXIS_ICON_PATH = QStringLiteral(":/icones/up.png");
29
16 const auto TOOLTIP_FORMAT = QStringLiteral("key: %1\nvalue: %2");
30 const auto TOOLTIP_FORMAT = QStringLiteral("key: %1\nvalue: %2");
17
31
18 /// Offset used to shift the tooltip of the mouse
32 /// Offset used to shift the tooltip of the mouse
@@ -24,6 +38,23 const auto TOOLTIP_RECT = QRect{10, 10, 10, 10};
24 /// Timeout after which the tooltip is displayed
38 /// Timeout after which the tooltip is displayed
25 const auto TOOLTIP_TIMEOUT = 500;
39 const auto TOOLTIP_TIMEOUT = 500;
26
40
41 /// Generates the appropriate ticker for an axis, depending on whether the axis displays time or
42 /// non-time data
43 QSharedPointer<QCPAxisTicker> axisTicker(bool isTimeAxis)
44 {
45 if (isTimeAxis) {
46 auto dateTicker = QSharedPointer<QCPAxisTickerDateTime>::create();
47 dateTicker->setDateTimeFormat(DATETIME_TICKER_FORMAT);
48 dateTicker->setDateTimeSpec(Qt::UTC);
49
50 return dateTicker;
51 }
52 else {
53 // default ticker
54 return QSharedPointer<QCPAxisTicker>::create();
55 }
56 }
57
27 /// Formats a data value according to the axis on which it is present
58 /// Formats a data value according to the axis on which it is present
28 QString formatValue(double value, const QCPAxis &axis)
59 QString formatValue(double value, const QCPAxis &axis)
29 {
60 {
@@ -45,6 +76,11 void initPointTracerStyle(QCPItemTracer &tracer) noexcept
45 tracer.setBrush(Qt::black);
76 tracer.setBrush(Qt::black);
46 }
77 }
47
78
79 QPixmap pixmap(const QString &iconPath) noexcept
80 {
81 return QIcon{iconPath}.pixmap(QSize{16, 16});
82 }
83
48 void initClosePixmapStyle(QCPItemPixmap &pixmap) noexcept
84 void initClosePixmapStyle(QCPItemPixmap &pixmap) noexcept
49 {
85 {
50 // Icon
86 // Icon
@@ -60,6 +96,20 void initClosePixmapStyle(QCPItemPixmap &pixmap) noexcept
60 pixmap.setSelectable(true);
96 pixmap.setSelectable(true);
61 }
97 }
62
98
99 void initXAxisPixmapStyle(QCPItemPixmap &itemPixmap) noexcept
100 {
101 // Icon
102 itemPixmap.setPixmap(pixmap(HIDE_AXIS_ICON_PATH));
103
104 // Position
105 itemPixmap.topLeft->setType(QCPItemPosition::ptAxisRectRatio);
106 itemPixmap.topLeft->setCoords(0, 1);
107 itemPixmap.setClipToAxisRect(false);
108
109 // Can be selected
110 itemPixmap.setSelectable(true);
111 }
112
63 void initTitleTextStyle(QCPItemText &text) noexcept
113 void initTitleTextStyle(QCPItemText &text) noexcept
64 {
114 {
65 // Font and background styles
115 // Font and background styles
@@ -80,7 +130,10 struct VisualizationGraphRenderingDelegate::VisualizationGraphRenderingDelegateP
80 m_PointTracer{new QCPItemTracer{&m_Plot}},
130 m_PointTracer{new QCPItemTracer{&m_Plot}},
81 m_TracerTimer{},
131 m_TracerTimer{},
82 m_ClosePixmap{new QCPItemPixmap{&m_Plot}},
132 m_ClosePixmap{new QCPItemPixmap{&m_Plot}},
83 m_TitleText{new QCPItemText{&m_Plot}}
133 m_TitleText{new QCPItemText{&m_Plot}},
134 m_XAxisPixmap{new QCPItemPixmap{&m_Plot}},
135 m_ShowXAxis{true},
136 m_XAxisLabel{}
84 {
137 {
85 initPointTracerStyle(*m_PointTracer);
138 initPointTracerStyle(*m_PointTracer);
86
139
@@ -103,6 +156,34 struct VisualizationGraphRenderingDelegate::VisualizationGraphRenderingDelegateP
103 m_TitleText->setLayer(OVERLAY_LAYER);
156 m_TitleText->setLayer(OVERLAY_LAYER);
104 m_TitleText->setText(graphWidget.name());
157 m_TitleText->setText(graphWidget.name());
105 initTitleTextStyle(*m_TitleText);
158 initTitleTextStyle(*m_TitleText);
159
160 // Inits "show x-axis button" in plot overlay
161 m_XAxisPixmap->setLayer(OVERLAY_LAYER);
162 initXAxisPixmapStyle(*m_XAxisPixmap);
163
164 // Connects pixmap selection to graph x-axis showing/hiding
165 QObject::connect(m_XAxisPixmap, &QCPItemPixmap::selectionChanged, [this]() {
166 if (m_XAxisPixmap->selected()) {
167 // Changes the selection state and refreshes the x-axis
168 m_ShowXAxis = !m_ShowXAxis;
169 updateXAxisState();
170 m_Plot.layer(AXES_LAYER)->replot();
171
172 // Deselects the x-axis pixmap and updates icon
173 m_XAxisPixmap->setSelected(false);
174 m_XAxisPixmap->setPixmap(
175 pixmap(m_ShowXAxis ? HIDE_AXIS_ICON_PATH : SHOW_AXIS_ICON_PATH));
176 m_Plot.layer(OVERLAY_LAYER)->replot();
177 }
178 });
179 }
180
181 /// Updates state of x-axis according to the current selection of x-axis pixmap
182 /// @remarks the method doesn't call plot refresh
183 void updateXAxisState() noexcept
184 {
185 m_Plot.xAxis->setTickLabels(m_ShowXAxis);
186 m_Plot.xAxis->setLabel(m_ShowXAxis ? m_XAxisLabel : QString{});
106 }
187 }
107
188
108 QCustomPlot &m_Plot;
189 QCustomPlot &m_Plot;
@@ -110,6 +191,9 struct VisualizationGraphRenderingDelegate::VisualizationGraphRenderingDelegateP
110 QTimer m_TracerTimer;
191 QTimer m_TracerTimer;
111 QCPItemPixmap *m_ClosePixmap; /// Graph's close button
192 QCPItemPixmap *m_ClosePixmap; /// Graph's close button
112 QCPItemText *m_TitleText; /// Graph's title
193 QCPItemText *m_TitleText; /// Graph's title
194 QCPItemPixmap *m_XAxisPixmap;
195 bool m_ShowXAxis; /// X-axis properties are shown or hidden
196 QString m_XAxisLabel;
113 };
197 };
114
198
115 VisualizationGraphRenderingDelegate::VisualizationGraphRenderingDelegate(
199 VisualizationGraphRenderingDelegate::VisualizationGraphRenderingDelegate(
@@ -161,6 +245,28 void VisualizationGraphRenderingDelegate::onMouseMove(QMouseEvent *event) noexce
161 }
245 }
162 }
246 }
163
247
248 void VisualizationGraphRenderingDelegate::setAxesProperties(const Unit &xAxisUnit,
249 const Unit &valuesUnit) noexcept
250 {
251 // Stores x-axis label to be able to retrieve it when x-axis pixmap is unselected
252 impl->m_XAxisLabel = xAxisUnit.m_Name;
253
254 auto setAxisProperties = [](auto axis, const auto &unit) {
255 // label (unit name)
256 axis->setLabel(unit.m_Name);
257
258 // ticker (depending on the type of unit)
259 axis->setTicker(axisTicker(unit.m_TimeUnit));
260 };
261 setAxisProperties(impl->m_Plot.xAxis, xAxisUnit);
262 setAxisProperties(impl->m_Plot.yAxis, valuesUnit);
263
264 // Updates x-axis state
265 impl->updateXAxisState();
266
267 impl->m_Plot.layer(AXES_LAYER)->replot();
268 }
269
164 void VisualizationGraphRenderingDelegate::showGraphOverlay(bool show) noexcept
270 void VisualizationGraphRenderingDelegate::showGraphOverlay(bool show) noexcept
165 {
271 {
166 auto overlay = impl->m_Plot.layer(OVERLAY_LAYER);
272 auto overlay = impl->m_Plot.layer(OVERLAY_LAYER);
@@ -103,6 +103,20 void VisualizationGraphWidget::addVariable(std::shared_ptr<Variable> variable, S
103 auto createdPlottables = VisualizationGraphHelper::create(variable, *ui->widget);
103 auto createdPlottables = VisualizationGraphHelper::create(variable, *ui->widget);
104 impl->m_VariableToPlotMultiMap.insert({variable, std::move(createdPlottables)});
104 impl->m_VariableToPlotMultiMap.insert({variable, std::move(createdPlottables)});
105
105
106 // Set axes properties according to the units of the data series
107 /// @todo : for the moment, no control is performed on the axes: the units and the tickers
108 /// are fixed for the default x-axis and y-axis of the plot, and according to the new graph
109 auto xAxisUnit = Unit{};
110 auto valuesUnit = Unit{};
111
112 if (auto dataSeries = variable->dataSeries()) {
113 dataSeries->lockRead();
114 xAxisUnit = dataSeries->xAxisUnit();
115 valuesUnit = dataSeries->valuesUnit();
116 dataSeries->unlock();
117 }
118 impl->m_RenderingDelegate->setAxesProperties(xAxisUnit, valuesUnit);
119
106 connect(variable.get(), SIGNAL(updated()), this, SLOT(onDataCacheVariableUpdated()));
120 connect(variable.get(), SIGNAL(updated()), this, SLOT(onDataCacheVariableUpdated()));
107
121
108 auto varRange = variable->range();
122 auto varRange = variable->range();
General Comments 0
You need to be logged in to leave comments. Login now