mirror of
https://github.com/chartjs/Chart.js.git
synced 2025-12-08 20:36:08 +00:00
Disable Path2D caching when chart is animated (#8319)
* Disable Path2D caching when chart is animated * Add note to performance docs
This commit is contained in:
parent
a58d43cbda
commit
ea34e8b814
@ -35,6 +35,7 @@ Set the [`ticks.sampleSize`](./axes/cartesian/index.mdx#tick-configuration) opti
|
||||
## Disable Animations
|
||||
|
||||
If your charts have long render times, it is a good idea to disable animations. Doing so will mean that the chart needs to only be rendered once during an update instead of multiple times. This will have the effect of reducing CPU usage and improving general page performance.
|
||||
Line charts use Path2D caching when animations are disabled.
|
||||
|
||||
To disable animations
|
||||
|
||||
|
||||
@ -29,9 +29,13 @@ export default class LineController extends DatasetController {
|
||||
|
||||
// Update Line
|
||||
line.points = points;
|
||||
|
||||
// In resize mode only point locations change, so no need to set the options.
|
||||
if (mode !== 'resize') {
|
||||
me.updateElement(line, undefined, {options: me.resolveDatasetElementOptions()}, mode);
|
||||
me.updateElement(line, undefined, {
|
||||
animated: !animationsDisabled,
|
||||
options: me.resolveDatasetElementOptions()
|
||||
}, mode);
|
||||
}
|
||||
|
||||
// Update Points
|
||||
|
||||
@ -3,7 +3,6 @@ import {_bezierInterpolation, _pointInLine, _steppedInterpolation} from '../help
|
||||
import {_computeSegments, _boundSegments} from '../helpers/helpers.segment';
|
||||
import {_steppedLineTo, _bezierCurveTo} from '../helpers/helpers.canvas';
|
||||
import {_updateBezierControlPoints} from '../helpers/helpers.curve';
|
||||
import {_coordsAnimated} from '../helpers/helpers.extras';
|
||||
|
||||
/**
|
||||
* @typedef { import("./element.point").default } PointElement
|
||||
@ -204,6 +203,7 @@ export default class LineElement extends Element {
|
||||
constructor(cfg) {
|
||||
super();
|
||||
|
||||
this.animated = true;
|
||||
this.options = undefined;
|
||||
this._loop = undefined;
|
||||
this._fullLoop = undefined;
|
||||
@ -351,8 +351,9 @@ export default class LineElement extends Element {
|
||||
* @param {number} [count]
|
||||
*/
|
||||
draw(ctx, chartArea, start, count) {
|
||||
const options = this.options || {};
|
||||
const points = this.points || [];
|
||||
const me = this;
|
||||
const options = me.options || {};
|
||||
const points = me.points || [];
|
||||
|
||||
if (!points.length || !options.borderWidth) {
|
||||
return;
|
||||
@ -362,10 +363,10 @@ export default class LineElement extends Element {
|
||||
|
||||
setStyle(ctx, options);
|
||||
|
||||
let path = this._path;
|
||||
let path = me._path;
|
||||
if (!path) {
|
||||
path = this._path = new Path2D();
|
||||
if (this.path(path, start, count)) {
|
||||
path = me._path = new Path2D();
|
||||
if (me.path(path, start, count)) {
|
||||
path.closePath();
|
||||
}
|
||||
}
|
||||
@ -374,12 +375,10 @@ export default class LineElement extends Element {
|
||||
|
||||
ctx.restore();
|
||||
|
||||
if (_coordsAnimated(points[0]) || _coordsAnimated(points[points.length - 1])) {
|
||||
// When point coordinates are animating, we need to recalculate the
|
||||
// path (and control points when beziers are used). Only coordinates
|
||||
// matter, other animations are ignored.
|
||||
this._pointsUpdated = false;
|
||||
this._path = undefined;
|
||||
if (me.animated) {
|
||||
// When line is animated, the control points and path are not cached.
|
||||
me._pointsUpdated = false;
|
||||
me._path = undefined;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -56,14 +56,3 @@ export const _toLeftRightCenter = (align) => align === 'start' ? 'left' : align
|
||||
* @private
|
||||
*/
|
||||
export const _alignStartEnd = (align, start, end) => align === 'start' ? start : align === 'end' ? end : (start + end) / 2;
|
||||
|
||||
/**
|
||||
* Return true if `x` or `y` property (coordinates) of the element is currently animated.
|
||||
* @param {object} element
|
||||
* @returns {boolean}
|
||||
* @private
|
||||
*/
|
||||
export function _coordsAnimated(element) {
|
||||
const anims = element && element.$animations;
|
||||
return anims && ((anims.x && anims.x.active()) || (anims.y && anims.y.active()));
|
||||
}
|
||||
|
||||
@ -10,4 +10,26 @@ describe('Chart.elements.LineElement', function() {
|
||||
expect(line).not.toBe(undefined);
|
||||
expect(line.points).toEqual([1, 2, 3, 4]);
|
||||
});
|
||||
|
||||
it('should not cache path when animations are enabled', function(done) {
|
||||
var chart = window.acquireChart({
|
||||
type: 'line',
|
||||
data: {
|
||||
datasets: [{
|
||||
data: [0, -1, 0],
|
||||
label: 'dataset1',
|
||||
}],
|
||||
labels: ['label1', 'label2', 'label3']
|
||||
},
|
||||
options: {
|
||||
animation: {
|
||||
duration: 50,
|
||||
onComplete: () => {
|
||||
expect(chart.getDatasetMeta(0).dataset._path).toBeUndefined();
|
||||
done();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user