Make all ticks objects (#6645)

Make all ticks object
This commit is contained in:
Ben McCann 2019-10-31 15:45:13 -07:00 committed by Evert Timberg
parent ae7a3c27a3
commit 99811328dc
21 changed files with 300 additions and 320 deletions

View File

@ -4,4 +4,7 @@ env:
browser: true
node: true
parserOptions:
ecmaVersion: 6
plugins: ['html']

View File

@ -31,7 +31,7 @@ There are a number of config callbacks that can be used to change parameters in
| `beforeDataLimits` | `axis` | Callback that runs before data limits are determined.
| `afterDataLimits` | `axis` | Callback that runs after data limits are determined.
| `beforeBuildTicks` | `axis` | Callback that runs before ticks are created.
| `afterBuildTicks` | `axis`, `ticks` | Callback that runs after ticks are created. Useful for filtering ticks. Should return the filtered ticks.
| `afterBuildTicks` | `axis` | Callback that runs after ticks are created. Useful for filtering ticks.
| `beforeTickToLabelConversion` | `axis` | Callback that runs before ticks are converted into strings.
| `afterTickToLabelConversion` | `axis` | Callback that runs after ticks are converted into strings.
| `beforeCalculateTickRotation` | `axis` | Callback that runs before tick rotation is determined.

View File

@ -43,13 +43,18 @@ Chart.js 3.0 introduces a number of breaking changes. Chart.js 2.0 was released
* `helpers.aliasPixel`
* `helpers.configMerge`
* `helpers.indexOf`
* `helpers.min`
* `helpers.max`
* `helpers.numberOfLabelLines`
* `helpers.removeEvent`
* `helpers.scaleMerge`
* `scale.mergeTicksOptions`
* `scale.ticksAsNumbers`
* `Chart.Controller`
* `Chart.chart.chart`
* `Chart.types`
* Made `scale.handleDirectionalChanges` private
* Made `scale.tickValues` private
### Renamed
@ -65,6 +70,13 @@ Chart.js 3.0 introduces a number of breaking changes. Chart.js 2.0 was released
### Changed
#### Ticks
* `scale.ticks` now contains objects instead of strings
* `buildTicks` is now expected to return tick objects
* `afterBuildTicks` now has no parameters like the other callbacks
* `convertTicksToLabels` was renamed to `generateTickLabels`. It is now expected to set the label property on the ticks given as input
#### Time Scale
* `getValueForPixel` now returns milliseconds since the epoch

View File

@ -130,8 +130,9 @@
maxRotation: 0,
sampleSize: 100
},
afterBuildTicks: function(scale, ticks) {
afterBuildTicks: function(scale) {
var majorUnit = scale._majorUnit;
var ticks = scale.ticks;
var firstTick = ticks[0];
var i, ilen, val, tick, currMajor, lastMajor;
@ -154,7 +155,6 @@
tick.major = currMajor !== lastMajor;
lastMajor = currMajor;
}
return ticks;
}
}],
yAxes: [{

View File

@ -71,21 +71,27 @@ module.exports = function() {
var rounded = Math.round(x);
return ((rounded - epsilon) <= x) && ((rounded + epsilon) >= x);
};
helpers.max = function(array) {
return array.reduce(function(max, value) {
helpers._setMinAndMax = function(array, target) {
var i, ilen, value;
for (i = 0, ilen = array.length; i < ilen; i++) {
value = array[i];
if (!isNaN(value)) {
return Math.max(max, value);
target.min = Math.min(target.min, value);
target.max = Math.max(target.max, value);
}
return max;
}, Number.NEGATIVE_INFINITY);
}
};
helpers.min = function(array) {
return array.reduce(function(min, value) {
helpers._setMinAndMaxByKey = function(array, target, property) {
var i, ilen, value;
for (i = 0, ilen = array.length; i < ilen; i++) {
value = array[i][property];
if (!isNaN(value)) {
return Math.min(min, value);
target.min = Math.min(target.min, value);
target.max = Math.max(target.max, value);
}
return min;
}, Number.POSITIVE_INFINITY);
}
};
helpers.sign = Math.sign ?
function(x) {

View File

@ -81,7 +81,7 @@ function sample(arr, numItems) {
}
function getPixelForGridLine(scale, index, offsetGridLines) {
var length = scale.getTicks().length;
var length = scale.ticks.length;
var validIndex = Math.min(index, length - 1);
var lineValue = scale.getPixelForTick(validIndex);
var start = scale._startPixel;
@ -348,7 +348,7 @@ var Scale = Element.extend({
* @since 2.7
*/
getTicks: function() {
return this._ticks;
return this.ticks;
},
/**
@ -379,7 +379,7 @@ var Scale = Element.extend({
var me = this;
var tickOpts = me.options.ticks;
var sampleSize = tickOpts.sampleSize;
var i, ilen, labels, ticks, samplingEnabled;
var samplingEnabled;
// Update Lifecycle - Probably don't want to ever extend or overwrite this function ;)
me.beforeUpdate();
@ -394,7 +394,6 @@ var Scale = Element.extend({
bottom: 0
}, margins);
me._ticks = null;
me.ticks = null;
me._labelSizes = null;
me._maxLabelLines = 0;
@ -413,39 +412,17 @@ var Scale = Element.extend({
me.determineDataLimits();
me.afterDataLimits();
// Ticks - `this.ticks` is now DEPRECATED!
// Internal ticks are now stored as objects in the PRIVATE `this._ticks` member
// and must not be accessed directly from outside this class. `this.ticks` being
// around for long time and not marked as private, we can't change its structure
// without unexpected breaking changes. If you need to access the scale ticks,
// use scale.getTicks() instead.
me.beforeBuildTicks();
// New implementations should return an array of objects but for BACKWARD COMPAT,
// we still support no return (`this.ticks` internally set by calling this method).
ticks = me.buildTicks() || [];
me.ticks = me.buildTicks() || [];
// Allow modification of ticks in callback.
ticks = me.afterBuildTicks(ticks) || ticks;
// Ensure ticks contains ticks in new tick format
if ((!ticks || !ticks.length) && me.ticks) {
ticks = [];
for (i = 0, ilen = me.ticks.length; i < ilen; ++i) {
ticks.push({
value: me.ticks[i],
major: false
});
}
}
me._ticks = ticks;
me.afterBuildTicks();
// Compute tick rotation and fit using a sampled subset of labels
// We generally don't need to compute the size of every single label for determining scale size
samplingEnabled = sampleSize < ticks.length;
labels = me._convertTicksToLabels(samplingEnabled ? sample(ticks, sampleSize) : ticks);
samplingEnabled = sampleSize < me.ticks.length;
me._convertTicksToLabels(samplingEnabled ? sample(me.ticks, sampleSize) : me.ticks);
// _configure is called twice, once here, once from core.controller.updateLayout.
// Here we haven't been positioned yet, but dimensions are correct.
@ -463,15 +440,13 @@ var Scale = Element.extend({
me.afterFit();
// Auto-skip
me._ticksToDraw = tickOpts.display && (tickOpts.autoSkip || tickOpts.source === 'auto') ? me._autoSkip(ticks) : ticks;
me._ticksToDraw = tickOpts.display && (tickOpts.autoSkip || tickOpts.source === 'auto') ? me._autoSkip(me.ticks) : me.ticks;
if (samplingEnabled) {
// Generate labels using all non-skipped ticks
labels = me._convertTicksToLabels(me._ticksToDraw);
me._convertTicksToLabels(me._ticksToDraw);
}
me.ticks = labels; // BACKWARD COMPATIBILITY
// IMPORTANT: after this point, we consider that `this.ticks` will NEVER change!
me.afterUpdate();
@ -553,25 +528,24 @@ var Scale = Element.extend({
helpers.callback(this.options.beforeBuildTicks, [this]);
},
buildTicks: helpers.noop,
afterBuildTicks: function(ticks) {
var me = this;
// ticks is empty for old axis implementations here
if (isArray(ticks) && ticks.length) {
return helpers.callback(me.options.afterBuildTicks, [me, ticks]);
}
// Support old implementations (that modified `this.ticks` directly in buildTicks)
me.ticks = helpers.callback(me.options.afterBuildTicks, [me, me.ticks]) || me.ticks;
return ticks;
afterBuildTicks: function() {
helpers.callback(this.options.afterBuildTicks, [this]);
},
beforeTickToLabelConversion: function() {
helpers.callback(this.options.beforeTickToLabelConversion, [this]);
},
convertTicksToLabels: function() {
/**
* Convert ticks to label strings
*/
generateTickLabels: function(ticks) {
var me = this;
// Convert ticks to strings
var tickOpts = me.options.ticks;
me.ticks = me.ticks.map(tickOpts.callback, this);
var i, ilen, tick;
for (i = 0, ilen = ticks.length; i < ilen; i++) {
tick = ticks[i];
tick.label = helpers.callback(tickOpts.callback, [tick.value, i, ticks], me);
}
},
afterTickToLabelConversion: function() {
helpers.callback(this.options.afterTickToLabelConversion, [this]);
@ -586,7 +560,7 @@ var Scale = Element.extend({
var me = this;
var options = me.options;
var tickOpts = options.ticks;
var numTicks = me.getTicks().length;
var numTicks = me.ticks.length;
var minRotation = tickOpts.minRotation || 0;
var maxRotation = tickOpts.maxRotation;
var labelRotation = minRotation;
@ -686,7 +660,7 @@ var Scale = Element.extend({
minSize.height = Math.min(me.maxHeight, minSize.height + labelHeight + tickPadding);
var offsetLeft = me.getPixelForTick(0) - me.left;
var offsetRight = me.right - me.getPixelForTick(me.getTicks().length - 1);
var offsetRight = me.right - me.getPixelForTick(me.ticks.length - 1);
var paddingLeft, paddingRight;
// Ensure that our ticks are always inside the canvas. When rotated, ticks are right aligned
@ -788,27 +762,12 @@ var Scale = Element.extend({
_convertTicksToLabels: function(ticks) {
var me = this;
var labels, i, ilen;
me.ticks = ticks.map(function(tick) {
return tick.value;
});
me.beforeTickToLabelConversion();
// New implementations should return the formatted tick labels but for BACKWARD
// COMPAT, we still support no return (`this.ticks` internally changed by calling
// this method and supposed to contain only string values).
labels = me.convertTicksToLabels(ticks) || me.ticks;
me.generateTickLabels(ticks);
me.afterTickToLabelConversion();
// BACKWARD COMPAT: synchronize `_ticks` with labels (so potentially `this.ticks`)
for (i = 0, ilen = ticks.length; i < ilen; ++i) {
ticks[i].label = labels[i];
}
return labels;
},
/**
@ -819,7 +778,7 @@ var Scale = Element.extend({
var labelSizes = me._labelSizes;
if (!labelSizes) {
me._labelSizes = labelSizes = computeLabelSizes(me.ctx, parseTickFontOptions(me.options.ticks), me.getTicks(), me.longestTextCache);
me._labelSizes = labelSizes = computeLabelSizes(me.ctx, parseTickFontOptions(me.options.ticks), me.ticks, me.longestTextCache);
me.longestLabelWidth = labelSizes.widest.width;
}
@ -895,7 +854,7 @@ var Scale = Element.extend({
getPixelForTick: function(index) {
var me = this;
var offset = me.options.offset;
var numTicks = me._ticks.length;
var numTicks = me.ticks.length;
var tickWidth = 1 / Math.max(numTicks - (offset ? 0 : 1), 1);
return index < 0 || index > numTicks - 1

View File

@ -33,7 +33,7 @@ module.exports = {
*/
linear: function(tickValue, index, ticks) {
// If we have lots of ticks, don't use the ones
var delta = ticks.length > 3 ? ticks[2] - ticks[1] : ticks[1] - ticks[0];
var delta = ticks.length > 3 ? ticks[2].value - ticks[1].value : ticks[1].value - ticks[0].value;
// If we have a number like 2.5 as the delta, figure out how many decimal places we need
if (Math.abs(delta) > 1) {
@ -47,7 +47,7 @@ module.exports = {
var tickString = '';
if (tickValue !== 0) {
var maxTick = Math.max(Math.abs(ticks[0]), Math.abs(ticks[ticks.length - 1]));
var maxTick = Math.max(Math.abs(ticks[0].value), Math.abs(ticks[ticks.length - 1].value));
if (maxTick < 1e-4) { // all ticks are small numbers; use scientific notation
var logTick = math.log10(Math.abs(tickValue));
var numExponential = Math.floor(logTick) - Math.floor(logDelta);

View File

@ -49,7 +49,10 @@ module.exports = Scale.extend({
var maxIndex = me.maxIndex;
// If we are viewing some subset of labels, slice the original array
me.ticks = (minIndex === 0 && maxIndex === labels.length - 1) ? labels : labels.slice(minIndex, maxIndex + 1);
labels = (minIndex === 0 && maxIndex === labels.length - 1) ? labels : labels.slice(minIndex, maxIndex + 1);
return labels.map(function(l) {
return {value: l};
});
},
getLabelForIndex: function(index, datasetIndex) {

View File

@ -107,8 +107,7 @@ module.exports = LinearScaleBase.extend({
helpers.each(stacks, function(stackValues) {
values = stackValues.pos.concat(stackValues.neg);
me.min = Math.min(me.min, helpers.min(values));
me.max = Math.max(me.max, helpers.max(values));
helpers._setMinAndMax(values, me);
});
me.min = helpers.isFinite(me.min) && !isNaN(me.min) ? me.min : DEFAULT_MIN;
@ -130,12 +129,13 @@ module.exports = LinearScaleBase.extend({
return Math.ceil(me.height / tickFont.lineHeight);
},
// Called after the ticks are built. We need
handleDirectionalChanges: function() {
if (!this.isHorizontal()) {
// We are in a vertical orientation. The top value is the highest. So reverse the array
this.ticks.reverse();
}
/**
* Called after the ticks are built
* @private
*/
_handleDirectionalChanges: function(ticks) {
// If we are in a vertical orientation the top value is the highest so reverse the array
return this.isHorizontal() ? ticks : ticks.reverse();
},
getLabelForIndex: function(index, datasetIndex) {
@ -153,7 +153,7 @@ module.exports = LinearScaleBase.extend({
},
getPixelForTick: function(index) {
var ticks = this.ticksAsNumbers;
var ticks = this._tickValues;
if (index < 0 || index > ticks.length - 1) {
return null;
}

View File

@ -3,7 +3,6 @@
var helpers = require('../helpers/index');
var Scale = require('../core/core.scale');
var noop = helpers.noop;
var isNullOrUndef = helpers.isNullOrUndef;
/**
@ -33,7 +32,7 @@ function generateTicks(generationOptions, dataRange) {
// Beyond MIN_SPACING floating point numbers being to lose precision
// such that we can't do the math necessary to generate ticks
if (spacing < MIN_SPACING && isNullOrUndef(min) && isNullOrUndef(max)) {
return [rmin, rmax];
return [{value: rmin}, {value: rmax}];
}
numSpaces = Math.ceil(rmax / spacing) - Math.floor(rmin / spacing);
@ -75,11 +74,11 @@ function generateTicks(generationOptions, dataRange) {
niceMin = Math.round(niceMin * factor) / factor;
niceMax = Math.round(niceMax * factor) / factor;
ticks.push(isNullOrUndef(min) ? niceMin : min);
ticks.push({value: isNullOrUndef(min) ? niceMin : min});
for (var j = 1; j < numSpaces; ++j) {
ticks.push(Math.round((niceMin + j * spacing) * factor) / factor);
ticks.push({value: Math.round((niceMin + j * spacing) * factor) / factor});
}
ticks.push(isNullOrUndef(max) ? niceMax : max);
ticks.push({value: isNullOrUndef(max) ? niceMax : max});
return ticks;
}
@ -184,7 +183,9 @@ module.exports = Scale.extend({
return Number.POSITIVE_INFINITY;
},
handleDirectionalChanges: noop,
_handleDirectionalChanges: function(ticks) {
return ticks;
},
buildTicks: function() {
var me = this;
@ -205,14 +206,13 @@ module.exports = Scale.extend({
precision: tickOpts.precision,
stepSize: helpers.valueOrDefault(tickOpts.fixedStepSize, tickOpts.stepSize)
};
var ticks = me.ticks = generateTicks(numericGeneratorOptions, me);
var ticks = generateTicks(numericGeneratorOptions, me);
me.handleDirectionalChanges();
ticks = me._handleDirectionalChanges(ticks);
// At this point, we need to update our max and min given the tick values since we have expanded the
// range of the scale
me.max = helpers.max(ticks);
me.min = helpers.min(ticks);
helpers._setMinAndMaxByKey(ticks, me, 'value');
if (tickOpts.reverse) {
ticks.reverse();
@ -223,14 +223,16 @@ module.exports = Scale.extend({
me.start = me.min;
me.end = me.max;
}
return ticks;
},
convertTicksToLabels: function() {
generateTickLabels: function(ticks) {
var me = this;
me.ticksAsNumbers = me.ticks.slice();
me.zeroLineIndex = me.ticks.indexOf(0);
me._tickValues = ticks.map(t => t.value);
me.zeroLineIndex = me._tickValues.indexOf(0);
Scale.prototype.convertTicksToLabels.call(me);
Scale.prototype.generateTickLabels.call(me, ticks);
},
_configure: function() {

View File

@ -27,7 +27,7 @@ function generateTicks(generationOptions, dataRange) {
exp = Math.floor(log10(dataRange.minNotZero));
significand = Math.floor(dataRange.minNotZero / Math.pow(10, exp));
ticks.push(tickVal);
ticks.push({value: tickVal});
tickVal = significand * Math.pow(10, exp);
} else {
exp = Math.floor(log10(tickVal));
@ -36,7 +36,7 @@ function generateTicks(generationOptions, dataRange) {
var precision = exp < 0 ? Math.pow(10, Math.abs(exp)) : 1;
do {
ticks.push(tickVal);
ticks.push({value: tickVal});
++significand;
if (significand === 10) {
@ -49,7 +49,7 @@ function generateTicks(generationOptions, dataRange) {
} while (exp < endExp || (exp === endExp && significand < endSignificand));
var lastTick = valueOrDefault(generationOptions.max, tickVal);
ticks.push(lastTick);
ticks.push({value: lastTick});
return ticks;
}
@ -130,10 +130,7 @@ module.exports = Scale.extend({
helpers.each(valuesPerStack, function(valuesForType) {
if (valuesForType.length > 0) {
var minVal = helpers.min(valuesForType);
var maxVal = helpers.max(valuesForType);
me.min = Math.min(me.min, minVal);
me.max = Math.max(me.max, maxVal);
helpers._setMinAndMax(valuesForType, me);
}
});
@ -214,12 +211,11 @@ module.exports = Scale.extend({
min: nonNegativeOrDefault(tickOpts.min),
max: nonNegativeOrDefault(tickOpts.max)
};
var ticks = me.ticks = generateTicks(generationOptions, me);
var ticks = generateTicks(generationOptions, me);
// At this point, we need to update our max and min given the tick values since we have expanded the
// range of the scale
me.max = helpers.max(ticks);
me.min = helpers.min(ticks);
helpers._setMinAndMaxByKey(ticks, me, 'value');
if (tickOpts.reverse) {
reverse = !reverse;
@ -232,12 +228,13 @@ module.exports = Scale.extend({
if (reverse) {
ticks.reverse();
}
return ticks;
},
convertTicksToLabels: function() {
this.tickValues = this.ticks.slice();
generateTickLabels: function(ticks) {
this._tickValues = ticks.map(t => t.value);
Scale.prototype.convertTicksToLabels.call(this);
return Scale.prototype.generateTickLabels.call(this, ticks);
},
// Get the correct tooltip label
@ -246,7 +243,7 @@ module.exports = Scale.extend({
},
getPixelForTick: function(index) {
var ticks = this.tickValues;
var ticks = this._tickValues;
if (index < 0 || index > ticks.length - 1) {
return null;
}

View File

@ -337,10 +337,10 @@ module.exports = LinearScaleBase.extend({
return Math.ceil(this.drawingArea / getTickBackdropHeight(this.options));
},
convertTicksToLabels: function() {
generateTickLabels: function(ticks) {
var me = this;
LinearScaleBase.prototype.convertTicksToLabels.call(me);
LinearScaleBase.prototype.generateTickLabels.call(me, ticks);
// Point labels
me.pointLabels = me.chart.data.labels.map(function() {
@ -467,9 +467,9 @@ module.exports = LinearScaleBase.extend({
}
if (gridLineOpts.display) {
helpers.each(me.ticks, function(label, index) {
helpers.each(me.ticks, function(tick, index) {
if (index !== 0) {
offset = me.getDistanceFromCenterForValue(me.ticksAsNumbers[index]);
offset = me.getDistanceFromCenterForValue(me._tickValues[index]);
drawRadiusLine(me, gridLineOpts, offset, index);
}
});
@ -522,15 +522,15 @@ module.exports = LinearScaleBase.extend({
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
helpers.each(me.ticks, function(label, index) {
helpers.each(me.ticks, function(tick, index) {
if (index === 0 && !tickOpts.reverse) {
return;
}
offset = me.getDistanceFromCenterForValue(me.ticksAsNumbers[index]);
offset = me.getDistanceFromCenterForValue(me._tickValues[index]);
if (tickOpts.showLabelBackdrop) {
width = ctx.measureText(label).width;
width = ctx.measureText(tick.label).width;
ctx.fillStyle = tickOpts.backdropColor;
ctx.fillRect(
@ -542,7 +542,7 @@ module.exports = LinearScaleBase.extend({
}
ctx.fillStyle = tickFontColor;
ctx.fillText(label, 0, -offset);
ctx.fillText(tick.label, 0, -offset);
});
ctx.restore();

View File

@ -621,15 +621,13 @@ module.exports = Scale.extend({
return formatter ? formatter(label, index, ticks) : label;
},
convertTicksToLabels: function(ticks) {
var labels = [];
var i, ilen;
generateTickLabels: function(ticks) {
var i, ilen, tick;
for (i = 0, ilen = ticks.length; i < ilen; ++i) {
labels.push(this.tickFormatFunction(ticks[i].value, i, ticks));
tick = ticks[i];
tick.label = this.tickFormatFunction(tick.value, i, ticks);
}
return labels;
},
/**

View File

@ -1,3 +1,7 @@
function getLabels(scale) {
return scale.ticks.map(t => t.label);
}
describe('Chart.layouts', function() {
it('should be exposed through Chart.layouts', function() {
expect(Chart.layouts).toBeDefined();
@ -651,7 +655,7 @@ describe('Chart.layouts', function() {
// issue #4441: y-axis labels partially hidden.
// minimum horizontal space required to fit labels
expect(yAxis.width).toBeCloseToPixel(33);
expect(yAxis.ticks).toEqual(['2.5', '2.0', '1.5', '1.0', '0.5', '0']);
expect(getLabels(yAxis)).toEqual(['2.5', '2.0', '1.5', '1.0', '0.5', '0']);
});
});
});

View File

@ -1,3 +1,7 @@
function getLabels(scale) {
return scale.ticks.map(t => t.label);
}
describe('Core.scale', function() {
describe('auto', jasmine.fixture.specs('core.scale'));
@ -390,8 +394,8 @@ describe('Core.scale', function() {
id: 'x',
type: 'category',
labels: labels,
afterBuildTicks: function(axis, ticks) {
return ticks.slice(1);
afterBuildTicks: function(scale) {
scale.ticks = scale.ticks.slice(1);
}
}]
}
@ -399,36 +403,7 @@ describe('Core.scale', function() {
});
var scale = chart.scales.x;
expect(scale.ticks).toEqual(labels.slice(1));
});
it('should allow filtering of ticks (for new implementation of buildTicks)', function() {
var chart = window.acquireChart({
type: 'line',
data: {
labels: ['2016', '2017', '2018']
},
options: {
scales: {
xAxes: [{
id: 'x',
type: 'time',
time: {
parser: 'YYYY'
},
ticks: {
source: 'labels'
},
afterBuildTicks: function(axis, ticks) {
return ticks.slice(1);
}
}]
}
}
});
var scale = chart.scales.x;
expect(scale.ticks.length).toEqual(2);
expect(getLabels(scale)).toEqual(labels.slice(1));
});
it('should allow no return value from callback', function() {
@ -448,7 +423,7 @@ describe('Core.scale', function() {
});
var scale = chart.scales.x;
expect(scale.ticks).toEqual(labels);
expect(getLabels(scale)).toEqual(labels);
});
it('should allow empty ticks', function() {
@ -461,8 +436,8 @@ describe('Core.scale', function() {
id: 'x',
type: 'category',
labels: labels,
afterBuildTicks: function() {
return [];
afterBuildTicks: function(scale) {
scale.ticks = [];
}
}]
}

View File

@ -1,3 +1,7 @@
function getLabels(scale) {
return scale.ticks.map(t => t.label);
}
describe('Test tick generators', function() {
// formatters are used as default config values so users want to be able to reference them
it('Should expose formatters api', function() {
@ -42,11 +46,11 @@ describe('Test tick generators', function() {
}
});
var xAxis = chart.scales['x-axis-0'];
var yAxis = chart.scales['y-axis-0'];
var xLabels = getLabels(chart.scales['x-axis-0']);
var yLabels = getLabels(chart.scales['y-axis-0']);
expect(xAxis.ticks).toEqual(['0', '0.1', '0.2', '0.3', '0.4', '0.5', '0.6', '0.7', '0.8', '0.9', '1']);
expect(yAxis.ticks).toEqual(['1', '0.9', '0.8', '0.7', '0.6', '0.5', '0.4', '0.3', '0.2', '0.1', '0']);
expect(xLabels).toEqual(['0', '0.1', '0.2', '0.3', '0.4', '0.5', '0.6', '0.7', '0.8', '0.9', '1']);
expect(yLabels).toEqual(['1', '0.9', '0.8', '0.7', '0.6', '0.5', '0.4', '0.3', '0.2', '0.1', '0']);
});
it('Should generate logarithmic spaced ticks with correct precision', function() {
@ -87,10 +91,10 @@ describe('Test tick generators', function() {
}
});
var xAxis = chart.scales['x-axis-0'];
var yAxis = chart.scales['y-axis-0'];
var xLabels = getLabels(chart.scales['x-axis-0']);
var yLabels = getLabels(chart.scales['y-axis-0']);
expect(xAxis.ticks).toEqual(['0.1', '0.2', '0.3', '0.4', '0.5', '0.6', '0.7', '0.8', '0.9', '1']);
expect(yAxis.ticks).toEqual(['1', '0.9', '0.8', '0.7', '0.6', '0.5', '0.4', '0.3', '0.2', '0.1']);
expect(xLabels).toEqual(['0.1', '0.2', '0.3', '0.4', '0.5', '0.6', '0.7', '0.8', '0.9', '1']);
expect(yLabels).toEqual(['1', '0.9', '0.8', '0.7', '0.6', '0.5', '0.4', '0.3', '0.2', '0.1']);
});
});

View File

@ -1,5 +1,13 @@
// Test the category scale
function getLabels(scale) {
return scale.ticks.map(t => t.label);
}
function getValues(scale) {
return scale.ticks.map(t => t.value);
}
describe('Category scale tests', function() {
it('Should register the constructor with the scale service', function() {
var Constructor = Chart.scaleService.getScaleConstructor('category');
@ -75,8 +83,8 @@ describe('Category scale tests', function() {
});
scale.determineDataLimits();
scale.buildTicks();
expect(scale.ticks).toEqual(mockData.labels);
scale.ticks = scale.buildTicks();
expect(getValues(scale)).toEqual(mockData.labels);
});
it('Should generate ticks from the data xLabels', function() {
@ -102,8 +110,8 @@ describe('Category scale tests', function() {
});
scale.determineDataLimits();
scale.buildTicks();
expect(scale.ticks).toEqual(mockData.xLabels);
scale.ticks = scale.buildTicks();
expect(getValues(scale)).toEqual(mockData.xLabels);
});
it('Should generate ticks from the data yLabels', function() {
@ -130,8 +138,8 @@ describe('Category scale tests', function() {
});
scale.determineDataLimits();
scale.buildTicks();
expect(scale.ticks).toEqual(mockData.yLabels);
scale.ticks = scale.buildTicks();
expect(getValues(scale)).toEqual(mockData.yLabels);
});
it('Should generate ticks from the axis labels', function() {
@ -153,7 +161,7 @@ describe('Category scale tests', function() {
});
var scale = chart.scales.x;
expect(scale.ticks).toEqual(labels);
expect(getLabels(scale)).toEqual(labels);
});
it('should get the correct label for the index', function() {

View File

@ -1,3 +1,7 @@
function getLabels(scale) {
return scale.ticks.map(t => t.label);
}
describe('Linear Scale', function() {
it('Should register the constructor with the scale service', function() {
var Constructor = Chart.scaleService.getScaleConstructor('linear');
@ -538,8 +542,9 @@ describe('Linear Scale', function() {
expect(chart.scales.yScale0).not.toEqual(undefined); // must construct
expect(chart.scales.yScale0.min).toBe(-1010);
expect(chart.scales.yScale0.max).toBe(1010);
expect(chart.scales.yScale0.ticks[0]).toBe('1010');
expect(chart.scales.yScale0.ticks[chart.scales.yScale0.ticks.length - 1]).toBe('-1010');
var labels = getLabels(chart.scales.yScale0);
expect(labels[0]).toBe('1010');
expect(labels[labels.length - 1]).toBe('-1010');
});
it('Should use min, max and stepSize to create fixed spaced ticks', function() {
@ -570,7 +575,7 @@ describe('Linear Scale', function() {
expect(chart.scales.yScale0).not.toEqual(undefined); // must construct
expect(chart.scales.yScale0.min).toBe(1);
expect(chart.scales.yScale0.max).toBe(11);
expect(chart.scales.yScale0.ticks).toEqual(['11', '10', '8', '6', '4', '2', '1']);
expect(getLabels(chart.scales.yScale0)).toEqual(['11', '10', '8', '6', '4', '2', '1']);
});
it('Should create decimal steps if stepSize is a decimal number', function() {
@ -599,7 +604,7 @@ describe('Linear Scale', function() {
expect(chart.scales.yScale0).not.toEqual(undefined); // must construct
expect(chart.scales.yScale0.min).toBe(0);
expect(chart.scales.yScale0.max).toBe(10);
expect(chart.scales.yScale0.ticks).toEqual(['10', '7.5', '5', '2.5', '0']);
expect(getLabels(chart.scales.yScale0)).toEqual(['10', '7.5', '5', '2.5', '0']);
});
describe('precision', function() {
@ -629,7 +634,7 @@ describe('Linear Scale', function() {
expect(chart.scales.yScale0).not.toEqual(undefined); // must construct
expect(chart.scales.yScale0.min).toBe(0);
expect(chart.scales.yScale0.max).toBe(2);
expect(chart.scales.yScale0.ticks).toEqual(['2', '1', '0']);
expect(getLabels(chart.scales.yScale0)).toEqual(['2', '1', '0']);
});
it('Should round the step size to the given number of decimal places', function() {
@ -658,7 +663,7 @@ describe('Linear Scale', function() {
expect(chart.scales.yScale0).not.toEqual(undefined); // must construct
expect(chart.scales.yScale0.min).toBe(0);
expect(chart.scales.yScale0.max).toBe(0.01);
expect(chart.scales.yScale0.ticks).toEqual(['0.01', '0']);
expect(getLabels(chart.scales.yScale0)).toEqual(['0.01', '0']);
});
});
@ -684,19 +689,19 @@ describe('Linear Scale', function() {
});
expect(chart.scales.yScale0).not.toEqual(undefined); // must construct
expect(chart.scales.yScale0.ticks).toEqual(['50', '45', '40', '35', '30', '25', '20']);
expect(getLabels(chart.scales.yScale0)).toEqual(['50', '45', '40', '35', '30', '25', '20']);
chart.scales.yScale0.options.ticks.beginAtZero = true;
chart.update();
expect(chart.scales.yScale0.ticks).toEqual(['50', '45', '40', '35', '30', '25', '20', '15', '10', '5', '0']);
expect(getLabels(chart.scales.yScale0)).toEqual(['50', '45', '40', '35', '30', '25', '20', '15', '10', '5', '0']);
chart.data.datasets[0].data = [-20, -30, -40, -50];
chart.update();
expect(chart.scales.yScale0.ticks).toEqual(['0', '-5', '-10', '-15', '-20', '-25', '-30', '-35', '-40', '-45', '-50']);
expect(getLabels(chart.scales.yScale0)).toEqual(['0', '-5', '-10', '-15', '-20', '-25', '-30', '-35', '-40', '-45', '-50']);
chart.scales.yScale0.options.ticks.beginAtZero = false;
chart.update();
expect(chart.scales.yScale0.ticks).toEqual(['-20', '-25', '-30', '-35', '-40', '-45', '-50']);
expect(getLabels(chart.scales.yScale0)).toEqual(['-20', '-25', '-30', '-35', '-40', '-45', '-50']);
});
it('Should generate tick marks in the correct order in reversed mode', function() {
@ -722,7 +727,7 @@ describe('Linear Scale', function() {
}
});
expect(chart.scales.yScale0.ticks).toEqual(['0', '10', '20', '30', '40', '50', '60', '70', '80']);
expect(getLabels(chart.scales.yScale0)).toEqual(['0', '10', '20', '30', '40', '50', '60', '70', '80']);
expect(chart.scales.yScale0.start).toBe(80);
expect(chart.scales.yScale0.end).toBe(0);
});
@ -746,7 +751,7 @@ describe('Linear Scale', function() {
}
}
});
expect(chart.scales.yScale0.ticks).toEqual(['0.06', '0.05', '0.04', '0.03', '0.02', '0.01', '0']);
expect(getLabels(chart.scales.yScale0)).toEqual(['0.06', '0.05', '0.04', '0.03', '0.02', '0.01', '0']);
});
it('Should correctly limit the maximum number of ticks', function() {
@ -767,17 +772,17 @@ describe('Linear Scale', function() {
}
});
expect(chart.scales.yScale.ticks).toEqual(['2.5', '2.0', '1.5', '1.0', '0.5']);
expect(getLabels(chart.scales.yScale)).toEqual(['2.5', '2.0', '1.5', '1.0', '0.5']);
chart.options.scales.yAxes[0].ticks.maxTicksLimit = 11;
chart.update();
expect(chart.scales.yScale.ticks).toEqual(['2.5', '2.0', '1.5', '1.0', '0.5']);
expect(getLabels(chart.scales.yScale)).toEqual(['2.5', '2.0', '1.5', '1.0', '0.5']);
chart.options.scales.yAxes[0].ticks.maxTicksLimit = 21;
chart.update();
expect(chart.scales.yScale.ticks).toEqual([
expect(getLabels(chart.scales.yScale)).toEqual([
'2.5', '2.4', '2.3', '2.2', '2.1', '2.0', '1.9', '1.8', '1.7', '1.6',
'1.5', '1.4', '1.3', '1.2', '1.1', '1.0', '0.9', '0.8', '0.7', '0.6',
'0.5'
@ -787,13 +792,13 @@ describe('Linear Scale', function() {
chart.options.scales.yAxes[0].ticks.stepSize = 0.01;
chart.update();
expect(chart.scales.yScale.ticks).toEqual(['2.5', '2.0', '1.5', '1.0', '0.5']);
expect(getLabels(chart.scales.yScale)).toEqual(['2.5', '2.0', '1.5', '1.0', '0.5']);
chart.options.scales.yAxes[0].ticks.min = 0.3;
chart.options.scales.yAxes[0].ticks.max = 2.8;
chart.update();
expect(chart.scales.yScale.ticks).toEqual(['2.8', '2.5', '2.0', '1.5', '1.0', '0.5', '0.3']);
expect(getLabels(chart.scales.yScale)).toEqual(['2.8', '2.5', '2.0', '1.5', '1.0', '0.5', '0.3']);
});
it('Should build labels using the user supplied callback', function() {
@ -822,7 +827,7 @@ describe('Linear Scale', function() {
});
// Just the index
expect(chart.scales.yScale0.ticks).toEqual(['0', '1', '2', '3', '4', '5', '6', '7', '8']);
expect(getLabels(chart.scales.yScale0)).toEqual(['0', '1', '2', '3', '4', '5', '6', '7', '8']);
});
it('Should get the correct pixel value for a point', function() {

View File

@ -1,3 +1,7 @@
function getLabels(scale) {
return scale.ticks.map(t => t.label);
}
describe('Logarithmic Scale tests', function() {
it('should register the constructor with the scale service', function() {
var Constructor = Chart.scaleService.getScaleConstructor('logarithmic');
@ -473,8 +477,8 @@ describe('Logarithmic Scale tests', function() {
var tickCount = yScale.ticks.length;
expect(yScale.min).toBe(10);
expect(yScale.max).toBe(1010);
expect(yScale.ticks[0]).toBe(1010);
expect(yScale.ticks[tickCount - 1]).toBe(10);
expect(yScale.ticks[0].value).toBe(1010);
expect(yScale.ticks[tickCount - 1].value).toBe(10);
});
it('should ignore negative min and max options', function() {
@ -564,11 +568,10 @@ describe('Logarithmic Scale tests', function() {
});
// Counts down because the lines are drawn top to bottom
expect(chart.scales.yScale).toEqual(jasmine.objectContaining({
ticks: [80, 70, 60, 50, 40, 30, 20, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1],
start: 1,
end: 80
}));
var scale = chart.scales.yScale;
expect(getLabels(scale)).toEqual([80, 70, 60, 50, 40, 30, 20, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1]);
expect(scale.start).toEqual(1);
expect(scale.end).toEqual(80);
});
it('should generate tick marks when 0 values are present', function() {
@ -595,12 +598,11 @@ describe('Logarithmic Scale tests', function() {
}
});
var scale = chart.scales.yScale;
// Counts down because the lines are drawn top to bottom
expect(chart.scales.yScale).toEqual(jasmine.objectContaining({
ticks: [30, 20, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0.9, 0.8, 0],
start: 0,
end: 30
}));
expect(getLabels(scale)).toEqual([30, 20, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0.9, 0.8, 0]);
expect(scale.start).toEqual(0);
expect(scale.end).toEqual(30);
});
@ -629,12 +631,10 @@ describe('Logarithmic Scale tests', function() {
}
});
// Counts down because the lines are drawn top to bottom
expect(chart.scales.yScale).toEqual(jasmine.objectContaining({
ticks: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 20, 30, 40, 50, 60, 70, 80],
start: 80,
end: 1
}));
var scale = chart.scales.yScale;
expect(getLabels(scale)).toEqual([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 20, 30, 40, 50, 60, 70, 80]);
expect(scale.start).toEqual(80);
expect(scale.end).toEqual(1);
});
it('should generate tick marks in the correct order in reversed mode when 0 values are present', function() {
@ -662,12 +662,10 @@ describe('Logarithmic Scale tests', function() {
}
});
// Counts down because the lines are drawn top to bottom
expect(chart.scales.yScale).toEqual(jasmine.objectContaining({
ticks: [0, 9, 10, 20, 30],
start: 30,
end: 0
}));
var scale = chart.scales.yScale;
expect(getLabels(scale)).toEqual([0, 9, 10, 20, 30]);
expect(scale.start).toEqual(30);
expect(scale.end).toEqual(0);
});
it('should build labels using the default template', function() {
@ -689,7 +687,7 @@ describe('Logarithmic Scale tests', function() {
}
});
expect(chart.scales.yScale.ticks).toEqual(['8e+1', '', '', '5e+1', '', '', '2e+1', '1e+1', '', '', '', '', '5e+0', '', '', '2e+0', '1e+0', '0']);
expect(getLabels(chart.scales.yScale)).toEqual(['8e+1', '', '', '5e+1', '', '', '2e+1', '1e+1', '', '', '', '', '5e+0', '', '', '2e+0', '1e+0', '0']);
});
it('should build labels using the user supplied callback', function() {
@ -717,7 +715,7 @@ describe('Logarithmic Scale tests', function() {
});
// Just the index
expect(chart.scales.yScale.ticks).toEqual(['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16']);
expect(getLabels(chart.scales.yScale)).toEqual(['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16']);
});
it('should correctly get the correct label for a data item', function() {

View File

@ -1,3 +1,7 @@
function getLabels(scale) {
return scale.ticks.map(t => t.label);
}
// Tests for the radial linear scale used by the polar area and radar charts
describe('Test the radial linear scale', function() {
describe('auto', jasmine.fixture.specs('scale.radialLinear'));
@ -220,7 +224,7 @@ describe('Test the radial linear scale', function() {
expect(chart.scale.min).toBe(-1010);
expect(chart.scale.max).toBe(1010);
expect(chart.scale.ticks).toEqual(['-1010', '-1000', '-500', '0', '500', '1000', '1010']);
expect(getLabels(chart.scale)).toEqual(['-1010', '-1000', '-500', '0', '500', '1000', '1010']);
});
it('should forcibly include 0 in the range if the beginAtZero option is used', function() {
@ -241,22 +245,22 @@ describe('Test the radial linear scale', function() {
}
});
expect(chart.scale.ticks).toEqual(['20', '25', '30', '35', '40', '45', '50']);
expect(getLabels(chart.scale)).toEqual(['20', '25', '30', '35', '40', '45', '50']);
chart.scale.options.ticks.beginAtZero = true;
chart.update();
expect(chart.scale.ticks).toEqual(['0', '5', '10', '15', '20', '25', '30', '35', '40', '45', '50']);
expect(getLabels(chart.scale)).toEqual(['0', '5', '10', '15', '20', '25', '30', '35', '40', '45', '50']);
chart.data.datasets[0].data = [-20, -30, -40, -50];
chart.update();
expect(chart.scale.ticks).toEqual(['-50', '-45', '-40', '-35', '-30', '-25', '-20', '-15', '-10', '-5', '0']);
expect(getLabels(chart.scale)).toEqual(['-50', '-45', '-40', '-35', '-30', '-25', '-20', '-15', '-10', '-5', '0']);
chart.scale.options.ticks.beginAtZero = false;
chart.update();
expect(chart.scale.ticks).toEqual(['-50', '-45', '-40', '-35', '-30', '-25', '-20']);
expect(getLabels(chart.scale)).toEqual(['-50', '-45', '-40', '-35', '-30', '-25', '-20']);
});
it('Should generate tick marks in the correct order in reversed mode', function() {
@ -277,7 +281,7 @@ describe('Test the radial linear scale', function() {
}
});
expect(chart.scale.ticks).toEqual(['80', '70', '60', '50', '40', '30', '20', '10', '0']);
expect(getLabels(chart.scale)).toEqual(['80', '70', '60', '50', '40', '30', '20', '10', '0']);
expect(chart.scale.start).toBe(80);
expect(chart.scale.end).toBe(0);
});
@ -300,23 +304,23 @@ describe('Test the radial linear scale', function() {
}
});
expect(chart.scale.ticks).toEqual(['0.5', '1.0', '1.5', '2.0', '2.5']);
expect(getLabels(chart.scale)).toEqual(['0.5', '1.0', '1.5', '2.0', '2.5']);
chart.options.scale.ticks.maxTicksLimit = 11;
chart.update();
expect(chart.scale.ticks).toEqual(['0.5', '1.0', '1.5', '2.0', '2.5']);
expect(getLabels(chart.scale)).toEqual(['0.5', '1.0', '1.5', '2.0', '2.5']);
chart.options.scale.ticks.stepSize = 0.01;
chart.update();
expect(chart.scale.ticks).toEqual(['0.5', '1.0', '1.5', '2.0', '2.5']);
expect(getLabels(chart.scale)).toEqual(['0.5', '1.0', '1.5', '2.0', '2.5']);
chart.options.scale.ticks.min = 0.3;
chart.options.scale.ticks.max = 2.8;
chart.update();
expect(chart.scale.ticks).toEqual(['0.3', '0.5', '1.0', '1.5', '2.0', '2.5', '2.8']);
expect(getLabels(chart.scale)).toEqual(['0.3', '0.5', '1.0', '1.5', '2.0', '2.5', '2.8']);
});
it('Should build labels using the user supplied callback', function() {
@ -339,7 +343,7 @@ describe('Test the radial linear scale', function() {
}
});
expect(chart.scale.ticks).toEqual(['0', '1', '2', '3', '4', '5', '6', '7', '8']);
expect(getLabels(chart.scale)).toEqual(['0', '1', '2', '3', '4', '5', '6', '7', '8']);
expect(chart.scale.pointLabels).toEqual(['label1', 'label2', 'label3', 'label4', 'label5']);
});

View File

@ -4,23 +4,25 @@ describe('Time scale tests', function() {
var scaleID = 'myScale';
var mockContext = window.createMockContext();
var Constructor = Chart.scaleService.getScaleConstructor('time');
var width = (dimensions && dimensions.width) || 400;
var height = (dimensions && dimensions.height) || 50;
var scale = new Constructor({
ctx: mockContext,
options: options,
chart: {
data: data
data: data,
width: width,
height: height
},
id: scaleID
});
var width = (dimensions && dimensions.width) || 400;
var height = (dimensions && dimensions.height) || 50;
scale.update(width, height);
return scale;
}
function getTicksLabels(scale) {
return scale.ticks;
function getLabels(scale) {
return scale.ticks.map(t => t.label);
}
beforeEach(function() {
@ -124,7 +126,7 @@ describe('Time scale tests', function() {
var scaleOptions = Chart.scaleService.getScaleDefaults('time');
var scale = createScale(mockData, scaleOptions, {width: 1000, height: 200});
var ticks = getTicksLabels(scale);
var ticks = getLabels(scale);
// `bounds === 'data'`: first and last ticks removed since outside the data range
expect(ticks.length).toEqual(217);
@ -135,7 +137,7 @@ describe('Time scale tests', function() {
labels: [newDateFromRef(0), newDateFromRef(1), newDateFromRef(2), newDateFromRef(4), newDateFromRef(6), newDateFromRef(7), newDateFromRef(9)], // days
};
var scale = createScale(mockData, Chart.scaleService.getScaleDefaults('time'), {width: 1000, height: 200});
var ticks = getTicksLabels(scale);
var ticks = getLabels(scale);
// `bounds === 'data'`: first and last ticks removed since outside the data range
expect(ticks.length).toEqual(217);
@ -183,7 +185,7 @@ describe('Time scale tests', function() {
}, {canvas: {width: 800, height: 200}});
var xScale = chart.scales.xScale0;
var ticks = getTicksLabels(xScale);
var ticks = getLabels(xScale);
// `bounds === 'data'`: first and last ticks removed since outside the data range
expect(ticks.length).toEqual(217);
@ -231,7 +233,7 @@ describe('Time scale tests', function() {
}, {canvas: {width: 800, height: 200}});
var tScale = chart.scales.tScale0;
var ticks = getTicksLabels(tScale);
var ticks = getLabels(tScale);
// `bounds === 'data'`: first and last ticks removed since outside the data range
expect(ticks.length).toEqual(217);
@ -272,11 +274,11 @@ describe('Time scale tests', function() {
});
// Counts down because the lines are drawn top to bottom
var xScale = chart.scales.xScale0;
var labels = getLabels(chart.scales.xScale0);
// Counts down because the lines are drawn top to bottom
expect(xScale.ticks[0]).toBe('Jan 2');
expect(xScale.ticks[1]).toBe('May 8');
expect(labels[0]).toBe('Jan 2');
expect(labels[1]).toBe('May 8');
});
it('should build ticks using the config unit', function() {
@ -288,7 +290,7 @@ describe('Time scale tests', function() {
config.time.unit = 'hour';
var scale = createScale(mockData, config, {width: 2500, height: 200});
var ticks = getTicksLabels(scale);
var ticks = getLabels(scale);
expect(ticks).toEqual(['8PM', '9PM', '10PM', '11PM', '12AM', '1AM', '2AM', '3AM', '4AM', '5AM', '6AM', '7AM', '8AM', '9AM', '10AM', '11AM', '12PM', '1PM', '2PM', '3PM', '4PM', '5PM', '6PM', '7PM', '8PM', '9PM']);
});
@ -306,7 +308,7 @@ describe('Time scale tests', function() {
}, Chart.scaleService.getScaleDefaults('time'));
var scale = createScale(mockData, config);
var ticks = getTicksLabels(scale);
var ticks = getLabels(scale);
expect(ticks).toEqual(['Jan 1', 'Jan 2', 'Jan 3']);
});
@ -361,7 +363,7 @@ describe('Time scale tests', function() {
}, Chart.scaleService.getScaleDefaults('time'));
var scale = createScale(mockData, config);
var ticks = getTicksLabels(scale);
var ticks = getLabels(scale);
expect(ticks).toEqual(['2012', '2013', '2014', '2015', '2016', '2017', '2018', '2019']);
});
@ -380,7 +382,7 @@ describe('Time scale tests', function() {
}, Chart.scaleService.getScaleDefaults('time'));
var scale = createScale(mockData, config, {width: 800, height: 200});
var ticks = getTicksLabels(scale);
var ticks = getLabels(scale);
// last date is feb 15 because we round to start of week
expect(ticks).toEqual(['Dec 28, 2014', 'Jan 4, 2015', 'Jan 11, 2015', 'Jan 18, 2015', 'Jan 25, 2015', 'Feb 1, 2015', 'Feb 8, 2015', 'Feb 15, 2015']);
@ -401,7 +403,7 @@ describe('Time scale tests', function() {
}, Chart.scaleService.getScaleDefaults('time'));
var scale = createScale(mockData, config, {width: 2500, height: 200});
var ticks = getTicksLabels(scale);
var ticks = getLabels(scale);
expect(ticks).toEqual(['8PM', '10PM']);
});
@ -422,29 +424,29 @@ describe('Time scale tests', function() {
it('should use the min option when less than first label for building ticks', function() {
config.ticks.min = '2014-12-29T04:00:00';
var scale = createScale(mockData, config);
expect(scale.ticks[0]).toEqual('Jan 1');
var labels = getLabels(createScale(mockData, config));
expect(labels[0]).toEqual('Jan 1');
});
it('should use the min option when greater than first label for building ticks', function() {
config.ticks.min = '2015-01-02T04:00:00';
var scale = createScale(mockData, config);
expect(scale.ticks[0]).toEqual('Jan 2');
var labels = getLabels(createScale(mockData, config));
expect(labels[0]).toEqual('Jan 2');
});
it('should use the max option when greater than last label for building ticks', function() {
config.ticks.max = '2015-01-05T06:00:00';
var scale = createScale(mockData, config);
expect(scale.ticks[scale.ticks.length - 1]).toEqual('Jan 3');
var labels = getLabels(createScale(mockData, config));
expect(labels[labels.length - 1]).toEqual('Jan 3');
});
it('should use the max option when less than last label for building ticks', function() {
config.ticks.max = '2015-01-02T23:00:00';
var scale = createScale(mockData, config);
expect(scale.ticks[scale.ticks.length - 1]).toEqual('Jan 2');
var labels = getLabels(createScale(mockData, config));
expect(labels[labels.length - 1]).toEqual('Jan 2');
});
});
@ -463,29 +465,29 @@ describe('Time scale tests', function() {
it('should use the min option when less than first label for building ticks', function() {
config.ticks.min = '2014-12-29T04:00:00';
var scale = createScale(mockData, config);
expect(scale.ticks[0]).toEqual('Jan 1');
var labels = getLabels(createScale(mockData, config));
expect(labels[0]).toEqual('Jan 1');
});
it('should use the min option when greater than first label for building ticks', function() {
config.ticks.min = '2015-01-02T04:00:00';
var scale = createScale(mockData, config);
expect(scale.ticks[0]).toEqual('Jan 2');
var labels = getLabels(createScale(mockData, config));
expect(labels[0]).toEqual('Jan 2');
});
it('should use the max option when greater than last label for building ticks', function() {
config.ticks.max = '2015-01-05T06:00:00';
var scale = createScale(mockData, config);
expect(scale.ticks[scale.ticks.length - 1]).toEqual('Jan 3');
var labels = getLabels(createScale(mockData, config));
expect(labels[labels.length - 1]).toEqual('Jan 3');
});
it('should use the max option when less than last label for building ticks', function() {
config.ticks.max = '2015-01-02T23:00:00';
var scale = createScale(mockData, config);
expect(scale.ticks[scale.ticks.length - 1]).toEqual('Jan 2');
var labels = getLabels(createScale(mockData, config));
expect(labels[labels.length - 1]).toEqual('Jan 2');
});
});
@ -507,7 +509,7 @@ describe('Time scale tests', function() {
}, Chart.scaleService.getScaleDefaults('time'));
var scale = createScale(mockData, config);
var ticks = getTicksLabels(scale);
var ticks = getLabels(scale);
expect(ticks).toEqual(['Dec 31, 2014', 'Jan 7, 2015']);
});
@ -616,7 +618,7 @@ describe('Time scale tests', function() {
});
it('should build the correct ticks', function() {
expect(getTicksLabels(this.scale)).toEqual(['2005', '2006', '2007', '2008', '2009', '2010', '2011', '2012', '2013', '2014', '2015', '2016', '2017', '2018']);
expect(getLabels(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() {
@ -698,24 +700,24 @@ describe('Time scale tests', function() {
});
it('should get the correct labels for ticks', function() {
var scale = this.scale;
var labels = getLabels(this.scale);
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>');
expect(labels.length).toEqual(61);
expect(labels[0]).toEqual('<8:00:00>');
expect(labels[labels.length - 1]).toEqual('<8:01:00>');
});
it('should update ticks.callback correctly', function() {
var chart = this.chart;
var scale = this.scale;
chart.options.scales.xAxes[0].ticks.callback = function(value) {
return '{' + value + '}';
};
chart.update();
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}');
var labels = getLabels(this.scale);
expect(labels.length).toEqual(61);
expect(labels[0]).toEqual('{8:00:00}');
expect(labels[labels.length - 1]).toEqual('{8:01:00}');
});
});
@ -759,46 +761,46 @@ describe('Time scale tests', function() {
});
it('should get the correct labels for major and minor ticks', function() {
var scale = this.scale;
var labels = getLabels(this.scale);
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]]');
expect(labels.length).toEqual(61);
expect(labels[0]).toEqual('[[8:00 pm]]');
expect(labels[Math.floor(labels.length / 2)]).toEqual('(8:00:30 pm)');
expect(labels[labels.length - 1]).toEqual('[[8:01 pm]]');
});
it('should only use ticks.minor callback if ticks.major.enabled is false', function() {
var chart = this.chart;
var scale = this.scale;
chart.options.scales.xAxes[0].ticks.major.enabled = false;
chart.update();
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)');
var labels = getLabels(this.scale);
expect(labels.length).toEqual(61);
expect(labels[0]).toEqual('(8:00:00 pm)');
expect(labels[labels.length - 1]).toEqual('(8:01:00 pm)');
});
it('should use ticks.callback if ticks.major.callback is omitted', function() {
var chart = this.chart;
var scale = this.scale;
chart.options.scales.xAxes[0].ticks.major.callback = undefined;
chart.update();
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>');
var labels = getLabels(this.scale);
expect(labels.length).toEqual(61);
expect(labels[0]).toEqual('<8:00 pm>');
expect(labels[labels.length - 1]).toEqual('<8:01 pm>');
});
it('should use ticks.callback if ticks.minor.callback is omitted', function() {
var chart = this.chart;
var scale = this.scale;
chart.options.scales.xAxes[0].ticks.minor.callback = undefined;
chart.update();
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]]');
var labels = getLabels(this.scale);
expect(labels.length).toEqual(61);
expect(labels[0]).toEqual('[[8:00 pm]]');
expect(labels[Math.floor(labels.length / 2)]).toEqual('<8:00:30 pm>');
expect(labels[labels.length - 1]).toEqual('[[8:01 pm]]');
});
});
@ -943,7 +945,7 @@ describe('Time scale tests', function() {
expect(scale.min).toEqual(+moment('2017', 'YYYY'));
expect(scale.max).toEqual(+moment('2042', 'YYYY'));
expect(getTicksLabels(scale)).toEqual([
expect(getLabels(scale)).toEqual([
'2017', '2019', '2020', '2025', '2042']);
});
it ('should not add ticks for min and max if they extend the labels range', function() {
@ -957,7 +959,7 @@ describe('Time scale tests', function() {
expect(scale.min).toEqual(+moment('2012', 'YYYY'));
expect(scale.max).toEqual(+moment('2051', 'YYYY'));
expect(getTicksLabels(scale)).toEqual([
expect(getLabels(scale)).toEqual([
'2017', '2019', '2020', '2025', '2042']);
});
it ('should not duplicate ticks if min and max are the labels limits', function() {
@ -971,7 +973,7 @@ describe('Time scale tests', function() {
expect(scale.min).toEqual(+moment('2017', 'YYYY'));
expect(scale.max).toEqual(+moment('2042', 'YYYY'));
expect(getTicksLabels(scale)).toEqual([
expect(getLabels(scale)).toEqual([
'2017', '2019', '2020', '2025', '2042']);
});
it ('should correctly handle empty `data.labels` using "day" if `time.unit` is undefined`', function() {
@ -983,7 +985,7 @@ describe('Time scale tests', function() {
expect(scale.min).toEqual(+moment().startOf('day'));
expect(scale.max).toEqual(+moment().endOf('day') + 1);
expect(getTicksLabels(scale)).toEqual([]);
expect(getLabels(scale)).toEqual([]);
});
it ('should correctly handle empty `data.labels` using `time.unit`', function() {
var chart = this.chart;
@ -996,7 +998,7 @@ describe('Time scale tests', function() {
expect(scale.min).toEqual(+moment().startOf('year'));
expect(scale.max).toEqual(+moment().endOf('year') + 1);
expect(getTicksLabels(scale)).toEqual([]);
expect(getLabels(scale)).toEqual([]);
});
});
@ -1037,7 +1039,7 @@ describe('Time scale tests', function() {
expect(scale.min).toEqual(+moment('2017', 'YYYY'));
expect(scale.max).toEqual(+moment('2043', 'YYYY'));
expect(getTicksLabels(scale)).toEqual([
expect(getLabels(scale)).toEqual([
'2017', '2018', '2019', '2020', '2025', '2042', '2043']);
});
it ('should not add ticks for min and max if they extend the labels range', function() {
@ -1051,7 +1053,7 @@ describe('Time scale tests', function() {
expect(scale.min).toEqual(+moment('2012', 'YYYY'));
expect(scale.max).toEqual(+moment('2051', 'YYYY'));
expect(getTicksLabels(scale)).toEqual([
expect(getLabels(scale)).toEqual([
'2017', '2018', '2019', '2020', '2025', '2042', '2043']);
});
it ('should not duplicate ticks if min and max are the labels limits', function() {
@ -1065,7 +1067,7 @@ describe('Time scale tests', function() {
expect(scale.min).toEqual(+moment('2017', 'YYYY'));
expect(scale.max).toEqual(+moment('2043', 'YYYY'));
expect(getTicksLabels(scale)).toEqual([
expect(getLabels(scale)).toEqual([
'2017', '2018', '2019', '2020', '2025', '2042', '2043']);
});
it ('should correctly handle empty `data.labels` using "day" if `time.unit` is undefined`', function() {
@ -1077,7 +1079,7 @@ describe('Time scale tests', function() {
expect(scale.min).toEqual(+moment('2018', 'YYYY'));
expect(scale.max).toEqual(+moment('2043', 'YYYY'));
expect(getTicksLabels(scale)).toEqual([
expect(getLabels(scale)).toEqual([
'2018', '2020', '2043']);
});
it ('should correctly handle empty `data.labels` and hidden datasets using `time.unit`', function() {
@ -1093,7 +1095,7 @@ describe('Time scale tests', function() {
expect(scale.min).toEqual(+moment().startOf('year'));
expect(scale.max).toEqual(+moment().endOf('year') + 1);
expect(getTicksLabels(scale)).toEqual([]);
expect(getLabels(scale)).toEqual([]);
});
});
});
@ -1277,7 +1279,7 @@ describe('Time scale tests', function() {
expect(scale.max).toEqual(+moment('02/23 11:00', 'MM/DD HH:mm'));
expect(scale.getPixelForValue('02/20 08:00')).toBeCloseToPixel(scale.left);
expect(scale.getPixelForValue('02/23 11:00')).toBeCloseToPixel(scale.left + scale.width);
expect(getTicksLabels(scale)).toEqual([
expect(getLabels(scale)).toEqual([
'Feb 21', 'Feb 22', 'Feb 23']);
});
});
@ -1315,7 +1317,7 @@ describe('Time scale tests', function() {
expect(scale.max).toEqual(ticks[ticks.length - 1].value);
expect(scale.getPixelForValue('02/20 08:00')).toBeCloseToPixel(60);
expect(scale.getPixelForValue('02/23 11:00')).toBeCloseToPixel(426);
expect(getTicksLabels(scale)).toEqual([
expect(getLabels(scale)).toEqual([
'Feb 20', 'Feb 21', 'Feb 22', 'Feb 23', 'Feb 24']);
});
});
@ -1767,10 +1769,10 @@ describe('Time scale tests', function() {
}
});
expect(getTicksLabels(chart.scales.x)).toEqual(['2015', '2016', '2017']);
expect(getTicksLabels(chart.scales.x2)).toEqual(['1985', '1986', '1987']);
expect(getTicksLabels(chart.scales.y)).toEqual(['1995', '1996', '1997']);
expect(getTicksLabels(chart.scales.y2)).toEqual(['2005', '2006', '2007']);
expect(getLabels(chart.scales.x)).toEqual(['2015', '2016', '2017']);
expect(getLabels(chart.scales.x2)).toEqual(['1985', '1986', '1987']);
expect(getLabels(chart.scales.y)).toEqual(['1995', '1996', '1997']);
expect(getLabels(chart.scales.y2)).toEqual(['2005', '2006', '2007']);
});
});