diff --git a/examples/setCurrent.js b/examples/setCurrent.js new file mode 100644 index 0000000..6093c07 --- /dev/null +++ b/examples/setCurrent.js @@ -0,0 +1,10 @@ +/** + * An example to show a progress bar using setCurrent methdod. + */ + +var ProgressBar = require('../'); + +var bar = new ProgressBar(':bar :current/:total', {total: 10}); +var timer = setInterval(function () { + bar.setCurrent(Math.ceil(Math.random() * bar.total), false); +}, 200); diff --git a/lib/node-progress.js b/lib/node-progress.js index 8eb0740..6fd65fe 100644 --- a/lib/node-progress.js +++ b/lib/node-progress.js @@ -106,6 +106,52 @@ ProgressBar.prototype.tick = function(len, tokens){ } }; +/** + * set the progress bar value with 'current' and optional `tokens`. + * it is like the tick() method but with two differences: + * - you directly set the value of the curr + * - you can also choose not to finish the progressBar when it reaches the end by param end_at_total + * @param {number} current + * @param {object} tokens + * @param {boolean} end_at_total + * @api public + */ + +ProgressBar.prototype.setCurrent = function(current, tokens, end_at_total = true){ + if (current !== 0) + current = current || 1; + + if ('boolean' == typeof tokens) end_at_total = tokens; + if ('boolean' == typeof current) current = 1, tokens = {}, end_at_total = current; + + // swap tokens + if ('object' == typeof current) tokens = current, current = 1; + if (tokens) this.tokens = tokens; + + // start time for eta + if (this.start === undefined) this.start = new Date; + + if (current && current < 0) { + current = 0; + } + if (this.total && current > this.total){ + current = this.total; + } + this.curr = current; + + // try to render + this.render(); + + // progress complete + if (end_at_total && this.curr >= this.total) { + this.render(undefined, true); + this.complete = true; + this.terminate(); + this.callback(this); + return; + } +}; + /** * Method to render the progress bar with optional `tokens` to place in the * progress bar's `fmt` field. @@ -139,13 +185,13 @@ ProgressBar.prototype.render = function (tokens, force) { /* populate the bar template with percentages and timestamps */ var str = this.fmt - .replace(':current', this.curr) - .replace(':total', this.total) - .replace(':elapsed', isNaN(elapsed) ? '0.0' : (elapsed / 1000).toFixed(1)) - .replace(':eta', (isNaN(eta) || !isFinite(eta)) ? '0.0' : (eta / 1000) - .toFixed(1)) - .replace(':percent', percent.toFixed(0) + '%') - .replace(':rate', Math.round(rate)); + .replace(':current', this.curr) + .replace(':total', this.total) + .replace(':elapsed', isNaN(elapsed) ? '0.0' : (elapsed / 1000).toFixed(1)) + .replace(':eta', (isNaN(eta) || !isFinite(eta)) ? '0.0' : (eta / 1000) + .toFixed(1)) + .replace(':percent', percent.toFixed(0) + '%') + .replace(':rate', Math.round(rate)); /* compute the available space (non-zero) for the bar */ var availableSpace = Math.max(0, this.stream.columns - str.replace(':bar', '').length);