github.com/phpdave11/gofpdf@v1.4.2/label.go (about) 1 package gofpdf 2 3 // Adapted from Nice Numbers for Graph Labels by Paul Heckbert from "Graphics 4 // Gems", Academic Press, 1990 5 6 // Paul Heckbert 2 Dec 88 7 8 // https://github.com/erich666/GraphicsGems 9 10 // LICENSE 11 12 // This code repository predates the concept of Open Source, and predates most 13 // licenses along such lines. As such, the official license truly is: 14 15 // EULA: The Graphics Gems code is copyright-protected. In other words, you 16 // cannot claim the text of the code as your own and resell it. Using the code 17 // is permitted in any program, product, or library, non-commercial or 18 // commercial. Giving credit is not required, though is a nice gesture. The 19 // code comes as-is, and if there are any flaws or problems with any Gems code, 20 // nobody involved with Gems - authors, editors, publishers, or webmasters - 21 // are to be held responsible. Basically, don't be a jerk, and remember that 22 // anything free comes with no guarantee. 23 24 import ( 25 "math" 26 ) 27 28 // niceNum returns a "nice" number approximately equal to x. The number is 29 // rounded if round is true, converted to its ceiling otherwise. 30 func niceNum(val float64, round bool) float64 { 31 var nf float64 32 33 exp := int(math.Floor(math.Log10(val))) 34 f := val / math.Pow10(exp) 35 if round { 36 switch { 37 case f < 1.5: 38 nf = 1 39 case f < 3.0: 40 nf = 2 41 case f < 7.0: 42 nf = 5 43 default: 44 nf = 10 45 } 46 } else { 47 switch { 48 case f <= 1: 49 nf = 1 50 case f <= 2.0: 51 nf = 2 52 case f <= 5.0: 53 nf = 5 54 default: 55 nf = 10 56 } 57 } 58 return nf * math.Pow10(exp) 59 } 60 61 // TickmarkPrecision returns an appropriate precision value for label 62 // formatting. 63 func TickmarkPrecision(div float64) int { 64 return int(math.Max(-math.Floor(math.Log10(div)), 0)) 65 } 66 67 // Tickmarks returns a slice of tickmarks appropriate for a chart axis and an 68 // appropriate precision for formatting purposes. The values min and max will 69 // be contained within the tickmark range. 70 func Tickmarks(min, max float64) (list []float64, precision int) { 71 if max > min { 72 spread := niceNum(max-min, false) 73 d := niceNum((spread / 4), true) 74 graphMin := math.Floor(min/d) * d 75 graphMax := math.Ceil(max/d) * d 76 precision = TickmarkPrecision(d) 77 for x := graphMin; x < graphMax+0.5*d; x += d { 78 list = append(list, x) 79 } 80 } 81 return 82 }