/*! * chartjs-plugin-deferred * http://chartjs.org/ * Version: 0.2.0 * * Copyright 2016 Simon Brunel * Released under the MIT license * https://github.com/chartjs/chartjs-plugin-deferred/blob/master/LICENSE.md */ /* global window: false */ 'use strict'; (function() { var Chart = window.Chart; var helpers = Chart.helpers; var STUB_KEY = '_chartjs_deferred'; var MODEL_KEY = '_deferred_model'; /** * Plugin based on discussion from Chart.js issue #2745. * @see https://github.com/chartjs/Chart.js/issues/2745 */ Chart.Deferred = Chart.Deferred || {}; Chart.Deferred.defaults = { enabled: true, xOffset: 0, yOffset: 0, delay: 0 }; // DOM implementation // @TODO move it in Chart.js: src/core/core.platform.js Chart.platform = helpers.extend(Chart.platform || {}, { defer: function(fn, delay, scope) { var callback = function() { fn.call(scope); }; if (!delay) { helpers.requestAnimFrame.call(window, callback); } else { window.setTimeout(callback, delay); } } }); function computeOffset(value, base) { var number = parseInt(value, 10); if (isNaN(number)) { return 0; } else if (typeof value === 'string' && value.indexOf('%') !== -1) { return number / 100 * base; } return number; } function chartInViewport(instance) { var model = instance[MODEL_KEY]; var canvas = instance.chart.canvas; // http://stackoverflow.com/a/21696585 if (canvas.offsetParent === null) { return false; } var rect = canvas.getBoundingClientRect(); var dy = computeOffset(model.yOffset || 0, rect.height); var dx = computeOffset(model.xOffset || 0, rect.width); return rect.right - dx >= 0 && rect.bottom - dy >= 0 && rect.left + dx <= window.innerWidth && rect.top + dy <= window.innerHeight; } function buildDeferredModel(instance) { var defaults = Chart.Deferred.defaults; var options = instance.options.deferred; var getValue = helpers.getValueOrDefault; if (options === undefined) { options = {}; } else if (typeof options === 'boolean') { // accepting { options: { deferred: true } } options = {enabled: options}; } return { enabled: getValue(options.enabled, defaults.enabled), xOffset: getValue(options.xOffset, defaults.xOffset), yOffset: getValue(options.yOffset, defaults.yOffset), delay: getValue(options.delay, defaults.delay), appeared: false, delayed: false, loaded: false, elements: [] }; } function onScroll(event) { var node = event.target; var stub = node[STUB_KEY]; if (stub.ticking) { return; } stub.ticking = true; Chart.platform.defer(function() { var instances = stub.instances.slice(); var ilen = instances.length; var instance, i; for (i=0; i 0) { model.delayed = true; Chart.platform.defer(function() { model.delayed = false; instance.update(); }, model.delay); return false; } } if (model.delayed) { // in case of delayed update, ensure to block external requests, such // as interacting with the legend label, or direct calls to update() return false; } } }); }());