Sparkline is a term Edward Tufte invented for "small, high resolution graphics embedded in a context of words, numbers, images". On the Internet, however, the term has come to mean rough text charts made with block characters, like this: ▁▂▃▅▂▇.
dbohdan 2014-12-29: This particular implementation was inspired by using one for Bash (sadly, incompatible with the POSIX sh). It works in both Tcl 8.4+ and recent versions of Jim Tcl.
It adds a bit of functionality not offered by the Bash script. The command-line arguments --min and --max let you set the scale of the chart.
Download with wiki-reaper: wiki-reaper -x 40990 0 > sparkline.tcl
#! /usr/bin/env tclsh # Draw sparklines (small inline charts) with Unicode block characters. # Copyright (c) 2014, 2021, 2023 D. Bohdan. License: MIT. namespace eval sparkline { namespace export create variable version 1.0.0 variable ticks [list ▁ ▂ ▃ ▄ ▅ ▆ ▇ █] variable tickMax [expr {[llength $ticks] - 1}] } proc sparkline::create {data {formalMin {}} {formalMax {}}} { variable tickMax set sorted [lsort -real $data] set realMin [lindex $sorted 0] set realMax [lindex $sorted end] unset sorted set min $formalMin if {$min eq {}} { set min $realMin } set max $formalMax if {$max eq {}} { set max $realMax } set repeatChar {} if {$formalMin ne {} && ($formalMin > $realMax || ($formalMax ne {} && $formalMin > $formalMax))} { set repeatChar { } } elseif {$formalMax ne {} && $realMin > $formalMax} { set repeatChar [tick 0 1 1] } elseif {$min == $max} { # Either the data are all the same or the formal min and max # are. set repeatChar [tick 0 $tickMax [expr { $tickMax / 2 }]] } if {$repeatChar ne {}} { return [string repeat $repeatChar [llength $data]] } set result {} foreach x $data { append result [tick $min $max $x] } return $result } proc sparkline::tick {min max x} { variable ticks variable tickMax set normalized [expr { $x < $max ? int($tickMax * ($x - $min) / ($max - $min)) : $tickMax }] set tick [lindex $ticks $normalized] if {$tick eq {}} { set tick { } } return $tick } # The following code allows you to use this script from the command # line. proc main-script? {} { # From https://wiki.tcl-lang.org/40097. global argv0 if {[info exists argv0] && [file exists [info script]] && [file exists $argv0]} { file stat $argv0 argv0Info file stat [info script] scriptInfo return [expr { $argv0Info(dev) == $scriptInfo(dev) && $argv0Info(ino) == $scriptInfo(ino) }] } return 0 } if {[main-script?]} { if {$argv in {/? -h -help --help help {}}} { set minMax {[--min min] [--max max]} set me [file tail [info script]] puts "usage: $me $minMax value1 \[value2 ...\]" puts " $me $minMax \"value1 \[value2 ...\]\"" puts " $me help" puts " $me test" puts " $me version" exit 0 } if {$argv eq {test}} { proc assert {v1 v2} { if {$v1 eq $v2} { puts $v1 } else { error [list assertion failed: $v1 ne $v2] } } assert [sparkline::create {1 5 22 13 53}] {▁▁▃▂█} assert [sparkline::create {0 30 55 80 33 150}] {▁▂▃▄▂█} assert [sparkline::create {9 13 5 17 1}] {▄▆▂█▁} assert [sparkline::create {1 1 1 1}] {▄▄▄▄} assert [sparkline::create {1 1 1 1} -1 -1] {████} assert [sparkline::create {1 1 1 1} 2 2] { } assert [sparkline::create {1 2 3 4 5} 1 100] {▁▁▁▁▁} assert [sparkline::create {1 2 3 4 5} 3 100] { ▁▁▁} assert [sparkline::create {1 2 3 4 5} 0 2] {▄████} assert [sparkline::create {1 2 3 4 5} -20 -10] {█████} assert [sparkline::create {1 2 3 4 5} -10 -20] { } assert [sparkline::create {1 2 3} {} {}] {▁▄█} assert [sparkline::create {1 2 3} {} 3] {▁▄█} assert [sparkline::create {1 2 3} 1 {}] {▁▄█} assert [sparkline::create {1 2 3} 1 3] {▁▄█} assert [sparkline::create {1 2 3} 5 {}] { } puts ok exit 0 } if {$argv eq {version}} { puts $sparkline::version exit 0 } set min {} set max {} while {[regexp -- {^--?(.*)$} [lindex $argv 0] flag flagTrimmed]} { switch -- $flagTrimmed { min { set argv [lassign $argv _ min] } max { set argv [lassign $argv _ max] } default { puts [list unknown flag: $flag] exit 1 } } } if {[llength $argv] == 1} { set argv [lindex $argv 0] } puts [sparkline::create $argv $min $max] }