-
Notifications
You must be signed in to change notification settings - Fork 7
/
nicenum.go
57 lines (53 loc) · 1.39 KB
/
nicenum.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
// Copyright (c) 2019, The Goki Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package minmax
import "math"
// notes: gonum/plot has function labelling: talbotLinHanrahan
// based on this algorithm: http://vis.stanford.edu/files/2010-TickLabels-InfoVis.pdf
// but it is goes beyond this basic functionality, and is not exported in any case..
// but could be accessed using DefaultTicks api.
// NiceRoundNumber returns the closest nice round number either above or below
// the given number, based on the observation that numbers 1, 2, 5
// at any power are "nice".
// This is used for choosing graph labels, and auto-scaling ranges to contain
// a given value.
// if below == true then returned number is strictly less than given number
// otherwise it is strictly larger.
func NiceRoundNumber(x float64, below bool) float64 {
rn := x
neg := false
if x < 0 {
neg = true
below = !below // reverses..
}
abs := math.Abs(x)
exp := int(math.Floor(math.Log10(abs)))
order := math.Pow(10, float64(exp))
f := abs / order // fraction between 1 and 10
if below {
switch {
case f >= 5:
rn = 5
case f >= 2:
rn = 2
default:
rn = 1
}
} else {
switch {
case f <= 1:
rn = 1
case f <= 2:
rn = 2
case f <= 5:
rn = 5
default:
rn = 10
}
}
if neg {
return -rn * order
}
return rn * order
}