'use strict';
+var color = require('chartjs-color');
+
module.exports = function(Chart) {
var helpers = Chart.helpers;
+ function interpolate(start, view, model, ease) {
+ var keys = Object.keys(model);
+ var i, ilen, key, actual, origin, target, type, c0, c1;
+
+ for (i=0, ilen=keys.length; i<ilen; ++i) {
+ key = keys[i];
+
+ target = model[key];
+
+ // if a value is added to the model after pivot() has been called, the view
+ // doesn't contain it, so let's initialize the view to the target value.
+ if (!view.hasOwnProperty(key)) {
+ view[key] = target;
+ }
+
+ actual = view[key];
+
+ if (actual === target || key[0] === '_') {
+ continue;
+ }
+
+ if (!start.hasOwnProperty(key)) {
+ start[key] = actual;
+ }
+
+ origin = start[key];
+
+ type = typeof(target);
+
+ if (type === typeof(origin)) {
+ if (type === 'string') {
+ c0 = color(origin);
+ if (c0.valid) {
+ c1 = color(target);
+ if (c1.valid) {
+ view[key] = c1.mix(c0, ease).rgbString();
+ continue;
+ }
+ }
+ } else if (type === 'number' && isFinite(origin) && isFinite(target)) {
+ view[key] = origin + (target - origin) * ease;
+ continue;
+ }
+ }
+
+ view[key] = target;
+ }
+ }
+
Chart.elements = {};
Chart.Element = function(configuration) {
if (!me._view) {
me._view = helpers.clone(me._model);
}
- me._start = helpers.clone(me._view);
+ me._start = {};
return me;
},
transition: function(ease) {
var me = this;
-
- if (!me._view) {
- me._view = helpers.clone(me._model);
- }
+ var model = me._model;
+ var start = me._start;
+ var view = me._view;
// No animation -> No Transition
- if (ease === 1) {
- me._view = me._model;
+ if (!model || ease === 1) {
+ me._view = model;
me._start = null;
return me;
}
- if (!me._start) {
- me.pivot();
+ if (!view) {
+ view = me._view = {};
}
- helpers.each(me._model, function(value, key) {
+ if (!start) {
+ start = me._start = {};
+ }
- if (key[0] === '_') {
- // Only non-underscored properties
- // Init if doesn't exist
- } else if (!me._view.hasOwnProperty(key)) {
- if (typeof value === 'number' && !isNaN(me._view[key])) {
- me._view[key] = value * ease;
- } else {
- me._view[key] = value;
- }
- // No unnecessary computations
- } else if (value === me._view[key]) {
- // It's the same! Woohoo!
- // Color transitions if possible
- } else if (typeof value === 'string') {
- try {
- var color = helpers.color(me._model[key]).mix(helpers.color(me._start[key]), ease);
- me._view[key] = color.rgbString();
- } catch (err) {
- me._view[key] = value;
- }
- // Number transitions
- } else if (typeof value === 'number') {
- var startVal = me._start[key] !== undefined && isNaN(me._start[key]) === false ? me._start[key] : 0;
- me._view[key] = ((me._model[key] - startVal) * ease) + startVal;
- // Everything else
- } else {
- me._view[key] = value;
- }
- }, me);
+ interpolate(start, view, model, ease);
return me;
},
});
Chart.Element.extend = helpers.inherits;
-
};
ctx.quadraticCurveTo(x, y, x + radius, y);
ctx.closePath();
};
- helpers.color = function(c) {
- if (!color) {
+
+ helpers.color = !color?
+ function(value) {
console.error('Color.js not found!');
- return c;
- }
+ return value;
+ } :
+ function(value) {
+ /* global CanvasGradient */
+ if (value instanceof CanvasGradient) {
+ value = Chart.defaults.global.defaultColor;
+ }
- /* global CanvasGradient */
- if (c instanceof CanvasGradient) {
- return color(Chart.defaults.global.defaultColor);
- }
+ return color(value);
+ };
- return color(c);
- };
helpers.isArray = Array.isArray?
function(obj) {
return Array.isArray(obj);
// First transition clones model into view
element.transition(0.25);
- expect(element._view).toEqual(element._model);
- expect(element._start).toEqual(element._model); // also cloned
+ expect(element._view).toEqual(element._model);
expect(element._view.objectProp).toBe(element._model.objectProp); // not cloned
- expect(element._start.objectProp).toEqual(element._model.objectProp); // not cloned
element._model.numberProp = 100;
element._model.numberProp2 = 250;
element._model.colorProp = 'rgb(255, 255, 0)';
element.transition(0.25);
+
expect(element._view).toEqual({
numberProp: 25,
numberProp2: 137.5,