From: Simon Brunel Date: Sat, 25 Feb 2017 12:06:36 +0000 (+0100) Subject: Handle incoming model values on element transition X-Git-Tag: v2.6.0~2^2~52 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=d25e7b1e1a250b225e6fb5a5fda3cf42153d3d93;p=thirdparty%2FChart.js.git Handle incoming model values on element transition If a value is set on the model after `pivot()` has been called, the view wasn't initialized and the animation started from 0. Now, `_start` and incomplete `_view` are initialized to the model value during the transition (no initial implicit transition). Also remove exception handling when animating a string (color), which is faster when string are not valid colors (e.g. tooltip position). It requires to update `chartjs-color` to version 2.1.0. --- diff --git a/package.json b/package.json index 1dd362e95..6a3a28ea9 100644 --- a/package.json +++ b/package.json @@ -46,7 +46,7 @@ "main": "Chart.js" }, "dependencies": { - "chartjs-color": "~2.0.0", + "chartjs-color": "^2.1.0", "moment": "^2.10.6" } } diff --git a/src/core/core.element.js b/src/core/core.element.js index d8dc57208..4fecfb338 100644 --- a/src/core/core.element.js +++ b/src/core/core.element.js @@ -1,9 +1,60 @@ '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 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; }, @@ -92,5 +116,4 @@ module.exports = function(Chart) { }); Chart.Element.extend = helpers.inherits; - }; diff --git a/src/core/core.helpers.js b/src/core/core.helpers.js index f95af269f..c32e9a76c 100644 --- a/src/core/core.helpers.js +++ b/src/core/core.helpers.js @@ -911,19 +911,21 @@ module.exports = function(Chart) { 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); diff --git a/test/core.element.tests.js b/test/core.element.tests.js index 7d194562e..ca8f9b03e 100644 --- a/test/core.element.tests.js +++ b/test/core.element.tests.js @@ -16,11 +16,9 @@ describe('Core element tests', function() { // 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; @@ -30,6 +28,7 @@ describe('Core element tests', function() { element._model.colorProp = 'rgb(255, 255, 0)'; element.transition(0.25); + expect(element._view).toEqual({ numberProp: 25, numberProp2: 137.5,