diff --git a/NanoVNASaver/Charts/LogMag.py b/NanoVNASaver/Charts/LogMag.py index c0852bd..32efad7 100644 --- a/NanoVNASaver/Charts/LogMag.py +++ b/NanoVNASaver/Charts/LogMag.py @@ -23,35 +23,29 @@ from typing import List from PyQt5 import QtGui -from NanoVNASaver.RFTools import Datapoint from NanoVNASaver.Charts.Chart import Chart from NanoVNASaver.Charts.Frequency import FrequencyChart +from NanoVNASaver.RFTools import Datapoint +from NanoVNASaver.SITools import log_floor_125 logger = logging.getLogger(__name__) @dataclass class TickVal: - count: int - first: float - step: float + count: int = 0 + first: float = 0.0 + step: float = 0.0 def span2ticks(span: float, min_val: float) -> TickVal: - for spn, dbs in ((50.0, 10.0), - (20.0, 5.0), - (10.0, 2.0), - (5.0, 1.0), - (2.0, 0.5), - (1.0, 0.2), - (0.0, 0.1)): - if span >= spn: - count = math.floor(span / dbs) - first = math.ceil(min_val / dbs) * dbs - step = dbs - if first == min_val: - first += dbs - break + logger.debug("span2ticks(%s, %s)", span, min_val) + span = abs(span) + step = log_floor_125(span / 5) + count = math.floor(span / step) + first = math.ceil(min_val / step) * step + if first == min_val: + first += step return TickVal(count, first, step) diff --git a/NanoVNASaver/SITools.py b/NanoVNASaver/SITools.py index c3262b1..dcc019b 100644 --- a/NanoVNASaver/SITools.py +++ b/NanoVNASaver/SITools.py @@ -41,6 +41,16 @@ def round_floor(value: Real, digits: int = 0) -> Real: return factor * math.floor(value / factor) +def log_floor_125(x: float) -> float: + log_base = 10**(math.floor(math.log10(x))) + log_factor = x / log_base + if log_factor >= 5: + return 5 * log_base + if log_factor >= 2: + return 2 * log_base + return log_base + + class Format(NamedTuple): max_nr_digits: int = 6 fix_decimals: bool = False diff --git a/test/test_sitools.py b/test/test_sitools.py index 6b718ff..ca324b1 100644 --- a/test/test_sitools.py +++ b/test/test_sitools.py @@ -21,7 +21,9 @@ from math import inf, nan from decimal import Decimal # Needed for test_representation() # Import targets to be tested -from NanoVNASaver.SITools import Format, Value, round_floor, round_ceil +from NanoVNASaver.SITools import ( + Format, Value, round_floor, round_ceil, log_floor_125 +) F_DEFAULT = Format() @@ -43,7 +45,7 @@ F_WITH_SPACE = Format(space_str=" ") F_WITH_UNDERSCORE = Format(space_str="_") -class TestTSIToolsValue(unittest.TestCase): +class TestSIToolsValue(unittest.TestCase): def test_format_assertions(self): self.assertRaises(AssertionError, Value, fmt=F_ASSERT_DIGITS_0) @@ -167,3 +169,20 @@ class TestTSIToolsValue(unittest.TestCase): # TODO: test F_DIGITS_31 # F_WITH_SPACE # F_WITH_UNDERSCORE + + +class TestSIToolsFunctions(unittest.TestCase): + + def test_log_floor_125(self): + self.assertEqual(log_floor_125(1), 1) + self.assertEqual(log_floor_125(2), 2) + self.assertEqual(log_floor_125(5), 5) + self.assertEqual(log_floor_125(1000), 1000) + self.assertEqual(log_floor_125(2000), 2000) + self.assertEqual(log_floor_125(5000), 5000) + self.assertEqual(log_floor_125(.01), .01) + self.assertEqual(log_floor_125(.02), .02) + self.assertEqual(log_floor_125(.05), .05) + self.assertEqual(log_floor_125(1.9), 1) + self.assertEqual(log_floor_125(4.5), 2) + self.assertEqual(log_floor_125(9.9), 5)