Last active
March 4, 2017 17:51
-
-
Save jszakmeister/7561939 to your computer and use it in GitHub Desktop.
Paul Heckbert's loose labeling (nice numbers) algorithm.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(import 'java.lang.Math) | |
;; This implementation comes from the "Nice Numbers for Graph Labels" in | |
;; Graphics Gems by Andrew S. Glassner. This is Paul Heckbert's algorithm | |
;; though. | |
(defn ^double nice-num [^double x round] | |
(let [exp (Math/floor (Math/log10 x)) | |
f (/ x (Math/pow 10. exp)) | |
nf (if round | |
(condp >= f | |
1.5 1. | |
3. 2. | |
7. 5. | |
10.) | |
(condp > f | |
1. 1. | |
2. 2. | |
5. 5. | |
10.))] | |
(* nf (Math/pow 10. exp)))) | |
(defn loose-label | |
"Provides some sane tick values given the minimum and maximum values, and | |
the number of ticks desired. You are *not* guaranteed to get the desired | |
number of ticks, it's just what the algorithm shoots for." | |
[^double min-val ^double max-val num-ticks] | |
(let [range-val (nice-num (- max-val min-val) false) | |
d (nice-num (/ range-val (dec num-ticks)) true) | |
graph-min (* (Math/floor (/ min-val d)) d) | |
graph-max (* (Math/ceil (/ max-val d)) d) | |
nfrac (long (max (- (Math/floor (Math/log10 d))) 0)) | |
format-str (str "%." nfrac "f")] | |
(for [x (range graph-min (+ graph-max (* 0.5 d)) d)] | |
(format format-str x)))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment