Skip to content

Commit a69b386

Browse files
committed
Scales
1 parent 752b572 commit a69b386

File tree

5 files changed

+71
-88
lines changed

5 files changed

+71
-88
lines changed

src/core/core.controller.js

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -248,15 +248,10 @@ class Chart {
248248
ensureScalesHaveIDs() {
249249
const options = this.options;
250250
const scalesOptions = options.scales || {};
251-
const scaleOptions = options.scale;
252251

253252
each(scalesOptions, (axisOptions, axisID) => {
254253
axisOptions.id = axisID;
255254
});
256-
257-
if (scaleOptions) {
258-
scaleOptions.id = scaleOptions.id || 'scale';
259-
}
260255
}
261256

262257
/**
@@ -266,7 +261,7 @@ class Chart {
266261
const me = this;
267262
const options = me.options;
268263
const scaleOpts = options.scales;
269-
const scales = me.scales || {};
264+
const scales = me.scales;
270265
const updated = Object.keys(scales).reduce((obj, id) => {
271266
obj[id] = false;
272267
return obj;
@@ -323,8 +318,6 @@ class Chart {
323318
}
324319
});
325320

326-
me.scales = scales;
327-
328321
each(scales, (scale) => {
329322
layouts.configure(me, scale, scale.options);
330323
layouts.addBox(me, scale);

src/core/core.scale.js

Lines changed: 32 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import Element from './core.element';
33
import {_alignPixel, _measureText, renderText, clipArea, unclipArea} from '../helpers/helpers.canvas';
44
import {callback as call, each, finiteOrDefault, isArray, isFinite, isNullOrUndef, isObject, valueOrDefault} from '../helpers/helpers.core';
55
import {_factorize, toDegrees, toRadians, _int16Range, HALF_PI} from '../helpers/helpers.math';
6-
import {toFont, resolve, toPadding} from '../helpers/helpers.options';
6+
import {toFont, toPadding} from '../helpers/helpers.options';
77
import Ticks from './core.ticks';
88

99
/**
@@ -34,9 +34,13 @@ defaults.set('scale', {
3434
drawOnChartArea: true,
3535
drawTicks: true,
3636
tickLength: 10,
37+
tickWidth: (_ctx, options) => options.lineWidth,
38+
tickColor: (_ctx, options) => options.color,
3739
offsetGridLines: false,
3840
borderDash: [],
39-
borderDashOffset: 0.0
41+
borderDashOffset: 0.0,
42+
borderColor: (_ctx, options) => options.color,
43+
borderWidth: (_ctx, options) => options.lineWidth
4044
},
4145

4246
// scale label
@@ -80,15 +84,9 @@ defaults.route('scale.gridLines', 'color', '', 'borderColor');
8084
defaults.route('scale.scaleLabel', 'color', '', 'color');
8185

8286
defaults.describe('scales', {
83-
_defaultId: (ctx, options) => options.axis === options.indexAxis ? '_index_' : '_value_',
8487
_fallback: 'scale',
85-
_scriptable: (name) => !name.startsWith('before') && !name.startsWith('after'),
86-
ticks: {
87-
_scriptable: (name) => name !== 'callback'
88-
},
89-
gridLines: {
90-
_indexable: (name) => name !== 'borderDash' && name !== 'tickBorderDash'
91-
}
88+
_scriptable: (name) => !name.startsWith('before') && !name.startsWith('after') && name !== 'callback' && name !== 'parser',
89+
_indexable: (name) => name !== 'borderDash' && name !== 'tickBorderDash',
9290
});
9391

9492
/**
@@ -408,7 +406,7 @@ export default class Scale extends Element {
408406
const me = this;
409407
me.options = options;
410408

411-
me.axis = me.isHorizontal() ? 'x' : 'y';
409+
me.axis = options.axis;
412410

413411
// parse min/max value, so we can properly determine min/max for other scales
414412
me._userMin = me.parse(options.min);
@@ -1218,8 +1216,8 @@ export default class Scale extends Element {
12181216
const tl = getTickMarkLength(gridLines);
12191217
const items = [];
12201218

1221-
let context = this.getContext(0);
1222-
const axisWidth = gridLines.drawBorder ? resolve([gridLines.borderWidth, gridLines.lineWidth, 0], context, 0) : 0;
1219+
const borderOpts = gridLines.setContext(me.getContext(0));
1220+
const axisWidth = borderOpts.drawBorder ? borderOpts.borderWidth : 0;
12231221
const axisHalfWidth = axisWidth / 2;
12241222
const alignBorderValue = function(pixel) {
12251223
return _alignPixel(chart, pixel, axisWidth);
@@ -1280,17 +1278,17 @@ export default class Scale extends Element {
12801278
}
12811279

12821280
for (i = 0; i < ticksLength; ++i) {
1283-
context = this.getContext(i);
1281+
const optsAtIndex = gridLines.setContext(me.getContext(i));
12841282

1285-
const lineWidth = resolve([gridLines.lineWidth], context, i);
1286-
const lineColor = resolve([gridLines.color], context, i);
1283+
const lineWidth = optsAtIndex.lineWidth;
1284+
const lineColor = optsAtIndex.color;
12871285
const borderDash = gridLines.borderDash || [];
1288-
const borderDashOffset = resolve([gridLines.borderDashOffset], context, i);
1286+
const borderDashOffset = optsAtIndex.borderDashOffset;
12891287

1290-
const tickWidth = resolve([gridLines.tickWidth, lineWidth], context, i);
1291-
const tickColor = resolve([gridLines.tickColor, lineColor], context, i);
1292-
const tickBorderDash = gridLines.tickBorderDash || borderDash;
1293-
const tickBorderDashOffset = resolve([gridLines.tickBorderDashOffset, borderDashOffset], context, i);
1288+
const tickWidth = optsAtIndex.tickWidth;
1289+
const tickColor = optsAtIndex.tickColor;
1290+
const tickBorderDash = optsAtIndex.tickBorderDash || [];
1291+
const tickBorderDashOffset = optsAtIndex.tickBorderDashOffset;
12941292

12951293
lineValue = getPixelForGridLine(me, i, offsetGridLines);
12961294

@@ -1398,14 +1396,15 @@ export default class Scale extends Element {
13981396
tick = ticks[i];
13991397
label = tick.label;
14001398

1399+
const optsAtIndex = optionTicks.setContext(me.getContext(i));
14011400
pixel = me.getPixelForTick(i) + optionTicks.labelOffset;
14021401
font = me._resolveTickFontOptions(i);
14031402
lineHeight = font.lineHeight;
14041403
lineCount = isArray(label) ? label.length : 1;
14051404
const halfCount = lineCount / 2;
1406-
const color = resolve([optionTicks.color], me.getContext(i), i);
1407-
const strokeColor = resolve([optionTicks.textStrokeColor], me.getContext(i), i);
1408-
const strokeWidth = resolve([optionTicks.textStrokeWidth], me.getContext(i), i);
1405+
const color = optsAtIndex.color;
1406+
const strokeColor = optsAtIndex.textStrokeColor;
1407+
const strokeWidth = optsAtIndex.textStrokeWidth;
14091408

14101409
if (isHorizontal) {
14111410
x = pixel;
@@ -1551,8 +1550,8 @@ export default class Scale extends Element {
15511550
const gridLines = me.options.gridLines;
15521551
const ctx = me.ctx;
15531552
const chart = me.chart;
1554-
let context = me.getContext(0);
1555-
const axisWidth = gridLines.drawBorder ? resolve([gridLines.borderWidth, gridLines.lineWidth, 0], context, 0) : 0;
1553+
const borderOpts = gridLines.setContext(me.getContext(0));
1554+
const axisWidth = gridLines.drawBorder ? borderOpts.borderWidth : 0;
15561555
const items = me._gridLineItems || (me._gridLineItems = me._computeGridLineItems(chartArea));
15571556
let i, ilen;
15581557

@@ -1597,24 +1596,23 @@ export default class Scale extends Element {
15971596

15981597
if (axisWidth) {
15991598
// Draw the line at the edge of the axis
1600-
const firstLineWidth = axisWidth;
1601-
context = me.getContext(me._ticksLength - 1);
1602-
const lastLineWidth = resolve([gridLines.lineWidth, 1], context, me._ticksLength - 1);
1599+
const edgeOpts = gridLines.setContext(me.getContext(me._ticksLength - 1));
1600+
const lastLineWidth = edgeOpts.lineWidth;
16031601
const borderValue = me._borderValue;
16041602
let x1, x2, y1, y2;
16051603

16061604
if (me.isHorizontal()) {
1607-
x1 = _alignPixel(chart, me.left, firstLineWidth) - firstLineWidth / 2;
1605+
x1 = _alignPixel(chart, me.left, axisWidth) - axisWidth / 2;
16081606
x2 = _alignPixel(chart, me.right, lastLineWidth) + lastLineWidth / 2;
16091607
y1 = y2 = borderValue;
16101608
} else {
1611-
y1 = _alignPixel(chart, me.top, firstLineWidth) - firstLineWidth / 2;
1609+
y1 = _alignPixel(chart, me.top, axisWidth) - axisWidth / 2;
16121610
y2 = _alignPixel(chart, me.bottom, lastLineWidth) + lastLineWidth / 2;
16131611
x1 = x2 = borderValue;
16141612
}
16151613

16161614
ctx.lineWidth = axisWidth;
1617-
ctx.strokeStyle = resolve([gridLines.borderColor, gridLines.color], context, 0);
1615+
ctx.strokeStyle = edgeOpts.borderColor;
16181616
ctx.beginPath();
16191617
ctx.moveTo(x1, y1);
16201618
ctx.lineTo(x2, y2);
@@ -1800,11 +1798,8 @@ export default class Scale extends Element {
18001798
* @protected
18011799
*/
18021800
_resolveTickFontOptions(index) {
1803-
const me = this;
1804-
const chart = me.chart;
1805-
const options = me.options.ticks;
1806-
const context = me.getContext(index);
1807-
return toFont(resolve([options.font], context), chart.options.font);
1801+
const opts = this.options.ticks.setContext(this.getContext(index));
1802+
return toFont(opts.font);
18081803
}
18091804
}
18101805

src/helpers/helpers.config.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,8 @@ export function _attachContext(proxy, context, subProxy) {
4848
_context: context,
4949
_subProxy: subProxy,
5050
_stack: new Set(),
51-
_descriptors: _descriptors(proxy)
51+
_descriptors: _descriptors(proxy),
52+
setContext: (ctx) => _attachContext(proxy, ctx, subProxy)
5253
};
5354
return new Proxy(cache, {
5455
get(target, prop, receiver) {
@@ -83,7 +84,7 @@ export function _descriptors(proxy) {
8384
}
8485

8586
const readKey = (prefix, name) => prefix ? prefix + _capitalize(name) : name;
86-
const needsSubResolver = (prop, value) => isObject(value) && prop !== 'scales';
87+
const needsSubResolver = (prop, value) => isObject(value);
8788

8889
function _cached(target, prop, resolve) {
8990
let value = target[prop]; // cached value

src/scales/scale.radialLinear.js

Lines changed: 33 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import {HALF_PI, isNumber, TAU, toDegrees, toRadians, _normalizeAngle} from '../
44
import LinearScaleBase from './scale.linearbase';
55
import Ticks from '../core/core.ticks';
66
import {valueOrDefault, isArray, isFinite, callback as callCallback, isNullOrUndef} from '../helpers/helpers.core';
7-
import {toFont, resolve} from '../helpers/helpers.options';
7+
import {toFont} from '../helpers/helpers.options';
88

99
function getTickBackdropHeight(opts) {
1010
const tickOpts = opts.ticks;
@@ -95,9 +95,8 @@ function fitWithPointLabels(scale) {
9595
const valueCount = scale.chart.data.labels.length;
9696
for (i = 0; i < valueCount; i++) {
9797
pointPosition = scale.getPointPosition(i, scale.drawingArea + 5);
98-
99-
const context = scale.getContext(i);
100-
const plFont = toFont(resolve([scale.options.pointLabels.font], context, i), scale.chart.options.font);
98+
const opts = scale.options.pointLabels.setContext(scale.getContext(i));
99+
const plFont = toFont(opts.font);
101100
scale.ctx.font = plFont.string;
102101
textSize = measureLabelSize(scale.ctx, plFont.lineHeight, scale.pointLabels[i]);
103102
scale._pointLabelSizes[i] = textSize;
@@ -166,8 +165,8 @@ function drawPointLabels(scale) {
166165
const extra = (i === 0 ? tickBackdropHeight / 2 : 0);
167166
const pointLabelPosition = scale.getPointPosition(i, outerDistance + extra + 5);
168167

169-
const context = scale.getContext(i);
170-
const plFont = toFont(resolve([pointLabelOpts.font], context, i), scale.chart.options.font);
168+
const optsAtIndex = pointLabelOpts.setContext(scale.getContext(i));
169+
const plFont = toFont(optsAtIndex.font);
171170
const angle = toDegrees(scale.getIndexAngle(i));
172171
adjustPointPositionForLabelHeight(angle, scale._pointLabelSizes[i], pointLabelPosition);
173172
renderText(
@@ -177,22 +176,21 @@ function drawPointLabels(scale) {
177176
pointLabelPosition.y + (plFont.lineHeight / 2),
178177
plFont,
179178
{
180-
color: resolve([pointLabelOpts.color], context, i),
179+
color: optsAtIndex.color,
181180
textAlign: getTextAlignForAngle(angle),
182181
}
183182
);
184183
}
185184
ctx.restore();
186185
}
187186

188-
function drawRadiusLine(scale, gridLineOpts, radius, index) {
187+
function drawRadiusLine(scale, gridLineOpts, radius) {
189188
const ctx = scale.ctx;
190189
const circular = gridLineOpts.circular;
191190
const valueCount = scale.chart.data.labels.length;
192191

193-
const context = scale.getContext(index);
194-
const lineColor = resolve([gridLineOpts.color], context, index - 1);
195-
const lineWidth = resolve([gridLineOpts.lineWidth], context, index - 1);
192+
const lineColor = gridLineOpts.color;
193+
const lineWidth = gridLineOpts.lineWidth;
196194
let pointPosition;
197195

198196
if ((!circular && !valueCount) || !lineColor || !lineWidth || radius < 0) {
@@ -202,10 +200,8 @@ function drawRadiusLine(scale, gridLineOpts, radius, index) {
202200
ctx.save();
203201
ctx.strokeStyle = lineColor;
204202
ctx.lineWidth = lineWidth;
205-
if (ctx.setLineDash) {
206-
ctx.setLineDash(resolve([gridLineOpts.borderDash, []], context));
207-
ctx.lineDashOffset = resolve([gridLineOpts.borderDashOffset], context, index - 1);
208-
}
203+
ctx.setLineDash(gridLineOpts.borderDash);
204+
ctx.lineDashOffset = gridLineOpts.borderDashOffset;
209205

210206
ctx.beginPath();
211207
if (circular) {
@@ -245,11 +241,6 @@ export default class RadialLinearScale extends LinearScaleBase {
245241
this.pointLabels = [];
246242
}
247243

248-
init(options) {
249-
super.init(options);
250-
this.axis = 'r';
251-
}
252-
253244
setDimensions() {
254245
const me = this;
255246

@@ -408,7 +399,8 @@ export default class RadialLinearScale extends LinearScaleBase {
408399
me.ticks.forEach((tick, index) => {
409400
if (index !== 0) {
410401
offset = me.getDistanceFromCenterForValue(me.ticks[index].value);
411-
drawRadiusLine(me, gridLineOpts, offset, index);
402+
const optsAtIndex = gridLineOpts.setContext(me.getContext(index - 1));
403+
drawRadiusLine(me, optsAtIndex, offset);
412404
}
413405
});
414406
}
@@ -417,9 +409,9 @@ export default class RadialLinearScale extends LinearScaleBase {
417409
ctx.save();
418410

419411
for (i = me.chart.data.labels.length - 1; i >= 0; i--) {
420-
const context = me.getContext(i);
421-
const lineWidth = resolve([angleLineOpts.lineWidth, gridLineOpts.lineWidth], context, i);
422-
const color = resolve([angleLineOpts.color, gridLineOpts.color], context, i);
412+
const optsAtIndex = angleLineOpts.setContext(me.getContext(i));
413+
const lineWidth = optsAtIndex.lineWidth;
414+
const color = optsAtIndex.color;
423415

424416
if (!lineWidth || !color) {
425417
continue;
@@ -428,10 +420,8 @@ export default class RadialLinearScale extends LinearScaleBase {
428420
ctx.lineWidth = lineWidth;
429421
ctx.strokeStyle = color;
430422

431-
if (ctx.setLineDash) {
432-
ctx.setLineDash(resolve([angleLineOpts.borderDash, gridLineOpts.borderDash, []], context));
433-
ctx.lineDashOffset = resolve([angleLineOpts.borderDashOffset, gridLineOpts.borderDashOffset, 0.0], context, i);
434-
}
423+
ctx.setLineDash(optsAtIndex.borderDash);
424+
ctx.lineDashOffset = optsAtIndex.borderDashOffset;
435425

436426
offset = me.getDistanceFromCenterForValue(opts.ticks.reverse ? me.min : me.max);
437427
position = me.getPointPosition(i, offset);
@@ -472,26 +462,24 @@ export default class RadialLinearScale extends LinearScaleBase {
472462
return;
473463
}
474464

475-
const context = me.getContext(index);
476-
const tickFont = me._resolveTickFontOptions(index);
465+
const optsAtIndex = tickOpts.setContext(me.getContext(index));
466+
const tickFont = toFont(optsAtIndex.font);
477467
offset = me.getDistanceFromCenterForValue(me.ticks[index].value);
478468

479-
const showLabelBackdrop = resolve([tickOpts.showLabelBackdrop], context, index);
480-
481-
if (showLabelBackdrop) {
469+
if (optsAtIndex.showLabelBackdrop) {
482470
width = ctx.measureText(tick.label).width;
483-
ctx.fillStyle = resolve([tickOpts.backdropColor], context, index);
471+
ctx.fillStyle = optsAtIndex.backdropColor;
484472

485473
ctx.fillRect(
486-
-width / 2 - tickOpts.backdropPaddingX,
487-
-offset - tickFont.size / 2 - tickOpts.backdropPaddingY,
488-
width + tickOpts.backdropPaddingX * 2,
489-
tickFont.size + tickOpts.backdropPaddingY * 2
474+
-width / 2 - optsAtIndex.backdropPaddingX,
475+
-offset - tickFont.size / 2 - optsAtIndex.backdropPaddingY,
476+
width + optsAtIndex.backdropPaddingX * 2,
477+
tickFont.size + optsAtIndex.backdropPaddingY * 2
490478
);
491479
}
492480

493481
renderText(ctx, tick.label, 0, -offset, tickFont, {
494-
color: tickOpts.color,
482+
color: optsAtIndex.color,
495483
});
496484
});
497485

@@ -565,3 +553,9 @@ RadialLinearScale.defaultRoutes = {
565553
'pointLabels.color': 'color',
566554
'ticks.color': 'color'
567555
};
556+
557+
RadialLinearScale.descriptors = {
558+
angleLines: {
559+
_fallback: 'gridLines'
560+
}
561+
};

test/fixtures/scale.radialLinear/gridlines-scriptable.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,10 @@ module.exports = {
1111
gridLines: {
1212
display: true,
1313
color: function(context) {
14-
return context.index % 2 === 0 ? 'red' : 'green';
14+
return context.index % 2 === 0 ? 'green' : 'red';
1515
},
1616
lineWidth: function(context) {
17-
return context.index % 2 === 0 ? 1 : 5;
17+
return context.index % 2 === 0 ? 5 : 1;
1818
},
1919
},
2020
angleLines: {

0 commit comments

Comments
 (0)