commit 3200a4618f3b09aaee2798af1cdd4a38456cce21
parent 3a3dce91b1d0935f9a6df528a91cd3a89cc9137e
Author: Daniel Barlow <dan@telent.net>
Date: Thu, 14 Nov 2024 19:07:43 +0000
add Paul Heckbert's "Nice numbers for graph labels" algo
Diffstat:
2 files changed, 78 insertions(+), 0 deletions(-)
diff --git a/frontend/src/Lib.elm b/frontend/src/Lib.elm
@@ -0,0 +1,47 @@
+-- miscellaneous functions extracted from Main so
+-- we can more easily test them
+
+module Lib exposing(looseLabels)
+
+
+maybe default val =
+ case val of
+ Just v -> v
+ Nothing -> default
+
+-- https://github.com/cenfun/nice-ticks/blob/master/docs/Nice-Numbers-for-Graph-Labels.pdf
+
+log10 x = logBase 10 x
+expt b x = b^(toFloat x)
+
+niceNumber x round =
+ let exp = floor (log10 x)
+ f = x / (expt 10.0 exp)
+ nfRound = if f < 1.5
+ then 1
+ else if f < 3
+ then 2
+ else if f < 7
+ then 5
+ else 10
+ nf = if f <= 1
+ then 1
+ else if f <= 2
+ then 2
+ else if f <= 5
+ then 5
+ else 10
+ in
+ if round
+ then
+ nfRound * expt 10 exp
+ else
+ nf * expt 10 exp
+
+looseLabels ticks min max =
+ let
+ range = niceNumber (max-min) False
+ d = niceNumber (range/(ticks - 1)) True
+ graphmin = toFloat (floor (min/d)) * d
+ graphmax = toFloat (ceiling (max/d)) * d
+ in (graphmin, graphmax, d)
diff --git a/frontend/tests/LibTest.elm b/frontend/tests/LibTest.elm
@@ -0,0 +1,31 @@
+module LibTest exposing (specs)
+
+import Lib exposing (..)
+import Test exposing (..)
+import Expect exposing (Expectation)
+
+specs: Test
+specs =
+ describe "looseLabels"
+ [ test "0-100" <|
+ \_ ->
+ let (u, v, _) = looseLabels 10 0.0 100.0
+ in Expect.equal (0, 100) (u, v)
+ , test "2-98" <|
+ \_ ->
+ let (u, v, _) = looseLabels 10 2 98
+ in Expect.equal (0, 100) (u, v)
+ , test "8-91" <|
+ \_ ->
+ let (u, v, _) = looseLabels 10 8 91
+ in Expect.equal (0, 100) (u, v)
+ , test "1-32" <|
+ \_ ->
+ let (u, v, _) = looseLabels 8 1 32
+ in Expect.equal (0, 40) (u, v)
+ , test "1-4" <|
+ \_ ->
+ let (u, v, _) = looseLabels 10 1 4
+ in Expect.equal (1, 4) (u, v)
+
+ ]