souplesse

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

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:
Afrontend/src/Lib.elm | 47+++++++++++++++++++++++++++++++++++++++++++++++
Afrontend/tests/LibTest.elm | 31+++++++++++++++++++++++++++++++
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) + + ]