bardot
v0.2.2
Published
Yet another console progress bar
Downloads
527
Maintainers
Readme
bardot
Yet another progress bar for console apps
Features
- Chainable syntax to easily derive bars from others and pass them around
- Customisable appearance: a template defines whether/where to show the bar, current value, max value, percentage complete, and any extra text you want
- Customisable bar symbols, including fractions
- Support for colour in templates (using
chalk
, for example) - Set the bar length you want, or the total length of the template (bar + labels), or make the template fill the line (leaving room if you want)
- Flowtype support
It's bardot as in Brigitte: bar-doe. But it's a bar, and there are dots, and the name was available.
Installation
$ yarn add bardot # or npm add bardot
Usage
import { bardot, template, symbol } from 'bardot';
// The default templates and bar symbols show the bar in green dots.
// Configure a bar that's 25% complete. Nothing's rendered yet.
const bar = bardot.current(25).maximum(100);
// Set the length of the bar in the final string to 10 chars,
// showing current and max (the default template),
// and output the formatted string.
console.log(bar.widthBar(10).toString());
// ⣿⣿⡇ 25/100
// Set the length of the final string as 20 chars,
// from the first block of the bar to the %.
// The bar fills the space left after rendering the label.
// Uses a template that just renders the bar and the percentage complete.
console.log(bar.widthTemplate(20).template(template.barPct).toString())
// ⣿⣿⣿⡇ 25%
// Set the length of the final string as console width (eg 80 chars)
// minus 10 chars. As above, the bar is sized to fit after rendering the label.
// Uses a template that renders everything.
console.log(bar.widthFill(10).template(template.barCurMaxPct).toString())
// ⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿ 25/100 25%
// As in the first example, but using different symbols for rendering.
// (Some symbol sets support fractional parts, some don't: this one doesn't)
console.log(bar.widthBar(10).symbols(symbol.blockdot).toString())
// ██⠿⠿⠿⠿⠿⠿⠿⠿ 25/100
Concepts and terminology
- bar: The part of the rendered output representing the fraction
current / maximum
, rendered as in a bar chart. - label: The parts of the rendered output that aren't the bar. May include fixed text and variable components (such as the maximum value in numeric form).
- template: A string with special sequences of characters that are replaced during rendering. Templates define which parts go where in the final string.
- symbols: An object defining which set of characters to use for the graphical representation of the bar.
API
The bardot
module exports:
bardot
: an object on which you can call various methods to configure and render a bar and label.template
: an object with predefined templates you can use with thebardot.template()
method.symbol
: an object with predefined symbols you can use with thebardot.symbols()
method.
bardot
The bardot
export is an object with several methods, most of them chainable. Each chainable method returns a new object with the same configuration as the old, plus whichever configuration change the method made.
At any point you can call toString()
on a bardot object to return a formatted string.
bardot.current(cur: number)
Return a new bardot
object setting the current value of the bar: the extent of the filled-in section of the bar. This is always clamped so that 0 <= current <= maximum
, and rounded to the nearest integer.
bardot.maximum(max: number)
Return a new bardot
object setting the maximum value of the bar: the value corresponding to a fully filled-in bar. This is always clamped so that 0 <= maximum
, rounded to the nearest integer, and current is changed if necessary to keep it no greater than the maximum.
(Which means: it's safest to use the sequence random_bardot_object.maximum(v1).current(v2)
, as calling current(v2)
first might clamp it to the old maximum.)
bardot.widthBar(ctChar: number)
Return a new bardot
object configured to render a bar ctChar
characters in length. The final rendered string might use more characters than this: it depends on the configured template.
bardot.widthTemplate(ctChar: number)
Return a new bardot
object configured to render output ctChar
characters in length, including both bar and label. The bar takes up the space left after rendering the label.
bardot.widthFill(ctCharMinus?: number, ctCharFull?: number)
Return a new bardot
object configured to render output ctCharFull - ctCharMinus
characters in length, where ctCharFull
defaults to the current number of columns in the console and ctCharMinus
defaults to zero.
This is a convenience method to help you fill up lines. Set ctCharMinus
if you need to save a few characters of the line for, say, a constant prefix or suffix in your output. You probably won't want to explicitly set ctCharFull
(it's there for testing purposes) but you can if you want.
bardot.template(tpl: string)
Return a new bardot
object configured with a specific template. The template
import defines some presets, but you can use your own. See below for details.
bardot.symbols({ full: string, empty: string, fractions: string[] })
Return a new bardot
object configured to render bars using a specific set of symbols. The symbol
import defines some presets, but you can use your own. See below for details.
bardot.toString()
Return the formatted bar and label as a string. You might not need to use this, as in many contexts it's called implicitly. Flow complains if you don't, though.
The bardot
object's current template defines where the various components are rendered in the string.
bardot
objects differing only in their current value always render strings the same length. This stops parts of the string shuffling about as the current value changes.
template
The template
import is an object mapping preset names to template strings. Here are the current template preset names and their output, for an object bardot.current(100).maximum(100).widthTemplate(30).symbols(symbol.blockspace)
. Actual rendering includes colour (green bars).
bar ██████████████████████████████
barCur ██████████████████████████ 100
barCurMax ██████████████████████ 100/100
barPct ████████████████████████ 100%
barCurMaxPct ████████████████ 100/100 100%
symbol
The symbol
export is an object mapping preset names to symbol objects. Here are the current symbol preset names and their output, for an object bardot.current(35).maximum(100).widthTemplate(30).template(template.bar)
.
dot8 ⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡇
dot6 ⠿⠿⠿⠿⠿⠿⠿⠿⠿⠿⠇
rod5 𝍤𝍤𝍤𝍤𝍤𝍤𝍤𝍤𝍤𝍤𝍡
pip ●●●●●●●●●●○○○○○○○○○○○○○○○○○○○○
blockspace ██████████
blockdot ██████████⠿⠿⠿⠿⠿⠿⠿⠿⠿⠿⠿⠿⠿⠿⠿⠿⠿⠿⠿⠿
tick ✓✓✓✓✓✓✓✓✓✓
starspace **********
hashdash ##########+-------------------
These bars may render in your browser as different lengths. In the console, they should be the same length: it depends on the font in use.
Defining your own template
A template is a string containing special character sequences that bardot replaces on render. These sequences are:
|bar|
: replaced with the rendered bar|cur|
: replaced with the current value|max|
: replaced with the maximum value|pct|
: replaced with100 * current / maximum
to one decimal place.
Everything else in the template is rendered as-is. For example, a simple template showing all elements might be:
TOTAL |cur|/|max| |bar| |pct|%
Here it is in action:
const bar = bardot
.maximum(100)
.widthTemplate(30)
.template('TOTAL |cur|/|max| |bar| |pct|%');
console.log(bar.current(35).toString());
// TOTAL 35/100 ⣿⣿⣿⡇ 35%
console.log(bar.current(79).toString());
// TOTAL 79/100 ⣿⣿⣿⣿⣿⣿⣿⣷ 79%
console.log(bar.current(100).toString());
// TOTAL 100/100 ⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿ 100%
You can include ANSI sequences in the template to add colour. chalk
is great for this. For example:
const tpl = `${chalk.green('|bar|')} |cur|${chalk.dim('/')}|max|`;
Defining your own symbol set
A symbol set is an object that defines:
- One character that's rendered for a fully filled segment of the bar
- One character that's rendered for a fully empty segment of the bar
- An array of characters, one of which is rendered for the fractional segment of the bar, if needed.
The fractional segment helps to improve accuracy, especially of short bars, and it helps to convince users something's happening when animating slow-changing bars. However, there aren't many usable characters for partially complete bar segments, and you might not need to use them.
To show how it works, here's the default symbol set, symbol.dot8
:
{
full: '⣿',
empty: ' ',
fractions: ['⡀', '⡄', '⡆', '⡇', '⣇', '⣧', '⣷'],
}
And here's an example rendering:
const bar = bardot
.current(6).maximum(9)
.widthBar(4)
.template('>|bar|<')
.symbols(symbol.dot8);
console.log(bar.toString());
// >⣿⣿⣇ <
As the fractions
array contains 7 characters, each character corresponds to 1/(7+1) = 1/8 of a full segment. The value 6/9 corresponds to two segments plus 2/3 of a segment, and 2/3 is between 5/8 and 6/8, so the fifth string in the fractions
array is used.
In other words: put as many strings in the fractions
array as you want fractional segments in the bar. Use an empty array for no fractional segments.
Multi-character symbols
You can, technically, define a symbol set that uses multiple characters for each bar segment. For example:
{
full: '<>',
empty: ' ',
fractions: ['< ', '> ',],
}
If you do this it'll just about work, but you'll have fun with character counts in the widthTemplate
and widthFill
cases as they assume each bar segment is one character wide. I might fix this at some point.
Developer notes
Building and testing
The package uses nps
as a layer above npm scripts. See package-scripts.js
for all the build targets. Common targets:
$ nps b # or nps build - full build with linting and tests
$ nps b.q # or nps build.quick - build without linting or tests
$ nps l # or nps lint - lint js and check flow types
$ nps l.j # or nps lint.js - lint js only
$ nps t # or nps test - run tests
$ nps t.w # or nps test.watch - test with watch
$ nps f # or nps flow - check flow types
$ nps f.t # or nps flow.typed - update all third-party types via flow-typed
Branches and merging
When merging to master select Squash and Merge.
In the commit message, follow conventional-changelog-standard conventions.
Releasing
When ready to release to npm:
git checkout master
git pull origin master
nps release
- Engage pre-publication paranoia
git push --follow-tags origin master
npm publish