Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 14 additions & 13 deletions samples/advanced/progress-bar.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,7 @@
<script src="../utils.js"></script>
<style>
canvas {
-moz-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
user-select: none;
}
</style>
</head>
Expand Down Expand Up @@ -58,23 +56,26 @@
}]
},
options: {
plugins: {
title: {
display: true,
text: 'Chart.js Line Chart - Animation Progress Bar'
}
},
animation: {
duration: 2000,
onProgress: function(animation) {
progress.value = animation.currentStep / animation.numSteps;
},
onComplete: function() {
window.setTimeout(function() {
progress.value = 0;
}, 2000);
//
}
},
interaction: {
mode: 'nearest',
axis: 'x',
intersect: false
},
plugins: {
title: {
display: true,
text: 'Chart.js Line Chart - Animation Progress Bar'
}
}
},
}
};

Expand Down
3 changes: 2 additions & 1 deletion src/core/core.animation.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ export default class Animation {
this._fn = cfg.fn || interpolators[cfg.type || typeof from];
this._easing = effects[cfg.easing] || effects.linear;
this._start = Math.floor(Date.now() + (cfg.delay || 0));
this._duration = Math.floor(cfg.duration);
this._duration = this._total = Math.floor(cfg.duration);
this._loop = !!cfg.loop;
this._target = target;
this._prop = prop;
Expand All @@ -53,6 +53,7 @@ export default class Animation {
const remain = me._duration - elapsed;
me._start = date;
me._duration = Math.floor(Math.max(remain, cfg.duration));
me._total += elapsed;
me._loop = !!cfg.loop;
me._to = resolve([cfg.to, to, currentValue, cfg.from]);
me._from = resolve([cfg.from, currentValue, to]);
Expand Down
5 changes: 5 additions & 0 deletions src/core/core.animator.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,11 @@ export class Animator {
item = items[i];

if (item._active) {
if (item._total > anims.duration) {
// if the animation has been updated and its duration prolonged,
// update to total duration of current animations run (for progress event)
anims.duration = item._total;
}
item.tick(date);
draw = true;
} else {
Expand Down
77 changes: 46 additions & 31 deletions src/core/core.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -167,31 +167,35 @@ export default class Config {
* Returns the option scope keys for resolving dataset options.
* These keys do not include the dataset itself, because it is not under options.
* @param {string} datasetType
* @return {string[]}
* @return {string[][]}
*/
datasetScopeKeys(datasetType) {
return cachedKeys(datasetType,
() => [
() => [[
`datasets.${datasetType}`,
''
]);
]]);
}

/**
* Returns the option scope keys for resolving dataset animation options.
* These keys do not include the dataset itself, because it is not under options.
* @param {string} datasetType
* @param {string} transition
* @return {string[]}
* @return {string[][]}
*/
datasetAnimationScopeKeys(datasetType, transition) {
return cachedKeys(`${datasetType}.transition.${transition}`,
() => [
`datasets.${datasetType}.transitions.${transition}`,
`transitions.${transition}`,
[
`datasets.${datasetType}.transitions.${transition}`,
`transitions.${transition}`,
],
// The following are used for looking up the `animations` and `animation` keys
`datasets.${datasetType}`,
''
[
`datasets.${datasetType}`,
''
]
]);
}

Expand All @@ -201,65 +205,76 @@ export default class Config {
* is not under options.
* @param {string} datasetType
* @param {string} elementType
* @return {string[]}
* @return {string[][]}
*/
datasetElementScopeKeys(datasetType, elementType) {
return cachedKeys(`${datasetType}-${elementType}`,
() => [
() => [[
`datasets.${datasetType}.elements.${elementType}`,
`datasets.${datasetType}`,
`elements.${elementType}`,
''
]);
]]);
}

/**
* Returns the options scope keys for resolving plugin options.
* @param {{id: string, additionalOptionScopes?: string[]}} plugin
* @return {string[]}
* @return {string[][]}
*/
pluginScopeKeys(plugin) {
const id = plugin.id;
const type = this.type;
return cachedKeys(`${type}-plugin-${id}`,
() => [
() => [[
`plugins.${id}`,
...plugin.additionalOptionScopes || [],
]);
]]);
}

/**
* Resolves the objects from options and defaults for option value resolution.
* @param {object} mainScope - The main scope object for options
* @param {string[]} scopeKeys - The keys in resolution order
* @param {boolean} [resetCache] - reset the cache for this mainScope
* @private
*/
getOptionScopes(mainScope, scopeKeys, resetCache) {
const {_scopeCache, options, type} = this;
_cachedScopes(mainScope, resetCache) {
const _scopeCache = this._scopeCache;
let cache = _scopeCache.get(mainScope);
if (!cache || resetCache) {
cache = new Map();
_scopeCache.set(mainScope, cache);
}
const cached = cache.get(scopeKeys);
return cache;
}

/**
* Resolves the objects from options and defaults for option value resolution.
* @param {object} mainScope - The main scope object for options
* @param {string[][]} keyLists - The arrays of keys in resolution order
* @param {boolean} [resetCache] - reset the cache for this mainScope
*/
getOptionScopes(mainScope, keyLists, resetCache) {
const {options, type} = this;
const cache = this._cachedScopes(mainScope, resetCache);
const cached = cache.get(keyLists);
if (cached) {
return cached;
}

const scopes = new Set();

if (mainScope) {
scopes.add(mainScope);
scopeKeys.forEach(key => addIfFound(scopes, mainScope, key));
}
scopeKeys.forEach(key => addIfFound(scopes, options, key));
scopeKeys.forEach(key => addIfFound(scopes, overrides[type] || {}, key));
scopeKeys.forEach(key => addIfFound(scopes, defaults, key));
scopeKeys.forEach(key => addIfFound(scopes, descriptors, key));
keyLists.forEach(keys => {
if (mainScope) {
scopes.add(mainScope);
keys.forEach(key => addIfFound(scopes, mainScope, key));
}
keys.forEach(key => addIfFound(scopes, options, key));
keys.forEach(key => addIfFound(scopes, overrides[type] || {}, key));
keys.forEach(key => addIfFound(scopes, defaults, key));
keys.forEach(key => addIfFound(scopes, descriptors, key));
});

const array = [...scopes];
if (keysCached.has(scopeKeys)) {
cache.set(scopeKeys, array);
if (keysCached.has(keyLists)) {
cache.set(keyLists, array);
}
return array;
}
Expand Down
2 changes: 1 addition & 1 deletion src/core/core.datasetController.js
Original file line number Diff line number Diff line change
Expand Up @@ -828,7 +828,7 @@ export default class DatasetController {
* @protected
*/
updateSharedOptions(sharedOptions, mode, newOptions) {
if (sharedOptions) {
if (sharedOptions && !isDirectUpdateMode(mode)) {
this._resolveAnimations(undefined, mode).update(sharedOptions, newOptions);
}
}
Expand Down
5 changes: 1 addition & 4 deletions src/helpers/helpers.core.js
Original file line number Diff line number Diff line change
Expand Up @@ -306,11 +306,8 @@ export function resolveObjectKey(obj, key) {
}
let pos = 0;
let idx = indexOfDotOrLength(key, pos);
while (idx > pos) {
while (obj && idx > pos) {
obj = obj[key.substr(pos, idx - pos)];
if (!obj) {
break;
}
pos = idx + 1;
idx = indexOfDotOrLength(key, pos);
}
Expand Down