Skip to content

Commit

Permalink
Cartesian scale tick backdrop (#8931)
Browse files Browse the repository at this point in the history
  • Loading branch information
etimberg committed Apr 18, 2021
1 parent e29ba78 commit af7965f
Show file tree
Hide file tree
Showing 9 changed files with 154 additions and 32 deletions.
3 changes: 3 additions & 0 deletions docs/axes/_common_ticks.md
Expand Up @@ -4,12 +4,15 @@ Namespace: `options.scales[scaleId].ticks`

| Name | Type | Scriptable | Default | Description
| ---- | ---- | :-------------------------------: | ------- | -----------
| `backdropColor` | [`Color`](../../general/colors.md) | Yes | `'rgba(255, 255, 255, 0.75)'` | Color of label backdrops.
| `backdropPadding` | [`Padding`](../../general/padding.md) | Yes | `2` | Padding of label backdrop.
| `callback` | `function` | | | Returns the string representation of the tick value as it should be displayed on the chart. See [callback](/axes/labelling.md#creating-custom-tick-formats).
| `display` | `boolean` | | `true` | If true, show tick labels.
| `color` | [`Color`](/general/colors.md) | Yes | `Chart.defaults.color` | Color of ticks.
| `font` | `Font` | Yes | `Chart.defaults.font` | See [Fonts](/general/fonts.md)
| `major` | `object` | | `{}` | [Major ticks configuration](/axes/styling.md#major-tick-configuration).
| `padding` | `number` | | `3` | Sets the offset of the tick labels from the axis
| `showLabelBackdrop` | `boolean` | Yes | `true` for radial scale, `false` otherwise | If true, draw a background behind the tick labels.
| `textStrokeColor` | [`Color`](/general/colors.md) | Yes | `` | The color of the stroke around the text.
| `textStrokeWidth` | `number` | Yes | `0` | Stroke width around the text.
| `z` | `number` | | `0` | z-index of tick layer. Useful when ticks are drawn on chart area. Values <= 0 are drawn under datasets, > 0 on top.
3 changes: 0 additions & 3 deletions docs/axes/radial/linear.md
Expand Up @@ -28,14 +28,11 @@ Namespace: `options.scales[scaleId].ticks`

| Name | Type | Scriptable | Default | Description
| ---- | ---- | ------- | ------- | -----------
| `backdropColor` | [`Color`](../../general/colors.md) | Yes | `'rgba(255, 255, 255, 0.75)'` | Color of label backdrops.
| `backdropPadding` | [`Padding`](../../general/padding.md) | Yes | `2` | Padding of label backdrop.
| `count` | `number` | Yes | `undefined` | The number of ticks to generate. If specified, this overrides the automatic generation.
| `format` | `object` | Yes | | 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` | Yes | `11` | Maximum number of ticks and gridlines to show.
| `precision` | `number` | Yes | | if defined and `stepSize` is not specified, the step size will be rounded to this many decimal places.
| `stepSize` | `number` | Yes | | User defined fixed step size for the scale. [more...](#step-size)
| `showLabelBackdrop` | `boolean` | Yes | `true` | If true, draw a background behind the tick labels.

!!!include(axes/_common_ticks.md)!!!

Expand Down
4 changes: 4 additions & 0 deletions src/core/core.scale.defaults.js
Expand Up @@ -71,6 +71,10 @@ defaults.set('scale', {
major: {},
align: 'center',
crossAlign: 'near',

showLabelBackdrop: false,
backdropColor: 'rgba(255, 255, 255, 0.75)',
backdropPadding: 2,
}
});

Expand Down
59 changes: 55 additions & 4 deletions src/core/core.scale.js
Expand Up @@ -773,7 +773,7 @@ export default class Scale extends Element {
}

/**
* @return {{ first: object, last: object, widest: object, highest: object }}
* @return {{ first: object, last: object, widest: object, highest: object, widths: Array, heights: array }}
* @private
*/
_getLabelSizes() {
Expand All @@ -796,7 +796,7 @@ export default class Scale extends Element {
/**
* Returns {width, height, offset} objects for the first, last, widest, highest tick
* labels where offset indicates the anchor point offset from the top in pixels.
* @return {{ first: object, last: object, widest: object, highest: object }}
* @return {{ first: object, last: object, widest: object, highest: object, widths: Array, heights: array }}
* @private
*/
_computeLabelSizes(ticks, length) {
Expand Down Expand Up @@ -845,7 +845,9 @@ export default class Scale extends Element {
first: valueAt(0),
last: valueAt(length - 1),
widest: valueAt(widest),
highest: valueAt(highest)
highest: valueAt(highest),
widths,
heights,
};
}

Expand Down Expand Up @@ -1226,6 +1228,48 @@ export default class Scale extends Element {
textOffset = (1 - lineCount) * lineHeight / 2;
}

let backdrop;

if (optsAtIndex.showLabelBackdrop) {
const labelPadding = toPadding(optsAtIndex.backdropPadding);
const height = labelSizes.heights[i];
const width = labelSizes.widths[i];

let top = y + textOffset - labelPadding.top;
let left = x - labelPadding.left;

switch (textBaseline) {
case 'middle':
top -= height / 2;
break;
case 'bottom':
top -= height;
break;
default:
break;
}

switch (textAlign) {
case 'center':
left -= width / 2;
break;
case 'right':
left -= width;
break;
default:
break;
}

backdrop = {
left,
top,
width: width + labelPadding.width,
height: height + labelPadding.height,

color: optsAtIndex.backdropColor,
};
}

items.push({
rotation,
label,
Expand All @@ -1236,7 +1280,8 @@ export default class Scale extends Element {
textOffset,
textAlign,
textBaseline,
translation: [x, y]
translation: [x, y],
backdrop,
});
}

Expand Down Expand Up @@ -1466,6 +1511,12 @@ export default class Scale extends Element {
const item = items[i];
const tickFont = item.font;
const label = item.label;

if (item.backdrop) {
ctx.fillStyle = item.backdrop.color;
ctx.fillRect(item.backdrop.left, item.backdrop.top, item.backdrop.width, item.backdrop.height);
}

let y = item.textOffset;
renderText(ctx, label, 0, y, tickFont, item);
}
Expand Down
6 changes: 0 additions & 6 deletions src/scales/scale.radialLinear.js
Expand Up @@ -594,12 +594,6 @@ RadialLinearScale.defaults = {
// Boolean - Show a backdrop to the scale label
showLabelBackdrop: true,

// String - The colour of the label backdrop
backdropColor: 'rgba(255,255,255,0.75)',

// Number/Object - The backdrop padding of the label in pixels
backdropPadding: 2,

callback: Ticks.formatters.numeric
},

Expand Down
76 changes: 76 additions & 0 deletions test/fixtures/core.scale/tick-backdrop.js
@@ -0,0 +1,76 @@
const grid = {
display: false
};
const title = {
display: false,
};
module.exports = {
config: {
type: 'line',
options: {
events: [],
scales: {
top: {
type: 'linear',
position: 'top',
ticks: {
display: true,
showLabelBackdrop: true,
backdropColor: 'red',
backdropPadding: 5,
align: 'start',
crossAlign: 'near',
},
grid,
title
},
left: {
type: 'linear',
position: 'left',
ticks: {
display: true,
showLabelBackdrop: true,
backdropColor: 'green',
backdropPadding: 5,
crossAlign: 'center',
},
grid,
title
},
bottom: {
type: 'linear',
position: 'bottom',
ticks: {
display: true,
showLabelBackdrop: true,
backdropColor: 'blue',
backdropPadding: 5,
align: 'end',
crossAlign: 'far',
},
grid,
title
},
right: {
type: 'linear',
position: 'right',
ticks: {
display: true,
showLabelBackdrop: true,
backdropColor: 'gray',
backdropPadding: 5,
},
grid,
title
},
}
}
},
options: {
canvas: {
height: 256,
width: 256
},
spriteText: true,
}
};
Binary file added test/fixtures/core.scale/tick-backdrop.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 0 additions & 2 deletions test/specs/scale.radialLinear.tests.js
Expand Up @@ -36,8 +36,6 @@ describe('Test the radial linear scale', function() {
ticks: {
color: Chart.defaults.color,
showLabelBackdrop: true,
backdropColor: 'rgba(255,255,255,0.75)',
backdropPadding: 2,
callback: defaultConfig.ticks.callback
},

Expand Down
33 changes: 16 additions & 17 deletions types/index.esm.d.ts
Expand Up @@ -2693,6 +2693,17 @@ export interface GridLineOptions {
}

export interface TickOptions {
/**
* Color of label backdrops.
* @default 'rgba(255, 255, 255, 0.75)'
*/
backdropColor: Scriptable<Color, ScriptableScaleContext>;
/**
* Padding of tick backdrop.
* @default 2
*/
backdropPadding: number | ChartArea;

/**
* Returns the string representation of the tick value as it should be displayed on the chart. See callback.
*/
Expand All @@ -2715,6 +2726,11 @@ export interface TickOptions {
* Sets the offset of the tick labels from the axis
*/
padding: number;
/**
* If true, draw a background behind the tick labels.
* @default false
*/
showLabelBackdrop: Scriptable<boolean, ScriptableScaleContext>;
/**
* The color of the stroke around the text.
* @default undefined
Expand Down Expand Up @@ -3116,17 +3132,6 @@ export type RadialLinearScaleOptions = CoreScaleOptions & {
suggestedMin: number;

ticks: TickOptions & {
/**
* Color of label backdrops.
* @default 'rgba(255, 255, 255, 0.75)'
*/
backdropColor: Scriptable<Color, ScriptableScaleContext>;
/**
* Padding of label backdrop.
* @default 2
*/
backdropPadding: number | ChartArea;

/**
* The Intl.NumberFormat options used by the default label formatter
*/
Expand All @@ -3152,12 +3157,6 @@ export type RadialLinearScaleOptions = CoreScaleOptions & {
* User defined number of ticks
*/
count: number;

/**
* If true, draw a background behind the tick labels.
* @default true
*/
showLabelBackdrop: Scriptable<boolean, ScriptableScaleContext>;
};
};

Expand Down

0 comments on commit af7965f

Please sign in to comment.