##// END OF EJS Templates
Adds button on plot overlay to show/hide x-axis properties
Alexandre Leroux -
r729:94000392d1e8
parent child
Show More
1 NO CONTENT: new file 100644, binary diff hidden
1 NO CONTENT: new file 100644, binary diff hidden
@@ -5,6 +5,7
5 5
6 6 class QCustomPlot;
7 7 class QMouseEvent;
8 class Unit;
8 9 class VisualizationGraphWidget;
9 10
10 11 class VisualizationGraphRenderingDelegate {
@@ -16,6 +17,9 public:
16 17
17 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 23 /// Shows or hides graph overlay (name, close button, etc.)
20 24 void showGraphOverlay(bool show) noexcept;
21 25
@@ -5,10 +5,12
5 5 <file>icones/dataSourceProduct.png</file>
6 6 <file>icones/dataSourceRoot.png</file>
7 7 <file>icones/delete.png</file>
8 <file>icones/down.png</file>
8 9 <file>icones/openInspector.png</file>
9 10 <file>icones/next.png</file>
10 11 <file>icones/plot.png</file>
11 12 <file>icones/previous.png</file>
12 13 <file>icones/unplot.png</file>
14 <file>icones/up.png</file>
13 15 </qresource>
14 16 </RCC>
@@ -17,44 +17,6 public:
17 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 21 * Struct used to create plottables, depending on the type of the data series from which to create
60 22 * them
@@ -99,11 +61,6 struct PlottablesCreator<T,
99 61 result.insert({i, graph});
100 62 }
101 63
102 // Axes properties
103 dataSeries.lockRead();
104 setAxesProperties(dataSeries, plot);
105 dataSeries.unlock();
106
107 64 plot.replot();
108 65
109 66 return result;
@@ -4,15 +4,29
4 4
5 5 #include <Common/DateUtils.h>
6 6
7 #include <Data/IDataSeries.h>
8
7 9 #include <SqpApplication.h>
8 10
9 11 namespace {
10 12
13 /// Name of the axes layer in QCustomPlot
14 const auto AXES_LAYER = QStringLiteral("axes");
15
11 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 24 /// Name of the overlay layer in QCustomPlot
14 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 30 const auto TOOLTIP_FORMAT = QStringLiteral("key: %1\nvalue: %2");
17 31
18 32 /// Offset used to shift the tooltip of the mouse
@@ -24,6 +38,23 const auto TOOLTIP_RECT = QRect{10, 10, 10, 10};
24 38 /// Timeout after which the tooltip is displayed
25 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 58 /// Formats a data value according to the axis on which it is present
28 59 QString formatValue(double value, const QCPAxis &axis)
29 60 {
@@ -45,6 +76,11 void initPointTracerStyle(QCPItemTracer &tracer) noexcept
45 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 84 void initClosePixmapStyle(QCPItemPixmap &pixmap) noexcept
49 85 {
50 86 // Icon
@@ -60,6 +96,20 void initClosePixmapStyle(QCPItemPixmap &pixmap) noexcept
60 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 113 void initTitleTextStyle(QCPItemText &text) noexcept
64 114 {
65 115 // Font and background styles
@@ -80,7 +130,10 struct VisualizationGraphRenderingDelegate::VisualizationGraphRenderingDelegateP
80 130 m_PointTracer{new QCPItemTracer{&m_Plot}},
81 131 m_TracerTimer{},
82 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 138 initPointTracerStyle(*m_PointTracer);
86 139
@@ -103,6 +156,34 struct VisualizationGraphRenderingDelegate::VisualizationGraphRenderingDelegateP
103 156 m_TitleText->setLayer(OVERLAY_LAYER);
104 157 m_TitleText->setText(graphWidget.name());
105 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 189 QCustomPlot &m_Plot;
@@ -110,6 +191,9 struct VisualizationGraphRenderingDelegate::VisualizationGraphRenderingDelegateP
110 191 QTimer m_TracerTimer;
111 192 QCPItemPixmap *m_ClosePixmap; /// Graph's close button
112 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 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 270 void VisualizationGraphRenderingDelegate::showGraphOverlay(bool show) noexcept
165 271 {
166 272 auto overlay = impl->m_Plot.layer(OVERLAY_LAYER);
@@ -103,6 +103,20 void VisualizationGraphWidget::addVariable(std::shared_ptr<Variable> variable, S
103 103 auto createdPlottables = VisualizationGraphHelper::create(variable, *ui->widget);
104 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 120 connect(variable.get(), SIGNAL(updated()), this, SLOT(onDataCacheVariableUpdated()));
107 121
108 122 auto varRange = variable->range();
General Comments 0
You need to be logged in to leave comments. Login now