From 7ccf9e2d4d2e052de0fb71da52d9d41f8eeda85c Mon Sep 17 00:00:00 2001 From: Jukka Kurkela Date: Sun, 7 Mar 2021 00:18:49 +0200 Subject: [PATCH] Add `grace` option for linear scale (#8581) * Add `grace` option for linear scale * cc --- docs/docs/axes/cartesian/linear.mdx | 40 +++++++++++++++++++++++ src/controllers/controller.doughnut.js | 4 +-- src/core/core.scale.js | 6 ++++ src/helpers/helpers.core.js | 2 +- src/helpers/helpers.options.js | 15 ++++++++- src/scales/scale.linearbase.js | 3 +- test/fixtures/scale.linear/grace-neg.js | 30 +++++++++++++++++ test/fixtures/scale.linear/grace-neg.png | Bin 0 -> 6753 bytes test/fixtures/scale.linear/grace-pos.js | 30 +++++++++++++++++ test/fixtures/scale.linear/grace-pos.png | Bin 0 -> 5286 bytes test/fixtures/scale.linear/grace.js | 30 +++++++++++++++++ test/fixtures/scale.linear/grace.png | Bin 0 -> 4729 bytes 12 files changed, 155 insertions(+), 5 deletions(-) create mode 100644 test/fixtures/scale.linear/grace-neg.js create mode 100644 test/fixtures/scale.linear/grace-neg.png create mode 100644 test/fixtures/scale.linear/grace-pos.js create mode 100644 test/fixtures/scale.linear/grace-pos.png create mode 100644 test/fixtures/scale.linear/grace.js create mode 100644 test/fixtures/scale.linear/grace.png diff --git a/docs/docs/axes/cartesian/linear.mdx b/docs/docs/axes/cartesian/linear.mdx index ac1418389..da7a3b4dc 100644 --- a/docs/docs/axes/cartesian/linear.mdx +++ b/docs/docs/axes/cartesian/linear.mdx @@ -18,6 +18,7 @@ Namespace: `options.scales[scaleId]` | Name | Type | Description | ---- | ---- | ----------- | `beginAtZero` | `boolean` | if true, scale will include 0 if it is not already included. +| `grace` | `number`\|`string` | Percentage (string ending with `%`) or amount (number) for added room in the scale range above and below data. [more...](#grace) @@ -58,6 +59,45 @@ let options = { }; ``` +## Grace + +If the value is string ending with `%`, its treat as percentage. If number, its treat as value. +The value is added to the maximum data value and subtracted from the minumum data. This extends the scale range as if the data values were that much greater. + +import { useEffect, useRef } from 'react'; + +```jsx live +function example() { + const canvas = useRef(null); + useEffect(() => { + const cfg = { + type: 'bar', + data: { + labels: ['Positive', 'Negative'], + datasets: [{ + data: [100, -50], + backgroundColor: 'rgb(255, 99, 132)' + }], + }, + options: { + scales: { + y: { + type: 'linear', + grace: '5%' + } + }, + plugins: { + legend: false + } + } + }; + const chart = new Chart(canvas.current.getContext('2d'), cfg); + return () => chart.destroy(); + }); + return
; +} +``` + ## Internal data format Internally, the linear scale uses numeric data diff --git a/src/controllers/controller.doughnut.js b/src/controllers/controller.doughnut.js index a8a3fbcbd..427316c32 100644 --- a/src/controllers/controller.doughnut.js +++ b/src/controllers/controller.doughnut.js @@ -1,6 +1,6 @@ import DatasetController from '../core/core.datasetController'; import {formatNumber} from '../core/core.intl'; -import {isArray, toPercentage, toPixels, valueOrDefault} from '../helpers/helpers.core'; +import {isArray, toPercentage, toDimension, valueOrDefault} from '../helpers/helpers.core'; import {toRadians, PI, TAU, HALF_PI, _angleBetween} from '../helpers/helpers.math'; /** @@ -123,7 +123,7 @@ export default class DoughnutController extends DatasetController { const maxWidth = (chartArea.width - spacing) / ratioX; const maxHeight = (chartArea.height - spacing) / ratioY; const maxRadius = Math.max(Math.min(maxWidth, maxHeight) / 2, 0); - const outerRadius = toPixels(me.options.radius, maxRadius); + const outerRadius = toDimension(me.options.radius, maxRadius); const innerRadius = Math.max(outerRadius * cutout, 0); const radiusLength = (outerRadius - innerRadius) / me._getVisibleDatasetWeightTotal(); me.offsetX = offsetX * outerRadius; diff --git a/src/core/core.scale.js b/src/core/core.scale.js index ec8a42ae8..ca7b278dd 100644 --- a/src/core/core.scale.js +++ b/src/core/core.scale.js @@ -26,6 +26,12 @@ defaults.set('scale', { */ bounds: 'ticks', + /** + * Addition grace added to max and reduced from min data value. + * @since 3.0.0 + */ + grace: 0, + // grid line settings gridLines: { display: true, diff --git a/src/helpers/helpers.core.js b/src/helpers/helpers.core.js index 78ce47409..cf3170ea9 100644 --- a/src/helpers/helpers.core.js +++ b/src/helpers/helpers.core.js @@ -90,7 +90,7 @@ export const toPercentage = (value, dimension) => parseFloat(value) / 100 : value / dimension; -export const toPixels = (value, dimension) => +export const toDimension = (value, dimension) => typeof value === 'string' && value.endsWith('%') ? parseFloat(value) / 100 * dimension : +value; diff --git a/src/helpers/helpers.options.js b/src/helpers/helpers.options.js index 604c09603..25302133a 100644 --- a/src/helpers/helpers.options.js +++ b/src/helpers/helpers.options.js @@ -1,5 +1,5 @@ import defaults from '../core/core.defaults'; -import {isArray, isObject, valueOrDefault} from './helpers.core'; +import {isArray, isObject, toDimension, valueOrDefault} from './helpers.core'; import {toFontString} from './helpers.canvas'; const LINE_HEIGHT = new RegExp(/^(normal|(\d+(?:\.\d+)?)(px|em|%)?)$/); @@ -175,3 +175,16 @@ export function resolve(inputs, context, index, info) { } } } + +/** + * @param {{min: number, max: number}} minmax + * @param {number|string} grace + * @private + */ +export function _addGrace(minmax, grace) { + const {min, max} = minmax; + return { + min: min - Math.abs(toDimension(grace, min)), + max: max + toDimension(grace, max) + }; +} diff --git a/src/scales/scale.linearbase.js b/src/scales/scale.linearbase.js index fe954a43f..1dbaf285a 100644 --- a/src/scales/scale.linearbase.js +++ b/src/scales/scale.linearbase.js @@ -2,6 +2,7 @@ import {isNullOrUndef} from '../helpers/helpers.core'; import {almostEquals, almostWhole, niceNum, _decimalPlaces, _setMinAndMaxByKey, sign} from '../helpers/helpers.math'; import Scale from '../core/core.scale'; import {formatNumber} from '../core/core.intl'; +import {_addGrace} from '../helpers/helpers.options'; /** * Generate a set of linear ticks @@ -205,7 +206,7 @@ export default class LinearScaleBase extends Scale { precision: tickOpts.precision, stepSize: tickOpts.stepSize }; - const ticks = generateTicks(numericGeneratorOptions, me); + const ticks = generateTicks(numericGeneratorOptions, _addGrace(me, opts.grace)); // At this point, we need to update our max and min given the tick values, // since we probably have expanded the range of the scale diff --git a/test/fixtures/scale.linear/grace-neg.js b/test/fixtures/scale.linear/grace-neg.js new file mode 100644 index 000000000..f606202ae --- /dev/null +++ b/test/fixtures/scale.linear/grace-neg.js @@ -0,0 +1,30 @@ +module.exports = { + description: 'https://github.com/chartjs/Chart.js/issues/7734', + config: { + type: 'bar', + data: { + labels: ['a'], + datasets: [{ + data: [-0.18], + }], + }, + options: { + indexAxis: 'y', + scales: { + y: { + display: false + }, + x: { + grace: '5%' + } + } + } + }, + options: { + spriteText: true, + canvas: { + width: 512, + height: 128 + } + } +}; diff --git a/test/fixtures/scale.linear/grace-neg.png b/test/fixtures/scale.linear/grace-neg.png new file mode 100644 index 0000000000000000000000000000000000000000..fbe444b3847f71ce10a3b8ea9faa7a8bdf9ea5ac GIT binary patch literal 6753 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 ONJjeRdc|ka5&r_wa*iwj literal 0 Hc-jL100001 diff --git a/test/fixtures/scale.linear/grace-pos.js b/test/fixtures/scale.linear/grace-pos.js new file mode 100644 index 000000000..76d6c693d --- /dev/null +++ b/test/fixtures/scale.linear/grace-pos.js @@ -0,0 +1,30 @@ +module.exports = { + description: 'https://github.com/chartjs/Chart.js/issues/7734', + config: { + type: 'bar', + data: { + labels: ['a'], + datasets: [{ + data: [0.18], + }], + }, + options: { + indexAxis: 'y', + scales: { + y: { + display: false + }, + x: { + grace: '5%' + } + } + } + }, + options: { + spriteText: true, + canvas: { + width: 512, + height: 128 + } + } +}; diff --git a/test/fixtures/scale.linear/grace-pos.png b/test/fixtures/scale.linear/grace-pos.png new file mode 100644 index 0000000000000000000000000000000000000000..e6b654505899ac04bf3af32930559f8528e2771a GIT binary patch literal 5286 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 PZ^(T_``r(AkrMs`pRFpX literal 0 Hc-jL100001 diff --git a/test/fixtures/scale.linear/grace.js b/test/fixtures/scale.linear/grace.js new file mode 100644 index 000000000..8f3f09f96 --- /dev/null +++ b/test/fixtures/scale.linear/grace.js @@ -0,0 +1,30 @@ +module.exports = { + description: 'https://github.com/chartjs/Chart.js/issues/7734', + config: { + type: 'bar', + data: { + labels: ['a', 'b'], + datasets: [{ + data: [1.2, -0.2], + }], + }, + options: { + indexAxis: 'y', + scales: { + y: { + display: false + }, + x: { + grace: 0.3 + } + } + } + }, + options: { + spriteText: true, + canvas: { + width: 512, + height: 128 + } + } +}; diff --git a/test/fixtures/scale.linear/grace.png b/test/fixtures/scale.linear/grace.png new file mode 100644 index 0000000000000000000000000000000000000000..b7556e412eda2a4fd730c08187497d59b5de958a GIT binary patch literal 4729 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 literal 0 Hc-jL100001 -- 2.47.2