Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: Thresholds and Colors #94

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
172 changes: 154 additions & 18 deletions spark
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
# spark takes a comma-separated or space-separated list of data and then prints
# a sparkline out of it.
#
# See help for color options (inspired by Alexandre Pretto Nunes - https://github.com/apretto)
#
# Examples:
#
# spark 1 5 22 13 53
Expand All @@ -27,8 +29,7 @@
# Generates sparklines.
#
# $1 - The data we'd like to graph.
_echo()
{
_echo(){
if [ "X$1" = "X-n" ]; then
shift
printf "%s" "$*"
Expand All @@ -37,14 +38,69 @@ _echo()
fi
}

spark()
{
local n numbers=
_colorize(){
local ticks="${1}"
local colors=(${2//,/ })
local output=""
for i in "${!colors[@]}";do
output+="$(tput setaf ${colors[$i]})${ticks:$i:1}"
done
# reset the formatting/colors at end of the graph
output+="$(tput sgr0)"
echo "${output}"
}

# find min/max values
# The following two functions are shamelessly lifted (with minimal changes) from:
# http://unix.stackexchange.com/questions/269077/tput-setaf-color-table-how-to-determine-color-codes
# Thank you user79743!
_color_table_out(){
for c; do
printf "$(tput setab ${c}) %03d" "${c}"
done
echo "$(tput sgr0)"
}

_color_table(){
local IFS=$' \t\n'
echo ""
_color_table_out {0..15}
for ((i=0;i<6;i++)); do
_color_table_out $(seq $((i*36+16)) $((i*36+51)))
done
_color_table_out {232..255}
echo ""
}

spark(){
# Defaults
local n data numbers=
local min=0xffffffff max=0
local invert=false
local ticks=(▁ ▂ ▃ ▄ ▅ ▆ ▇ █)
local tick_colors=(7 7 7 7 7 7 7 7) # default white

for n in ${@//,/ }
while getopts :t:p:c:n:iah opt; do
case "${opt}" in
t) local thold="${OPTARG}";; # threshold
p) local pcolor="${OPTARG}";; # color palette
c) local tcolor="${OPTARG}";; # threshold color
n) local name="${OPTARG}";; # graph display name
i) local invert=true;; # invert threshold from >= to <=
a) _color_table;exit 0;;
h) help;;
:) echo "Missing Option Argument for -${OPTARG}" >&2;exit 1;;
\?) echo "Option -${OPTARG} Unknown." >&2;exit 1;;
esac
done
shift "$((OPTIND-1))"

# opts cleanup
[ "$1" = "--" ] && shift
if [ "$#" -eq 0 ]; then data=$(cat);else data="$@";fi
# validate data
if ! [[ "${data}" =~ ^[0-9\ ,.]*$ ]];then echo "Data not valid: ${data}";exit 1;fi
# find min/max
for n in ${data//,/ }
do
# on Linux (or with bash4) we could use `printf %.0f $n` here to
# round the number but that doesn't work on OS X (bash3) nor does
Expand All @@ -55,40 +111,120 @@ spark()
numbers=$numbers${numbers:+ }$n
done

# print ticks
local ticks=(▁ ▂ ▃ ▄ ▅ ▆ ▇ █)

# use a high tick if data is constant
(( min == max )) && ticks=(▅ ▆)

local f=$(( (($max-$min)<<8)/(${#ticks[@]}-1) ))
(( f < 1 )) && f=1

# set threshold color
if [[ -n "${tcolor}" ]];then
case "${tcolor}" in
black) tcolor=0;;
red) tcolor=1;;
green) tcolor=2;;
yellow) tcolor=3;;
blue) tcolor=4;;
magenta) tcolor=5;;
cyan) tcolor=6;;
white) tcolor=7;;
[0-9]*) ;; # if an integer, pass the int as an ansi color code to tput setaf
*) echo "Threshold color option \"${tcolor}\" unknown" >&2;exit 1;;
esac
fi

# set color palette
if [[ -n "${pcolor}" ]];then
case "${pcolor}" in
fire) tick_colors=(228 227 226 220 214 208 202 196);;
ice) tick_colors=(20 21 27 33 39 14 255 15);;
smoke) tick_colors=(254 249 247 244 242 240 238 0);;
earth) tick_colors=(12 94 100 34 22 240 244 246);;
pride) tick_colors=(205 1 214 3 2 6 4 92);; # 8 color original design by Gilbert Baker in 1978
lolcat) for i in {0..7};do tick_colors[${i}]=$(( RANDOM % 255 ));done;; # random colors
[0-9]*,[0-9]*,[0-9]*,[0-9]*,[0-9]*,[0-9]*,[0-9]*,[0-9]*) tick_colors=(${pcolor//,/ });; # ansi codes as a comma-seperated 8 element list
*) echo "Base color option \"${pcolor}\" unknown";exit 1;;
esac
fi

# prepend title and min/max to graph
[[ -n "${name}" ]] && echo -n "[${name}][${min}/${max}] "
local output=""
for n in $numbers
do
_echo -n ${ticks[$(( ((($n-$min)<<8)/$f) ))]}
local tval=$(( ((($n-$min)<<8)/$f) ))
# test for inverted threshold color
if ${invert} && [[ -n "${thold}" ]] && [[ -n "${tcolor}" ]] && [[ "${n}" -le "${thold}" ]];then
output+="$(tput setaf ${tcolor})${ticks[${tval}]}"
# test for non-iverted threshold color
elif ! ${invert} && [[ -n "${thold}" ]] && [[ -n "${tcolor}" ]] && [[ "${n}" -ge "${thold}" ]];then
output+="$(tput setaf ${tcolor})${ticks[${tval}]}"
# test for colors without triggered threshold
elif [[ -n "${pcolor}" ]] || ( [[ -n "${thold}" ]] && [[ -n "${tcolor}" ]] );then
output+="$(tput setaf ${tick_colors[${tval}]})${ticks[${tval}]}"
# draw graph without colors
else
output+="${ticks[${tval}]}"
fi
done
_echo
# if colors are used, reset the format/colors at the end of the graph
if [[ -n "${pcolor}" ]] || ( [[ -n "${thold}" ]] && [[ -n "${tcolor}" ]] );then
output+="$(tput sgr0)"
fi
_echo "${output}"
}

# If we're being sourced, don't worry about such things
if [ "$BASH_SOURCE" == "$0" ]; then
# Prints the help text for spark.
help()
{
help(){
local spark=$(basename $0)
cat <<EOF

USAGE:
$spark [-h|--help] VALUE,...
Usage:
$spark [-h|--help|-t <threshold>|-c <threshold_color>|-n <name>|-p <color_palette>] VALUE,...

EXAMPLES:
Options:
-n <name>
Specify name/title of graph. Includes min/max.

-c <threshold_color|ansi_color_code>
Specify tick color for values exceeding the threshold.
Options:
black, red, green, yellow, blue, magenta, cyan, white
ANSI color codes (0-255)

-t <threshold>
Specify threshold (greater than or equal) as an integer.

-i
Invert the threshold logic to less than or equal.

-p <color_palette|8_char_csv_of_ansi_color_codes>
Specify color palette for ticks.
Options:
fire, ice, earth, smoke, pride, lolcat
Comma-seperated 8 element list ansi color codes (0-255)
eg. 1,2,3,4,55,121,73,254
-a
Print ansi color table and exit.

Examples:
$spark 1 5 22 13 53
▁▁▃▂█
$spark 0,30,55,80,33,150
▁▂▃▄▂█
echo 9 13 5 17 1 | $spark
▄▆▂█▁
$spark -p fire 1 2 3 4 5 6 7 8
$(_colorize "▁▂▃▄▅▆▇█" "228,227,226,220,214,208,202,196")
$spark -p ice -t 6 -c green 1 3 2 4 7 1 4 2 5 6
$(_colorize "▁▃▂▄█▁▄▂▅▆" "20,27,21,33,2,20,33,21,39,2")
$spark -p 200,205,210,215,220,225,230,235 -c 9 -t 6 -i 1,2,3,4,5,6,7,8,9
$(_colorize "▁▁▂▃▄▅▆▇█" "9,9,9,9,9,9,225,230,235")
$spark -n "Graph Title" 1 3 5 7 10 7 5 3 1
[Graph Title][1/10] ▁▂▄▅█▅▄▂▁

EOF
}

Expand All @@ -99,5 +235,5 @@ EOF
exit 0
fi

spark ${@:-`cat`}
spark "${@:-`cat`}"
fi
Loading