Clone cached options if enableOptionSharing!=true (#7837)

Clone cached options if enableOptionSharing!=true
This commit is contained in:
Jukka Kurkela 2020-10-02 15:15:47 +03:00 committed by GitHub
parent 2ac0436bd4
commit 07d50a59bc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 77 additions and 15 deletions

View File

@ -147,17 +147,11 @@ function getFirstScaleId(chart, axis) {
return Object.keys(scales).filter(key => scales[key].axis === axis).shift();
}
function optionKeys(optionNames) {
return isArray(optionNames) ? optionNames : Object.keys(optionNames);
}
function optionKey(key, active) {
return active ? 'hover' + _capitalize(key) : key;
}
function isDirectUpdateMode(mode) {
return mode === 'reset' || mode === 'none';
}
const optionKeys = (optionNames) => isArray(optionNames) ? optionNames : Object.keys(optionNames);
const optionKey = (key, active) => active ? 'hover' + _capitalize(key) : key;
const isDirectUpdateMode = (mode) => mode === 'reset' || mode === 'none';
const cloneIfNotShared = (cached, shared) => shared ? cached : Object.assign({}, cached);
const freezeIfShared = (values, shared) => shared ? Object.freeze(values) : values;
export default class DatasetController {
@ -732,10 +726,11 @@ export default class DatasetController {
mode = mode || 'default';
const me = this;
const active = mode === 'active';
const cached = me._cachedDataOpts;
const cache = me._cachedDataOpts;
const cached = cache[mode];
const sharing = me.enableOptionSharing;
if (cached[mode]) {
return cached[mode];
if (cached) {
return cloneIfNotShared(cached, sharing);
}
const info = {cacheable: !active};
@ -754,7 +749,7 @@ export default class DatasetController {
// We cache options by `mode`, which can be 'active' for example. This enables us
// to have the 'active' element options and 'default' options to switch between
// when interacting.
cached[mode] = sharing ? Object.freeze(values) : values;
cache[mode] = freezeIfShared(values, sharing);
}
return values;

View File

@ -664,6 +664,73 @@ describe('Chart.DatasetController', function() {
});
});
describe('resolveDataElementOptions', function() {
it('should cache options when possible', function() {
const chart = acquireChart({
type: 'line',
data: {
datasets: [{
data: [1, 2, 3],
}]
},
});
const controller = chart.getDatasetMeta(0).controller;
expect(controller.enableOptionSharing).toBeTrue();
const opts0 = controller.resolveDataElementOptions(0);
const opts1 = controller.resolveDataElementOptions(1);
expect(opts0 === opts1).toBeTrue();
expect(opts0.$shared).toBeTrue();
expect(Object.isFrozen(opts0)).toBeTrue();
});
it('should not cache options when option sharing is disabled', function() {
const chart = acquireChart({
type: 'radar',
data: {
datasets: [{
data: [1, 2, 3],
}]
},
});
const controller = chart.getDatasetMeta(0).controller;
expect(controller.enableOptionSharing).toBeFalse();
const opts0 = controller.resolveDataElementOptions(0);
const opts1 = controller.resolveDataElementOptions(1);
expect(opts0 === opts1).toBeFalse();
expect(opts0.$shared).not.toBeTrue();
expect(Object.isFrozen(opts0)).toBeFalse();
});
it('should not cache options when functions are used', function() {
const chart = acquireChart({
type: 'line',
data: {
datasets: [{
data: [1, 2, 3],
backgroundColor: () => 'red'
}]
},
});
const controller = chart.getDatasetMeta(0).controller;
const opts0 = controller.resolveDataElementOptions(0);
const opts1 = controller.resolveDataElementOptions(1);
expect(opts0 === opts1).toBeFalse();
expect(opts0.$shared).not.toBeTrue();
expect(Object.isFrozen(opts0)).toBeFalse();
});
});
describe('_resolveAnimations', function() {
it('should resolve to empty Animations when globally disabled', function() {
const chart = acquireChart({