Updated: 2017-12-06 Version: VisiData 1.0

Terminal Graphics in VisiData

VisiData can display low-resolution terminal graphics with a reasonable amount of user interactivity.

The current implementation uses braille Unicode characters (inspired by asciimoo/drawille). Unicode blocks or the sixel protocol may be supported in the future.

Class hierarchy

Summary

class Plotter

A Plotter is a Sheet with a pixel-addressable drawing surface that covers the entire terminal (minus the status line). Pixels and labels are plotted at exact locations in the terminal window, and must be recalculated after any zoomlevel change or terminal resizing.

Plotter.draw(scr) is called multiple times per second to update the screen, and chooses a curses attribute for each pixel. By default, the most common attr is chosen for each pixel, but if options.disp_pixel_random is set, an attr will be randomly chosen from the naturally weighted set of attrs (this may cause blocks of pixels to flicker between their possible attrs). If an attr is in the Canvas.hiddenAttrs set, then it is not considered for display at all (and its rows will be ignored during selection).

All Plotter coordinates must be integer numbers of pixels. [For performance reasons, they are presumed to already be integers, to save unnecessary calls to round().] Methods which plot multiple pixels on the canvas should be careful to gauge the display correctly; simply calling round() on each calculated float coordinate will work but can cause display artifacts.

Plotter methods

For Plotter methods, x and y must be integers, where 0 <= x < plotwidth, and 0 <= y < plotheight. (0,0) is in the upper-left corner of the terminal window.

Pixels can be plotted directly onto a Plotter with these methods:

attr is a curses attribute, and row is the object associated with the pixel.

The above plot* methods append the row to Plotter.pixels[y][x][attr].

These properties and methods are also available:

rowsWithin takes a Box object (described below). The Box class is otherwise unused by the Plotter.

class Canvas

A Canvas is a Plotter with a virtual surface on which lines and labels can be rendered in arbitrary units.

The onscreen portion (the area within the visible bounds) is scaled and rendered onto the Plotter, with the minimum coordinates in the upper-left [same orientation as Plotter].

The Canvas user interface supports zoom, scroll, cursor definition, and selection of the underlying rows. The source attribute should be the Sheet which owns the plotted row objects.

A call to Canvas.refresh() will trigger Canvas.render(), which is decorated with @async as it may take a perceptible amount of time for larger datasets. Any active render threads are cancelled first.

Box and Point helper classes

While the Plotter API requires literal integer values for x/y and width/height parameters, Canvas methods generally take float values contained in either Box or Point classes.

Point

Point is simply a container for an (x,y) coordinate (passed to the constructor). The individual components are stored as .x and .y, and the computed .xy property will return (x,y) as a simple tuple. Point can also stringify itself reasonably.

Box

Box is effectively a rectangle stretching over some area of the canvas. The constructor takes (x,y,w,h), but a Box can also be constructed using the BoundingBox(x1,y1,x2,y2) helper. [Note that in the BoundingBox case, the order of the individual points is not guaranteed; the individual coordinates may be swapped for convenience.]

Box has these members and properties:

Canvas methods

Canvas properties

These properties reserve an area of the Plotter that is outside the visibleBox: - Canvas.leftMarginPixels - Canvas.rightMarginPixels - Canvas.topMarginPixels - Canvas.bottomMarginPixels

During a mouse event, these properties indicate the mouse position for the current mouse event:

class InvertedCanvas

An InvertedCanvas is a Canvas with a few internal methods overridden, such that the Y axis is inverted. For an InvertedCanvas, the minimum coordinates are in the lower-left.

InvertedCanvas has not much else of interest. It should be completely interchangeable with Canvas.

class Graph

A Graph is an InvertedCanvas with axis labels and/or gridlines.