Skip to content

Commit cdba66c

Browse files
authored
Scale: draw offset grid for labels before autoSkip (#8748)
* Scale: draw offset grid for labels before autoSkip * fix tests
1 parent fe406bf commit cdba66c

21 files changed

+99
-33
lines changed

docs/docs/axes/styling.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ Namespace: `options.scales[scaleId].grid`, it defines options for the grid lines
2323
| `drawOnChartArea` | `boolean` | | | `true` | If true, draw lines on the chart area inside the axis lines. This is useful when there are multiple axes and you need to control which grid lines are drawn.
2424
| `drawTicks` | `boolean` | | | `true` | If true, draw lines beside the ticks in the axis area beside the chart.
2525
| `lineWidth` | `number` | Yes | Yes | `1` | Stroke width of grid lines.
26-
| `offset` | `boolean` | | | `false` | If true, grid lines will be shifted to be between labels. This is set to `true` for a bar chart by default.
26+
| `offset` | `boolean` | | | `false` | If true, grid lines will be shifted to be between labels. This is set to `true` for a bar chart by default. Note: AutoSkip does not remove offset grid lines.
2727
| `tickBorderDash` | `number[]` | | | | Length and spacing of the tick mark line. If not set, defaults to the grid line `borderDash` value.
2828
| `tickBorderDashOffset` | `number` | Yes | Yes | | Offset for the line dash of the tick mark. If unset, defaults to the grid line `borderDashOffset` value
2929
| `tickColor` | [`Color`](../general/colors.md) | Yes | Yes | | Color of the tick line. If unset, defaults to the grid line color.

src/core/core.scale.js

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -42,21 +42,21 @@ function sample(arr, numItems) {
4242
* @param {boolean} offsetGridLines
4343
*/
4444
function getPixelForGridLine(scale, index, offsetGridLines) {
45-
const length = scale.ticks.length;
45+
const length = offsetGridLines ? scale._allTicks.length : scale.ticks.length;
4646
const validIndex = Math.min(index, length - 1);
4747
const start = scale._startPixel;
4848
const end = scale._endPixel;
4949
const epsilon = 1e-6; // 1e-6 is margin in pixels for accumulated error.
50-
let lineValue = scale.getPixelForTick(validIndex);
50+
let lineValue = scale.getPixelForTick(validIndex, offsetGridLines);
5151
let offset;
5252

5353
if (offsetGridLines) {
5454
if (length === 1) {
5555
offset = Math.max(lineValue - start, end - lineValue);
5656
} else if (index === 0) {
57-
offset = (scale.getPixelForTick(1) - lineValue) / 2;
57+
offset = (scale.getPixelForTick(1, offsetGridLines) - lineValue) / 2;
5858
} else {
59-
offset = (lineValue - scale.getPixelForTick(validIndex - 1)) / 2;
59+
offset = (lineValue - scale.getPixelForTick(validIndex - 1, offsetGridLines)) / 2;
6060
}
6161
lineValue += validIndex < index ? offset : -offset;
6262

@@ -205,7 +205,7 @@ export default class Scale extends Element {
205205
this.min = undefined;
206206
this.max = undefined;
207207
/** @type {Tick[]} */
208-
this.ticks = [];
208+
this.ticks = this._allTicks = [];
209209
/** @type {object[]|null} */
210210
this._gridLineItems = null;
211211
/** @type {object[]|null} */
@@ -428,6 +428,7 @@ export default class Scale extends Element {
428428
me.afterCalculateLabelRotation();
429429

430430
// Auto-skip
431+
me._allTicks = me.ticks;
431432
if (tickOpts.display && (tickOpts.autoSkip || tickOpts.source === 'auto')) {
432433
me.ticks = autoSkip(me, me.ticks);
433434
me._labelSizes = null;
@@ -666,7 +667,7 @@ export default class Scale extends Element {
666667

667668
_calculatePadding(first, last, sin, cos) {
668669
const me = this;
669-
const {ticks: {align, padding}, position} = me.options;
670+
const {position, ticks: {align, padding}} = me.options;
670671
const isRotated = me.labelRotation !== 0;
671672
const labelsBelowTicks = position !== 'top' && me.axis === 'x';
672673

@@ -696,8 +697,8 @@ export default class Scale extends Element {
696697
}
697698

698699
// Adjust padding taking into account changes in offsets
699-
me.paddingLeft = Math.max((paddingLeft - offsetLeft + padding) * me.width / (me.width - offsetLeft), 0);
700-
me.paddingRight = Math.max((paddingRight - offsetRight + padding) * me.width / (me.width - offsetRight), 0);
700+
me.paddingLeft = Math.max((paddingLeft - offsetLeft + padding) * me.width / (me.width - offsetLeft), padding);
701+
me.paddingRight = Math.max((paddingRight - offsetRight + padding) * me.width / (me.width - offsetRight), padding);
701702
} else {
702703
let paddingTop = last.height / 2;
703704
let paddingBottom = first.height / 2;
@@ -871,10 +872,11 @@ export default class Scale extends Element {
871872
* Returns the location of the tick at the given index
872873
* The coordinate (0, 0) is at the upper-left corner of the canvas
873874
* @param {number} index
875+
* @param {boolean} [all] - use ticks before autoSkip
874876
* @return {number}
875877
*/
876-
getPixelForTick(index) {
877-
const ticks = this.ticks;
878+
getPixelForTick(index, all = false) {
879+
const ticks = all ? this._allTicks : this.ticks;
878880
if (index < 0 || index > ticks.length - 1) {
879881
return null;
880882
}
@@ -992,7 +994,7 @@ export default class Scale extends Element {
992994
const {grid, position} = options;
993995
const offset = grid.offset;
994996
const isHorizontal = me.isHorizontal();
995-
const ticks = me.ticks;
997+
const ticks = offset ? me._allTicks : me.ticks;
996998
const ticksLength = ticks.length + (offset ? 1 : 0);
997999
const tl = getTickMarkLength(grid);
9981000
const items = [];

src/scales/scale.category.js

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -109,17 +109,6 @@ export default class CategoryScale extends Scale {
109109
return value === null ? NaN : me.getPixelForDecimal((value - me._startValue) / me._valueRange);
110110
}
111111

112-
// Must override base implementation because it calls getPixelForValue
113-
// and category scale can have duplicate values
114-
getPixelForTick(index) {
115-
const me = this;
116-
const ticks = me.ticks;
117-
if (index < 0 || index > ticks.length - 1) {
118-
return null;
119-
}
120-
return me.getPixelForValue(ticks[index].value);
121-
}
122-
123112
getValueForPixel(pixel) {
124113
const me = this;
125114
return Math.round(me._startValue + me.getDecimalForPixel(pixel) * me._valueRange);
464 Bytes
Loading
-73 Bytes
Loading
-63 Bytes
Loading
-9 Bytes
Loading
-151 Bytes
Loading
12 Bytes
Loading
10 Bytes
Loading

0 commit comments

Comments
 (0)