Skip to content

Commit 9d4acdc

Browse files
committed
Rewrite animation logic
1 parent c8bdca6 commit 9d4acdc

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

49 files changed

+2282
-2455
lines changed

.eslintrc.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
extends: chartjs
22

33
env:
4+
es6: true
45
browser: true
56
node: true
67

docs/configuration/tooltip.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -356,7 +356,7 @@ The tooltip model contains parameters that can be used to render the tooltip.
356356

357357
// 0 opacity is a hidden tooltip
358358
opacity: number,
359-
legendColorBackground: Color,
359+
multiKeyBackground: Color,
360360
displayColors: boolean,
361361
borderColor: Color,
362362
borderWidth: number

docs/developers/api.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -175,5 +175,5 @@ Extensive examples of usage are available in the [Chart.js tests](https://github
175175

176176
```javascript
177177
var meta = myChart.getDatasetMeta(0);
178-
var x = meta.data[0]._model.x;
178+
var x = meta.data[0].x;
179179
```

docs/developers/charts.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -94,13 +94,13 @@ var custom = Chart.controllers.bubble.extend({
9494
// Now we can do some custom drawing for this dataset. Here we'll draw a red box around the first point in each dataset
9595
var meta = this.getMeta();
9696
var pt0 = meta.data[0];
97-
var radius = pt0._view.radius;
97+
var radius = pt0.radius;
9898

9999
var ctx = this.chart.chart.ctx;
100100
ctx.save();
101101
ctx.strokeStyle = 'red';
102102
ctx.lineWidth = 1;
103-
ctx.strokeRect(pt0._view.x - radius, pt0._view.y - radius, 2 * radius, 2 * radius);
103+
ctx.strokeRect(pt0.x - radius, pt0.y - radius, 2 * radius, 2 * radius);
104104
ctx.restore();
105105
}
106106
});

docs/getting-started/v3-migration.md

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -89,10 +89,8 @@ Chart.js 3.0 introduces a number of breaking changes. Chart.js 2.0 was released
8989

9090
* `Chart.data.datasets[datasetIndex]._meta`
9191
* `Element._ctx`
92-
* `Element._model.datasetLabel`
93-
* `Element._model.label`
94-
* `Point._model.tension`
95-
* `Point._model.steppedLine`
92+
* `Element._model`
93+
* `Element._view`
9694
* `TimeScale._getPixelForOffset`
9795
* `TimeScale.getLabelWidth`
9896

src/controllers/controller.bar.js

Lines changed: 31 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,13 @@ defaults._set('global', {
3030
datasets: {
3131
bar: {
3232
categoryPercentage: 0.8,
33-
barPercentage: 0.9
33+
barPercentage: 0.9,
34+
animation: {
35+
numbers: {
36+
type: 'number',
37+
properties: ['x', 'y', 'width', 'height']
38+
}
39+
}
3440
}
3541
}
3642
});
@@ -267,50 +273,53 @@ module.exports = DatasetController.extend({
267273
meta.bar = true;
268274
},
269275

270-
update: function(reset) {
276+
update: function(mode) {
271277
const me = this;
272278
const rects = me._cachedMeta.data;
273279

274-
me.updateElements(rects, 0, rects.length, reset);
280+
me.updateElements(rects, 0, rects.length, mode);
275281
},
276282

277-
updateElements: function(rectangles, start, count, reset) {
283+
updateElements: function(rectangles, start, count, mode) {
278284
const me = this;
285+
const reset = mode === 'reset';
279286
const vscale = me._cachedMeta.vScale;
280287
const base = vscale.getBasePixel();
281288
const horizontal = vscale.isHorizontal();
282289
const ruler = me.getRuler();
290+
const firstOpts = me._resolveDataElementOptions(start, mode);
291+
const sharedOptions = me._getSharedOptions(mode, rectangles[start], firstOpts);
292+
const includeOptions = me._includeOptions(mode, sharedOptions);
293+
283294
let i;
284295

285296
for (i = 0; i < start + count; i++) {
286-
const rectangle = rectangles[i];
287-
const options = me._resolveDataElementOptions(i);
297+
const options = me._resolveDataElementOptions(i, mode);
288298
const vpixels = me.calculateBarValuePixels(i, options);
289299
const ipixels = me.calculateBarIndexPixels(i, ruler, options);
290300

291-
rectangle._model = {
292-
backgroundColor: options.backgroundColor,
293-
borderColor: options.borderColor,
294-
borderSkipped: options.borderSkipped,
295-
borderWidth: options.borderWidth
301+
const properties = {
302+
horizontal,
303+
base: reset ? base : vpixels.base,
304+
x: horizontal ? reset ? base : vpixels.head : ipixels.center,
305+
y: horizontal ? ipixels.center : reset ? base : vpixels.head,
306+
height: horizontal ? ipixels.size : undefined,
307+
width: horizontal ? undefined : ipixels.size
296308
};
297309

298-
const model = rectangle._model;
299-
300310
// all borders are drawn for floating bar
311+
/* TODO: float bars border skipping magic
301312
if (me._getParsed(i)._custom) {
302313
model.borderSkipped = null;
303314
}
304-
305-
model.horizontal = horizontal;
306-
model.base = reset ? base : vpixels.base;
307-
model.x = horizontal ? reset ? base : vpixels.head : ipixels.center;
308-
model.y = horizontal ? ipixels.center : reset ? base : vpixels.head;
309-
model.height = horizontal ? ipixels.size : undefined;
310-
model.width = horizontal ? undefined : ipixels.size;
311-
312-
rectangle.pivot(me.chart._animationsDisabled);
315+
*/
316+
if (includeOptions) {
317+
properties.options = options;
318+
}
319+
me._updateElement(rectangles[i], i, properties, mode);
313320
}
321+
322+
me._updateSharedOptions(sharedOptions, mode);
314323
},
315324

316325
/**

src/controllers/controller.bubble.js

Lines changed: 48 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,18 @@
11
'use strict';
22

3-
var DatasetController = require('../core/core.datasetController');
4-
var defaults = require('../core/core.defaults');
5-
var elements = require('../elements/index');
6-
var helpers = require('../helpers/index');
3+
const DatasetController = require('../core/core.datasetController');
4+
const defaults = require('../core/core.defaults');
5+
const elements = require('../elements/index');
6+
const helpers = require('../helpers/index');
77

8-
var valueOrDefault = helpers.valueOrDefault;
9-
var resolve = helpers.options.resolve;
8+
const resolve = helpers.options.resolve;
109

1110
defaults._set('bubble', {
11+
animation: {
12+
numbers: {
13+
properties: ['x', 'y', 'borderWidth', 'radius']
14+
}
15+
},
1216
scales: {
1317
x: {
1418
type: 'linear',
@@ -43,11 +47,8 @@ module.exports = DatasetController.extend({
4347
'backgroundColor',
4448
'borderColor',
4549
'borderWidth',
46-
'hoverBackgroundColor',
47-
'hoverBorderColor',
48-
'hoverBorderWidth',
49-
'hoverRadius',
5050
'hitRadius',
51+
'radius',
5152
'pointStyle',
5253
'rotation'
5354
],
@@ -77,15 +78,14 @@ module.exports = DatasetController.extend({
7778
* @private
7879
*/
7980
_getMaxOverflow: function() {
80-
var me = this;
81-
var meta = me._cachedMeta;
82-
var data = meta.data || [];
83-
if (!data.length) {
84-
return false;
81+
const me = this;
82+
const meta = me._cachedMeta;
83+
let i = (meta.data || []).length - 1;
84+
let max = 0;
85+
for (; i >= 0; --i) {
86+
max = Math.max(max, me.getStyle(i, true).radius);
8587
}
86-
var firstPoint = data[0].size();
87-
var lastPoint = data[data.length - 1].size();
88-
return Math.max(firstPoint, lastPoint) / 2;
88+
return max > 0 && max;
8989
},
9090

9191
/**
@@ -109,72 +109,56 @@ module.exports = DatasetController.extend({
109109
/**
110110
* @protected
111111
*/
112-
update: function(reset) {
112+
update: function(mode) {
113113
const me = this;
114114
const points = me._cachedMeta.data;
115115

116116
// Update Points
117-
me.updateElements(points, 0, points.length, reset);
117+
me.updateElements(points, 0, points.length, mode);
118118
},
119119

120120
/**
121121
* @protected
122122
*/
123-
updateElements: function(points, start, count, reset) {
123+
updateElements: function(points, start, count, mode) {
124124
const me = this;
125+
const reset = mode === 'reset';
125126
const {xScale, yScale} = me._cachedMeta;
127+
const firstOpts = me._resolveDataElementOptions(start, mode);
128+
const sharedOptions = me._getSharedOptions(mode, points[start], firstOpts);
129+
const includeOptions = me._includeOptions(mode, sharedOptions);
126130
let i;
127131

128132
for (i = start; i < start + count; i++) {
129133
const point = points[i];
130-
const options = me._resolveDataElementOptions(i);
131134
const parsed = !reset && me._getParsed(i);
132135
const x = reset ? xScale.getPixelForDecimal(0.5) : xScale.getPixelForValue(parsed[xScale.id]);
133136
const y = reset ? yScale.getBasePixel() : yScale.getPixelForValue(parsed[yScale.id]);
134-
135-
point._options = options;
136-
point._model = {
137-
backgroundColor: options.backgroundColor,
138-
borderColor: options.borderColor,
139-
borderWidth: options.borderWidth,
140-
hitRadius: options.hitRadius,
141-
pointStyle: options.pointStyle,
142-
rotation: options.rotation,
143-
radius: reset ? 0 : options.radius,
144-
skip: isNaN(x) || isNaN(y),
145-
x: x,
146-
y: y,
137+
const properties = {
138+
x,
139+
y,
140+
skip: isNaN(x) || isNaN(y)
147141
};
148142

149-
point.pivot(me.chart._animationsDisabled);
150-
}
151-
},
143+
if (includeOptions) {
144+
properties.options = i === start ? firstOpts
145+
: me._resolveDataElementOptions(i, mode);
152146

153-
/**
154-
* @protected
155-
*/
156-
setHoverStyle: function(point) {
157-
var model = point._model;
158-
var options = point._options;
159-
var getHoverColor = helpers.getHoverColor;
160-
161-
point.$previousStyle = {
162-
backgroundColor: model.backgroundColor,
163-
borderColor: model.borderColor,
164-
borderWidth: model.borderWidth,
165-
radius: model.radius
166-
};
147+
if (reset) {
148+
properties.options.radius = 0;
149+
}
150+
}
167151

168-
model.backgroundColor = valueOrDefault(options.hoverBackgroundColor, getHoverColor(options.backgroundColor));
169-
model.borderColor = valueOrDefault(options.hoverBorderColor, getHoverColor(options.borderColor));
170-
model.borderWidth = valueOrDefault(options.hoverBorderWidth, options.borderWidth);
171-
model.radius = options.radius + options.hoverRadius;
152+
me._updateElement(point, i, properties, mode);
153+
}
154+
155+
me._updateSharedOptions(sharedOptions, mode);
172156
},
173157

174158
/**
175159
* @private
176160
*/
177-
_resolveDataElementOptions: function(index) {
161+
_resolveDataElementOptions: function(index, mode) {
178162
var me = this;
179163
var chart = me.chart;
180164
var dataset = me.getDataset();
@@ -190,12 +174,16 @@ module.exports = DatasetController.extend({
190174
};
191175

192176
// In case values were cached (and thus frozen), we need to clone the values
193-
if (me._cachedDataOpts === values) {
194-
values = helpers.extend({}, values);
177+
if (values.$shared) {
178+
values = helpers.extend({}, values, {$shared: false});
195179
}
196180

181+
197182
// Custom radius resolution
198-
values.radius = resolve([
183+
if (mode !== 'active') {
184+
values.radius = 0;
185+
}
186+
values.radius += resolve([
199187
parsed && parsed._custom,
200188
me._config.radius,
201189
chart.options.elements.point.radius

0 commit comments

Comments
 (0)