Skip to content

Commit d48a62a

Browse files
authored
Add backgroundColor for scales (#8606)
* Add backgroundColor for scales * Loosen the threshold
1 parent 0c83843 commit d48a62a

File tree

9 files changed

+215
-49
lines changed

9 files changed

+215
-49
lines changed

docs/docs/axes/_common.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ Namespace: `options.scales[scaleId]`
55
| Name | Type | Default | Description
66
| ---- | ---- | ------- | -----------
77
| `type` | `string` | | Type of scale being employed. Custom scales can be created and registered with a string key. This allows changing the type of an axis for a chart.
8+
| `backgroundColor` | [`Color`](../general/colors.md) | | Background color of the scale area.
89
| `display` | `boolean`\|`string` | `true` | Controls the axis global visibility (visible when `true`, hidden when `false`). When `display: 'auto'`, the axis is visible only if at least one associated dataset is visible.
910
| `gridLines` | `object` | | Grid line configuration. [more...](./styling.mdx#grid-line-configuration)
1011
| `min` | `number` | | User defined minimum number for the scale, overrides minimum value from data. [more...](./index.mdx#axis-range-settings)

src/core/core.scale.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1575,6 +1575,19 @@ export default class Scale extends Element {
15751575
}
15761576
}
15771577

1578+
/**
1579+
* @protected
1580+
*/
1581+
drawBackground() {
1582+
const {ctx, options: {backgroundColor}, left, top, width, height} = this;
1583+
if (backgroundColor) {
1584+
ctx.save();
1585+
ctx.fillStyle = backgroundColor;
1586+
ctx.fillRect(left, top, width, height);
1587+
ctx.restore();
1588+
}
1589+
}
1590+
15781591
/**
15791592
* @protected
15801593
*/
@@ -1730,6 +1743,7 @@ export default class Scale extends Element {
17301743
return;
17311744
}
17321745

1746+
me.drawBackground();
17331747
me.drawGrid(chartArea);
17341748
me.drawTitle();
17351749
me.drawLabels(chartArea);
@@ -1758,6 +1772,7 @@ export default class Scale extends Element {
17581772
return [{
17591773
z: gz,
17601774
draw(chartArea) {
1775+
me.drawBackground();
17611776
me.drawGrid(chartArea);
17621777
me.drawTitle();
17631778
}

src/scales/scale.radialLinear.js

Lines changed: 64 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ function fitWithPointLabels(scale) {
9393
const labelSizes = [];
9494
const padding = [];
9595

96-
const valueCount = scale.chart.data.labels.length;
96+
const valueCount = scale.getLabels().length;
9797
for (i = 0; i < valueCount; i++) {
9898
const opts = scale.options.pointLabels.setContext(scale.getContext(i));
9999
padding[i] = opts.padding;
@@ -196,17 +196,11 @@ function adjustPointPositionForLabelHeight(angle, textSize, position) {
196196
}
197197
}
198198

199-
function drawPointLabels(scale) {
200-
const ctx = scale.ctx;
201-
const opts = scale.options;
202-
const pointLabelOpts = opts.pointLabels;
203-
204-
ctx.save();
205-
206-
ctx.textBaseline = 'middle';
199+
function drawPointLabels(scale, labelCount) {
200+
const {ctx, options: {pointLabels}} = scale;
207201

208-
for (let i = scale.chart.data.labels.length - 1; i >= 0; i--) {
209-
const optsAtIndex = pointLabelOpts.setContext(scale.getContext(i));
202+
for (let i = labelCount - 1; i >= 0; i--) {
203+
const optsAtIndex = pointLabels.setContext(scale.getContext(i));
210204
const plFont = toFont(optsAtIndex.font);
211205
const {x, y, textAlign} = scale._pointLabelItems[i];
212206
renderText(
@@ -218,45 +212,47 @@ function drawPointLabels(scale) {
218212
{
219213
color: optsAtIndex.color,
220214
textAlign: textAlign,
215+
textBaseline: 'middle'
221216
}
222217
);
223218
}
224-
ctx.restore();
225219
}
226220

227-
function drawRadiusLine(scale, gridLineOpts, radius) {
221+
function pathRadiusLine(scale, radius, circular, labelCount) {
222+
const {ctx} = scale;
223+
if (circular) {
224+
// Draw circular arcs between the points
225+
ctx.arc(scale.xCenter, scale.yCenter, radius, 0, TAU);
226+
} else {
227+
// Draw straight lines connecting each index
228+
let pointPosition = scale.getPointPosition(0, radius);
229+
ctx.moveTo(pointPosition.x, pointPosition.y);
230+
231+
for (let i = 1; i < labelCount; i++) {
232+
pointPosition = scale.getPointPosition(i, radius);
233+
ctx.lineTo(pointPosition.x, pointPosition.y);
234+
}
235+
}
236+
}
237+
238+
function drawRadiusLine(scale, gridLineOpts, radius, labelCount) {
228239
const ctx = scale.ctx;
229240
const circular = gridLineOpts.circular;
230-
const valueCount = scale.chart.data.labels.length;
231241

232-
const lineColor = gridLineOpts.color;
233-
const lineWidth = gridLineOpts.lineWidth;
234-
let pointPosition;
242+
const {color, lineWidth} = gridLineOpts;
235243

236-
if ((!circular && !valueCount) || !lineColor || !lineWidth || radius < 0) {
244+
if ((!circular && !labelCount) || !color || !lineWidth || radius < 0) {
237245
return;
238246
}
239247

240248
ctx.save();
241-
ctx.strokeStyle = lineColor;
249+
ctx.strokeStyle = color;
242250
ctx.lineWidth = lineWidth;
243251
ctx.setLineDash(gridLineOpts.borderDash);
244252
ctx.lineDashOffset = gridLineOpts.borderDashOffset;
245253

246254
ctx.beginPath();
247-
if (circular) {
248-
// Draw circular arcs between the points
249-
ctx.arc(scale.xCenter, scale.yCenter, radius, 0, TAU);
250-
} else {
251-
// Draw straight lines connecting each index
252-
pointPosition = scale.getPointPosition(0, radius);
253-
ctx.moveTo(pointPosition.x, pointPosition.y);
254-
255-
for (let i = 1; i < valueCount; i++) {
256-
pointPosition = scale.getPointPosition(i, radius);
257-
ctx.lineTo(pointPosition.x, pointPosition.y);
258-
}
259-
}
255+
pathRadiusLine(scale, radius, circular, labelCount);
260256
ctx.closePath();
261257
ctx.stroke();
262258
ctx.restore();
@@ -319,7 +315,7 @@ export default class RadialLinearScale extends LinearScaleBase {
319315
LinearScaleBase.prototype.generateTickLabels.call(me, ticks);
320316

321317
// Point labels
322-
me._pointLabels = me.chart.data.labels.map((value, index) => {
318+
me._pointLabels = me.getLabels().map((value, index) => {
323319
const label = callCallback(me.options.pointLabels.callback, [value, index], me);
324320
return label || label === 0 ? label : '';
325321
});
@@ -428,38 +424,56 @@ export default class RadialLinearScale extends LinearScaleBase {
428424
};
429425
}
430426

427+
/**
428+
* @protected
429+
*/
430+
drawBackground() {
431+
const me = this;
432+
const {backgroundColor, gridLines: {circular}} = me.options;
433+
if (backgroundColor) {
434+
const ctx = me.ctx;
435+
ctx.save();
436+
ctx.beginPath();
437+
pathRadiusLine(me, me.getDistanceFromCenterForValue(me._endValue), circular, me.getLabels().length);
438+
ctx.closePath();
439+
ctx.fillStyle = backgroundColor;
440+
ctx.fill();
441+
ctx.restore();
442+
}
443+
}
444+
431445
/**
432446
* @protected
433447
*/
434448
drawGrid() {
435449
const me = this;
436450
const ctx = me.ctx;
437451
const opts = me.options;
438-
const gridLineOpts = opts.gridLines;
439-
const angleLineOpts = opts.angleLines;
452+
const {angleLines, gridLines} = opts;
453+
const labelCount = me.getLabels().length;
454+
440455
let i, offset, position;
441456

442457
if (opts.pointLabels.display) {
443-
drawPointLabels(me);
458+
drawPointLabels(me, labelCount);
444459
}
445460

446-
if (gridLineOpts.display) {
461+
if (gridLines.display) {
447462
me.ticks.forEach((tick, index) => {
448463
if (index !== 0) {
449-
offset = me.getDistanceFromCenterForValue(me.ticks[index].value);
450-
const optsAtIndex = gridLineOpts.setContext(me.getContext(index - 1));
451-
drawRadiusLine(me, optsAtIndex, offset);
464+
offset = me.getDistanceFromCenterForValue(tick.value);
465+
const optsAtIndex = gridLines.setContext(me.getContext(index - 1));
466+
drawRadiusLine(me, optsAtIndex, offset, labelCount);
452467
}
453468
});
454469
}
455470

456-
if (angleLineOpts.display) {
471+
if (angleLines.display) {
457472
ctx.save();
458473

459-
for (i = me.chart.data.labels.length - 1; i >= 0; i--) {
460-
const optsAtIndex = angleLineOpts.setContext(me.getContext(i));
461-
const lineWidth = optsAtIndex.lineWidth;
462-
const color = optsAtIndex.color;
474+
for (i = me.getLabels().length - 1; i >= 0; i--) {
475+
const optsAtIndex = angleLines.setContext(me.getContext(i));
476+
const {color, lineWidth} = optsAtIndex;
463477

464478
if (!lineWidth || !color) {
465479
continue;
@@ -518,11 +532,12 @@ export default class RadialLinearScale extends LinearScaleBase {
518532
width = ctx.measureText(tick.label).width;
519533
ctx.fillStyle = optsAtIndex.backdropColor;
520534

535+
const {backdropPaddingX, backdropPaddingY} = optsAtIndex;
521536
ctx.fillRect(
522-
-width / 2 - optsAtIndex.backdropPaddingX,
523-
-offset - tickFont.size / 2 - optsAtIndex.backdropPaddingY,
524-
width + optsAtIndex.backdropPaddingX * 2,
525-
tickFont.size + optsAtIndex.backdropPaddingY * 2
537+
-width / 2 - backdropPaddingX,
538+
-offset - tickFont.size / 2 - backdropPaddingY,
539+
width + backdropPaddingX * 2,
540+
tickFont.size + backdropPaddingY * 2
526541
);
527542
}
528543

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
const ticks = {
2+
display: false
3+
};
4+
const gridLines = {
5+
display: false
6+
};
7+
const title = {
8+
display: true,
9+
test: ''
10+
};
11+
module.exports = {
12+
config: {
13+
type: 'line',
14+
options: {
15+
events: [],
16+
scales: {
17+
top: {
18+
type: 'linear',
19+
backgroundColor: 'red',
20+
position: 'top',
21+
ticks,
22+
gridLines,
23+
title
24+
},
25+
left: {
26+
type: 'linear',
27+
backgroundColor: 'green',
28+
position: 'left',
29+
ticks,
30+
gridLines,
31+
title
32+
},
33+
bottom: {
34+
type: 'linear',
35+
backgroundColor: 'blue',
36+
position: 'bottom',
37+
ticks,
38+
gridLines,
39+
title
40+
},
41+
right: {
42+
type: 'linear',
43+
backgroundColor: 'gray',
44+
position: 'right',
45+
ticks,
46+
gridLines,
47+
title
48+
},
49+
}
50+
}
51+
},
52+
options: {
53+
canvas: {
54+
height: 256,
55+
width: 256
56+
},
57+
}
58+
};
2.07 KB
Loading
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
module.exports = {
2+
threshold: 0.01,
3+
config: {
4+
type: 'radar',
5+
data: {
6+
labels: [1, 2, 3, 4, 5, 6],
7+
datasets: [
8+
{
9+
data: [3, 2, 2, 1, 3, 1]
10+
}
11+
]
12+
},
13+
options: {
14+
plugins: {
15+
legend: false,
16+
tooltip: false,
17+
filler: false
18+
},
19+
scales: {
20+
r: {
21+
backgroundColor: '#00FF00',
22+
min: 0,
23+
max: 3,
24+
pointLabels: {
25+
display: false
26+
},
27+
ticks: {
28+
display: false,
29+
stepSize: 1,
30+
}
31+
}
32+
},
33+
responsive: true,
34+
maintainAspectRatio: false
35+
}
36+
},
37+
};
28.2 KB
Loading
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
module.exports = {
2+
threshold: 0.05,
3+
config: {
4+
type: 'radar',
5+
data: {
6+
labels: [1, 2, 3, 4, 5, 6],
7+
datasets: [
8+
{
9+
data: [3, 2, 2, 1, 3, 1]
10+
}
11+
]
12+
},
13+
options: {
14+
plugins: {
15+
legend: false,
16+
tooltip: false,
17+
filler: false
18+
},
19+
scales: {
20+
r: {
21+
backgroundColor: '#00FF00',
22+
min: 0,
23+
max: 3,
24+
gridLines: {
25+
circular: true
26+
},
27+
pointLabels: {
28+
display: false
29+
},
30+
ticks: {
31+
display: false,
32+
stepSize: 1,
33+
}
34+
}
35+
},
36+
responsive: true,
37+
maintainAspectRatio: false
38+
}
39+
},
40+
};
36.8 KB
Loading

0 commit comments

Comments
 (0)