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.
221 lines
5.1 KiB
221 lines
5.1 KiB
4 years ago
|
(function (global, factory) {
|
||
|
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
|
||
|
typeof define === 'function' && define.amd ? define(['exports'], factory) :
|
||
|
(global = global || self, factory(global.vega = {}));
|
||
|
}(this, (function (exports) { 'use strict';
|
||
|
|
||
|
/**
|
||
|
* Parse an event selector string.
|
||
|
* Returns an array of event stream definitions.
|
||
|
*/
|
||
|
function eventSelector(selector, source, marks) {
|
||
|
DEFAULT_SOURCE = source || VIEW;
|
||
|
MARKS = marks || DEFAULT_MARKS;
|
||
|
return parseMerge(selector.trim()).map(parseSelector);
|
||
|
}
|
||
|
|
||
|
var VIEW = 'view',
|
||
|
LBRACK = '[',
|
||
|
RBRACK = ']',
|
||
|
LBRACE = '{',
|
||
|
RBRACE = '}',
|
||
|
COLON = ':',
|
||
|
COMMA = ',',
|
||
|
NAME = '@',
|
||
|
GT = '>',
|
||
|
ILLEGAL = /[[\]{}]/,
|
||
|
DEFAULT_SOURCE,
|
||
|
MARKS,
|
||
|
DEFAULT_MARKS = {
|
||
|
'*': 1,
|
||
|
arc: 1,
|
||
|
area: 1,
|
||
|
group: 1,
|
||
|
image: 1,
|
||
|
line: 1,
|
||
|
path: 1,
|
||
|
rect: 1,
|
||
|
rule: 1,
|
||
|
shape: 1,
|
||
|
symbol: 1,
|
||
|
text: 1,
|
||
|
trail: 1
|
||
|
};
|
||
|
|
||
|
function isMarkType(type) {
|
||
|
return MARKS[type];
|
||
|
}
|
||
|
|
||
|
function find(s, i, endChar, pushChar, popChar) {
|
||
|
var count = 0,
|
||
|
n = s.length,
|
||
|
c;
|
||
|
for (; i<n; ++i) {
|
||
|
c = s[i];
|
||
|
if (!count && c === endChar) return i;
|
||
|
else if (popChar && popChar.indexOf(c) >= 0) --count;
|
||
|
else if (pushChar && pushChar.indexOf(c) >= 0) ++count;
|
||
|
}
|
||
|
return i;
|
||
|
}
|
||
|
|
||
|
function parseMerge(s) {
|
||
|
var output = [],
|
||
|
start = 0,
|
||
|
n = s.length,
|
||
|
i = 0;
|
||
|
|
||
|
while (i < n) {
|
||
|
i = find(s, i, COMMA, LBRACK + LBRACE, RBRACK + RBRACE);
|
||
|
output.push(s.substring(start, i).trim());
|
||
|
start = ++i;
|
||
|
}
|
||
|
|
||
|
if (output.length === 0) {
|
||
|
throw 'Empty event selector: ' + s;
|
||
|
}
|
||
|
return output;
|
||
|
}
|
||
|
|
||
|
function parseSelector(s) {
|
||
|
return s[0] === '['
|
||
|
? parseBetween(s)
|
||
|
: parseStream(s);
|
||
|
}
|
||
|
|
||
|
function parseBetween(s) {
|
||
|
var n = s.length,
|
||
|
i = 1,
|
||
|
b, stream;
|
||
|
|
||
|
i = find(s, i, RBRACK, LBRACK, RBRACK);
|
||
|
if (i === n) {
|
||
|
throw 'Empty between selector: ' + s;
|
||
|
}
|
||
|
|
||
|
b = parseMerge(s.substring(1, i));
|
||
|
if (b.length !== 2) {
|
||
|
throw 'Between selector must have two elements: ' + s;
|
||
|
}
|
||
|
|
||
|
s = s.slice(i + 1).trim();
|
||
|
if (s[0] !== GT) {
|
||
|
throw 'Expected \'>\' after between selector: ' + s;
|
||
|
}
|
||
|
|
||
|
b = b.map(parseSelector);
|
||
|
|
||
|
stream = parseSelector(s.slice(1).trim());
|
||
|
if (stream.between) {
|
||
|
return {
|
||
|
between: b,
|
||
|
stream: stream
|
||
|
};
|
||
|
} else {
|
||
|
stream.between = b;
|
||
|
}
|
||
|
|
||
|
return stream;
|
||
|
}
|
||
|
|
||
|
function parseStream(s) {
|
||
|
var stream = {source: DEFAULT_SOURCE},
|
||
|
source = [],
|
||
|
throttle = [0, 0],
|
||
|
markname = 0,
|
||
|
start = 0,
|
||
|
n = s.length,
|
||
|
i = 0, j,
|
||
|
filter;
|
||
|
|
||
|
// extract throttle from end
|
||
|
if (s[n-1] === RBRACE) {
|
||
|
i = s.lastIndexOf(LBRACE);
|
||
|
if (i >= 0) {
|
||
|
try {
|
||
|
throttle = parseThrottle(s.substring(i+1, n-1));
|
||
|
} catch (e) {
|
||
|
throw 'Invalid throttle specification: ' + s;
|
||
|
}
|
||
|
s = s.slice(0, i).trim();
|
||
|
n = s.length;
|
||
|
} else throw 'Unmatched right brace: ' + s;
|
||
|
i = 0;
|
||
|
}
|
||
|
|
||
|
if (!n) throw s;
|
||
|
|
||
|
// set name flag based on first char
|
||
|
if (s[0] === NAME) markname = ++i;
|
||
|
|
||
|
// extract first part of multi-part stream selector
|
||
|
j = find(s, i, COLON);
|
||
|
if (j < n) {
|
||
|
source.push(s.substring(start, j).trim());
|
||
|
start = i = ++j;
|
||
|
}
|
||
|
|
||
|
// extract remaining part of stream selector
|
||
|
i = find(s, i, LBRACK);
|
||
|
if (i === n) {
|
||
|
source.push(s.substring(start, n).trim());
|
||
|
} else {
|
||
|
source.push(s.substring(start, i).trim());
|
||
|
filter = [];
|
||
|
start = ++i;
|
||
|
if (start === n) throw 'Unmatched left bracket: ' + s;
|
||
|
}
|
||
|
|
||
|
// extract filters
|
||
|
while (i < n) {
|
||
|
i = find(s, i, RBRACK);
|
||
|
if (i === n) throw 'Unmatched left bracket: ' + s;
|
||
|
filter.push(s.substring(start, i).trim());
|
||
|
if (i < n-1 && s[++i] !== LBRACK) throw 'Expected left bracket: ' + s;
|
||
|
start = ++i;
|
||
|
}
|
||
|
|
||
|
// marshall event stream specification
|
||
|
if (!(n = source.length) || ILLEGAL.test(source[n-1])) {
|
||
|
throw 'Invalid event selector: ' + s;
|
||
|
}
|
||
|
|
||
|
if (n > 1) {
|
||
|
stream.type = source[1];
|
||
|
if (markname) {
|
||
|
stream.markname = source[0].slice(1);
|
||
|
} else if (isMarkType(source[0])) {
|
||
|
stream.marktype = source[0];
|
||
|
} else {
|
||
|
stream.source = source[0];
|
||
|
}
|
||
|
} else {
|
||
|
stream.type = source[0];
|
||
|
}
|
||
|
if (stream.type.slice(-1) === '!') {
|
||
|
stream.consume = true;
|
||
|
stream.type = stream.type.slice(0, -1);
|
||
|
}
|
||
|
if (filter != null) stream.filter = filter;
|
||
|
if (throttle[0]) stream.throttle = throttle[0];
|
||
|
if (throttle[1]) stream.debounce = throttle[1];
|
||
|
|
||
|
return stream;
|
||
|
}
|
||
|
|
||
|
function parseThrottle(s) {
|
||
|
var a = s.split(COMMA);
|
||
|
if (!s.length || a.length > 2) throw s;
|
||
|
return a.map(function(_) {
|
||
|
var x = +_;
|
||
|
if (x !== x) throw s;
|
||
|
return x;
|
||
|
});
|
||
|
}
|
||
|
|
||
|
exports.selector = eventSelector;
|
||
|
|
||
|
Object.defineProperty(exports, '__esModule', { value: true });
|
||
|
|
||
|
})));
|