1
0
mirror of https://github.com/f4exb/sdrangel.git synced 2025-06-17 05:52:29 -04:00

Spectrum frequency ticks MSB truncation: display

This commit is contained in:
f4exb 2022-10-16 11:29:45 +02:00
parent 45ef7c5be0
commit eab20ec66f
2 changed files with 96 additions and 31 deletions

View File

@ -32,7 +32,7 @@ QString ScaleEngine::formatTick(double value, int decimalPlaces)
{ {
if (m_truncated && (m_physicalUnit != Unit::Scientific)) if (m_truncated && (m_physicalUnit != Unit::Scientific))
{ {
value = ((value * m_scale) - m_truncationValue) / m_scale; // value = ((value * m_scale) - m_truncationValue) / m_scale;
qDebug("ScaleEngine::formatTick: value: %f decimalPlaces: %d m_scale: %f", value, decimalPlaces, m_scale); qDebug("ScaleEngine::formatTick: value: %f decimalPlaces: %d m_scale: %f", value, decimalPlaces, m_scale);
} }
@ -41,7 +41,10 @@ QString ScaleEngine::formatTick(double value, int decimalPlaces)
if (m_physicalUnit == Unit::Scientific) { if (m_physicalUnit == Unit::Scientific) {
return QString("%1").arg(m_makeOpposite ? -value : value, 0, 'e', m_fixedDecimalPlaces); return QString("%1").arg(m_makeOpposite ? -value : value, 0, 'e', m_fixedDecimalPlaces);
} else { } else {
return QString("%1%2").arg(m_truncated ? "'" : "").arg(m_makeOpposite ? -value : value, 0, 'f', decimalPlaces); return QString("%1%2%3")
.arg(m_truncated ? "'" : "")
.arg(m_makeOpposite ? -value : value, 0, 'f', decimalPlaces)
.arg(m_truncated ? m_multiplierStr : "");
} }
} }
else else
@ -123,13 +126,14 @@ void ScaleEngine::calcScaleFactor()
{ {
double median, range, freqBase; double median, range, freqBase;
double rangeMin = m_rangeMin; double rangeMin = m_truncated ? m_rangeMin - m_truncationValue : m_rangeMin;
double rangeMax = m_rangeMax; double rangeMax = m_truncated ? m_rangeMax - m_truncationValue : m_rangeMax;
median = ((rangeMax - rangeMin) / 2.0) + rangeMin; median = ((rangeMax - rangeMin) / 2.0) + rangeMin;
range = (rangeMax - rangeMin); range = (rangeMax - rangeMin);
freqBase = (median == 0 ? range : median); freqBase = (median == 0 ? range : median);
m_scale = 1.0; m_scale = 1.0;
m_multiplierStr.clear();
switch(m_physicalUnit) { switch(m_physicalUnit) {
case Unit::None: case Unit::None:
@ -140,17 +144,22 @@ void ScaleEngine::calcScaleFactor()
case Unit::Frequency: case Unit::Frequency:
if(freqBase < 1000.0) { if(freqBase < 1000.0) {
m_unitStr = QObject::tr("Hz"); m_unitStr = QObject::tr("Hz");
m_multiplierStr = "";
} else if(freqBase < 1000000.0) { } else if(freqBase < 1000000.0) {
m_unitStr = QObject::tr("kHz"); m_unitStr = QObject::tr("kHz");
m_multiplierStr = "k";
m_scale = 1000.0; m_scale = 1000.0;
} else if(freqBase < 1000000000.0) { } else if(freqBase < 1000000000.0) {
m_unitStr = QObject::tr("MHz"); m_unitStr = QObject::tr("MHz");
m_multiplierStr = "M";
m_scale = 1000000.0; m_scale = 1000000.0;
} else if(freqBase < 1000000000000.0){ } else if(freqBase < 1000000000000.0){
m_unitStr = QObject::tr("GHz"); m_unitStr = QObject::tr("GHz");
m_multiplierStr = "G";
m_scale = 1000000000.0; m_scale = 1000000000.0;
} else { } else {
m_unitStr = QObject::tr("THz"); m_unitStr = QObject::tr("THz");
m_multiplierStr = "T";
m_scale = 1000000000000.0; m_scale = 1000000000000.0;
} }
break; break;
@ -158,20 +167,26 @@ void ScaleEngine::calcScaleFactor()
case Unit::Information: case Unit::Information:
if(median < 1024.0) { if(median < 1024.0) {
m_unitStr = QObject::tr("Bytes"); m_unitStr = QObject::tr("Bytes");
m_multiplierStr = "";
} else if(median < 1048576.0) { } else if(median < 1048576.0) {
m_unitStr = QObject::tr("KiBytes"); m_unitStr = QObject::tr("KiBytes");
m_multiplierStr = "k";
m_scale = 1024.0; m_scale = 1024.0;
} else if(median < 1073741824.0) { } else if(median < 1073741824.0) {
m_unitStr = QObject::tr("MiBytes"); m_unitStr = QObject::tr("MiBytes");
m_multiplierStr = "M";
m_scale = 1048576.0; m_scale = 1048576.0;
} else if(median < 1099511627776.0) { } else if(median < 1099511627776.0) {
m_unitStr = QObject::tr("GiBytes"); m_unitStr = QObject::tr("GiBytes");
m_multiplierStr = "G";
m_scale = 1073741824.0; m_scale = 1073741824.0;
} else if(median < 1125899906842624.0) { } else if(median < 1125899906842624.0) {
m_unitStr = QObject::tr("TiBytes"); m_unitStr = QObject::tr("TiBytes");
m_multiplierStr = "T";
m_scale = 1099511627776.0; m_scale = 1099511627776.0;
} else { } else {
m_unitStr = QObject::tr("PiBytes"); m_unitStr = QObject::tr("PiBytes");
m_multiplierStr = "P";
m_scale = 1125899906842624.0; m_scale = 1125899906842624.0;
} }
break; break;
@ -200,14 +215,18 @@ void ScaleEngine::calcScaleFactor()
case Unit::TimeHMS: case Unit::TimeHMS:
if (median < 0.001) { if (median < 0.001) {
m_unitStr = QString("µs"); m_unitStr = QString("µs");
m_multiplierStr = "µ";
m_scale = 0.000001; m_scale = 0.000001;
} else if (median < 1.0) { } else if (median < 1.0) {
m_unitStr = QString("ms"); m_unitStr = QString("ms");
m_multiplierStr = "m";
m_scale = 0.001; m_scale = 0.001;
} else if (median < 1000.0) { } else if (median < 1000.0) {
m_unitStr = QString("s"); m_unitStr = QString("s");
m_multiplierStr = "";
} else { } else {
m_unitStr = QString("ks"); m_unitStr = QString("ks");
m_multiplierStr = "k";
m_scale = 1000.0; m_scale = 1000.0;
} }
break; break;
@ -215,18 +234,23 @@ void ScaleEngine::calcScaleFactor()
case Unit::Volt: case Unit::Volt:
if (median < 1e-9) { if (median < 1e-9) {
m_unitStr = QString("pV"); m_unitStr = QString("pV");
m_multiplierStr = "p";
m_scale = 1e-12; m_scale = 1e-12;
} else if (median < 1e-6) { } else if (median < 1e-6) {
m_unitStr = QString("nV"); m_unitStr = QString("nV");
m_multiplierStr = "n";
m_scale = 1e-9; m_scale = 1e-9;
} else if (median < 1e-3) { } else if (median < 1e-3) {
m_unitStr = QString("µV"); m_unitStr = QString("µV");
m_multiplierStr = "µ";
m_scale = 1e-6; m_scale = 1e-6;
} else if (median < 1.0) { } else if (median < 1.0) {
m_unitStr = QString("mV"); m_unitStr = QString("mV");
m_multiplierStr = "m";
m_scale = 1e-3; m_scale = 1e-3;
} else { } else {
m_unitStr = QString("V"); m_unitStr = QString("V");
m_multiplierStr = "";
} }
break; break;
} }
@ -324,11 +348,16 @@ int ScaleEngine::calcTickTextSize(double distance)
int tickLen; int tickLen;
int decimalPlaces; int decimalPlaces;
double rangeMin = m_truncated ? m_rangeMin - m_truncationValue : m_rangeMin;
double rangeMax = m_truncated ? m_rangeMax - m_truncationValue : m_rangeMax;
tickLen = 1; tickLen = 1;
tmp = formatTick(m_rangeMin / m_scale, 0).length(); tmp = formatTick(rangeMin / m_scale, 0).length();
if(tmp > tickLen) if(tmp > tickLen)
tickLen = tmp; tickLen = tmp;
tmp = formatTick(m_rangeMax / m_scale, 0).length(); tmp = formatTick(rangeMax / m_scale, 0).length();
if(tmp > tickLen) if(tmp > tickLen)
tickLen = tmp; tickLen = tmp;
@ -342,19 +371,22 @@ void ScaleEngine::forceTwoTicks()
Tick tick; Tick tick;
QFontMetricsF fontMetrics(m_font); QFontMetricsF fontMetrics(m_font);
double rangeMin = m_truncated ? m_rangeMin - m_truncationValue : m_rangeMin;
double rangeMax = m_truncated ? m_rangeMax - m_truncationValue : m_rangeMax;
m_tickList.clear(); m_tickList.clear();
tick.major = true; tick.major = true;
tick.pos = getPosFromValue(m_rangeMin); tick.pos = getPosFromValueTrunc(rangeMin);
tick.text = formatTick(m_rangeMin / m_scale, m_decimalPlaces); tick.text = formatTick(rangeMin / m_scale, m_decimalPlaces);
tick.textSize = fontMetrics.boundingRect(tick.text).width(); tick.textSize = fontMetrics.boundingRect(tick.text).width();
if(m_orientation == Qt::Vertical) if(m_orientation == Qt::Vertical)
tick.textPos = tick.pos - fontMetrics.ascent() / 2; tick.textPos = tick.pos - fontMetrics.ascent() / 2;
else tick.textPos = tick.pos - fontMetrics.boundingRect(tick.text).width() / 2; else tick.textPos = tick.pos - fontMetrics.boundingRect(tick.text).width() / 2;
m_tickList.append(tick); m_tickList.append(tick);
tick.pos = getPosFromValue(m_rangeMax); tick.pos = getPosFromValueTrunc(rangeMax);
tick.text = formatTick(m_rangeMax / m_scale, m_decimalPlaces); tick.text = formatTick(rangeMax / m_scale, m_decimalPlaces);
tick.textSize = fontMetrics.boundingRect(tick.text).width(); tick.textSize = fontMetrics.boundingRect(tick.text).width();
if(m_orientation == Qt::Vertical) if(m_orientation == Qt::Vertical)
tick.textPos = tick.pos - fontMetrics.ascent() / 2; tick.textPos = tick.pos - fontMetrics.ascent() / 2;
@ -387,13 +419,18 @@ void ScaleEngine::reCalc()
return; return;
} }
m_recalc = false; updateTruncation();
m_recalc = false;
m_tickList.clear(); m_tickList.clear();
calcScaleFactor(); calcScaleFactor();
rangeMinScaled = m_rangeMin / m_scale;
rangeMaxScaled = m_rangeMax / m_scale; double rangeMin = m_truncated ? m_rangeMin - m_truncationValue : m_rangeMin;
double rangeMax = m_truncated ? m_rangeMax - m_truncationValue : m_rangeMax;
rangeMinScaled = rangeMin / m_scale;
rangeMaxScaled = rangeMax / m_scale;
if(m_orientation == Qt::Vertical) if(m_orientation == Qt::Vertical)
{ {
@ -415,8 +452,6 @@ void ScaleEngine::reCalc()
numMajorTicks = (int)((rangeMaxScaled - rangeMinScaled) / m_majorTickValueDistance); numMajorTicks = (int)((rangeMaxScaled - rangeMinScaled) / m_majorTickValueDistance);
updateTruncation(numMajorTicks);
if(numMajorTicks == 0) { if(numMajorTicks == 0) {
forceTwoTicks(); forceTwoTicks();
return; return;
@ -442,23 +477,26 @@ void ScaleEngine::reCalc()
if(rangeMinScaled == rangeMaxScaled) if(rangeMinScaled == rangeMaxScaled)
return; return;
while(true) { while (true)
{
m_tickList.clear(); m_tickList.clear();
step = 0; step = 0;
lastEndPos = -100000000; lastEndPos = -100000000;
done = true; done = true;
for(i = 0; true; i++) { for (i = 0; true; i++)
{
value = majorTickValue(i); value = majorTickValue(i);
for(j = 1; j < m_numMinorTicks; j++) { for (j = 1; j < m_numMinorTicks; j++)
{
value2 = value + minorTickValue(j); value2 = value + minorTickValue(j);
if(value2 < rangeMinScaled) if(value2 < rangeMinScaled)
continue; continue;
if(value2 > rangeMaxScaled) if(value2 > rangeMaxScaled)
break; break;
pos = getPosFromValue((value + minorTickValue(j)) * m_scale); pos = getPosFromValueTrunc((value + minorTickValue(j)) * m_scale);
if((pos >= 0) && (pos < m_size)) { if((pos >= 0) && (pos < m_size)) {
tick.pos = pos; tick.pos = pos;
tick.major = false; tick.major = false;
@ -469,7 +507,7 @@ void ScaleEngine::reCalc()
m_tickList.append(tick); m_tickList.append(tick);
} }
pos = getPosFromValue(value * m_scale); pos = getPosFromValueTrunc(value * m_scale);
if(pos < 0.0) if(pos < 0.0)
continue; continue;
if(pos >= m_size) if(pos >= m_size)
@ -618,6 +656,20 @@ float ScaleEngine::getValueFromPos(double pos)
return ((pos * (m_rangeMax - m_rangeMin)) / (m_size - 1.0)) + m_rangeMin; return ((pos * (m_rangeMax - m_rangeMin)) / (m_size - 1.0)) + m_rangeMin;
} }
float ScaleEngine::getPosFromValueTrunc(double value)
{
double rangeMin = m_truncated ? m_rangeMin - m_truncationValue : m_rangeMin;
double rangeMax = m_truncated ? m_rangeMax - m_truncationValue : m_rangeMax;
return ((value - rangeMin) / (rangeMax - rangeMin)) * (m_size - 1.0);
}
float ScaleEngine::getValueFromPosTrunc(double pos)
{
double rangeMin = m_truncated ? m_rangeMin - m_truncationValue : m_rangeMin;
double rangeMax = m_truncated ? m_rangeMax - m_truncationValue : m_rangeMax;
return ((pos * (rangeMax - rangeMin)) / (m_size - 1.0)) + rangeMin;
}
const ScaleEngine::TickList& ScaleEngine::getTickList() const ScaleEngine::TickList& ScaleEngine::getTickList()
{ {
reCalc(); reCalc();
@ -626,16 +678,24 @@ const ScaleEngine::TickList& ScaleEngine::getTickList()
QString ScaleEngine::getRangeMinStr() QString ScaleEngine::getRangeMinStr()
{ {
if(m_unitStr.length() > 0) double rangeMin = m_truncated ? m_rangeMin - m_truncationValue : m_rangeMin;
return QString("%1 %2").arg(formatTick(m_rangeMin / m_scale, m_decimalPlaces)).arg(m_unitStr);
else return QString("%1").arg(formatTick(m_rangeMin / m_scale, m_decimalPlaces)); if (m_unitStr.length() > 0) {
return QString("%1 %2").arg(formatTick(rangeMin / m_scale, m_decimalPlaces)).arg(m_unitStr);
} else {
return QString("%1").arg(formatTick(rangeMin / m_scale, m_decimalPlaces));
}
} }
QString ScaleEngine::getRangeMaxStr() QString ScaleEngine::getRangeMaxStr()
{ {
if(m_unitStr.length() > 0) double rangeMax = m_truncated ? m_rangeMax - m_truncationValue : m_rangeMax;
return QString("%1 %2").arg(formatTick(m_rangeMax / m_scale, m_decimalPlaces)).arg(m_unitStr);
else return QString("%1").arg(formatTick(m_rangeMax / m_scale, m_decimalPlaces)); if (m_unitStr.length() > 0) {
return QString("%1 %2").arg(formatTick(rangeMax / m_scale, m_decimalPlaces)).arg(m_unitStr);
} else {
return QString("%1").arg(formatTick(rangeMax / m_scale, m_decimalPlaces));
}
} }
float ScaleEngine::getScaleWidth() float ScaleEngine::getScaleWidth()
@ -662,7 +722,7 @@ void ScaleEngine::setTruncateMode(bool mode)
reCalc(); reCalc();
} }
void ScaleEngine::updateTruncation(int numMajorTicks) void ScaleEngine::updateTruncation()
{ {
m_truncated = false; m_truncated = false;
m_truncationValue = 0.0; m_truncationValue = 0.0;

View File

@ -56,9 +56,6 @@ public:
float getValueFromPos(double pos); float getValueFromPos(double pos);
const TickList& getTickList(); const TickList& getTickList();
QString getRangeMinStr();
QString getRangeMaxStr();
float getScaleWidth(); float getScaleWidth();
private: private:
@ -77,6 +74,7 @@ private:
bool m_recalc; bool m_recalc;
double m_scale; double m_scale;
QString m_unitStr; QString m_unitStr;
QString m_multiplierStr;
TickList m_tickList; TickList m_tickList;
double m_majorTickValueDistance; double m_majorTickValueDistance;
double m_firstMajorTickValue; double m_firstMajorTickValue;
@ -95,7 +93,7 @@ private:
int calcTickTextSize(double distance); int calcTickTextSize(double distance);
void forceTwoTicks(); void forceTwoTicks();
void reCalc(); void reCalc();
void updateTruncation(int numMajorTicks); void updateTruncation();
inline int order(double value) { inline int order(double value) {
return floor(log10(value)); return floor(log10(value));
@ -103,6 +101,13 @@ private:
double majorTickValue(int tick); double majorTickValue(int tick);
double minorTickValue(int tick); double minorTickValue(int tick);
QString getRangeMinStr();
QString getRangeMaxStr();
float getPosFromValueTrunc(double value);
float getValueFromPosTrunc(double pos);
}; };
#endif // INCLUDE_SCALEENGINE_H #endif // INCLUDE_SCALEENGINE_H