* `options.ticks.userCallback` was renamed to `options.ticks.callback`
* `options.ticks.major` and `options.ticks.minor` were replaced with scriptable options for tick fonts.
+* `Chart.Ticks.formatters.linear` and `Chart.Ticks.formatters.logarithmic` were replaced with `Chart.Ticks.formatters.numeric`.
### Tooltip
},
/**
- * Formatter for linear numeric ticks
- * @method Chart.Ticks.formatters.linear
+ * Formatter for numeric ticks
+ * @method Chart.Ticks.formatters.numeric
* @param tickValue {number} the value to be formatted
* @param index {number} the position of the tickValue parameter in the ticks array
* @param ticks {object[]} the list of ticks being converted
* @return {string} string representation of the tickValue parameter
*/
- linear: function(tickValue, index, ticks) {
+ numeric: function(tickValue, index, ticks) {
+ if (tickValue === 0) {
+ return '0'; // never show decimal places for 0
+ }
+
// If we have lots of ticks, don't use the ones
- var delta = ticks.length > 3 ? ticks[2].value - ticks[1].value : ticks[1].value - ticks[0].value;
+ let 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) {
- if (tickValue !== Math.floor(tickValue)) {
- // not an integer
- delta = tickValue - Math.floor(tickValue);
- }
+ if (Math.abs(delta) > 1 && tickValue !== Math.floor(tickValue)) {
+ // not an integer
+ delta = tickValue - Math.floor(tickValue);
}
- var logDelta = log10(Math.abs(delta));
- var tickString = '';
+ const logDelta = log10(Math.abs(delta));
- if (tickValue !== 0) {
- 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 = log10(Math.abs(tickValue));
- var numExponential = Math.floor(logTick) - Math.floor(logDelta);
- numExponential = Math.max(Math.min(numExponential, 20), 0);
- tickString = tickValue.toExponential(numExponential);
- } else {
- var numDecimal = -1 * Math.floor(logDelta);
- numDecimal = Math.max(Math.min(numDecimal, 20), 0); // toFixed has a max of 20 decimal places
- tickString = tickValue.toFixed(numDecimal);
- }
- } else {
- tickString = '0'; // never show decimal places for 0
+ const maxTick = Math.max(Math.abs(ticks[0].value), Math.abs(ticks[ticks.length - 1].value));
+ const minTick = Math.min(Math.abs(ticks[0].value), Math.abs(ticks[ticks.length - 1].value));
+ const locale = this.chart.options.locale;
+ if (maxTick < 1e-4 || minTick > 1e+7) { // all ticks are small or big numbers; use scientific notation
+ const logTick = log10(Math.abs(tickValue));
+ let numExponential = Math.floor(logTick) - Math.floor(logDelta);
+ numExponential = Math.max(Math.min(numExponential, 20), 0);
+ return new Intl.NumberFormat(locale, {notation: 'scientific', minimumFractionDigits: numExponential, maximumFractionDigits: numExponential}).format(tickValue);
}
- return tickString;
- },
-
- logarithmic: function(tickValue) {
- return tickValue === 0 ? '0' : tickValue.toExponential();
+ let numDecimal = -1 * Math.floor(logDelta);
+ numDecimal = Math.max(Math.min(numDecimal, 20), 0); // toFixed has a max of 20 decimal places
+ return new Intl.NumberFormat(locale, {minimumFractionDigits: numDecimal, maximumFractionDigits: numDecimal}).format(tickValue);
}
}
};
const defaultConfig = {
ticks: {
- callback: Ticks.formatters.linear
+ callback: Ticks.formatters.numeric
}
};
}
getLabelForValue(value) {
- return new Intl.NumberFormat().format(value);
+ return new Intl.NumberFormat(this.options.locale).format(value);
}
}
const defaultConfig = {
// label settings
ticks: {
- callback: Ticks.formatters.logarithmic,
+ callback: Ticks.formatters.numeric,
major: {
enabled: true
}
}
getLabelForValue(value) {
- return value === undefined ? 0 : new Intl.NumberFormat().format(value);
+ return value === undefined ? 0 : new Intl.NumberFormat(this.options.locale).format(value);
}
getPixelForTick(index) {
// Number - The backdrop padding to the side of the label in pixels
backdropPaddingX: 2,
- callback: Ticks.formatters.linear
+ callback: Ticks.formatters.numeric
},
pointLabels: {
expect(typeof Chart.Ticks).toBeDefined();
expect(typeof Chart.Ticks.formatters).toBeDefined();
expect(typeof Chart.Ticks.formatters.values).toBe('function');
- expect(typeof Chart.Ticks.formatters.linear).toBe('function');
- expect(typeof Chart.Ticks.formatters.logarithmic).toBe('function');
+ expect(typeof Chart.Ticks.formatters.numeric).toBe('function');
});
it('Should generate linear spaced ticks with correct precision', function() {
expect(chart.scales.y.min).toBe(-1010);
expect(chart.scales.y.max).toBe(1010);
var labels = getLabels(chart.scales.y);
- expect(labels[0]).toBe('1010');
- expect(labels[labels.length - 1]).toBe('-1010');
+ expect(labels[0]).toBe('1,010');
+ expect(labels[labels.length - 1]).toBe('-1,010');
});
it('Should use min, max and stepSize to create fixed spaced ticks', function() {
}
});
- expect(getLabels(chart.scales.y)).toEqual(['8e+1', '7e+1', '6e+1', '5e+1', '4e+1', '3e+1', '2e+1', '1e+1', '9e+0', '8e+0', '7e+0', '6e+0', '5e+0', '4e+0', '3e+0', '2e+0', '1e+0']);
+ expect(getLabels(chart.scales.y)).toEqual(['80', '70', '60', '50', '40', '30', '20', '10', '9', '8', '7', '6', '5', '4', '3', '2', '1']);
});
it('should build labels using the user supplied callback', function() {
expect(chart.scales.r.min).toBe(-1010);
expect(chart.scales.r.max).toBe(1010);
- expect(getLabels(chart.scales.r)).toEqual(['-1010', '-1000', '-500', '0', '500', '1000', '1010']);
+ expect(getLabels(chart.scales.r)).toEqual(['-1,010', '-1,000', '-500', '0', '500', '1,000', '1,010']);
});
it('should forcibly include 0 in the range if the beginAtZero option is used', function() {
config.options.animation = config.options.animation === undefined ? false : config.options.animation;
config.options.responsive = config.options.responsive === undefined ? false : config.options.responsive;
config.options.fontFamily = config.options.fontFamily || 'Arial';
+ config.options.locale = config.options.locale || 'en-US';
wrapper.appendChild(canvas);
window.document.body.appendChild(wrapper);