From 17a1fe9d023ee151c06216200cb4a3aa8725b260 Mon Sep 17 00:00:00 2001 From: Ben McCann <322311+benmccann@users.noreply.github.com> Date: Mon, 8 Jun 2020 04:52:01 -0700 Subject: [PATCH] Better formatting of large tick values (#7335) Better formatting of large tick values --- docs/docs/axes/cartesian/linear.md | 1 + docs/docs/axes/cartesian/logarithmic.md | 6 ++++- docs/docs/axes/radial/linear.md | 5 +++-- src/core/core.ticks.js | 29 ++++++++++++++----------- 4 files changed, 25 insertions(+), 16 deletions(-) diff --git a/docs/docs/axes/cartesian/linear.md b/docs/docs/axes/cartesian/linear.md index 5769e960a..9e223001b 100644 --- a/docs/docs/axes/cartesian/linear.md +++ b/docs/docs/axes/cartesian/linear.md @@ -18,6 +18,7 @@ The following options are provided by the linear scale. They are all located in | Name | Type | Default | Description | ---- | ---- | ------- | ----------- +| `format` | `object` | | The [`Intl.NumberFormat`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat) options used by the default label formatter | `maxTicksLimit` | `number` | `11` | Maximum number of ticks and gridlines to show. | `precision` | `number` | | if defined and `stepSize` is not specified, the step size will be rounded to this many decimal places. | `stepSize` | `number` | | User defined fixed step size for the scale. [more...](#step-size) diff --git a/docs/docs/axes/cartesian/logarithmic.md b/docs/docs/axes/cartesian/logarithmic.md index 07490b50b..16eb071d7 100644 --- a/docs/docs/axes/cartesian/logarithmic.md +++ b/docs/docs/axes/cartesian/logarithmic.md @@ -6,7 +6,11 @@ The logarithmic scale is use to chart numerical data. It can be placed on either ## Tick Configuration Options -The logarithmic scale options extend the [common tick configuration](README.md#tick-configuration). This scale does not define any options that are unique to it. +The following options are provided by the linear scale. They are all located in the `ticks` sub options. These options extend the [common tick configuration](README.md#tick-configuration). + +| Name | Type | Default | Description +| ---- | ---- | ------- | ----------- +| `format` | `object` | | The [`Intl.NumberFormat`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat) options used by the default label formatter ## Internal data format diff --git a/docs/docs/axes/radial/linear.md b/docs/docs/axes/radial/linear.md index 4f3d468ca..eb7fdb10d 100644 --- a/docs/docs/axes/radial/linear.md +++ b/docs/docs/axes/radial/linear.md @@ -2,7 +2,7 @@ title: Linear Radial Axis --- -The linear scale is used to chart numerical data. As the name suggests, linear interpolation is used to determine where a value lies in relation the center of the axis. +The linear radial scale is used to chart numerical data. As the name suggests, linear interpolation is used to determine where a value lies in relation the center of the axis. The following additional configuration options are provided by the radial linear scale. @@ -24,13 +24,14 @@ The axis has configuration properties for ticks, angle lines (line that appear i ## Tick Options -The following options are provided by the linear scale. They are all located in the `ticks` sub options. The [common tick configuration](../styling.md#tick-configuration) options are supported by this axis. +The following options are provided by the linear radial scale. They are all located in the `ticks` sub options. The [common tick configuration](../styling.md#tick-configuration) options are supported by this axis. | Name | Type | Default | Description | ---- | ---- | ------- | ----------- | `backdropColor` | `Color` | `'rgba(255, 255, 255, 0.75)'` | Color of label backdrops. | `backdropPaddingX` | `number` | `2` | Horizontal padding of label backdrop. | `backdropPaddingY` | `number` | `2` | Vertical padding of label backdrop. +| `format` | `object` | | The [`Intl.NumberFormat`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat) options used by the default label formatter | `maxTicksLimit` | `number` | `11` | Maximum number of ticks and gridlines to show. | `precision` | `number` | | if defined and `stepSize` is not specified, the step size will be rounded to this many decimal places. | `stepSize` | `number` | | User defined fixed step size for the scale. [more...](#step-size) diff --git a/src/core/core.ticks.js b/src/core/core.ticks.js index 46bfc75bf..9380f16c6 100644 --- a/src/core/core.ticks.js +++ b/src/core/core.ticks.js @@ -29,7 +29,17 @@ const formatters = { return '0'; // never show decimal places for 0 } - // If we have lots of ticks, don't use the ones + 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'; + } + + // 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 @@ -39,20 +49,13 @@ const formatters = { } const logDelta = log10(Math.abs(delta)); + const numDecimal = Math.max(Math.min(-1 * Math.floor(logDelta), 20), 0); // toFixed has a max of 20 decimal places - 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 tickValue.toExponential(numExponential); - } + const options = {notation, minimumFractionDigits: numDecimal, maximumFractionDigits: numDecimal}; + Object.assign(options, this.options.ticks.format); - 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); + // @ts-ignore until TypeScript 4.0 because "notation" was previously experimental API + return new Intl.NumberFormat(locale, options).format(tickValue); } }; -- 2.47.2