@@ -10,6 +10,9 class QCPAxis; | |||||
10 | class QCPColorScale; |
|
10 | class QCPColorScale; | |
11 | class QCustomPlot; |
|
11 | class QCustomPlot; | |
12 |
|
12 | |||
|
13 | /// Formats a data value according to the axis on which it is present | |||
|
14 | QString formatValue(double value, const QCPAxis &axis); | |||
|
15 | ||||
13 | /** |
|
16 | /** | |
14 | * Helper used to handle axes rendering |
|
17 | * Helper used to handle axes rendering | |
15 | */ |
|
18 | */ |
@@ -3,6 +3,9 | |||||
3 |
|
3 | |||
4 | #include <Common/spimpl.h> |
|
4 | #include <Common/spimpl.h> | |
5 |
|
5 | |||
|
6 | #include <Visualization/VisualizationDefs.h> | |||
|
7 | ||||
|
8 | class IDataSeries; | |||
6 | class QCustomPlot; |
|
9 | class QCustomPlot; | |
7 | class QMouseEvent; |
|
10 | class QMouseEvent; | |
8 | class Unit; |
|
11 | class Unit; | |
@@ -17,8 +20,9 public: | |||||
17 |
|
20 | |||
18 | void onMouseMove(QMouseEvent *event) noexcept; |
|
21 | void onMouseMove(QMouseEvent *event) noexcept; | |
19 |
|
22 | |||
20 | /// Sets properties of the plot's axes |
|
23 | /// Sets properties of the plot's axes from the data series passed as parameter | |
21 | void setAxesProperties(const Unit &xAxisUnit, const Unit &valuesUnit) noexcept; |
|
24 | void setAxesProperties(std::shared_ptr<IDataSeries> dataSeries) noexcept; | |
|
25 | ||||
22 |
|
26 | |||
23 | /// Shows or hides graph overlay (name, close button, etc.) |
|
27 | /// Shows or hides graph overlay (name, close button, etc.) | |
24 | void showGraphOverlay(bool show) noexcept; |
|
28 | void showGraphOverlay(bool show) noexcept; |
@@ -7,6 +7,47 | |||||
7 |
|
7 | |||
8 | namespace { |
|
8 | namespace { | |
9 |
|
9 | |||
|
10 | const auto DATETIME_FORMAT = QStringLiteral("yyyy/MM/dd hh:mm:ss:zzz"); | |||
|
11 | ||||
|
12 | /// Format for datetimes on a axis | |||
|
13 | const auto DATETIME_TICKER_FORMAT = QStringLiteral("yyyy/MM/dd \nhh:mm:ss"); | |||
|
14 | ||||
|
15 | /// Generates the appropriate ticker for an axis, depending on whether the axis displays time or | |||
|
16 | /// non-time data | |||
|
17 | QSharedPointer<QCPAxisTicker> axisTicker(bool isTimeAxis) | |||
|
18 | { | |||
|
19 | if (isTimeAxis) { | |||
|
20 | auto dateTicker = QSharedPointer<QCPAxisTickerDateTime>::create(); | |||
|
21 | dateTicker->setDateTimeFormat(DATETIME_TICKER_FORMAT); | |||
|
22 | dateTicker->setDateTimeSpec(Qt::UTC); | |||
|
23 | ||||
|
24 | return dateTicker; | |||
|
25 | } | |||
|
26 | else { | |||
|
27 | // default ticker | |||
|
28 | return QSharedPointer<QCPAxisTicker>::create(); | |||
|
29 | } | |||
|
30 | } | |||
|
31 | ||||
|
32 | /** | |||
|
33 | * Sets properties of the axis passed as parameter | |||
|
34 | * @param axis the axis to set | |||
|
35 | * @param unit the unit to set for the axis | |||
|
36 | * @param scaleType the scale type to set for the axis | |||
|
37 | */ | |||
|
38 | void setAxisProperties(QCPAxis &axis, const Unit &unit, | |||
|
39 | QCPAxis::ScaleType scaleType = QCPAxis::stLinear) | |||
|
40 | { | |||
|
41 | // label (unit name) | |||
|
42 | axis.setLabel(unit.m_Name); | |||
|
43 | ||||
|
44 | // scale type | |||
|
45 | axis.setScaleType(scaleType); | |||
|
46 | ||||
|
47 | // ticker (depending on the type of unit) | |||
|
48 | axis.setTicker(axisTicker(unit.m_TimeUnit)); | |||
|
49 | } | |||
|
50 | ||||
10 | /** |
|
51 | /** | |
11 | * Delegate used to set axes properties |
|
52 | * Delegate used to set axes properties | |
12 | */ |
|
53 | */ | |
@@ -28,7 +69,13 struct AxisSetter<T, typename std::enable_if_t<std::is_base_of<ScalarSeries, T>: | |||||
28 | or std::is_base_of<VectorSeries, T>::value> > { |
|
69 | or std::is_base_of<VectorSeries, T>::value> > { | |
29 | static void setProperties(T &dataSeries, QCustomPlot &plot, QCPColorScale &) |
|
70 | static void setProperties(T &dataSeries, QCustomPlot &plot, QCPColorScale &) | |
30 | { |
|
71 | { | |
31 | /// @todo ALX |
|
72 | dataSeries.lockRead(); | |
|
73 | auto xAxisUnit = dataSeries.xAxisUnit(); | |||
|
74 | auto valuesUnit = dataSeries.valuesUnit(); | |||
|
75 | dataSeries.unlock(); | |||
|
76 | ||||
|
77 | setAxisProperties(*plot.xAxis, xAxisUnit); | |||
|
78 | setAxisProperties(*plot.yAxis, valuesUnit); | |||
32 | } |
|
79 | } | |
33 | }; |
|
80 | }; | |
34 |
|
81 | |||
@@ -50,6 +97,17 struct AxisHelper : public IAxisHelper { | |||||
50 |
|
97 | |||
51 | } // namespace |
|
98 | } // namespace | |
52 |
|
99 | |||
|
100 | QString formatValue(double value, const QCPAxis &axis) | |||
|
101 | { | |||
|
102 | // If the axis is a time axis, formats the value as a date | |||
|
103 | if (auto axisTicker = qSharedPointerDynamicCast<QCPAxisTickerDateTime>(axis.ticker())) { | |||
|
104 | return DateUtils::dateTime(value, axisTicker->dateTimeSpec()).toString(DATETIME_FORMAT); | |||
|
105 | } | |||
|
106 | else { | |||
|
107 | return QString::number(value); | |||
|
108 | } | |||
|
109 | } | |||
|
110 | ||||
53 | std::unique_ptr<IAxisHelper> |
|
111 | std::unique_ptr<IAxisHelper> | |
54 | IAxisHelperFactory::create(std::shared_ptr<IDataSeries> dataSeries) noexcept |
|
112 | IAxisHelperFactory::create(std::shared_ptr<IDataSeries> dataSeries) noexcept | |
55 | { |
|
113 | { |
@@ -1,4 +1,5 | |||||
1 | #include "Visualization/VisualizationGraphRenderingDelegate.h" |
|
1 | #include "Visualization/VisualizationGraphRenderingDelegate.h" | |
|
2 | #include "Visualization/AxisRenderingUtils.h" | |||
2 | #include "Visualization/VisualizationGraphWidget.h" |
|
3 | #include "Visualization/VisualizationGraphWidget.h" | |
3 | #include "Visualization/qcustomplot.h" |
|
4 | #include "Visualization/qcustomplot.h" | |
4 |
|
5 | |||
@@ -13,11 +14,6 namespace { | |||||
13 | /// Name of the axes layer in QCustomPlot |
|
14 | /// Name of the axes layer in QCustomPlot | |
14 | const auto AXES_LAYER = QStringLiteral("axes"); |
|
15 | const auto AXES_LAYER = QStringLiteral("axes"); | |
15 |
|
16 | |||
16 | const auto DATETIME_FORMAT = QStringLiteral("yyyy/MM/dd hh:mm:ss:zzz"); |
|
|||
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 |
|
17 | /// Icon used to show x-axis properties | |
22 | const auto HIDE_AXIS_ICON_PATH = QStringLiteral(":/icones/down.png"); |
|
18 | const auto HIDE_AXIS_ICON_PATH = QStringLiteral(":/icones/down.png"); | |
23 |
|
19 | |||
@@ -38,35 +34,6 const auto TOOLTIP_RECT = QRect{10, 10, 10, 10}; | |||||
38 | /// Timeout after which the tooltip is displayed |
|
34 | /// Timeout after which the tooltip is displayed | |
39 | const auto TOOLTIP_TIMEOUT = 500; |
|
35 | const auto TOOLTIP_TIMEOUT = 500; | |
40 |
|
36 | |||
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 |
|
||||
58 | /// Formats a data value according to the axis on which it is present |
|
|||
59 | QString formatValue(double value, const QCPAxis &axis) |
|
|||
60 | { |
|
|||
61 | // If the axis is a time axis, formats the value as a date |
|
|||
62 | if (auto axisTicker = qSharedPointerDynamicCast<QCPAxisTickerDateTime>(axis.ticker())) { |
|
|||
63 | return DateUtils::dateTime(value, axisTicker->dateTimeSpec()).toString(DATETIME_FORMAT); |
|
|||
64 | } |
|
|||
65 | else { |
|
|||
66 | return QString::number(value); |
|
|||
67 | } |
|
|||
68 | } |
|
|||
69 |
|
||||
70 | void initPointTracerStyle(QCPItemTracer &tracer) noexcept |
|
37 | void initPointTracerStyle(QCPItemTracer &tracer) noexcept | |
71 | { |
|
38 | { | |
72 | tracer.setInterpolating(false); |
|
39 | tracer.setInterpolating(false); | |
@@ -245,21 +212,14 void VisualizationGraphRenderingDelegate::onMouseMove(QMouseEvent *event) noexce | |||||
245 | } |
|
212 | } | |
246 | } |
|
213 | } | |
247 |
|
214 | |||
248 |
void VisualizationGraphRenderingDelegate::setAxesProperties( |
|
215 | void VisualizationGraphRenderingDelegate::setAxesProperties( | |
249 | const Unit &valuesUnit) noexcept |
|
216 | std::shared_ptr<IDataSeries> dataSeries) noexcept | |
250 | { |
|
217 | { | |
251 | // Stores x-axis label to be able to retrieve it when x-axis pixmap is unselected |
|
218 | // Stores x-axis label to be able to retrieve it when x-axis pixmap is unselected | |
252 | impl->m_XAxisLabel = xAxisUnit.m_Name; |
|
219 | impl->m_XAxisLabel = dataSeries->xAxisUnit().m_Name; | |
253 |
|
||||
254 | auto setAxisProperties = [](auto axis, const auto &unit) { |
|
|||
255 | // label (unit name) |
|
|||
256 | axis->setLabel(unit.m_Name); |
|
|||
257 |
|
220 | |||
258 | // ticker (depending on the type of unit) |
|
221 | auto axisHelper = IAxisHelperFactory::create(dataSeries); | |
259 | axis->setTicker(axisTicker(unit.m_TimeUnit)); |
|
222 | axisHelper->setProperties(impl->m_Plot, *impl->m_ColorScale); | |
260 | }; |
|
|||
261 | setAxisProperties(impl->m_Plot.xAxis, xAxisUnit); |
|
|||
262 | setAxisProperties(impl->m_Plot.yAxis, valuesUnit); |
|
|||
263 |
|
223 | |||
264 | // Updates x-axis state |
|
224 | // Updates x-axis state | |
265 | impl->updateXAxisState(); |
|
225 | impl->updateXAxisState(); |
@@ -114,21 +114,13 void VisualizationGraphWidget::addVariable(std::shared_ptr<Variable> variable, S | |||||
114 | { |
|
114 | { | |
115 | // Uses delegate to create the qcpplot components according to the variable |
|
115 | // Uses delegate to create the qcpplot components according to the variable | |
116 | auto createdPlottables = VisualizationGraphHelper::create(variable, *ui->widget); |
|
116 | auto createdPlottables = VisualizationGraphHelper::create(variable, *ui->widget); | |
117 | impl->m_VariableToPlotMultiMap.insert({variable, std::move(createdPlottables)}); |
|
|||
118 |
|
||||
119 | // Set axes properties according to the units of the data series |
|
|||
120 | /// @todo : for the moment, no control is performed on the axes: the units and the tickers |
|
|||
121 | /// are fixed for the default x-axis and y-axis of the plot, and according to the new graph |
|
|||
122 | auto xAxisUnit = Unit{}; |
|
|||
123 | auto valuesUnit = Unit{}; |
|
|||
124 |
|
117 | |||
125 | if (auto dataSeries = variable->dataSeries()) { |
|
118 | if (auto dataSeries = variable->dataSeries()) { | |
126 | dataSeries->lockRead(); |
|
119 | // Set axes properties according to the units of the data series | |
127 | xAxisUnit = dataSeries->xAxisUnit(); |
|
120 | impl->m_RenderingDelegate->setAxesProperties(dataSeries); | |
128 | valuesUnit = dataSeries->valuesUnit(); |
|
|||
129 | dataSeries->unlock(); |
|
|||
130 | } |
|
121 | } | |
131 | impl->m_RenderingDelegate->setAxesProperties(xAxisUnit, valuesUnit); |
|
122 | ||
|
123 | impl->m_VariableToPlotMultiMap.insert({variable, std::move(createdPlottables)}); | |||
132 |
|
124 | |||
133 | connect(variable.get(), SIGNAL(updated()), this, SLOT(onDataCacheVariableUpdated())); |
|
125 | connect(variable.get(), SIGNAL(updated()), this, SLOT(onDataCacheVariableUpdated())); | |
134 |
|
126 |
General Comments 0
You need to be logged in to leave comments.
Login now