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.
402 lines
12 KiB
402 lines
12 KiB
(function (global, factory) {
|
|
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('vega-util'), require('d3-time'), require('d3-time-format'), require('d3-array')) :
|
|
typeof define === 'function' && define.amd ? define(['exports', 'vega-util', 'd3-time', 'd3-time-format', 'd3-array'], factory) :
|
|
(global = global || self, factory(global.vega = {}, global.vega, global.d3, global.d3, global.d3));
|
|
}(this, (function (exports, vegaUtil, d3Time, d3TimeFormat, d3Array) { 'use strict';
|
|
|
|
const YEAR = 'year';
|
|
const QUARTER = 'quarter';
|
|
const MONTH = 'month';
|
|
const WEEK = 'week';
|
|
const DATE = 'date';
|
|
const DAY = 'day';
|
|
const HOURS = 'hours';
|
|
const MINUTES = 'minutes';
|
|
const SECONDS = 'seconds';
|
|
const MILLISECONDS = 'milliseconds';
|
|
|
|
const UNITS = [
|
|
YEAR,
|
|
QUARTER,
|
|
MONTH,
|
|
WEEK,
|
|
DATE,
|
|
DAY,
|
|
HOURS,
|
|
MINUTES,
|
|
SECONDS,
|
|
MILLISECONDS
|
|
].reduce((o, u, i) => (o[u] = 1 + i, o), {});
|
|
|
|
function timeUnits(units) {
|
|
const u = vegaUtil.array(units).slice(),
|
|
m = {};
|
|
|
|
// check validity
|
|
if (!u.length) vegaUtil.error('Missing time unit.');
|
|
|
|
u.forEach(unit => {
|
|
if (vegaUtil.hasOwnProperty(UNITS, unit)) {
|
|
m[unit] = 1;
|
|
} else {
|
|
vegaUtil.error(`Invalid time unit: ${unit}.`);
|
|
}
|
|
});
|
|
|
|
if ((m[WEEK] || m[DAY]) && (m[QUARTER] || m[MONTH] || m[DATE])) {
|
|
vegaUtil.error(`Incompatible time units: ${units}`);
|
|
}
|
|
|
|
// ensure proper sort order
|
|
u.sort((a, b) => UNITS[a] - UNITS[b]);
|
|
|
|
return u;
|
|
}
|
|
|
|
const t0 = new Date;
|
|
|
|
function floor(units, step, fn, newDate) {
|
|
const s = step || 1,
|
|
b = vegaUtil.peek(units),
|
|
_ = (unit, p, key) => skip(fn[key || unit], unit === b && s, p);
|
|
|
|
const t = new Date,
|
|
u = vegaUtil.toSet(units),
|
|
y = u[YEAR] ? _(YEAR) : vegaUtil.constant(2012),
|
|
m = u[MONTH] ? _(MONTH)
|
|
: u[QUARTER] ? _(QUARTER)
|
|
: vegaUtil.zero,
|
|
d = u[WEEK] && u[DAY] ? _(DAY, 1, WEEK + DAY)
|
|
: u[WEEK] ? _(WEEK, 1)
|
|
: u[DAY] ? _(DAY, 1)
|
|
: u[DATE] ? _(DATE, 1)
|
|
: vegaUtil.one,
|
|
H = u[HOURS] ? _(HOURS) : vegaUtil.zero,
|
|
M = u[MINUTES] ? _(MINUTES) : vegaUtil.zero,
|
|
S = u[SECONDS] ? _(SECONDS) : vegaUtil.zero,
|
|
L = u[MILLISECONDS] ? _(MILLISECONDS) : vegaUtil.zero;
|
|
|
|
return function(v) {
|
|
t.setTime(+v);
|
|
const year = y(t);
|
|
return newDate(year, m(t), d(t, year), H(t), M(t), S(t), L(t));
|
|
};
|
|
}
|
|
|
|
function skip(f, step, phase) {
|
|
return step <= 1 ? f
|
|
: phase ? (d, y) => phase + step * Math.floor((f(d, y) - phase) / step)
|
|
: (d, y) => step * Math.floor(f(d, y) / step);
|
|
}
|
|
|
|
// returns the day of the year based on week number, day of week,
|
|
// and the day of the week for the first day of the year
|
|
function weekday(week, day, firstDay) {
|
|
return day + week * 7 - (firstDay + 6) % 7;
|
|
}
|
|
|
|
// -- LOCAL TIME --
|
|
|
|
const localGet = {
|
|
[YEAR]: d => d.getFullYear(),
|
|
[QUARTER]: d => 3 * ~~(d.getMonth() / 3),
|
|
[MONTH]: d => d.getMonth(),
|
|
[DATE]: d => d.getDate(),
|
|
[HOURS]: d => d.getHours(),
|
|
[MINUTES]: d => d.getMinutes(),
|
|
[SECONDS]: d => d.getSeconds(),
|
|
[MILLISECONDS]: d => d.getMilliseconds(),
|
|
[DAY]: (d, y) => weekday(1, d.getDay(), localFirst(y)),
|
|
[WEEK]: (d, y) => weekday(localWeekNum(d), 0, localFirst(y)),
|
|
[WEEK + DAY]: (d, y) => weekday(localWeekNum(d), d.getDay(), localFirst(y))
|
|
};
|
|
|
|
function localYear(y) {
|
|
t0.setFullYear(y);
|
|
t0.setMonth(0);
|
|
t0.setDate(1);
|
|
t0.setHours(0, 0, 0, 0);
|
|
return t0;
|
|
}
|
|
|
|
function localWeekNum(d) {
|
|
return d3Time.timeWeek.count(localYear(d.getFullYear()) - 1, d);
|
|
}
|
|
|
|
function localFirst(y) {
|
|
return localYear(y).getDay();
|
|
}
|
|
|
|
function localDate(y, m, d, H, M, S, L) {
|
|
if (0 <= y && y < 100) {
|
|
var date = new Date(-1, m, d, H, M, S, L);
|
|
date.setFullYear(y);
|
|
return date;
|
|
}
|
|
return new Date(y, m, d, H, M, S, L);
|
|
}
|
|
|
|
function timeFloor(units, step) {
|
|
return floor(units, step || 1, localGet, localDate);
|
|
}
|
|
|
|
// -- UTC TIME --
|
|
|
|
const utcGet = {
|
|
[YEAR]: d => d.getUTCFullYear(),
|
|
[QUARTER]: d => 3 * ~~(d.getUTCMonth() / 3),
|
|
[MONTH]: d => d.getUTCMonth(),
|
|
[DATE]: d => d.getUTCDate(),
|
|
[HOURS]: d => d.getUTCHours(),
|
|
[MINUTES]: d => d.getUTCMinutes(),
|
|
[SECONDS]: d => d.getUTCSeconds(),
|
|
[MILLISECONDS]: d => d.getUTCMilliseconds(),
|
|
[DAY]: (d, y) => weekday(1, d.getUTCDay(), utcFirst(y)),
|
|
[WEEK]: (d, y) => weekday(utcWeekNum(d), 0, utcFirst(y)),
|
|
[WEEK + DAY]: (d, y) => weekday(utcWeekNum(d), d.getUTCDay(), utcFirst(y))
|
|
};
|
|
|
|
function utcWeekNum(d) {
|
|
const y = Date.UTC(d.getUTCFullYear(), 0, 1);
|
|
return d3Time.utcWeek.count(y - 1, d);
|
|
}
|
|
|
|
function utcFirst(y) {
|
|
t0.setTime(Date.UTC(y, 0, 1));
|
|
return t0.getUTCDay();
|
|
}
|
|
|
|
function utcDate(y, m, d, H, M, S, L) {
|
|
if (0 <= y && y < 100) {
|
|
var date = new Date(Date.UTC(-1, m, d, H, M, S, L));
|
|
date.setUTCFullYear(d.y);
|
|
return date;
|
|
}
|
|
return new Date(Date.UTC(y, m, d, H, M, S, L));
|
|
}
|
|
|
|
function utcFloor(units, step) {
|
|
return floor(units, step || 1, utcGet, utcDate);
|
|
}
|
|
|
|
const timeIntervals = {
|
|
[YEAR]: d3Time.timeYear,
|
|
[QUARTER]: d3Time.timeMonth.every(3),
|
|
[MONTH]: d3Time.timeMonth,
|
|
[WEEK]: d3Time.timeWeek,
|
|
[DATE]: d3Time.timeDay,
|
|
[DAY]: d3Time.timeDay,
|
|
[HOURS]: d3Time.timeHour,
|
|
[MINUTES]: d3Time.timeMinute,
|
|
[SECONDS]: d3Time.timeSecond,
|
|
[MILLISECONDS]: d3Time.timeMillisecond
|
|
};
|
|
|
|
const utcIntervals = {
|
|
[YEAR]: d3Time.utcYear,
|
|
[QUARTER]: d3Time.utcMonth.every(3),
|
|
[MONTH]: d3Time.utcMonth,
|
|
[WEEK]: d3Time.utcWeek,
|
|
[DATE]: d3Time.utcDay,
|
|
[DAY]: d3Time.utcDay,
|
|
[HOURS]: d3Time.utcHour,
|
|
[MINUTES]: d3Time.utcMinute,
|
|
[SECONDS]: d3Time.utcSecond,
|
|
[MILLISECONDS]: d3Time.utcMillisecond
|
|
};
|
|
|
|
function timeInterval(unit) {
|
|
return timeIntervals[unit];
|
|
}
|
|
|
|
function utcInterval(unit) {
|
|
return utcIntervals[unit];
|
|
}
|
|
|
|
function offset(ival, date, step) {
|
|
return ival ? ival.offset(date, step) : undefined;
|
|
}
|
|
|
|
function timeOffset(unit, date, step) {
|
|
return offset(timeInterval(unit), date, step);
|
|
}
|
|
|
|
function utcOffset(unit, date, step) {
|
|
return offset(utcInterval(unit), date, step);
|
|
}
|
|
|
|
function sequence(ival, start, stop, step) {
|
|
return ival ? ival.range(start, stop, step) : undefined;
|
|
}
|
|
|
|
function timeSequence(unit, start, stop, step) {
|
|
return sequence(timeInterval(unit), start, stop, step);
|
|
}
|
|
|
|
function utcSequence(unit, start, stop, step) {
|
|
return sequence(utcInterval(unit), start, stop, step);
|
|
}
|
|
|
|
const defaultSpecifiers = {
|
|
[YEAR]: '%Y ',
|
|
[QUARTER]: 'Q%q ',
|
|
[MONTH]: '%b ',
|
|
[DATE]: '%d ',
|
|
[WEEK]: 'W%U ',
|
|
[DAY]: '%a ',
|
|
[HOURS]: '%H:00',
|
|
[MINUTES]: '00:%M',
|
|
[SECONDS]: ':%S',
|
|
[MILLISECONDS]: '.%L',
|
|
[`${YEAR}-${MONTH}`]: '%Y-%m ',
|
|
[`${YEAR}-${MONTH}-${DATE}`]: '%Y-%m-%d ',
|
|
[`${HOURS}-${MINUTES}`]: '%H:%M'
|
|
};
|
|
|
|
function timeUnitSpecifier(units, specifiers) {
|
|
const s = vegaUtil.extend({}, defaultSpecifiers, specifiers),
|
|
u = timeUnits(units),
|
|
n = u.length;
|
|
|
|
let fmt = '', start = 0, end, key;
|
|
|
|
for (start=0; start<n; ) {
|
|
for (end=u.length; end > start; --end) {
|
|
key = u.slice(start, end).join('-');
|
|
if (s[key] != null) {
|
|
fmt += s[key];
|
|
start = end;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
return fmt.trim();
|
|
}
|
|
|
|
function timeFormat(specifier) {
|
|
return formatter(d3TimeFormat.timeFormat, timeInterval, specifier);
|
|
}
|
|
|
|
function utcFormat(specifier) {
|
|
return formatter(d3TimeFormat.utcFormat, utcInterval, specifier);
|
|
}
|
|
|
|
function formatter(format, interval, specifier) {
|
|
return vegaUtil.isString(specifier)
|
|
? format(specifier)
|
|
: multiFormat(format, interval, specifier);
|
|
}
|
|
|
|
function multiFormat(format, interval, spec) {
|
|
spec = spec || {};
|
|
if (!vegaUtil.isObject(spec)) {
|
|
vegaUtil.error(`Invalid time multi-format specifier: ${spec}`);
|
|
}
|
|
|
|
const second = interval(SECONDS),
|
|
minute = interval(MINUTES),
|
|
hour = interval(HOURS),
|
|
day = interval(DATE),
|
|
week = interval(WEEK),
|
|
month = interval(MONTH),
|
|
quarter = interval(QUARTER),
|
|
year = interval(YEAR),
|
|
L = format(spec[MILLISECONDS] || '.%L'),
|
|
S = format(spec[SECONDS] || ':%S'),
|
|
M = format(spec[MINUTES] || '%I:%M'),
|
|
H = format(spec[HOURS] || '%I %p'),
|
|
d = format(spec[DATE] || spec[DAY] || '%a %d'),
|
|
w = format(spec[WEEK] || '%b %d'),
|
|
m = format(spec[MONTH] || '%B'),
|
|
q = format(spec[QUARTER] || '%B'),
|
|
y = format(spec[YEAR] || '%Y');
|
|
|
|
return function(date) {
|
|
return (second(date) < date ? L
|
|
: minute(date) < date ? S
|
|
: hour(date) < date ? M
|
|
: day(date) < date ? H
|
|
: month(date) < date ? (week(date) < date ? d : w)
|
|
: year(date) < date ? (quarter(date) < date ? m : q)
|
|
: y)(date);
|
|
};
|
|
}
|
|
|
|
const durationSecond = 1000,
|
|
durationMinute = durationSecond * 60,
|
|
durationHour = durationMinute * 60,
|
|
durationDay = durationHour * 24,
|
|
durationWeek = durationDay * 7,
|
|
durationMonth = durationDay * 30,
|
|
durationYear = durationDay * 365;
|
|
|
|
const Milli = [YEAR, MONTH, DATE, HOURS, MINUTES, SECONDS, MILLISECONDS],
|
|
Seconds = Milli.slice(0, -1),
|
|
Minutes = Seconds.slice(0, -1),
|
|
Hours = Minutes.slice(0, -1),
|
|
Day = Hours.slice(0, -1),
|
|
Week = [YEAR, WEEK],
|
|
Month = [YEAR, MONTH],
|
|
Year = [YEAR];
|
|
|
|
const intervals = [
|
|
[Seconds, 1, durationSecond],
|
|
[Seconds, 5, 5 * durationSecond],
|
|
[Seconds, 15, 15 * durationSecond],
|
|
[Seconds, 30, 30 * durationSecond],
|
|
[Minutes, 1, durationMinute],
|
|
[Minutes, 5, 5 * durationMinute],
|
|
[Minutes, 15, 15 * durationMinute],
|
|
[Minutes, 30, 30 * durationMinute],
|
|
[ Hours, 1, durationHour ],
|
|
[ Hours, 3, 3 * durationHour ],
|
|
[ Hours, 6, 6 * durationHour ],
|
|
[ Hours, 12, 12 * durationHour ],
|
|
[ Day, 1, durationDay ],
|
|
[ Week, 1, durationWeek ],
|
|
[ Month, 1, durationMonth ],
|
|
[ Month, 3, 3 * durationMonth ],
|
|
[ Year, 1, durationYear ]
|
|
];
|
|
|
|
function bin(opt) {
|
|
const ext = opt.extent,
|
|
max = opt.maxbins || 40,
|
|
target = Math.abs(vegaUtil.span(ext)) / max;
|
|
|
|
let i = d3Array.bisector(i => i[2]).right(intervals, target),
|
|
units, step;
|
|
|
|
if (i === intervals.length) {
|
|
units = Year,
|
|
step = d3Array.tickStep(ext[0] / durationYear, ext[1] / durationYear, max);
|
|
} else if (i) {
|
|
i = intervals[target / intervals[i - 1][2] < intervals[i][2] / target ? i - 1 : i];
|
|
units = i[0];
|
|
step = i[1];
|
|
} else {
|
|
units = Milli;
|
|
step = Math.max(d3Array.tickStep(ext[0], ext[1], max), 1);
|
|
}
|
|
|
|
return {units, step};
|
|
}
|
|
|
|
exports.timeBin = bin;
|
|
exports.timeFloor = timeFloor;
|
|
exports.timeFormat = timeFormat;
|
|
exports.timeInterval = timeInterval;
|
|
exports.timeOffset = timeOffset;
|
|
exports.timeSequence = timeSequence;
|
|
exports.timeUnitSpecifier = timeUnitSpecifier;
|
|
exports.timeUnits = timeUnits;
|
|
exports.utcFloor = utcFloor;
|
|
exports.utcFormat = utcFormat;
|
|
exports.utcInterval = utcInterval;
|
|
exports.utcOffset = utcOffset;
|
|
exports.utcSequence = utcSequence;
|
|
|
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
|
|
})));
|
|
|