Skip to content

Instantly share code, notes, and snippets.

@abhin4v
Created December 28, 2010 22:34
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save abhin4v/757834 to your computer and use it in GitHub Desktop.
Save abhin4v/757834 to your computer and use it in GitHub Desktop.
Prints a horizontal ASCII bar chart for the data given. Written in Clojure.
(defn ascii-bar-chart
"
Prints the horizontal ASCII bar chart for the data given.
Handles both positive and negative values.
Use it to visualize data in the REPL.
Arguments:
data: a seq of key value pairs. the chart is printed in the order of this seq.
keys should be strings (or have a proper toString method).
values should be numbers.
marker: the string to use as the marker in the chart.
scale: the scale of the chart.
Example:
user=> (ascii-bar-chart [[\"Jan\" 80] [\"Feb\" -50] [\"Mar\" 35] [\"Apr\" -10]] \"|\" 40)
|||||||||||||||||||||||||| Jan - 80
|||||||||||||||| Feb - -50
|||||||||||| Mar - 35
|||| Apr - -10
nil
"
[data marker scale]
(let [vals (map second data)
max-val (apply max vals)
min-val (apply min vals)
val-range (- (max 0 max-val) (min 0 min-val))
scaled-min-val (/ (* scale (- min-val)) val-range)
scaled-max-val (/ (* scale max-val) val-range)
marker-len (count marker)]
(doseq [[k v] data]
(let [neg-bars (if (< v 0) (round (/ (* scale (- v)) val-range)) 0)
pos-bars (if (>= v 0) (round (/ (* scale v) val-range)) 0)
neg-ws (- scaled-min-val neg-bars)
pos-ws (- scaled-max-val pos-bars)]
(println
(str
(apply str (take (* marker-len neg-ws) (repeat " ")))
(apply str (take neg-bars (repeat marker)))
(apply str (take (inc pos-bars) (repeat marker)))
(apply str (take (* marker-len pos-ws) (repeat " "))))
k "-" v)))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment