(function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('vega-util'), require('d3-time'), require('d3-array')) : typeof define === 'function' && define.amd ? define(['exports', 'vega-util', 'd3-time', 'd3-array'], factory) : (global = global || self, factory(global.vega = {}, global.vega, global.d3, global.d3)); }(this, (function (exports, vegaUtil, d3Time, d3Array) { 'use strict'; const YEAR = 'year'; const QUARTER = 'quarter'; const MONTH = 'month'; const WEEK = 'week'; const DATE = 'date'; const DAY = 'day'; const DAYOFYEAR = 'dayofyear'; const HOURS = 'hours'; const MINUTES = 'minutes'; const SECONDS = 'seconds'; const MILLISECONDS = 'milliseconds'; const TIME_UNITS = [ YEAR, QUARTER, MONTH, WEEK, DATE, DAY, DAYOFYEAR, HOURS, MINUTES, SECONDS, MILLISECONDS ]; const UNITS = TIME_UNITS.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}.`); } }); const numTypes = ( (m[WEEK] || m[DAY] ? 1 : 0) + (m[QUARTER] || m[MONTH] || m[DATE] ? 1 : 0) + (m[DAYOFYEAR] ? 1 : 0) ); if (numTypes > 1) { vegaUtil.error(`Incompatible time units: ${units}`); } // ensure proper sort order u.sort((a, b) => UNITS[a] - UNITS[b]); return u; } const defaultSpecifiers = { [YEAR]: '%Y ', [QUARTER]: 'Q%q ', [MONTH]: '%b ', [DATE]: '%d ', [WEEK]: 'W%U ', [DAY]: '%a ', [DAYOFYEAR]: '%j ', [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 start; --end) { key = u.slice(start, end).join('-'); if (s[key] != null) { fmt += s[key]; start = end; break; } } } return fmt.trim(); } const t0 = new Date; function localYear(y) { t0.setFullYear(y); t0.setMonth(0); t0.setDate(1); t0.setHours(0, 0, 0, 0); return t0; } function dayofyear(d) { return localDayOfYear(new Date(d)); } function week(d) { return localWeekNum(new Date(d)); } function localDayOfYear(d) { return d3Time.timeDay.count(localYear(d.getFullYear()) - 1, d); } 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 utcdayofyear(d) { return utcDayOfYear(new Date(d)); } function utcweek(d) { return utcWeekNum(new Date(d)); } function utcDayOfYear(d) { const y = Date.UTC(d.getUTCFullYear(), 0, 1); return d3Time.utcDay.count(y - 1, d); } 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 floor(units, step, get, inv, newDate) { const s = step || 1, b = vegaUtil.peek(units), _ = (unit, p, key) => { key = key || unit; return getUnit(get[key], inv[key], 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) : u[DAYOFYEAR] ? _(DAYOFYEAR, 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 getUnit(f, inv, step, phase) { const u = step <= 1 ? f : phase ? (d, y) => phase + step * Math.floor((f(d, y) - phase) / step) : (d, y) => step * Math.floor(f(d, y) / step); return inv ? (d, y) => inv(u(d, y), y) : u; } // 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 => Math.floor(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(), [DAYOFYEAR]: d => localDayOfYear(d), [WEEK]: d => localWeekNum(d), [WEEK + DAY]: (d, y) => weekday(localWeekNum(d), d.getDay(), localFirst(y)), [DAY]: (d, y) => weekday(1, d.getDay(), localFirst(y)) }; const localInv = { [QUARTER]: q => 3 * q, [WEEK]: (w, y) => weekday(w, 0, localFirst(y)) }; function timeFloor(units, step) { return floor(units, step || 1, localGet, localInv, localDate); } // -- UTC TIME -- const utcGet = { [YEAR]: d => d.getUTCFullYear(), [QUARTER]: d => Math.floor(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(), [DAYOFYEAR]: d => utcDayOfYear(d), [WEEK]: d => utcWeekNum(d), [DAY]: (d, y) => weekday(1, d.getUTCDay(), utcFirst(y)), [WEEK + DAY]: (d, y) => weekday(utcWeekNum(d), d.getUTCDay(), utcFirst(y)) }; const utcInv = { [QUARTER]: q => 3 * q, [WEEK]: (w, y) => weekday(w, 0, utcFirst(y)) }; function utcFloor(units, step) { return floor(units, step || 1, utcGet, utcInv, utcDate); } const timeIntervals = { [YEAR]: d3Time.timeYear, [QUARTER]: d3Time.timeMonth.every(3), [MONTH]: d3Time.timeMonth, [WEEK]: d3Time.timeWeek, [DATE]: d3Time.timeDay, [DAY]: d3Time.timeDay, [DAYOFYEAR]: 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, [DAYOFYEAR]: 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 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.DATE = DATE; exports.DAY = DAY; exports.DAYOFYEAR = DAYOFYEAR; exports.HOURS = HOURS; exports.MILLISECONDS = MILLISECONDS; exports.MINUTES = MINUTES; exports.MONTH = MONTH; exports.QUARTER = QUARTER; exports.SECONDS = SECONDS; exports.TIME_UNITS = TIME_UNITS; exports.WEEK = WEEK; exports.YEAR = YEAR; exports.dayofyear = dayofyear; exports.timeBin = bin; exports.timeFloor = timeFloor; exports.timeInterval = timeInterval; exports.timeOffset = timeOffset; exports.timeSequence = timeSequence; exports.timeUnitSpecifier = timeUnitSpecifier; exports.timeUnits = timeUnits; exports.utcFloor = utcFloor; exports.utcInterval = utcInterval; exports.utcOffset = utcOffset; exports.utcSequence = utcSequence; exports.utcdayofyear = utcdayofyear; exports.utcweek = utcweek; exports.week = week; Object.defineProperty(exports, '__esModule', { value: true }); })));