summaryrefslogtreecommitdiff
path: root/label.go
diff options
context:
space:
mode:
authorKurt <kurt.w.jung@gmail.com>2018-03-19 12:55:37 -0400
committerKurt <kurt.w.jung@gmail.com>2018-03-19 12:55:37 -0400
commitc4bf431472e0d2bac050f5a2c5ade09a50d55f2c (patch)
tree9e19b2320b369021a2df61586c74e3a008188942 /label.go
parent55d415070ffee71e28bcef384221384bd2d582ca (diff)
Add charting facility
Diffstat (limited to 'label.go')
-rw-r--r--label.go82
1 files changed, 82 insertions, 0 deletions
diff --git a/label.go b/label.go
new file mode 100644
index 0000000..b90d8f3
--- /dev/null
+++ b/label.go
@@ -0,0 +1,82 @@
+package gofpdf
+
+// Adapted from Nice Numbers for Graph Labels by Paul Heckbert from "Graphics
+// Gems", Academic Press, 1990
+
+// Paul Heckbert 2 Dec 88
+
+// https://github.com/erich666/GraphicsGems
+
+// LICENSE
+
+// This code repository predates the concept of Open Source, and predates most
+// licenses along such lines. As such, the official license truly is:
+
+// EULA: The Graphics Gems code is copyright-protected. In other words, you
+// cannot claim the text of the code as your own and resell it. Using the code
+// is permitted in any program, product, or library, non-commercial or
+// commercial. Giving credit is not required, though is a nice gesture. The
+// code comes as-is, and if there are any flaws or problems with any Gems code,
+// nobody involved with Gems - authors, editors, publishers, or webmasters -
+// are to be held responsible. Basically, don't be a jerk, and remember that
+// anything free comes with no guarantee.
+
+import (
+ "math"
+)
+
+// niceNum returns a "nice" number approximately equal to x. The number is
+// rounded if round is true, converted to its ceiling otherwise.
+func niceNum(val float64, round bool) float64 {
+ var nf float64
+
+ exp := int(math.Floor(math.Log10(val)))
+ f := val / math.Pow10(exp)
+ if round {
+ switch {
+ case f < 1.5:
+ nf = 1
+ case f < 3.0:
+ nf = 2
+ case f < 7.0:
+ nf = 5
+ default:
+ nf = 10
+ }
+ } else {
+ switch {
+ case f <= 1:
+ nf = 1
+ case f <= 2.0:
+ nf = 2
+ case f <= 5.0:
+ nf = 5
+ default:
+ nf = 10
+ }
+ }
+ return nf * math.Pow10(exp)
+}
+
+// TickmarkPrecision returns an appropriate precision value for label
+// formatting.
+func TickmarkPrecision(div float64) int {
+ return int(math.Max(-math.Floor(math.Log10(div)), 0))
+}
+
+// Tickmarks returns a slice of tickmarks appropriate for a chart axis and an
+// appropriate precision for formatting purposes. The values min and max will
+// be contained within the tickmark range.
+func Tickmarks(min, max float64) (list []float64, precision int) {
+ if max > min {
+ spread := niceNum(max-min, false)
+ d := niceNum((spread / 4), true)
+ graphMin := math.Floor(min/d) * d
+ graphMax := math.Ceil(max/d) * d
+ precision = TickmarkPrecision(d)
+ for x := graphMin; x < graphMax+0.5*d; x += d {
+ list = append(list, x)
+ }
+ }
+ return
+}