diff --git a/samples/scales/time/financial.html b/samples/scales/time/financial.html
index 084bacc3622..c4eb040423f 100644
--- a/samples/scales/time/financial.html
+++ b/samples/scales/time/financial.html
@@ -76,7 +76,7 @@
var now = moment();
var data = [];
var lessThanDay = unitLessThanDay();
- for (; data.length < 60 && date.isBefore(now); date = date.clone().add(1, unit).startOf(unit)) {
+ for (; data.length < 600 && date.isBefore(now); date = date.clone().add(1, unit).startOf(unit)) {
if (outsideMarketHours(date)) {
if (!lessThanDay || !beforeNineThirty(date)) {
date = date.clone().add(date.isoWeekday() >= 5 ? 8 - date.isoWeekday() : 1, 'day');
@@ -112,13 +112,49 @@
}]
},
options: {
+ animation: {
+ duration: 0
+ },
scales: {
xAxes: [{
type: 'time',
distribution: 'series',
ticks: {
+ major: {
+ enabled: true,
+ fontStyle: 'bold'
+ },
source: 'data',
- autoSkip: true
+ autoSkip: true,
+ autoSkipPadding: 75,
+ maxRotation: 0,
+ sampleSize: 100
+ },
+ afterBuildTicks: function(scale, ticks) {
+ var majorUnit = scale._majorUnit;
+ var firstTick = ticks[0];
+ var i, ilen, val, tick, currMajor, lastMajor;
+
+ val = moment(ticks[0].value);
+ if ((majorUnit === 'minute' && val.second() === 0)
+ || (majorUnit === 'hour' && val.minute() === 0)
+ || (majorUnit === 'day' && val.hour() === 9)
+ || (majorUnit === 'month' && val.date() <= 3 && val.isoWeekday() === 1)
+ || (majorUnit === 'year' && val.month() === 0)) {
+ firstTick.major = true;
+ } else {
+ firstTick.major = false;
+ }
+ lastMajor = val.get(majorUnit);
+
+ for (i = 1, ilen = ticks.length; i < ilen; i++) {
+ tick = ticks[i];
+ val = moment(tick.value);
+ currMajor = val.get(majorUnit);
+ tick.major = currMajor !== lastMajor;
+ lastMajor = currMajor;
+ }
+ return ticks;
}
}],
yAxes: [{
diff --git a/src/core/core.scale.js b/src/core/core.scale.js
index 95a5f5c5f6c..6a5f7bf012b 100644
--- a/src/core/core.scale.js
+++ b/src/core/core.scale.js
@@ -214,6 +214,109 @@ function parseTickFontOptions(options) {
return {minor: minor, major: major};
}
+function nonSkipped(ticksToFilter) {
+ var filtered = [];
+ var item, index, len;
+ for (index = 0, len = ticksToFilter.length; index < len; ++index) {
+ item = ticksToFilter[index];
+ if (typeof item._index !== 'undefined') {
+ filtered.push(item);
+ }
+ }
+ return filtered;
+}
+
+function getEvenSpacing(arr) {
+ var len = arr.length;
+ var i, diff;
+
+ if (len < 2) {
+ return false;
+ }
+
+ for (diff = arr[0], i = 1; i < len; ++i) {
+ if (arr[i] - arr[i - 1] !== diff) {
+ return false;
+ }
+ }
+ return diff;
+}
+
+function calculateSpacing(majorIndices, ticks, axisLength, ticksLimit) {
+ var evenMajorSpacing = getEvenSpacing(majorIndices);
+ var spacing = (ticks.length - 1) / ticksLimit;
+ var factors, factor, i, ilen;
+
+ // If the major ticks are evenly spaced apart, place the minor ticks
+ // so that they divide the major ticks into even chunks
+ if (!evenMajorSpacing) {
+ return Math.max(spacing, 1);
+ }
+
+ factors = helpers.math._factorize(evenMajorSpacing);
+ for (i = 0, ilen = factors.length - 1; i < ilen; i++) {
+ factor = factors[i];
+ if (factor > spacing) {
+ return factor;
+ }
+ }
+ return Math.max(spacing, 1);
+}
+
+function getMajorIndices(ticks) {
+ var result = [];
+ var i, ilen;
+ for (i = 0, ilen = ticks.length; i < ilen; i++) {
+ if (ticks[i].major) {
+ result.push(i);
+ }
+ }
+ return result;
+}
+
+function skipMajors(ticks, majorIndices, spacing) {
+ var count = 0;
+ var next = majorIndices[0];
+ var i, tick;
+
+ spacing = Math.ceil(spacing);
+ for (i = 0; i < ticks.length; i++) {
+ tick = ticks[i];
+ if (i === next) {
+ tick._index = i;
+ count++;
+ next = majorIndices[count * spacing];
+ } else {
+ delete tick.label;
+ }
+ }
+}
+
+function skip(ticks, spacing, majorStart, majorEnd) {
+ var start = valueOrDefault(majorStart, 0);
+ var end = Math.min(valueOrDefault(majorEnd, ticks.length), ticks.length);
+ var count = 0;
+ var length, i, tick, next;
+
+ spacing = Math.ceil(spacing);
+ if (majorEnd) {
+ length = majorEnd - majorStart;
+ spacing = length / Math.floor(length / spacing);
+ }
+
+ next = start;
+ for (i = Math.max(start, 0); i < end; i++) {
+ tick = ticks[i];
+ if (i === next) {
+ tick._index = i;
+ count++;
+ next = Math.round(start + count * spacing);
+ } else {
+ delete tick.label;
+ }
+ }
+}
+
var Scale = Element.extend({
zeroLineIndex: 0,
@@ -364,7 +467,7 @@ var Scale = Element.extend({
me.afterFit();
// Auto-skip
- me._ticksToDraw = tickOpts.display && tickOpts.autoSkip ? me._autoSkip(ticks) : ticks;
+ me._ticksToDraw = tickOpts.display && (tickOpts.autoSkip || tickOpts.source === 'auto') ? me._autoSkip(ticks) : ticks;
if (samplingEnabled) {
// Generate labels using all non-skipped ticks
@@ -848,40 +951,34 @@ var Scale = Element.extend({
*/
_autoSkip: function(ticks) {
var me = this;
- var optionTicks = me.options.ticks;
- var tickCount = ticks.length;
- var skipRatio = false;
- var maxTicks = optionTicks.maxTicksLimit;
-
- // Total space needed to display all ticks. First and last ticks are
- // drawn as their center at end of axis, so tickCount-1
- var ticksLength = me._tickSize() * (tickCount - 1);
-
+ var tickOpts = me.options.ticks;
var axisLength = me._length;
- var result = [];
- var i, tick;
-
- if (ticksLength > axisLength) {
- skipRatio = 1 + Math.floor(ticksLength / axisLength);
- }
-
- // if they defined a max number of optionTicks,
- // increase skipRatio until that number is met
- if (tickCount > maxTicks) {
- skipRatio = Math.max(skipRatio, 1 + Math.floor(tickCount / maxTicks));
+ var ticksLimit = tickOpts.maxTicksLimit || axisLength / me._tickSize() + 1;
+ var majorIndices = tickOpts.major.enabled ? getMajorIndices(ticks) : [];
+ var numMajorIndices = majorIndices.length;
+ var first = majorIndices[0];
+ var last = majorIndices[numMajorIndices - 1];
+ var i, ilen, spacing, avgMajorSpacing;
+
+ // If there are too many major ticks to display them all
+ if (numMajorIndices > ticksLimit) {
+ skipMajors(ticks, majorIndices, numMajorIndices / ticksLimit);
+ return nonSkipped(ticks);
}
- for (i = 0; i < tickCount; i++) {
- tick = ticks[i];
+ spacing = calculateSpacing(majorIndices, ticks, axisLength, ticksLimit);
- if (skipRatio <= 1 || i % skipRatio === 0) {
- tick._index = i;
- result.push(tick);
- } else {
- delete tick.label;
+ if (numMajorIndices > 0) {
+ for (i = 0, ilen = numMajorIndices - 1; i < ilen; i++) {
+ skip(ticks, spacing, majorIndices[i], majorIndices[i + 1]);
}
+ avgMajorSpacing = numMajorIndices > 1 ? (last - first) / (numMajorIndices - 1) : null;
+ skip(ticks, spacing, helpers.isNullOrUndef(avgMajorSpacing) ? 0 : first - avgMajorSpacing, first);
+ skip(ticks, spacing, last, helpers.isNullOrUndef(avgMajorSpacing) ? ticks.length : last + avgMajorSpacing);
+ return nonSkipped(ticks);
}
- return result;
+ skip(ticks, spacing);
+ return nonSkipped(ticks);
},
/**
@@ -955,7 +1052,7 @@ var Scale = Element.extend({
var alignBorderValue = function(pixel) {
return alignPixel(chart, pixel, axisWidth);
};
- var borderValue, i, tick, label, lineValue, alignedLineValue;
+ var borderValue, i, tick, lineValue, alignedLineValue;
var tx1, ty1, tx2, ty2, x1, y1, x2, y2, lineWidth, lineColor, borderDash, borderDashOffset;
if (position === 'top') {
@@ -986,10 +1083,9 @@ var Scale = Element.extend({
for (i = 0; i < ticksLength; ++i) {
tick = ticks[i] || {};
- label = tick.label;
// autoskipper skipped this tick (#4635)
- if (isNullOrUndef(label) && i < ticks.length) {
+ if (isNullOrUndef(tick.label) && i < ticks.length) {
continue;
}
diff --git a/src/scales/scale.time.js b/src/scales/scale.time.js
index 9b29916c8d3..38428c8ffd7 100644
--- a/src/scales/scale.time.js
+++ b/src/scales/scale.time.js
@@ -5,8 +5,8 @@ var defaults = require('../core/core.defaults');
var helpers = require('../helpers/index');
var Scale = require('../core/core.scale');
+var resolve = helpers.options.resolve;
var valueOrDefault = helpers.valueOrDefault;
-var factorize = helpers.math._factorize;
// Integer constants are from the ES6 spec.
var MIN_INTEGER = Number.MIN_SAFE_INTEGER || -9007199254740991;
@@ -16,42 +16,42 @@ var INTERVALS = {
millisecond: {
common: true,
size: 1,
- steps: factorize(1000)
+ steps: 1000
},
second: {
common: true,
size: 1000,
- steps: factorize(60)
+ steps: 60
},
minute: {
common: true,
size: 60000,
- steps: factorize(60)
+ steps: 60
},
hour: {
common: true,
size: 3600000,
- steps: factorize(24)
+ steps: 24
},
day: {
common: true,
size: 86400000,
- steps: factorize(10)
+ steps: 30
},
week: {
common: false,
size: 604800000,
- steps: factorize(4)
+ steps: 4
},
month: {
common: true,
size: 2.628e9,
- steps: factorize(12)
+ steps: 12
},
quarter: {
common: false,
size: 7.884e9,
- steps: factorize(4)
+ steps: 4
},
year: {
common: true,
@@ -248,31 +248,6 @@ function parse(scale, input) {
return value;
}
-/**
- * Returns the number of unit to skip to be able to display up to `capacity` number of ticks
- * in `unit` for the given `min` / `max` range and respecting the interval steps constraints.
- */
-function determineStepSize(min, max, unit, capacity) {
- var range = max - min;
- var interval = INTERVALS[unit];
- var milliseconds = interval.size;
- var steps = interval.steps;
- var i, ilen, factor;
-
- if (!steps) {
- return Math.ceil(range / (capacity * milliseconds));
- }
-
- for (i = 0, ilen = steps.length; i < ilen; ++i) {
- factor = steps[i];
- if (Math.ceil(range / (milliseconds * factor)) <= capacity) {
- break;
- }
- }
-
- return factor;
-}
-
/**
* Figures out what unit results in an appropriate number of auto-generated ticks
*/
@@ -282,7 +257,7 @@ function determineUnitForAutoTicks(minUnit, min, max, capacity) {
for (i = UNITS.indexOf(minUnit); i < ilen - 1; ++i) {
interval = INTERVALS[UNITS[i]];
- factor = interval.steps ? interval.steps[interval.steps.length - 1] : MAX_INTEGER;
+ factor = interval.steps ? interval.steps / 2 : MAX_INTEGER;
if (interval.common && Math.ceil((max - min) / (factor * interval.size)) <= capacity) {
return UNITS[i];
@@ -296,10 +271,9 @@ function determineUnitForAutoTicks(minUnit, min, max, capacity) {
* Figures out what unit to format a set of ticks with
*/
function determineUnitForFormatting(scale, ticks, minUnit, min, max) {
- var ilen = UNITS.length;
var i, unit;
- for (i = ilen - 1; i >= UNITS.indexOf(minUnit); i--) {
+ for (i = UNITS.length - 1; i >= UNITS.indexOf(minUnit); i--) {
unit = UNITS[i];
if (INTERVALS[unit].common && scale._adapter.diff(max, min, unit) >= ticks.length - 1) {
return unit;
@@ -319,7 +293,7 @@ function determineMajorUnit(unit) {
/**
* Generates a maximum of `capacity` timestamps between min and max, rounded to the
- * `minor` unit, aligned on the `major` unit and using the given scale time `options`.
+ * `minor` unit using the given scale time `options`.
* Important: this method can return ticks outside the min and max range, it's the
* responsibility of the calling code to clamp values if needed.
*/
@@ -328,51 +302,33 @@ function generate(scale, min, max, capacity) {
var options = scale.options;
var timeOpts = options.time;
var minor = timeOpts.unit || determineUnitForAutoTicks(timeOpts.minUnit, min, max, capacity);
- var major = determineMajorUnit(minor);
- var stepSize = valueOrDefault(timeOpts.stepSize, timeOpts.unitStepSize);
+ var stepSize = resolve([timeOpts.stepSize, timeOpts.unitStepSize, 1]);
var weekday = minor === 'week' ? timeOpts.isoWeekday : false;
- var majorTicksEnabled = options.ticks.major.enabled;
- var interval = INTERVALS[minor];
var first = min;
- var last = max;
var ticks = [];
var time;
- if (!stepSize) {
- stepSize = determineStepSize(min, max, minor, capacity);
- }
-
// For 'week' unit, handle the first day of week option
if (weekday) {
first = +adapter.startOf(first, 'isoWeek', weekday);
- last = +adapter.startOf(last, 'isoWeek', weekday);
}
- // Align first/last ticks on unit
+ // Align first ticks on unit
first = +adapter.startOf(first, weekday ? 'day' : minor);
- last = +adapter.startOf(last, weekday ? 'day' : minor);
- // Make sure that the last tick include max
- if (last < max) {
- last = +adapter.add(last, 1, minor);
+ // Prevent browser from freezing in case user options request millions of milliseconds
+ if (adapter.diff(max, min, minor) > 100000 * stepSize) {
+ throw min + ' and ' + max + ' are too far apart with stepSize of ' + stepSize + ' ' + minor;
}
- time = first;
-
- if (majorTicksEnabled && major && !weekday && !timeOpts.round) {
- // Align the first tick on the previous `minor` unit aligned on the `major` unit:
- // we first aligned time on the previous `major` unit then add the number of full
- // stepSize there is between first and the previous major time.
- time = +adapter.startOf(time, major);
- time = +adapter.add(time, ~~((first - time) / (interval.size * stepSize)) * stepSize, minor);
+ for (time = first; time < max; time = +adapter.add(time, stepSize, minor)) {
+ ticks.push(time);
}
- for (; time < last; time = +adapter.add(time, stepSize, minor)) {
- ticks.push(+time);
+ if (time === max || options.bounds === 'ticks') {
+ ticks.push(time);
}
- ticks.push(+time);
-
return ticks;
}
@@ -609,18 +565,17 @@ module.exports = Scale.extend({
var timeOpts = options.time;
var timestamps = me._timestamps;
var ticks = [];
+ var capacity = me.getLabelCapacity(min);
+ var source = options.ticks.source;
+ var distribution = options.distribution;
var i, ilen, timestamp;
- switch (options.ticks.source) {
- case 'data':
+ if (source === 'data' || (source === 'auto' && distribution === 'series')) {
timestamps = timestamps.data;
- break;
- case 'labels':
+ } else if (source === 'labels') {
timestamps = timestamps.labels;
- break;
- case 'auto':
- default:
- timestamps = generate(me, min, max, me.getLabelCapacity(min), options);
+ } else {
+ timestamps = generate(me, min, max, capacity, options);
}
if (options.bounds === 'ticks' && timestamps.length) {
@@ -645,8 +600,9 @@ module.exports = Scale.extend({
// PRIVATE
me._unit = timeOpts.unit || determineUnitForFormatting(me, ticks, timeOpts.minUnit, me.min, me.max);
- me._majorUnit = determineMajorUnit(me._unit);
- me._table = buildLookupTable(me._timestamps.data, min, max, options.distribution);
+ me._majorUnit = !options.ticks.major.enabled || me._unit === 'year' ? undefined
+ : determineMajorUnit(me._unit);
+ me._table = buildLookupTable(me._timestamps.data, min, max, distribution);
me._offsets = computeOffsets(me._table, ticks, min, max, options);
if (options.ticks.reverse) {
@@ -690,11 +646,10 @@ module.exports = Scale.extend({
var majorFormat = formats[majorUnit];
var tick = ticks[index];
var tickOpts = options.ticks;
- var majorTickOpts = tickOpts.major;
- var major = majorTickOpts.enabled && majorUnit && majorFormat && tick && tick.major;
+ var major = majorUnit && majorFormat && tick && tick.major;
var label = adapter.format(time, format ? format : major ? majorFormat : minorFormat);
- var nestedTickOpts = major ? majorTickOpts : tickOpts.minor;
- var formatter = helpers.options.resolve([
+ var nestedTickOpts = major ? tickOpts.major : tickOpts.minor;
+ var formatter = resolve([
nestedTickOpts.callback,
nestedTickOpts.userCallback,
tickOpts.callback,
diff --git a/test/specs/scale.time.tests.js b/test/specs/scale.time.tests.js
index 08292521297..593a846b0f9 100755
--- a/test/specs/scale.time.tests.js
+++ b/test/specs/scale.time.tests.js
@@ -617,21 +617,22 @@ describe('Time scale tests', function() {
});
it('should build the correct ticks', function() {
- // Where 'correct' is a two year spacing.
- expect(getTicksLabels(this.scale)).toEqual(['2005', '2007', '2009', '2011', '2013', '2015', '2017', '2019']);
+ expect(getTicksLabels(this.scale)).toEqual(['2005', '2006', '2007', '2008', '2009', '2010', '2011', '2012', '2013', '2014', '2015', '2016', '2017', '2018']);
});
it('should have ticks with accurate labels', function() {
var scale = this.scale;
var ticks = scale.getTicks();
- var pixelsPerYear = scale.width / 14;
+ // pixelsPerTick is an aproximation which assumes same number of milliseconds per year (not true)
+ // we use a threshold of 1 day so that we still match these values
+ var pixelsPerTick = scale.width / (ticks.length - 1);
for (var i = 0; i < ticks.length - 1; i++) {
- var offset = 2 * pixelsPerYear * i;
+ var offset = pixelsPerTick * i;
expect(scale.getValueForPixel(scale.left + offset)).toBeCloseToTime({
value: moment(ticks[i].label + '-01-01'),
unit: 'day',
- threshold: 0.5,
+ threshold: 1,
});
}
});
@@ -700,10 +701,9 @@ describe('Time scale tests', function() {
it('should get the correct labels for ticks', function() {
var scale = this.scale;
- expect(scale._ticks.map(function(tick) {
- return tick.major;
- })).toEqual([true, false, false, false, false, false, true]);
- expect(scale.ticks).toEqual(['<8:00:00>', '<8:00:10>', '<8:00:20>', '<8:00:30>', '<8:00:40>', '<8:00:50>', '<8:01:00>']);
+ expect(scale.ticks.length).toEqual(61);
+ expect(scale.ticks[0]).toEqual('<8:00:00>');
+ expect(scale.ticks[scale.ticks.length - 1]).toEqual('<8:01:00>');
});
it('should update ticks.callback correctly', function() {
@@ -714,7 +714,9 @@ describe('Time scale tests', function() {
return '{' + value + '}';
};
chart.update();
- expect(scale.ticks).toEqual(['{8:00:00}', '{8:00:10}', '{8:00:20}', '{8:00:30}', '{8:00:40}', '{8:00:50}', '{8:01:00}']);
+ expect(scale.ticks.length).toEqual(61);
+ expect(scale.ticks[0]).toEqual('{8:00:00}');
+ expect(scale.ticks[scale.ticks.length - 1]).toEqual('{8:01:00}');
});
});
@@ -760,10 +762,10 @@ describe('Time scale tests', function() {
it('should get the correct labels for major and minor ticks', function() {
var scale = this.scale;
- expect(scale._ticks.map(function(tick) {
- return tick.major;
- })).toEqual([true, false, false, false, false, false, true]);
- expect(scale.ticks).toEqual(['[[8:00 pm]]', '(8:00:10 pm)', '(8:00:20 pm)', '(8:00:30 pm)', '(8:00:40 pm)', '(8:00:50 pm)', '[[8:01 pm]]']);
+ expect(scale.ticks.length).toEqual(61);
+ expect(scale.ticks[0]).toEqual('[[8:00 pm]]');
+ expect(scale.ticks[Math.floor(scale.ticks.length / 2)]).toEqual('(8:00:30 pm)');
+ expect(scale.ticks[scale.ticks.length - 1]).toEqual('[[8:01 pm]]');
});
it('should only use ticks.minor callback if ticks.major.enabled is false', function() {
@@ -772,7 +774,9 @@ describe('Time scale tests', function() {
chart.options.scales.xAxes[0].ticks.major.enabled = false;
chart.update();
- expect(scale.ticks).toEqual(['(8:00:00 pm)', '(8:00:10 pm)', '(8:00:20 pm)', '(8:00:30 pm)', '(8:00:40 pm)', '(8:00:50 pm)', '(8:01:00 pm)']);
+ expect(scale.ticks.length).toEqual(61);
+ expect(scale.ticks[0]).toEqual('(8:00:00 pm)');
+ expect(scale.ticks[scale.ticks.length - 1]).toEqual('(8:01:00 pm)');
});
it('should use ticks.callback if ticks.major.callback is omitted', function() {
@@ -781,7 +785,9 @@ describe('Time scale tests', function() {
chart.options.scales.xAxes[0].ticks.major.callback = undefined;
chart.update();
- expect(scale.ticks).toEqual(['<8:00 pm>', '(8:00:10 pm)', '(8:00:20 pm)', '(8:00:30 pm)', '(8:00:40 pm)', '(8:00:50 pm)', '<8:01 pm>']);
+ expect(scale.ticks.length).toEqual(61);
+ expect(scale.ticks[0]).toEqual('<8:00 pm>');
+ expect(scale.ticks[scale.ticks.length - 1]).toEqual('<8:01 pm>');
});
it('should use ticks.callback if ticks.minor.callback is omitted', function() {
@@ -790,7 +796,10 @@ describe('Time scale tests', function() {
chart.options.scales.xAxes[0].ticks.minor.callback = undefined;
chart.update();
- expect(scale.ticks).toEqual(['[[8:00 pm]]', '<8:00:10 pm>', '<8:00:20 pm>', '<8:00:30 pm>', '<8:00:40 pm>', '<8:00:50 pm>', '[[8:01 pm]]']);
+ expect(scale.ticks.length).toEqual(61);
+ expect(scale.ticks[0]).toEqual('[[8:00 pm]]');
+ expect(scale.ticks[Math.floor(scale.ticks.length / 2)]).toEqual('<8:00:30 pm>');
+ expect(scale.ticks[scale.ticks.length - 1]).toEqual('[[8:01 pm]]');
});
});
@@ -1766,6 +1775,52 @@ describe('Time scale tests', function() {
});
});
+ it('should handle autoskip with major and minor ticks', function() {
+ var date = moment('Jan 01 1990', 'MMM DD YYYY');
+ var data = [];
+ for (var i = 0; i < 60; i++) {
+ data.push({x: date.valueOf(), y: Math.random()});
+ date = date.clone().add(1, 'month');
+ }
+
+ var chart = window.acquireChart({
+ type: 'line',
+ data: {
+ datasets: [{
+ xAxisID: 'xScale0',
+ data: data
+ }],
+ },
+ options: {
+ scales: {
+ xAxes: [{
+ id: 'xScale0',
+ type: 'time',
+ ticks: {
+ major: {
+ enabled: true
+ },
+ source: 'data',
+ autoSkip: true
+ }
+ }],
+ }
+ }
+ });
+
+ var scale = chart.scales.xScale0;
+
+ var labels = scale._ticksToDraw.map(function(t) {
+ return t.label;
+ });
+ expect(labels).toEqual([
+ '1990', 'Apr 1990', 'Jul 1990', 'Oct 1990',
+ '1991', 'Apr 1991', 'Jul 1991', 'Oct 1991',
+ '1992', 'Apr 1992', 'Jul 1992', 'Oct 1992',
+ '1993', 'Apr 1993', 'Jul 1993', 'Oct 1993',
+ '1994', 'Apr 1994', 'Jul 1994', 'Oct 1994']);
+ });
+
describe('Deprecations', function() {
describe('options.time.displayFormats', function() {
it('should generate defaults from adapter presets', function() {