Last active
May 27, 2023 13:31
-
-
Save andrewthauer/261c916a9b07036c0b04b463ae5e94eb to your computer and use it in GitHub Desktop.
Deno Progress Bar
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { tty } from "https://deno.land/x/[email protected]/ansi/tty.ts"; | |
interface ProgressBarOptions { | |
label?: string; | |
total?: number; | |
width?: number; | |
} | |
/** | |
* A simple progress bar for Deno | |
* @param options | |
* - `label` - The label to display before the progress bar | |
* - `total` - The total number of steps to completion | |
* - `width` - The width of the progress bar (defaults to the width of the terminal) | |
* @constructor | |
* @example | |
* const bar = new ProgresBar({ label: "Downloading", total: 100 }); | |
* for (let i = 0; i <= 100; i++) { | |
* bar.update(i); | |
* await sleep(100); | |
* } | |
*/ | |
export class ProgressBar { | |
private label = ""; | |
private total: number; | |
private barWidth: number; | |
private barStart: number; | |
private barEnd: number; | |
private pctStart = 0; | |
private pctLength = "100.0%".length; | |
private chars = ["░", "▒", "▓", "█"]; | |
private _tty = tty({ | |
stdout: Deno.stdout, | |
stdin: Deno.stdin, | |
}); | |
constructor(options?: ProgressBarOptions) { | |
const columns = Deno.consoleSize().columns; | |
this.label = options?.label ?? "Progress"; | |
this.total = options?.total ?? 100; | |
this.pctStart = columns - this.pctLength; | |
this.barEnd = this.pctStart - 1; | |
this.barStart = this.label.length + 1; | |
this.barWidth = options?.width ?? this.barEnd - this.barStart; | |
} | |
update(i: number) { | |
const pct = i / this.total; | |
const pctText = `${(i / this.total * 100).toFixed(1)}%`.padStart( | |
this.pctLength, | |
); | |
const filled = this.barWidth * pct; | |
const filledWhole = Math.floor(filled); | |
const bar = this.chars[this.chars.length - 1].repeat(filledWhole); | |
const empty = this.chars[0].repeat( | |
Math.max(0, this.barWidth - filledWhole - 1), | |
); | |
const str = `${this.label} ${bar}${empty} ${pctText}`; | |
this._tty.text(str).cursorLeft(); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const sleep = (ms: number) => { | |
return new Promise((resolve) => setTimeout(resolve, ms)); | |
}; | |
const loop = async () => { | |
const pb = new ProgresBar(); | |
for (let i = 0; i < 100; i++) { | |
await sleep(20); | |
pb.update(i); | |
} | |
}; | |
await loop(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment