Browse Source

Improve scaling of speed graphs

Make Y axis scale to fix on predetermined nice looking positions
adaptive-webui-19844
dzmat 7 years ago
parent
commit
fabd7e34f5
  1. 65
      src/base/utils/misc.cpp
  2. 3
      src/base/utils/misc.h
  3. 77
      src/gui/properties/speedplotview.cpp
  4. 2
      src/gui/search/searchjobwidget.cpp

65
src/base/utils/misc.cpp

@ -84,6 +84,27 @@ namespace
QT_TRANSLATE_NOOP3("misc", "PiB", "pebibytes (1024 tebibytes)"), QT_TRANSLATE_NOOP3("misc", "PiB", "pebibytes (1024 tebibytes)"),
QT_TRANSLATE_NOOP3("misc", "EiB", "exbibytes (1024 pebibytes)") QT_TRANSLATE_NOOP3("misc", "EiB", "exbibytes (1024 pebibytes)")
}; };
// return best userfriendly storage unit (B, KiB, MiB, GiB, TiB, ...)
// use Binary prefix standards from IEC 60027-2
// see http://en.wikipedia.org/wiki/Kilobyte
// value must be given in bytes
// to send numbers instead of strings with suffixes
bool splitToFriendlyUnit(const qint64 sizeInBytes, qreal &val, Utils::Misc::SizeUnit &unit)
{
if (sizeInBytes < 0) return false;
int i = 0;
qreal rawVal = static_cast<qreal>(sizeInBytes);
while ((rawVal >= 1024.) && (i <= static_cast<int>(Utils::Misc::SizeUnit::ExbiByte))) {
rawVal /= 1024.;
++i;
}
val = rawVal;
unit = static_cast<Utils::Misc::SizeUnit>(i);
return true;
}
} }
void Utils::Misc::shutdownComputer(const ShutdownDialogAction &action) void Utils::Misc::shutdownComputer(const ShutdownDialogAction &action)
@ -237,52 +258,30 @@ QPoint Utils::Misc::screenCenter(const QWidget *w)
} }
#endif #endif
QString Utils::Misc::unitString(Utils::Misc::SizeUnit unit) QString Utils::Misc::unitString(const SizeUnit unit, const bool isSpeed)
{ {
return QCoreApplication::translate("misc", const auto &unitString = units[static_cast<int>(unit)];
units[static_cast<int>(unit)].source, units[static_cast<int>(unit)].comment); QString ret = QCoreApplication::translate("misc", unitString.source, unitString.comment);
} if (isSpeed)
ret += QCoreApplication::translate("misc", "/s", "per second");
// return best userfriendly storage unit (B, KiB, MiB, GiB, TiB, ...) return ret;
// use Binary prefix standards from IEC 60027-2
// see http://en.wikipedia.org/wiki/Kilobyte
// value must be given in bytes
// to send numbers instead of strings with suffixes
bool Utils::Misc::friendlyUnit(qint64 sizeInBytes, qreal &val, Utils::Misc::SizeUnit &unit)
{
if (sizeInBytes < 0) return false;
int i = 0;
qreal rawVal = static_cast<qreal>(sizeInBytes);
while ((rawVal >= 1024.) && (i <= static_cast<int>(SizeUnit::ExbiByte))) {
rawVal /= 1024.;
++i;
}
val = rawVal;
unit = static_cast<SizeUnit>(i);
return true;
} }
QString Utils::Misc::friendlyUnit(qint64 bytesValue, bool isSpeed) QString Utils::Misc::friendlyUnit(qint64 bytesValue, bool isSpeed)
{ {
SizeUnit unit; SizeUnit unit;
qreal friendlyVal; qreal friendlyVal;
if (!friendlyUnit(bytesValue, friendlyVal, unit)) if (!splitToFriendlyUnit(bytesValue, friendlyVal, unit))
return QCoreApplication::translate("misc", "Unknown", "Unknown (size)"); return QCoreApplication::translate("misc", "Unknown", "Unknown (size)");
QString ret; return Utils::String::fromDouble(friendlyVal, friendlyUnitPrecision(unit))
if (unit == SizeUnit::Byte) + QString::fromUtf8(C_NON_BREAKING_SPACE)
ret = QString::number(bytesValue) + QString::fromUtf8(C_NON_BREAKING_SPACE) + unitString(unit); + unitString(unit, isSpeed);
else
ret = Utils::String::fromDouble(friendlyVal, friendlyUnitPrecision(unit)) + QString::fromUtf8(C_NON_BREAKING_SPACE) + unitString(unit);
if (isSpeed)
ret += QCoreApplication::translate("misc", "/s", "per second");
return ret;
} }
int Utils::Misc::friendlyUnitPrecision(SizeUnit unit) int Utils::Misc::friendlyUnitPrecision(SizeUnit unit)
{ {
// friendlyUnit's number of digits after the decimal point // friendlyUnit's number of digits after the decimal point
if (unit == SizeUnit::Byte) return 0;
if (unit <= SizeUnit::MebiByte) return 1; if (unit <= SizeUnit::MebiByte) return 1;
else if (unit == SizeUnit::GibiByte) return 2; else if (unit == SizeUnit::GibiByte) return 2;
else return 3; else return 3;

3
src/base/utils/misc.h

@ -79,11 +79,10 @@ namespace Utils
QString boostVersionString(); QString boostVersionString();
QString libtorrentVersionString(); QString libtorrentVersionString();
QString unitString(SizeUnit unit); QString unitString(SizeUnit unit, bool isSpeed = false);
// return the best user friendly storage unit (B, KiB, MiB, GiB, TiB) // return the best user friendly storage unit (B, KiB, MiB, GiB, TiB)
// value must be given in bytes // value must be given in bytes
bool friendlyUnit(qint64 sizeInBytes, qreal &val, SizeUnit &unit);
QString friendlyUnit(qint64 bytesValue, bool isSpeed = false); QString friendlyUnit(qint64 bytesValue, bool isSpeed = false);
int friendlyUnitPrecision(SizeUnit unit); int friendlyUnitPrecision(SizeUnit unit);
qint64 sizeInBytes(qreal size, SizeUnit unit); qint64 sizeInBytes(qreal size, SizeUnit unit);

77
src/gui/properties/speedplotview.cpp

@ -28,9 +28,11 @@
#include "speedplotview.h" #include "speedplotview.h"
#include <QLocale>
#include <QPainter> #include <QPainter>
#include <QPen> #include <QPen>
#include "base/global.h" #include "base/global.h"
#include "base/unicodestrings.h"
#include "base/utils/misc.h" #include "base/utils/misc.h"
namespace namespace
@ -48,6 +50,63 @@ namespace
const int HOUR6_BUF_SIZE = 5 * 60; const int HOUR6_BUF_SIZE = 5 * 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;
// table of supposed nice steps for grid marks to get nice looking quarters of scale
const double roundingTable[] = {1.2, 1.6, 2, 2.4, 2.8, 3.2, 4, 6, 8};
struct SplittedValue
{
double arg;
Utils::Misc::SizeUnit unit;
qint64 sizeInBytes() const
{
return Utils::Misc::sizeInBytes(arg, unit);
}
};
SplittedValue getRoundedYScale(double value)
{
using Utils::Misc::SizeUnit;
if (value == 0.0) return {0, SizeUnit::Byte};
if (value <= 12.0) return {12, SizeUnit::Byte};
SizeUnit calculatedUnit = SizeUnit::Byte;
while (value > 1024) {
value /= 1024;
calculatedUnit = static_cast<SizeUnit>(static_cast<int>(calculatedUnit) + 1);
}
if (value > 100.0) {
int roundedValue = static_cast<int>(value / 40) * 40;
while (roundedValue < value)
roundedValue += 40;
return {static_cast<double>(roundedValue), calculatedUnit};
}
if (value > 10.0) {
int roundedValue = static_cast<int>(value / 4) * 4;
while (roundedValue < value)
roundedValue += 4;
return {static_cast<double>(roundedValue), calculatedUnit};
}
for (const auto &roundedValue : roundingTable) {
if (value <= roundedValue)
return {roundedValue, calculatedUnit};
}
return {10.0, calculatedUnit};
}
QString formatLabel(const double argValue, const Utils::Misc::SizeUnit unit)
{
// check is there need for digits after decimal separator
const int precision = (argValue < 10) ? friendlyUnitPrecision(unit) : 0;
return QLocale::system().toString(argValue, 'f', precision)
+ QString::fromUtf8(C_NON_BREAKING_SPACE)
+ unitString(unit, true);
}
} }
SpeedPlotView::Averager::Averager(int divider, boost::circular_buffer<PointData> &sink) SpeedPlotView::Averager::Averager(int divider, boost::circular_buffer<PointData> &sink)
@ -211,18 +270,16 @@ void SpeedPlotView::paintEvent(QPaintEvent *)
QFontMetrics fontMetrics = painter.fontMetrics(); QFontMetrics fontMetrics = painter.fontMetrics();
rect.adjust(4, 4, 0, -4); // Add padding rect.adjust(4, 4, 0, -4); // Add padding
const SplittedValue niceScale = getRoundedYScale(maxYValue());
quint64 maxY = maxYValue();
rect.adjust(0, fontMetrics.height(), 0, 0); // Add top padding for top speed text rect.adjust(0, fontMetrics.height(), 0, 0); // Add top padding for top speed text
// draw Y axis speed labels // draw Y axis speed labels
QVector<QString> speedLabels = { QVector<QString> speedLabels = {
Utils::Misc::friendlyUnit(maxY, true), formatLabel(niceScale.arg, niceScale.unit),
Utils::Misc::friendlyUnit(0.75 * maxY, true), formatLabel((0.75 * niceScale.arg), niceScale.unit),
Utils::Misc::friendlyUnit(0.5 * maxY, true), formatLabel((0.50 * niceScale.arg), niceScale.unit),
Utils::Misc::friendlyUnit(0.25 * maxY, true), formatLabel((0.25 * niceScale.arg), niceScale.unit),
Utils::Misc::friendlyUnit(0, true) formatLabel(0.0, niceScale.unit),
}; };
int yAxisWidth = 0; int yAxisWidth = 0;
@ -264,8 +321,8 @@ void SpeedPlotView::paintEvent(QPaintEvent *)
// draw graphs // draw graphs
rect.adjust(3, 0, 0, 0); // Need, else graphs cross left gridline rect.adjust(3, 0, 0, 0); // Need, else graphs cross left gridline
double yMultiplier = (maxY == 0) ? 0.0 : static_cast<double>(rect.height()) / maxY; const double yMultiplier = (niceScale.arg == 0.0) ? 0.0 : (rect.height() / niceScale.sizeInBytes());
double xTickSize = static_cast<double>(rect.width()) / m_viewablePointsCount; const double xTickSize = static_cast<double>(rect.width()) / m_viewablePointsCount;
boost::circular_buffer<PointData> &queue = getCurrentData(); boost::circular_buffer<PointData> &queue = getCurrentData();

2
src/gui/search/searchjobwidget.cpp

@ -315,6 +315,8 @@ void SearchJobWidget::updateFilter()
void SearchJobWidget::fillFilterComboBoxes() void SearchJobWidget::fillFilterComboBoxes()
{ {
using Utils::Misc::SizeUnit; using Utils::Misc::SizeUnit;
using Utils::Misc::unitString;
QStringList unitStrings; QStringList unitStrings;
unitStrings.append(unitString(SizeUnit::Byte)); unitStrings.append(unitString(SizeUnit::Byte));
unitStrings.append(unitString(SizeUnit::KibiByte)); unitStrings.append(unitString(SizeUnit::KibiByte));

Loading…
Cancel
Save