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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

P^qA)EF?!OQi>J%R4>@uiAnwhs-e zUtnLsh0nW8-&V(aP1Bk#vZO05K# zgLYQiref~g7Sl>TKVH#q;}~)ei9TNrDq5TREe(T{Fv4YBWz^$quWf0wnPCYredUn6 ze0S3m-Gxt*O0EHQb08YOn8$<9NTVav-%vqEW_NpY+4FT^A3tGI6kh?=z9xwgI*@=g zSk&*4S-bBywWazxzTs_Lmz;{9G62^8o1SR!BFrKV=T3w+jBo(n2ufkh8-jfz2r7!__~N_YGm63Z{*1g+q)^2b8uGj{CA5n zKw!(lYhYvFKGQJyJi0>~-kvke4lIG1#-p*K?d3Y$51=VwAT4YBYxc+sgM@hwDVZut zNr+?7AvkN=jR9L+dhJpTHW}PA6D8#14RS~wp?=E+yCH8izP|Xc>SfKo@feHDuwA^e zP;Jae2)AE!7%|Ox#!q;|PPWtrAc0U6Ey{9d_hIQ8VZ5OO6e{2ilq@W4j3?9&#L){`SxP3{}mWOEKlU@ zs$Tv4`UfvSeb{QV>&f^NlIgXR@emqF#GL~zOp z^Xv<{11lP=fp)Zkvt zrPrUlYjd#}Wk_SCs^>2K-f9+Qpi%fHfwO}}3aY+XeqmDt&}eIud>Bz+!1+QR-hPDE zlFmcz6E4en(_$MTsT*^Y96aiJ->eyQ194qlO1QXK^Qlf?9O#~Zo(UJajCqo)@!=qk zSi*>NqAWwhJb`i@lZ=IZnZ{zQx+*yHeZcC7Tqtt`-E$V-G2jU@374Cn@&kA7V`K)e zi_&5aOSwsx6^!siH#R^acXuRU>i8O!BtEtQ`cDgqY7lOzKy3+<+M9?Kryh9Lpz0WeiytH97e$+OI92HVOffX(;YP^mr5nz`5`H$^HfXfl4ac2;;~>Z7W& zKL2Ylsk9|`pUSe7ZdfL5B0){6YvRdJpUOG}XOt*yvN48t1LIg1R8$0KtW2VUYJ)*6 zRFw7I$}s4fV*9ds*4rWbKUuN{j*mu?`w1nwlRg|=!U&12nRqjp`&r+Kf=pC*ERCRU zo;(Fe@3oFGNT)KdL`qdvfqIw53OHhlOLcaGV~(aip9c0CbqoH@coDV!U&4fWodl}V z&7z6{&-~q+Gbzt&4X(e+z$KT15IYq9az~=DLU!Uuf0Hg?93iA4=#^UKdr$O;Ynth9 zCAu|CL9%gkw?}N8X9_(fD<_bps3oLdA|#!r*s7zLCS};{M4{-QK0}n%1%~D}O2~Vs z?QZm2;ig)jG6sgOFrEUv&wzPEY(<|xrZ&t=@se(tZuo77wi!}HT;IkDqXVbbi9w5f zHh`61p}}w}{Qeq7!m>`t@z!dxOb0jfpNE7B_wC=(5l>JGnF;1v>0;PjJE-LB8Lmas!}N>vjV`5Z$)w=^71RC;DtX@F2IB znGYy=x`Mn)^7>_AQ`FlFbfF$&Xk?v~;|_GF@*T9kQl3!D`MLGOsBAyWWmERltx~zq zC|*(*m4^e_u<4+T7)nOSHcCa2V{GhhJH(0;(-iQ(wWItY_bsH z(d5GA4hMNq@u9c(_#{*;(6M3RTGUbfoJ*fSy4cUXPAvGiKnvMjK2IIXgEV4?Xe-t2 z%q{Vm&b?OCS}?S-TdURn=~14}ulwXHL5}3mT~krQNqlj?Z&7FBpyqG)v8CspP^F^4 z)Qra-|rC`;IsnGa&yKM&|WN;giBe(`LKD4-B`ySjt6z+GhC*{u%r|&p6#{K8)q! z7e-eZrYORJ1N84Zn!d!mk|7x(?FWA6{W^I;h`|%cJ=IWg`S%%K2of-6`h9dkf_`1Q ex5D-JnSDlfJ!nw_PpKFHZbtg%dc|ka5&r_wa*iwj literal 0 HcmV?d00001 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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 literal 0 HcmV?d00001 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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 uk1v3Lz&>$zga6yAhk#n7iwS}Mnx&IYiW~7wZfO