From: Talla2XLC <50024798+Talla2XLC@users.noreply.github.com> Date: Sat, 12 Feb 2022 15:07:00 +0000 (+0300) Subject: Add new align 'inner' for X axis (#10106) X-Git-Tag: v3.8.0~43 X-Git-Url: http://git.ipfire.org/gitweb/gitweb.cgi?a=commitdiff_plain;h=7c14ab74aaeeba4cb3672f4a980abfda44f793a7;p=thirdparty%2FChart.js.git Add new align 'inner' for X axis (#10106) * Add new align for X axis new align 'left-right' for options.scales['x'].ticks namespace will allow users to aling ticks: 'start" for first (left) tick and 'end' for last (right) tick * corrected name of aligment to "inner", documentation and add test for inner labels * delete unnecessary changes * corrected logic for reverse axis, add tests for reverse axis and withoutY axis * corrected chart paddings for "inner" tick align * code clearness * Update types/index.esm.d.ts Co-authored-by: Jacco van den Berg <39033624+LeeLenaleee@users.noreply.github.com> Co-authored-by: Talla2XLC Co-authored-by: Jukka Kurkela Co-authored-by: Jacco van den Berg <39033624+LeeLenaleee@users.noreply.github.com> --- diff --git a/docs/axes/cartesian/_common_ticks.md b/docs/axes/cartesian/_common_ticks.md index aeb3992a0..ccc98588d 100644 --- a/docs/axes/cartesian/_common_ticks.md +++ b/docs/axes/cartesian/_common_ticks.md @@ -4,7 +4,7 @@ Namespace: `options.scales[scaleId].ticks` | Name | Type | Default | Description | ---- | ---- | ------- | ----------- -| `align` | `string` | `'center'` | The tick alignment along the axis. Can be `'start'`, `'center'`, or `'end'`. +| `align` | `string` | `'center'` | The tick alignment along the axis. Can be `'start'`, `'center'`, `'end'`, or `'inner'`. `inner` alignment means align `start` for first tick and `end` for the last tick of horizontal axis | `crossAlign` | `string` | `'near'` | The tick alignment perpendicular to the axis. Can be `'near'`, `'center'`, or `'far'`. See [Tick Alignment](/axes/cartesian/#tick-alignment) | `sampleSize` | `number` | `ticks.length` | The number of ticks to examine when deciding how many labels will fit. Setting a smaller value will be faster, but may be less accurate when there is large variability in label length. | `autoSkip` | `boolean` | `true` | If true, automatically calculates how many labels can be shown and hides labels accordingly. Labels will be rotated up to `maxRotation` before skipping any. Turn `autoSkip` off to show all labels no matter what. diff --git a/src/core/core.scale.js b/src/core/core.scale.js index 97529e591..1e79c1d97 100644 --- a/src/core/core.scale.js +++ b/src/core/core.scale.js @@ -705,7 +705,7 @@ export default class Scale extends Element { paddingRight = last.width; } else if (align === 'end') { paddingLeft = first.width; - } else { + } else if (align !== 'inner') { paddingLeft = first.width / 2; paddingRight = last.width / 2; } @@ -1206,9 +1206,21 @@ export default class Scale extends Element { const color = optsAtIndex.color; const strokeColor = optsAtIndex.textStrokeColor; const strokeWidth = optsAtIndex.textStrokeWidth; + let tickTextAlign = textAlign; if (isHorizontal) { x = pixel; + + if (textAlign === 'inner') { + if (i === ilen - 1) { + tickTextAlign = !this.options.reverse ? 'right' : 'left'; + } else if (i === 0) { + tickTextAlign = !this.options.reverse ? 'left' : 'right'; + } else { + tickTextAlign = 'center'; + } + } + if (position === 'top') { if (crossAlign === 'near' || rotation !== 0) { textOffset = -lineCount * lineHeight + lineHeight / 2; @@ -1285,7 +1297,7 @@ export default class Scale extends Element { strokeColor, strokeWidth, textOffset, - textAlign, + textAlign: tickTextAlign, textBaseline, translation: [x, y], backdrop, @@ -1309,6 +1321,8 @@ export default class Scale extends Element { align = 'left'; } else if (ticks.align === 'end') { align = 'right'; + } else if (ticks.align === 'inner') { + align = 'inner'; } return align; diff --git a/test/fixtures/core.scale/label-align-inner-onlyX.js b/test/fixtures/core.scale/label-align-inner-onlyX.js new file mode 100644 index 000000000..a64157c31 --- /dev/null +++ b/test/fixtures/core.scale/label-align-inner-onlyX.js @@ -0,0 +1,30 @@ +module.exports = { + config: { + type: 'line', + data: { + datasets: [{ + data: [1, 2, 3], + }], + labels: ['Label1_long', 'Label2_long', 'Label3_long'] + }, + options: { + scales: { + x: { + ticks: { + align: 'inner', + }, + }, + y: { + display: false + } + } + } + }, + options: { + spriteText: true, + canvas: { + height: 256, + width: 512 + } + } +}; diff --git a/test/fixtures/core.scale/label-align-inner-onlyX.png b/test/fixtures/core.scale/label-align-inner-onlyX.png new file mode 100644 index 000000000..7d5b039b5 Binary files /dev/null and b/test/fixtures/core.scale/label-align-inner-onlyX.png differ diff --git a/test/fixtures/core.scale/label-align-inner-reverse.js b/test/fixtures/core.scale/label-align-inner-reverse.js new file mode 100644 index 000000000..d56f6a04f --- /dev/null +++ b/test/fixtures/core.scale/label-align-inner-reverse.js @@ -0,0 +1,28 @@ +module.exports = { + config: { + type: 'line', + data: { + datasets: [{ + data: [1, 2, 3], + }], + labels: ['Label1', 'Label2', 'Label3'] + }, + options: { + scales: { + x: { + ticks: { + align: 'inner' + }, + reverse: true + } + } + } + }, + options: { + spriteText: true, + canvas: { + height: 256, + width: 512 + } + } +}; diff --git a/test/fixtures/core.scale/label-align-inner-reverse.png b/test/fixtures/core.scale/label-align-inner-reverse.png new file mode 100644 index 000000000..f1d8330bf Binary files /dev/null and b/test/fixtures/core.scale/label-align-inner-reverse.png differ diff --git a/test/fixtures/core.scale/label-align-inner-rotate.js b/test/fixtures/core.scale/label-align-inner-rotate.js new file mode 100644 index 000000000..7cee63a95 --- /dev/null +++ b/test/fixtures/core.scale/label-align-inner-rotate.js @@ -0,0 +1,29 @@ +module.exports = { + config: { + type: 'line', + data: { + datasets: [{ + data: [1, 2, 3], + }], + labels: ['Label1', 'Label2', 'Label3'] + }, + options: { + scales: { + x: { + ticks: { + align: 'inner', + maxRotation: 45, + minRotation: 45 + }, + } + } + } + }, + options: { + spriteText: true, + canvas: { + height: 256, + width: 512 + } + } +}; diff --git a/test/fixtures/core.scale/label-align-inner-rotate.png b/test/fixtures/core.scale/label-align-inner-rotate.png new file mode 100644 index 000000000..d3aca46fa Binary files /dev/null and b/test/fixtures/core.scale/label-align-inner-rotate.png differ diff --git a/test/fixtures/core.scale/label-align-inner.js b/test/fixtures/core.scale/label-align-inner.js new file mode 100644 index 000000000..ef62e9b66 --- /dev/null +++ b/test/fixtures/core.scale/label-align-inner.js @@ -0,0 +1,27 @@ +module.exports = { + config: { + type: 'line', + data: { + datasets: [{ + data: [1, 2, 3], + }], + labels: ['Label1', 'Label2', 'Label3'] + }, + options: { + scales: { + x: { + ticks: { + align: 'inner', + }, + } + } + } + }, + options: { + spriteText: true, + canvas: { + height: 256, + width: 512 + } + } +}; diff --git a/test/fixtures/core.scale/label-align-inner.png b/test/fixtures/core.scale/label-align-inner.png new file mode 100644 index 000000000..f420956f6 Binary files /dev/null and b/test/fixtures/core.scale/label-align-inner.png differ diff --git a/types/index.esm.d.ts b/types/index.esm.d.ts index ccea41280..a4f463c25 100644 --- a/types/index.esm.d.ts +++ b/types/index.esm.d.ts @@ -3020,7 +3020,7 @@ export interface CartesianScaleOptions extends CoreScaleOptions { * The label alignment * @default 'center' */ - align: Align; + align: Align | 'inner'; /** * If true, automatically calculates how many labels can be shown and hides labels accordingly. Labels will be rotated up to maxRotation before skipping any. Turn autoSkip off to show all labels no matter what. * @default true