This is a great hack, but it makes bad sparklines. It’s probably about as good as you can get with unicode, so props to Jon.
Sparklines have a few important properties which these do not exhibit. They’re typically higher resolution, with more data per inch. Also the slopes from point to point, and the whitespace under the typical graph/sparkline, help readability.
One can use Braille characters to get slightly more negative space and horizontal resolution, at the cost of vertical resolution. (They are 2×4 blocks IIRC.)
Speaking of misaligned characters: an upgrade a few months back in some thing (font, terminal, or renderer) caused the characters to be shifted up or down one pixel so the bottom and top now touch between lines
I recently had to look at the implementation of the Sparkline [1] widget in Ratatui which uses a similar Unicode technique but scales nicely for sparklines with larger vertical size.
There are already several escape sequences for doing just this. In fact the original way of drawing terminal graphics was using a 7bit escape sequence to switch to a terminal graphics font.
Personally I’d rather see in-lined vector graphics become better supported. This was available on some of the Techtonix (iirc) hardware VTs and as far as I know, the only widespread terminal emulator to support that particular mode is xterm.
Sixel graphics on the vt220 (1983) worked by defining a custom font of 10x10 px characters (9x10 in high-resolution mode), which you could then switch to for any given character.
As far as I know, there is no terminal emulator that supports this flavor if sixel graphics.
Sixel is different. It’s a way of drawing graphics rather than switching to alternative character sets.
Sixels could be used here too, but native support for vector graphics would be nicer.
I’m also of the opinion that sixel sucks as a modern option. It’s got a low DPI resolution, cannot be compressed, and is its own bespoke specification which means lots of additional work for terminal maintainers. Which is why most terms these days go with their own escape sequences for natively supporting common formats like PNG and JPEG.
In my own terminal emulator, I’ve got support for several image formats but I doubt I’ll ever bother with sixel.
> One day this spring, an HTTP request popped out the back of my old Swan 386/25, rattled through our LAN, jumped across an X.25 link to BIX, negotiated its way through three major carriers and a dozen hosts, and made a final hop over a PPP link to its rendezvous with BYTE's newborn Web server, an Alpha AXP 150 located just 2 feet from the Swan.
Beyond Unicode, it should be possible to define a Web Component that generates SVG on-the-fly from a datasource.
Imagine:
<sparkline src="an image or csv"\>
One cool thing about SVG is it can inherit styles from your application, so you can produce e.g. dark-mode aware graphics rather easily, also one of the perks of this Unicode approach.
Eh, you'd probably use <rect> rather than a single <path>, because then you can trivially slice your sparkline and tag every tick with metadata. So for simple sparklines you don't really need a custom element. Page elements already follow a box model, just CSS them boxes =)
But for an annotated data set that renders as a sparkline, a custom element with an SVG shadow DOM probably makes sense. Definitely more work than the "this'll do for most folks" solution though =D
the unicode angle is great for moving sparklines back into the terminal especially making it into a postgres function, since it makes so much ad-hoc analysis easier at the point of query.
it also solves the problem where sparklines feel useful to somebody reading a summary and not so useful to somebody that's just exploring data "in the moment." having it be available in postgres is brilliant.
a bit of shameless self promotion, i had done something similar ages ago but with a custom webfont and some small js to handle scaling of the input dataset, solving the problem of unicode graph characters not being baseline aligned well. http://nsfmc.github.io/chartjunk/ (turns into dust while looking at the last commit date)
It really depends on the font choice and terminal engine. Some terminals (such as VTE, which is the base for most Gnome terminals) renders blocks and boxes without using a font, which makes them perfectly fit the character cell.
With Unicode 16, which is coming out very shortly, there will be 2x4 mosaics (originally identified on Kaypro CP/M machines), which have about half the vertical resolution of the blocks, but twice the time resolution (and allows us to leave Braille for what it was intended for).
After this post came out, Unicode 13 introduced Teletext 2x3 mosaics and their "smoothed" versions (with diagonal lines). Those are also useful for sparklines.
OP discusses the below-the-baseline issue describes it as “annoying but not a deal breaker”.
If this is a deal breaker because you’re aspiring for Edward Tufte levels of visualization purity, OP also offers an alternative that omits below-the-baseline U+2584 and U+2588. The trade off is having fewer unequally sized buckets for the data.
(Could there be font faces without this rendering issue?)
> (Could there be font faces without this rendering issue?)
A comment under OP suggests that the rendering issue is font-dependent. When I view a Unicode sparkline on a test page [1], the rendering issue occurs using Arial, Courier New, Gill Sans, Helvetica, or Times New Roman, but appears to be fixed if I use Georgia, Menlo, or Comic Sans.
As a fan of Sparklines (and Tufte in general), I have to shout out to one of my favourite places that sparklines have been used - in sudara's Audio Sparkline library for the popular JUCE Audio processing framework:
The reason this is such a nerd tickle, is that sudara even went as far as to teach lldb how to render arrays' using sparklines, meaning one can get a pretty useful clue about the contents of an audio buffer within the debugger:
This, to me, aligns very much with the "Tao" of sparklines - although of course I've modified my local copy to use unicode fonts, which is either heinous or fabulous, depending on how much coffee I've had before I have to hit up lldb for details about why my day is going to be good/bad... ;)
FULL BLOCK is slightly shorter than LOWER SEVEN EIGHTHS BLOCK for me. They would be the same height except LOWER SEVEN EIGHTHS BLOCK has some antialiasing that extends a tiny bit higher while FULL BLOCK is a solid edge.
Also none of them drop below the baseline in the main page text, only in the code block.
I once had a bash script to produce such horizontal spark lines from numeric input, but I forgot it's name. Anyone remembers it? From about the same time.
As described here: https://rosettacode.org/wiki/Sparkline_in_unicode
Alas, the .zip file containing those fonts is no longer accessible.
Along similar lines, the absolutely delightful FF Chartwell has sparkline capabilities, plus a lot, lot more to boot (and it actually predates After-the-Floods attempt by half a decade):
Teletext in Unicode - each character is three pixels tall, two pixels wide, with separate characters for inverse as well, and diagonals to get you from one set to another.
Intended for use with teletext graphics, but hey, do a sparkline with them, why not? Sure, it'll only do you four levels, but do you really need more than that in this use case?
Actually... they're not meant to have gaps between these lines, so: (never mind, Hacker News stripped some characters, probably because of non-BMP things, it looks like, but imagine the above on subsequent lines without a gap)
By that argument any shaded line chart which is rasterized becomes a histogram by way of each column of pixels being a bar :p. (i.e. the "binning" is just the horizontal resolution of the rasterization, not a choice in abandoning the intent of showing a line).
More Unicode mission creep. What's next, 4 characters that form 90 degree line segments, so you can write a circle? If you want images, use gifs. Grump grump grump.
Upvote for the grump thing, but really, Unicode is about scripts, and scripts are evolving. If we want to write sparklines, we get to with pen and paper, but then... we can't transliterate them into Unicode? That makes no sense. No, characters for sparklines make a lot of sense, more than for emojis, but when you consider that CJK characters are basically monochrome stylized emojis, modern emojis make sense too.
My biggest gripe here is that we will need to kill UTF-16 so we can have a larger set of codepoints, and that's only a gripe because killing UTF-16 is going to be really difficult, not because I want to keep UTF-16 (oh no, UTF-16 really needs to die).
I personally like getting more terminal-oriented ideographical symbols in the Unicode; what I don't like is yet another font variation for the basic Latin alphabet. Oh well.
I think there comes a point we should just embrace sixels so you can draw whatever it is you want to be shown in a character cell. That point is usually somewhere around here where it's "sure, I can copy it as normal text data but is it actually going to look like anything like it's supposed in a normal font anyways?". Even Windows is getting support for sixels now.
I mean, I wasn't really joking - because yes, pictograms are images too. Isn't it the case that pretty much every device we see, is an image? I'm being 'smart-ass' about it, but I do think there is some use case where, eventually, its all just pictures, all the way down ..
I, for one, would love to see a UI that is composed entirely of typographic symbology, even to the point that it would function beyond the normal UI paradigms. I'm a huge fan of things like FF Chartwell, where the font contains super rich, detailed information that is not just a 'letter' or 'character' .. See https://news.ycombinator.com/item?id=41365761 if you don't know what FF Chartwell is yet, maybe you'll enjoy it, maybe not ..
Sparklines have a few important properties which these do not exhibit. They’re typically higher resolution, with more data per inch. Also the slopes from point to point, and the whitespace under the typical graph/sparkline, help readability.