forked from holman/spark
-
Notifications
You must be signed in to change notification settings - Fork 0
/
spark
executable file
·153 lines (132 loc) · 2.71 KB
/
spark
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
#!/usr/bin/env bash
#
# spark
# https://github.com/holman/spark
#
# Generates sparklines for a set of data.
#
# Here's a a good web-based sparkline generator that was a bit of inspiration
# for spark:
#
# https://datacollective.org/sparkblocks
#
# spark takes a comma-separated list of data and then prints a sparkline out of
# it.
#
# Examples:
#
# spark 1,5,22,13,53
# # => ▁▁▃▂▇
#
# spark 0,30,55,80,33,150
# # => ▁▂▃▅▂▇
#
# spark -h
# # => Prints the spark help text.
set -e
# Prints the help text for spark.
#
# Returns nothing.
help()
{
cat <<-EOF
USAGE:
spark [comma,separated,value,list]
EXAMPLES:
spark 1,5,22,13,53
▁▁▃▂▇
spark 0,30,55,80,33,150
▁▂▃▅▂▇
EOF
}
# The actual fun characters we are generating in the sparkline.
ticks=(▁ ▂ ▃ ▄ ▅ ▆ ▇)
# The numbers the user gave us.
numbers=()
# The sorted array of the numbers.
sorted=()
# This sets up our secondary array so we can actually generate the correct
# tick.
#
# Returns nothing.
setup_array() {
# 3,6,2 => 2,3,6
sorted=$(echo $1 | tr ',' '\n' | sort -k1,1n | paste -s -d',' -)
# convert comma-separated string to array
IFS=,
sorted=($sorted)
numbers=($1)
}
# The maximum value of the sorted array. In other words, the last value.
sort_max()
{
last=${#sorted[@]}
echo ${sorted[$last - 1]}
}
# The minimum value of the sorted array. In other words, the first value.
sort_min()
{
echo ${sorted[0]}
}
# Find the distance between tiers so we know which tick to assign a character.
tier()
{
number_of_ticks=${#ticks[@]}
distance=$(( $(sort_max) / $number_of_ticks ))
echo $distance
}
# Determines what tick we should print for this number and prints it.
#
# Returns nothing.
print_tick()
{
tier=$(tier)
for (( i = 0 ; i < ${#numbers[@]} ; i++ ))
do
tick=${ticks[$i]}
number=$1
less_than=$(( $i * $tier + sort_min + $tier ))
greater_than=$(( ($i - 1) * $tier + sort_min + $tier ))
result=$(( $number <= $less_than && $number >= $greater_than ))
if [ $result -eq 1 ]
then
printf '%s' "$tick"
return
fi
done
last=${#ticks[@]}
printf '%s' ${ticks[$last-1]}
}
# Iterate over all of our ticks and print them out.
#
# Returns nothing.
print_ticks()
{
for number in ${numbers[@]}
do
print_tick $number
done
echo
}
while getopts ":h" option; do
case "$option" in
h) help && exit ;;
# [?]) echo "$OPTARG";;
esac
done
# Accept input from $1 or from the pipeline.
if test "$*" != ""
then
data="$*"
else
# check to see if stdin's a tty
if [ -t 0 ]; then
help
exit
fi
read data
fi
# Trim spaces to allow input like '1, 2, 3'
data=$(echo $data | tr -d ' ')
setup_array $data
print_ticks $data