mirror of
https://github.com/chartjs/Chart.js.git
synced 2025-12-08 20:36:08 +00:00
formatters.numeric: verify ticks length (#8705)
* formatters.numeric: verify ticks length * use tickValue as fallback delta, add tests * cc, chore
This commit is contained in:
parent
4cd26fad6a
commit
bbf298f461
@ -8,45 +8,40 @@ import {log10} from '../helpers/helpers.math';
|
||||
*/
|
||||
const formatters = {
|
||||
/**
|
||||
* Formatter for value labels
|
||||
* @method Chart.Ticks.formatters.values
|
||||
* @param value the value to display
|
||||
* @return {string|string[]} the label to display
|
||||
*/
|
||||
* Formatter for value labels
|
||||
* @method Chart.Ticks.formatters.values
|
||||
* @param value the value to display
|
||||
* @return {string|string[]} the label to display
|
||||
*/
|
||||
values(value) {
|
||||
return isArray(value) ? value : '' + value;
|
||||
},
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
* 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
|
||||
*/
|
||||
numeric(tickValue, index, ticks) {
|
||||
if (tickValue === 0) {
|
||||
return '0'; // never show decimal places for 0
|
||||
}
|
||||
|
||||
const locale = this.chart.options.locale;
|
||||
|
||||
// all ticks are small or there huge numbers; use scientific notation
|
||||
const maxTick = Math.max(Math.abs(ticks[0].value), Math.abs(ticks[ticks.length - 1].value));
|
||||
let notation;
|
||||
if (maxTick < 1e-4 || maxTick > 1e+15) {
|
||||
notation = 'scientific';
|
||||
}
|
||||
let delta = tickValue; // This is used when there are less than 2 ticks as the tick interval.
|
||||
|
||||
// Figure out how many digits to show
|
||||
// The space between the first two ticks might be smaller than normal spacing
|
||||
let delta = ticks.length > 3 ? ticks[2].value - ticks[1].value : ticks[1].value - ticks[0].value;
|
||||
if (ticks.length > 1) {
|
||||
// all ticks are small or there huge numbers; use scientific notation
|
||||
const maxTick = Math.max(Math.abs(ticks[0].value), Math.abs(ticks[ticks.length - 1].value));
|
||||
if (maxTick < 1e-4 || maxTick > 1e+15) {
|
||||
notation = 'scientific';
|
||||
}
|
||||
|
||||
// If we have a number like 2.5 as the delta, figure out how many decimal places we need
|
||||
if (Math.abs(delta) > 1 && tickValue !== Math.floor(tickValue)) {
|
||||
// not an integer
|
||||
delta = tickValue - Math.floor(tickValue);
|
||||
delta = calculateDelta(tickValue, ticks);
|
||||
}
|
||||
|
||||
const logDelta = log10(Math.abs(delta));
|
||||
@ -56,27 +51,43 @@ const formatters = {
|
||||
Object.assign(options, this.options.ticks.format);
|
||||
|
||||
return formatNumber(tickValue, locale, options);
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* Formatter for logarithmic ticks
|
||||
* @method Chart.Ticks.formatters.logarithmic
|
||||
* @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
|
||||
*/
|
||||
logarithmic(tickValue, index, ticks) {
|
||||
if (tickValue === 0) {
|
||||
return '0';
|
||||
}
|
||||
const remain = tickValue / (Math.pow(10, Math.floor(log10(tickValue))));
|
||||
if (remain === 1 || remain === 2 || remain === 5) {
|
||||
return formatters.numeric.call(this, tickValue, index, ticks);
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Formatter for logarithmic ticks
|
||||
* @method Chart.Ticks.formatters.logarithmic
|
||||
* @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
|
||||
*/
|
||||
formatters.logarithmic = function(tickValue, index, ticks) {
|
||||
if (tickValue === 0) {
|
||||
return '0';
|
||||
|
||||
function calculateDelta(tickValue, ticks) {
|
||||
// Figure out how many digits to show
|
||||
// The space between the first two ticks might be smaller than normal spacing
|
||||
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 && tickValue !== Math.floor(tickValue)) {
|
||||
// not an integer
|
||||
delta = tickValue - Math.floor(tickValue);
|
||||
}
|
||||
const remain = tickValue / (Math.pow(10, Math.floor(log10(tickValue))));
|
||||
if (remain === 1 || remain === 2 || remain === 5) {
|
||||
return formatters.numeric.call(this, tickValue, index, ticks);
|
||||
}
|
||||
return '';
|
||||
};
|
||||
return delta;
|
||||
}
|
||||
|
||||
/**
|
||||
* Namespace to hold static tick generation functions
|
||||
|
||||
@ -96,4 +96,13 @@ describe('Test tick generators', function() {
|
||||
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(['0.1', '0.2', '0.3', '0.4', '0.5', '0.6', '0.7', '0.8', '0.9', '1']);
|
||||
});
|
||||
|
||||
describe('formatters.numeric', function() {
|
||||
it('should not fail on empty or 1 item array', function() {
|
||||
const scale = {chart: {options: {locale: 'en'}}, options: {ticks: {format: {}}}};
|
||||
expect(Chart.Ticks.formatters.numeric.apply(scale, [1, 0, []])).toEqual('1');
|
||||
expect(Chart.Ticks.formatters.numeric.apply(scale, [1, 0, [{value: 1}]])).toEqual('1');
|
||||
expect(Chart.Ticks.formatters.numeric.apply(scale, [1, 0, [{value: 1}, {value: 1.01}]])).toEqual('1.00');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user