|
|
@ -42,14 +42,20 @@ namespace |
|
|
|
MIN1_SEC = 60, |
|
|
|
MIN1_SEC = 60, |
|
|
|
MIN5_SEC = 5 * 60, |
|
|
|
MIN5_SEC = 5 * 60, |
|
|
|
MIN30_SEC = 30 * 60, |
|
|
|
MIN30_SEC = 30 * 60, |
|
|
|
HOUR6_SEC = 6 * 60 * 60 |
|
|
|
HOUR6_SEC = 6 * 60 * 60, |
|
|
|
|
|
|
|
HOUR12_SEC = 12 * 60 * 60, |
|
|
|
|
|
|
|
HOUR24_SEC = 24 * 60 * 60 |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
const int MIN5_BUF_SIZE = 5 * 60; |
|
|
|
const int MIN5_BUF_SIZE = 5 * 60; |
|
|
|
const int MIN30_BUF_SIZE = 5 * 60; |
|
|
|
const int MIN30_BUF_SIZE = 5 * 60; |
|
|
|
const int HOUR6_BUF_SIZE = 5 * 60; |
|
|
|
const int HOUR6_BUF_SIZE = 5 * 60; |
|
|
|
|
|
|
|
const int HOUR12_BUF_SIZE = 10 * 60; |
|
|
|
|
|
|
|
const int HOUR24_BUF_SIZE = 10 * 60; |
|
|
|
const int DIVIDER_30MIN = MIN30_SEC / MIN30_BUF_SIZE; |
|
|
|
const int DIVIDER_30MIN = MIN30_SEC / MIN30_BUF_SIZE; |
|
|
|
const int DIVIDER_6HOUR = HOUR6_SEC / HOUR6_BUF_SIZE; |
|
|
|
const int DIVIDER_6HOUR = HOUR6_SEC / HOUR6_BUF_SIZE; |
|
|
|
|
|
|
|
const int DIVIDER_12HOUR = HOUR12_SEC / HOUR12_BUF_SIZE; |
|
|
|
|
|
|
|
const int DIVIDER_24HOUR = HOUR24_SEC / HOUR24_BUF_SIZE; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// table of supposed nice steps for grid marks to get nice looking quarters of scale
|
|
|
|
// table of supposed nice steps for grid marks to get nice looking quarters of scale
|
|
|
@ -120,9 +126,9 @@ SpeedPlotView::Averager::Averager(int divider, boost::circular_buffer<PointData> |
|
|
|
void SpeedPlotView::Averager::push(const PointData &pointData) |
|
|
|
void SpeedPlotView::Averager::push(const PointData &pointData) |
|
|
|
{ |
|
|
|
{ |
|
|
|
// Accumulator overflow will be hit in worst case on longest used averaging span,
|
|
|
|
// Accumulator overflow will be hit in worst case on longest used averaging span,
|
|
|
|
// defined by divider value. Maximum divider is DIVIDER_6HOUR = 72
|
|
|
|
// defined by divider value. Maximum divider is DIVIDER_24HOUR = 144
|
|
|
|
// Using int32 for accumulator we get overflow when transfer speed reaches 2^31/72 ~~ 28.4 MBytes/s.
|
|
|
|
// Using int32 for accumulator we get overflow when transfer speed reaches 2^31/144 ~~ 14.2 MBytes/s.
|
|
|
|
// With quint64 this speed limit is 2^64/72 ~~ 228 PBytes/s.
|
|
|
|
// With quint64 this speed limit is 2^64/144 ~~ 114 PBytes/s.
|
|
|
|
// This speed is inaccessible to an ordinary user.
|
|
|
|
// This speed is inaccessible to an ordinary user.
|
|
|
|
m_accumulator.x += pointData.x; |
|
|
|
m_accumulator.x += pointData.x; |
|
|
|
for (int id = UP; id < NB_GRAPHS; ++id) |
|
|
|
for (int id = UP; id < NB_GRAPHS; ++id) |
|
|
@ -149,8 +155,13 @@ SpeedPlotView::SpeedPlotView(QWidget *parent) |
|
|
|
, m_data5Min(MIN5_BUF_SIZE) |
|
|
|
, m_data5Min(MIN5_BUF_SIZE) |
|
|
|
, m_data30Min(MIN30_BUF_SIZE) |
|
|
|
, m_data30Min(MIN30_BUF_SIZE) |
|
|
|
, m_data6Hour(HOUR6_BUF_SIZE) |
|
|
|
, m_data6Hour(HOUR6_BUF_SIZE) |
|
|
|
|
|
|
|
, m_data12Hour(HOUR12_BUF_SIZE) |
|
|
|
|
|
|
|
, m_data24Hour(HOUR24_BUF_SIZE) |
|
|
|
|
|
|
|
, m_currentData(&m_data5Min) |
|
|
|
, m_averager30Min(DIVIDER_30MIN, m_data30Min) |
|
|
|
, m_averager30Min(DIVIDER_30MIN, m_data30Min) |
|
|
|
, m_averager6Hour(DIVIDER_6HOUR, m_data6Hour) |
|
|
|
, m_averager6Hour(DIVIDER_6HOUR, m_data6Hour) |
|
|
|
|
|
|
|
, m_averager12Hour(DIVIDER_12HOUR, m_data12Hour) |
|
|
|
|
|
|
|
, m_averager24Hour(DIVIDER_24HOUR, m_data24Hour) |
|
|
|
, m_period(MIN5) |
|
|
|
, m_period(MIN5) |
|
|
|
, m_viewablePointsCount(MIN5_SEC) |
|
|
|
, m_viewablePointsCount(MIN5_SEC) |
|
|
|
{ |
|
|
|
{ |
|
|
@ -196,24 +207,38 @@ void SpeedPlotView::pushPoint(const SpeedPlotView::PointData &point) |
|
|
|
m_data5Min.push_back(point); |
|
|
|
m_data5Min.push_back(point); |
|
|
|
m_averager30Min.push(point); |
|
|
|
m_averager30Min.push(point); |
|
|
|
m_averager6Hour.push(point); |
|
|
|
m_averager6Hour.push(point); |
|
|
|
|
|
|
|
m_averager12Hour.push(point); |
|
|
|
|
|
|
|
m_averager24Hour.push(point); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void SpeedPlotView::setViewableLastPoints(TimePeriod period) |
|
|
|
void SpeedPlotView::setPeriod(const TimePeriod period) |
|
|
|
{ |
|
|
|
{ |
|
|
|
m_period = period; |
|
|
|
m_period = period; |
|
|
|
|
|
|
|
|
|
|
|
switch (period) { |
|
|
|
switch (period) { |
|
|
|
case SpeedPlotView::MIN1: |
|
|
|
case SpeedPlotView::MIN1: |
|
|
|
m_viewablePointsCount = MIN1_SEC; |
|
|
|
m_viewablePointsCount = MIN1_SEC; |
|
|
|
|
|
|
|
m_currentData = &m_data5Min; |
|
|
|
break; |
|
|
|
break; |
|
|
|
case SpeedPlotView::MIN5: |
|
|
|
case SpeedPlotView::MIN5: |
|
|
|
m_viewablePointsCount = MIN5_SEC; |
|
|
|
m_viewablePointsCount = MIN5_SEC; |
|
|
|
|
|
|
|
m_currentData = &m_data5Min; |
|
|
|
break; |
|
|
|
break; |
|
|
|
case SpeedPlotView::MIN30: |
|
|
|
case SpeedPlotView::MIN30: |
|
|
|
m_viewablePointsCount = MIN30_BUF_SIZE; |
|
|
|
m_viewablePointsCount = MIN30_BUF_SIZE; |
|
|
|
|
|
|
|
m_currentData = &m_data30Min; |
|
|
|
break; |
|
|
|
break; |
|
|
|
case SpeedPlotView::HOUR6: |
|
|
|
case SpeedPlotView::HOUR6: |
|
|
|
m_viewablePointsCount = HOUR6_BUF_SIZE; |
|
|
|
m_viewablePointsCount = HOUR6_BUF_SIZE; |
|
|
|
|
|
|
|
m_currentData = &m_data6Hour; |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
case SpeedPlotView::HOUR12: |
|
|
|
|
|
|
|
m_viewablePointsCount = HOUR12_BUF_SIZE; |
|
|
|
|
|
|
|
m_currentData = &m_data12Hour; |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
case SpeedPlotView::HOUR24: |
|
|
|
|
|
|
|
m_viewablePointsCount = HOUR24_BUF_SIZE; |
|
|
|
|
|
|
|
m_currentData = &m_data24Hour; |
|
|
|
break; |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -225,22 +250,15 @@ void SpeedPlotView::replot() |
|
|
|
if ((m_period == MIN1) |
|
|
|
if ((m_period == MIN1) |
|
|
|
|| (m_period == MIN5) |
|
|
|
|| (m_period == MIN5) |
|
|
|
|| ((m_period == MIN30) && m_averager30Min.isReady()) |
|
|
|
|| ((m_period == MIN30) && m_averager30Min.isReady()) |
|
|
|
|| ((m_period == HOUR6) && m_averager6Hour.isReady()) ) |
|
|
|
|| ((m_period == HOUR6) && m_averager6Hour.isReady()) |
|
|
|
|
|
|
|
|| ((m_period == HOUR12) && m_averager12Hour.isReady()) |
|
|
|
|
|
|
|
|| ((m_period == HOUR24) && m_averager24Hour.isReady()) ) |
|
|
|
viewport()->update(); |
|
|
|
viewport()->update(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
boost::circular_buffer<SpeedPlotView::PointData> &SpeedPlotView::getCurrentData() |
|
|
|
boost::circular_buffer<SpeedPlotView::PointData> &SpeedPlotView::getCurrentData() |
|
|
|
{ |
|
|
|
{ |
|
|
|
switch (m_period) { |
|
|
|
return *m_currentData; |
|
|
|
case SpeedPlotView::MIN1: |
|
|
|
|
|
|
|
case SpeedPlotView::MIN5: |
|
|
|
|
|
|
|
default: |
|
|
|
|
|
|
|
return m_data5Min; |
|
|
|
|
|
|
|
case SpeedPlotView::MIN30: |
|
|
|
|
|
|
|
return m_data30Min; |
|
|
|
|
|
|
|
case SpeedPlotView::HOUR6: |
|
|
|
|
|
|
|
return m_data6Hour; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
quint64 SpeedPlotView::maxYValue() |
|
|
|
quint64 SpeedPlotView::maxYValue() |
|
|
@ -309,11 +327,11 @@ void SpeedPlotView::paintEvent(QPaintEvent *) |
|
|
|
painter.drawLine(fullRect.left(), rect.top() + 0.75 * rect.height(), rect.right(), rect.top() + 0.75 * rect.height()); |
|
|
|
painter.drawLine(fullRect.left(), rect.top() + 0.75 * rect.height(), rect.right(), rect.top() + 0.75 * rect.height()); |
|
|
|
painter.drawLine(fullRect.left(), rect.bottom(), rect.right(), rect.bottom()); |
|
|
|
painter.drawLine(fullRect.left(), rect.bottom(), rect.right(), rect.bottom()); |
|
|
|
|
|
|
|
|
|
|
|
painter.drawLine(rect.left(), fullRect.top(), rect.left(), fullRect.bottom()); |
|
|
|
const int TIME_AXIS_DIVISIONS = 6; |
|
|
|
painter.drawLine(rect.left() + 0.2 * rect.width(), fullRect.top(), rect.left() + 0.2 * rect.width(), fullRect.bottom()); |
|
|
|
for (int i = 0; i < TIME_AXIS_DIVISIONS; ++i) { |
|
|
|
painter.drawLine(rect.left() + 0.4 * rect.width(), fullRect.top(), rect.left() + 0.4 * rect.width(), fullRect.bottom()); |
|
|
|
const int x = rect.left() + (i * rect.width()) / TIME_AXIS_DIVISIONS; |
|
|
|
painter.drawLine(rect.left() + 0.6 * rect.width(), fullRect.top(), rect.left() + 0.6 * rect.width(), fullRect.bottom()); |
|
|
|
painter.drawLine(x, fullRect.top(), x, fullRect.bottom()); |
|
|
|
painter.drawLine(rect.left() + 0.8 * rect.width(), fullRect.top(), rect.left() + 0.8 * rect.width(), fullRect.bottom()); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Set antialiasing for graphs
|
|
|
|
// Set antialiasing for graphs
|
|
|
|
painter.setRenderHints(QPainter::Antialiasing | QPainter::HighQualityAntialiasing); |
|
|
|
painter.setRenderHints(QPainter::Antialiasing | QPainter::HighQualityAntialiasing); |
|
|
|