StackGenVis: Alignment of Data, Algorithms, and Models for Stacking Ensemble Learning Using Performance Metrics
https://doi.org/10.1109/TVCG.2020.3030352
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
184 lines
4.4 KiB
184 lines
4.4 KiB
4 years ago
|
'use strict';
|
||
|
|
||
|
/**
|
||
|
* Base prompt implementation
|
||
|
* Should be extended by prompt types.
|
||
|
*/
|
||
|
|
||
|
var ScreenManager = require('../utils/screen-manager');
|
||
|
var Choices = require('../objects/choices');
|
||
|
var utils = require('../utils/');
|
||
|
|
||
|
var Prompt = module.exports = function(question, rl, answers) {
|
||
|
// Setup instance defaults property
|
||
|
utils.extend(this, {
|
||
|
answers: answers,
|
||
|
status: 'pending'
|
||
|
});
|
||
|
|
||
|
// Set defaults prompt options
|
||
|
this.opt = utils.extend({}, {
|
||
|
validate: function() {
|
||
|
return true;
|
||
|
},
|
||
|
filter: function(val) {
|
||
|
return val;
|
||
|
},
|
||
|
when: function() {
|
||
|
return true;
|
||
|
}
|
||
|
}, utils.extend({}, question));
|
||
|
|
||
|
// Check to make sure prompt requirements are there
|
||
|
if (!this.opt.message) {
|
||
|
this.throwParamError('message');
|
||
|
}
|
||
|
if (!this.opt.name) {
|
||
|
this.throwParamError('name');
|
||
|
}
|
||
|
|
||
|
// Normalize choices
|
||
|
if (Array.isArray(this.opt.choices)) {
|
||
|
this.opt.choices = new Choices(this.opt.choices, answers);
|
||
|
}
|
||
|
|
||
|
this.rl = rl;
|
||
|
this.screen = new ScreenManager(this.rl);
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Start the Inquiry session and manage output value filtering
|
||
|
* @param {Function} cb Callback when prompt is done
|
||
|
* @return {this}
|
||
|
*/
|
||
|
|
||
|
Prompt.prototype.run = function(cb) {
|
||
|
this._run(function(value) {
|
||
|
this.filter(value, cb);
|
||
|
}.bind(this));
|
||
|
};
|
||
|
|
||
|
// default noop (this one should be overwritten in prompts)
|
||
|
Prompt.prototype._run = function(cb) {
|
||
|
cb();
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Throw an error telling a required parameter is missing
|
||
|
* @param {String} name Name of the missing param
|
||
|
* @return {Throw Error}
|
||
|
*/
|
||
|
|
||
|
Prompt.prototype.throwParamError = function(name) {
|
||
|
throw new Error('You must provide a `' + name + '` parameter');
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Validate a given input
|
||
|
* @param {String} value Input string
|
||
|
* @param {Function} callback Pass `true` (if input is valid) or an error message as
|
||
|
* parameter.
|
||
|
* @return {null}
|
||
|
*/
|
||
|
|
||
|
Prompt.prototype.validate = function(input, cb) {
|
||
|
utils.runAsync(this.opt.validate, cb, input);
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Run the provided validation method each time a submit event occur.
|
||
|
* @param {Rx.Observable} submit - submit event flow
|
||
|
* @return {Object} Object containing two observables: `success` and `error`
|
||
|
*/
|
||
|
|
||
|
Prompt.prototype.handleSubmitEvents = function(submit) {
|
||
|
var self = this;
|
||
|
var validation = submit.flatMap(function(value) {
|
||
|
return utils.rx.Observable.create(function(observer) {
|
||
|
utils.runAsync(self.opt.validate, function(isValid) {
|
||
|
observer.onNext({
|
||
|
isValid: isValid,
|
||
|
value: self.getCurrentValue(value)
|
||
|
});
|
||
|
observer.onCompleted();
|
||
|
}, self.getCurrentValue(value), self.answers);
|
||
|
});
|
||
|
}).share();
|
||
|
|
||
|
var success = validation
|
||
|
.filter(function(state) {
|
||
|
return state.isValid === true;
|
||
|
})
|
||
|
.take(1);
|
||
|
|
||
|
var error = validation
|
||
|
.filter(function(state) {
|
||
|
return state.isValid !== true;
|
||
|
})
|
||
|
.takeUntil(success);
|
||
|
|
||
|
return {
|
||
|
success: success,
|
||
|
error: error
|
||
|
};
|
||
|
};
|
||
|
|
||
|
Prompt.prototype.getCurrentValue = function(value) {
|
||
|
return value;
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Filter a given input before sending back
|
||
|
* @param {String} value Input string
|
||
|
* @param {Function} callback Pass the filtered input as parameter.
|
||
|
* @return {null}
|
||
|
*/
|
||
|
|
||
|
Prompt.prototype.filter = function(input, cb) {
|
||
|
utils.runAsync(this.opt.filter, cb, input);
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Return the prompt line prefix
|
||
|
* @param {String} [optionnal] String to concatenate to the prefix
|
||
|
* @return {String} prompt prefix
|
||
|
*/
|
||
|
|
||
|
Prompt.prototype.prefix = function(str) {
|
||
|
return utils.chalk.green('?') + ' ' + (str || '');
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Return the prompt line suffix
|
||
|
* @param {String} [optionnal] String to concatenate to the suffix
|
||
|
* @return {String} prompt suffix
|
||
|
*/
|
||
|
|
||
|
var reStrEnd = function() {
|
||
|
return new RegExp('(?:' + utils.ansiRegex().source + ')$|$');
|
||
|
};
|
||
|
|
||
|
Prompt.prototype.suffix = function(str) {
|
||
|
if (!str) str = '';
|
||
|
// make sure we get the `:` inside the styles
|
||
|
if (str.length < 1 || /[a-z1-9]$/i.test(utils.chalk.stripColor(str))) {
|
||
|
str = str.replace(reStrEnd(), ':$&');
|
||
|
}
|
||
|
return str.trim() + ' ';
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Generate the prompt question string
|
||
|
* @return {String} prompt question string
|
||
|
*/
|
||
|
|
||
|
Prompt.prototype.getQuestion = function() {
|
||
|
var message = utils.chalk.green('?') + ' ' + utils.chalk.bold(this.opt.message) + ' ';
|
||
|
|
||
|
// Append the default if available, and if question isn't answered
|
||
|
if (this.opt.default != null && this.status !== 'answered') {
|
||
|
message += utils.chalk.dim('(' + this.opt.default+') ');
|
||
|
}
|
||
|
return message;
|
||
|
};
|