nathanpeck / clui

Command Line UI toolkit for Node.js
MIT License
1.66k stars 40 forks source link

How to update progress bar in place? #22

Open stefek99 opened 6 years ago

stefek99 commented 6 years ago

There is an existing example that updates progress bar in place: https://github.com/nathanpeck/clui/blob/master/examples/progress.js (60 lines in total)

There is much simpler example directly in the readme: https://github.com/nathanpeck/clui/blob/master/README.md (4 lines only)

var clui = require('clui');

var Progress = clui.Progress;

var thisProgressBar = new Progress(20);
console.log(thisProgressBar.update(10, 30));

So I've added setInterval so that it updates the progress. I've also added line to clear the console and new console.log with each interval:

var clui = require('clui');

var Progress = clui.Progress;

var value = 50;

var thisProgressBar = new Progress(20);

console.log(thisProgressBar.update(value, 100));

var intervalId = setInterval(function() {
    value++;
    // console.log("Updated value: " + value);

    process.stdout.write('\033c'); // clearing the console
    console.log(thisProgressBar.update(value, 100));

    if (value === 100) {
        clearInterval(intervalId);
    }
}, 500)

In the example with countdown spinner I don't have clear the console and do console.log, see example: https://github.com/nathanpeck/clui/blob/master/README.md#spinnerstatustext

Ideally I would like to do just thisProgressBar.update(value, 100) and the progress bar should be updated in places easily...

(without clearing the existing console - I may have so many other progress bars and elements running)

Jack89ita commented 6 years ago

Same problem here. I would like to update the bar instead of create a new line with another one.

cmcnamara87 commented 6 years ago

i had the same problem, so i ended up doing this

process.stdout.clearLine();
process.stdout.cursorTo(0);
process.stdout.write(thisPercentBar.update(percent));

it works, not sure if its the best way to do it though

itsgoofer commented 5 years ago

Any ideas on this?

marquettec commented 5 years ago

Feature would be really needed ;)

ourarash commented 5 years ago

I wrote log-with-statusbar package for a similar problem. The following should get what you want:

    var clui = require("clui");
    var log = require("log-with-statusbar")();

    var Progress = clui.Progress;
    var value = 50;

    var thisProgressBar = new Progress(20);
    // console.log(thisProgressBar.update(value, 100));
    log.setStatusBarText([thisProgressBar.update(value, 100)]);

    var intervalId = setInterval(function() {
      value++;
      // console.log("Updated value: " + value);
      log("Updated value: " + value);

      // process.stdout.write('\033c'); // clearing the console
      log.setStatusBarText([thisProgressBar.update(value, 100)]);
      // console.log(thisProgressBar.update(value, 100));
      if (value === 100) {
        clearInterval(intervalId);
      }
    }, 500);
jeremyk commented 3 years ago

I noticed that the default output function adds a return. So I just get the output with .contents() instead and write it myself to keep it on the same line. Here is an example you can call repeatedly and it will update in place:

function showProgress(current, total, message) {
  process.stdout.clearLine();
  process.stdout.cursorTo(0);
  const progress = new Line()
    .column('Syncing items')
    .column(Gauge(current, total, 40, total, message), 80)
    .fill()
    .contents();
  process.stdout.write(progress);
}