Skip to content

Commit 1df8095

Browse files
committed
Option resolution with proxies
1 parent eb7ce4e commit 1df8095

38 files changed

+863
-698
lines changed

samples/animations/delay.html

Lines changed: 12 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -62,29 +62,23 @@
6262

6363
};
6464
window.onload = function() {
65+
var delayed = false;
6566
var ctx = document.getElementById('canvas').getContext('2d');
6667
window.myBar = new Chart(ctx, {
6768
type: 'bar',
6869
data: barChartData,
6970
options: {
70-
animation: (context) => {
71-
if (context.active) {
72-
return {
73-
duration: 400
74-
};
75-
}
76-
var delay = 0;
77-
var dsIndex = context.datasetIndex;
78-
var index = context.dataIndex;
79-
if (context.parsed && !context.delayed) {
80-
delay = index * 300 + dsIndex * 100;
81-
context.delayed = true;
82-
}
83-
return {
84-
easing: 'linear',
85-
duration: 600,
86-
delay
87-
};
71+
animation: {
72+
onComplete: () => {
73+
delayed = true;
74+
},
75+
delay: (context) => {
76+
let delay = 0;
77+
if (context.type === 'data' && context.mode === 'default' && !delayed) {
78+
delay = context.dataIndex * 300 + context.datasetIndex * 100;
79+
}
80+
return delay;
81+
},
8882
},
8983
plugins: {
9084
title: {

samples/animations/loop.html

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -62,16 +62,13 @@
6262
}]
6363
},
6464
options: {
65-
animation: (context) => Object.assign({},
66-
Chart.defaults.animation,
67-
{
68-
radius: {
69-
duration: 400,
70-
easing: 'linear',
71-
loop: context.active
72-
}
65+
animation: {
66+
radius: {
67+
duration: 400,
68+
easing: 'linear',
69+
loop: (context) => context.active
7370
}
74-
),
71+
},
7572
elements: {
7673
point: {
7774
hoverRadius: 6

src/controllers/controller.bar.js

Lines changed: 9 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -266,9 +266,8 @@ export default class BarController extends DatasetController {
266266
me.updateSharedOptions(sharedOptions, mode, firstOpts);
267267

268268
for (let i = start; i < start + count; i++) {
269-
const options = sharedOptions || me.resolveDataElementOptions(i, mode);
270-
const vpixels = me._calculateBarValuePixels(i, options);
271-
const ipixels = me._calculateBarIndexPixels(i, ruler, options);
269+
const vpixels = me._calculateBarValuePixels(i);
270+
const ipixels = me._calculateBarIndexPixels(i, ruler);
272271

273272
const properties = {
274273
horizontal,
@@ -280,7 +279,7 @@ export default class BarController extends DatasetController {
280279
};
281280

282281
if (includeOptions) {
283-
properties.options = options;
282+
properties.options = sharedOptions || me.resolveDataElementOptions(i, mode);
284283
}
285284
me.updateElement(bars[i], i, properties, mode);
286285
}
@@ -400,11 +399,11 @@ export default class BarController extends DatasetController {
400399
* Note: pixel values are not clamped to the scale area.
401400
* @private
402401
*/
403-
_calculateBarValuePixels(index, options) {
402+
_calculateBarValuePixels(index) {
404403
const me = this;
405404
const meta = me._cachedMeta;
406405
const vScale = meta.vScale;
407-
const {base: baseValue, minBarLength} = options;
406+
const {base: baseValue, minBarLength} = me.options;
408407
const parsed = me.getParsed(index);
409408
const custom = parsed._custom;
410409
const floating = isFloatBar(custom);
@@ -459,9 +458,10 @@ export default class BarController extends DatasetController {
459458
/**
460459
* @private
461460
*/
462-
_calculateBarIndexPixels(index, ruler, options) {
461+
_calculateBarIndexPixels(index, ruler) {
463462
const me = this;
464-
const stackCount = me.chart.options.skipNull ? me._getStackCount(index) : ruler.stackCount;
463+
const options = me.options;
464+
const stackCount = options.skipNull ? me._getStackCount(index) : ruler.stackCount;
465465
const range = options.barThickness === 'flex'
466466
? computeFlexCategoryTraits(index, ruler, options, stackCount)
467467
: computeFitCategoryTraits(index, ruler, options, stackCount);
@@ -510,20 +510,7 @@ BarController.id = 'bar';
510510
BarController.defaults = {
511511
datasetElementType: false,
512512
dataElementType: 'bar',
513-
dataElementOptions: [
514-
'backgroundColor',
515-
'borderColor',
516-
'borderSkipped',
517-
'borderWidth',
518-
'borderRadius',
519-
'barPercentage',
520-
'barThickness',
521-
'base',
522-
'categoryPercentage',
523-
'maxBarThickness',
524-
'minBarLength',
525-
'pointStyle'
526-
],
513+
527514
interaction: {
528515
mode: 'index'
529516
},

src/controllers/controller.bubble.js

Lines changed: 5 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import DatasetController from '../core/core.datasetController';
2-
import {resolve} from '../helpers/helpers.options';
3-
import {resolveObjectKey} from '../helpers/helpers.core';
2+
import {resolveObjectKey, valueOrDefault} from '../helpers/helpers.core';
43

54
export default class BubbleController extends DatasetController {
65
initialize() {
@@ -107,29 +106,20 @@ export default class BubbleController extends DatasetController {
107106
* @protected
108107
*/
109108
resolveDataElementOptions(index, mode) {
110-
const me = this;
111-
const chart = me.chart;
112-
const parsed = me.getParsed(index);
109+
const parsed = this.getParsed(index);
113110
let values = super.resolveDataElementOptions(index, mode);
114111

115-
// Scriptable options
116-
const context = me.getContext(index, mode === 'active');
117-
118112
// In case values were cached (and thus frozen), we need to clone the values
119113
if (values.$shared) {
120114
values = Object.assign({}, values, {$shared: false});
121115
}
122116

123-
124117
// Custom radius resolution
118+
const radius = values.radius;
125119
if (mode !== 'active') {
126120
values.radius = 0;
127121
}
128-
values.radius += resolve([
129-
parsed && parsed._custom,
130-
me._config.radius,
131-
chart.options.elements.point.radius
132-
], context, index);
122+
values.radius += valueOrDefault(parsed && parsed._custom, radius);
133123

134124
return values;
135125
}
@@ -143,15 +133,6 @@ BubbleController.id = 'bubble';
143133
BubbleController.defaults = {
144134
datasetElementType: false,
145135
dataElementType: 'point',
146-
dataElementOptions: [
147-
'backgroundColor',
148-
'borderColor',
149-
'borderWidth',
150-
'hitRadius',
151-
'radius',
152-
'pointStyle',
153-
'rotation'
154-
],
155136
animation: {
156137
numbers: {
157138
properties: ['x', 'y', 'borderWidth', 'radius']
@@ -168,6 +149,7 @@ BubbleController.defaults = {
168149
plugins: {
169150
tooltip: {
170151
callbacks: {
152+
_scriptable: false,
171153
title() {
172154
// Title doesn't make sense for scatter since we format the data as a point
173155
return '';

src/controllers/controller.doughnut.js

Lines changed: 15 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -81,14 +81,14 @@ export default class DoughnutController extends DatasetController {
8181
* @private
8282
*/
8383
_getRotation() {
84-
return toRadians(valueOrDefault(this._config.rotation, this.chart.options.rotation) - 90);
84+
return toRadians(this.options.rotation - 90);
8585
}
8686

8787
/**
8888
* @private
8989
*/
9090
_getCircumference() {
91-
return toRadians(valueOrDefault(this._config.circumference, this.chart.options.circumference));
91+
return toRadians(this.options.circumference);
9292
}
9393

9494
/**
@@ -124,10 +124,10 @@ export default class DoughnutController extends DatasetController {
124124
update(mode) {
125125
const me = this;
126126
const chart = me.chart;
127-
const {chartArea, options} = chart;
127+
const {chartArea} = chart;
128128
const meta = me._cachedMeta;
129129
const arcs = meta.data;
130-
const cutout = options.cutoutPercentage / 100 || 0;
130+
const cutout = me.options.cutoutPercentage / 100 || 0;
131131
const chartWeight = me._getRingWeight(me.index);
132132

133133
// Compute the maximal rotation & circumference limits.
@@ -157,7 +157,7 @@ export default class DoughnutController extends DatasetController {
157157
*/
158158
_circumference(i, reset) {
159159
const me = this;
160-
const opts = me.chart.options;
160+
const opts = me.options;
161161
const meta = me._cachedMeta;
162162
const circumference = me._getCircumference();
163163
return reset && opts.animation.animateRotate ? 0 : this.chart.getDataVisibility(i) ? me.calculateCircumference(meta._parsed[i] * circumference / TAU) : 0;
@@ -328,13 +328,6 @@ DoughnutController.id = 'doughnut';
328328
DoughnutController.defaults = {
329329
datasetElementType: false,
330330
dataElementType: 'arc',
331-
dataElementOptions: [
332-
'backgroundColor',
333-
'borderColor',
334-
'borderWidth',
335-
'borderAlign',
336-
'offset'
337-
],
338331
animation: {
339332
numbers: {
340333
type: 'number',
@@ -347,19 +340,22 @@ DoughnutController.defaults = {
347340
},
348341
aspectRatio: 1,
349342

350-
// The percentage of the chart that we cut out of the middle.
351-
cutoutPercentage: 50,
343+
datasets: {
344+
// The percentage of the chart that we cut out of the middle.
345+
cutoutPercentage: 50,
352346

353-
// The rotation of the chart, where the first data arc begins.
354-
rotation: 0,
347+
// The rotation of the chart, where the first data arc begins.
348+
rotation: 0,
355349

356-
// The total circumference of the chart.
357-
circumference: 360,
350+
// The total circumference of the chart.
351+
circumference: 360
352+
},
358353

359354
// Need to override these to give a nice default
360355
plugins: {
361356
legend: {
362357
labels: {
358+
_scriptable: false,
363359
generateLabels(chart) {
364360
const data = chart.data;
365361
if (data.labels.length && data.datasets.length) {
@@ -390,6 +386,7 @@ DoughnutController.defaults = {
390386
},
391387
tooltip: {
392388
callbacks: {
389+
_scriptable: false,
393390
title() {
394391
return '';
395392
},

src/controllers/controller.line.js

Lines changed: 10 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
import DatasetController from '../core/core.datasetController';
2-
import {valueOrDefault} from '../helpers/helpers.core';
32
import {isNumber, _limitValue} from '../helpers/helpers.math';
4-
import {resolve} from '../helpers/helpers.options';
53
import {_lookupByKey} from '../helpers/helpers.collection';
64

75
export default class LineController extends DatasetController {
@@ -32,9 +30,13 @@ export default class LineController extends DatasetController {
3230

3331
// In resize mode only point locations change, so no need to set the options.
3432
if (mode !== 'resize') {
33+
const options = me.resolveDatasetElementOptions(mode);
34+
if (!me.options.showLine) {
35+
options.borderWidth = 0;
36+
}
3537
me.updateElement(line, undefined, {
3638
animated: !animationsDisabled,
37-
options: me.resolveDatasetElementOptions()
39+
options
3840
}, mode);
3941
}
4042

@@ -49,7 +51,7 @@ export default class LineController extends DatasetController {
4951
const firstOpts = me.resolveDataElementOptions(start, mode);
5052
const sharedOptions = me.getSharedOptions(firstOpts);
5153
const includeOptions = me.includeOptions(mode, sharedOptions);
52-
const spanGaps = valueOrDefault(me._config.spanGaps, me.chart.options.spanGaps);
54+
const spanGaps = me.options.spanGaps;
5355
const maxGapLength = isNumber(spanGaps) ? spanGaps : Number.POSITIVE_INFINITY;
5456
const directUpdate = me.chart._animationsDisabled || reset || mode === 'none';
5557
let prevParsed = start > 0 && me.getParsed(start - 1);
@@ -77,32 +79,6 @@ export default class LineController extends DatasetController {
7779
me.updateSharedOptions(sharedOptions, mode, firstOpts);
7880
}
7981

80-
/**
81-
* @param {boolean} [active]
82-
* @protected
83-
*/
84-
resolveDatasetElementOptions(active) {
85-
const me = this;
86-
const config = me._config;
87-
const options = me.chart.options;
88-
const lineOptions = options.elements.line;
89-
const values = super.resolveDatasetElementOptions(active);
90-
const showLine = valueOrDefault(config.showLine, options.showLine);
91-
92-
// The default behavior of lines is to break at null values, according
93-
// to https://github.com/chartjs/Chart.js/issues/2435#issuecomment-216718158
94-
// This option gives lines the ability to span gaps
95-
values.spanGaps = valueOrDefault(config.spanGaps, options.spanGaps);
96-
values.tension = valueOrDefault(config.tension, lineOptions.tension);
97-
values.stepped = resolve([config.stepped, lineOptions.stepped]);
98-
99-
if (!showLine) {
100-
values.borderWidth = 0;
101-
}
102-
103-
return values;
104-
}
105-
10682
/**
10783
* @protected
10884
*/
@@ -132,37 +108,12 @@ LineController.id = 'line';
132108
*/
133109
LineController.defaults = {
134110
datasetElementType: 'line',
135-
datasetElementOptions: [
136-
'backgroundColor',
137-
'borderCapStyle',
138-
'borderColor',
139-
'borderDash',
140-
'borderDashOffset',
141-
'borderJoinStyle',
142-
'borderWidth',
143-
'capBezierPoints',
144-
'cubicInterpolationMode',
145-
'fill'
146-
],
147-
148111
dataElementType: 'point',
149-
dataElementOptions: {
150-
backgroundColor: 'pointBackgroundColor',
151-
borderColor: 'pointBorderColor',
152-
borderWidth: 'pointBorderWidth',
153-
hitRadius: 'pointHitRadius',
154-
hoverHitRadius: 'pointHitRadius',
155-
hoverBackgroundColor: 'pointHoverBackgroundColor',
156-
hoverBorderColor: 'pointHoverBorderColor',
157-
hoverBorderWidth: 'pointHoverBorderWidth',
158-
hoverRadius: 'pointHoverRadius',
159-
pointStyle: 'pointStyle',
160-
radius: 'pointRadius',
161-
rotation: 'pointRotation'
162-
},
163112

164-
showLine: true,
165-
spanGaps: false,
113+
datasets: {
114+
showLine: true,
115+
spanGaps: false,
116+
},
166117

167118
interaction: {
168119
mode: 'index'

0 commit comments

Comments
 (0)