]> git.ipfire.org Git - thirdparty/Chart.js.git/commitdiff
Make `Chart.helpers` importable (#4479)
authorSimon Brunel <simonbrunel@users.noreply.github.com>
Sat, 15 Jul 2017 13:13:56 +0000 (15:13 +0200)
committerGitHub <noreply@github.com>
Sat, 15 Jul 2017 13:13:56 +0000 (15:13 +0200)
Properly export helpers and remove dependencies to `Chart.helpers`. Helpers can now be accessed from `src/helpers/index.js` (`var helpers = require('path/to/helpers/index')`, instead of `var helpers = Chart.helpers`).

37 files changed:
src/chart.js
src/controllers/controller.bar.js
src/controllers/controller.bubble.js
src/controllers/controller.doughnut.js
src/controllers/controller.line.js
src/controllers/controller.polarArea.js
src/controllers/controller.radar.js
src/core/core.animation.js
src/core/core.controller.js
src/core/core.datasetController.js
src/core/core.element.js
src/core/core.helpers.js
src/core/core.interaction.js
src/core/core.layoutService.js
src/core/core.plugin.js
src/core/core.scale.js
src/core/core.scaleService.js
src/core/core.ticks.js
src/core/core.tooltip.js
src/elements/element.arc.js
src/elements/element.line.js
src/elements/element.point.js
src/helpers/helpers.canvas.js
src/helpers/helpers.core.js
src/helpers/helpers.easing.js
src/helpers/helpers.time.js
src/helpers/index.js [new file with mode: 0644]
src/platforms/platform.dom.js
src/platforms/platform.js
src/plugins/plugin.filler.js
src/plugins/plugin.legend.js
src/plugins/plugin.title.js
src/scales/scale.linear.js
src/scales/scale.linearbase.js
src/scales/scale.logarithmic.js
src/scales/scale.radialLinear.js
src/scales/scale.time.js

index 8026cc856b7168cb8d26415ddfdb9d04fa01c33f..493568686902e0a43d656f26ea271968df5b7e53 100644 (file)
@@ -3,11 +3,10 @@
  */
 var Chart = require('./core/core')();
 
-require('./helpers/helpers.core')(Chart);
-require('./helpers/helpers.easing')(Chart);
+Chart.helpers = require('./helpers/index');
+
+// @todo dispatch these helpers into appropriated helpers/helpers.* file and write unit tests!
 require('./core/core.helpers')(Chart);
-require('./helpers/helpers.time')(Chart);
-require('./helpers/helpers.canvas')(Chart);
 
 require('./platforms/platform')(Chart);
 require('./core/core.element')(Chart);
@@ -66,3 +65,14 @@ module.exports = Chart;
 if (typeof window !== 'undefined') {
        window.Chart = Chart;
 }
+
+// DEPRECATIONS
+
+/**
+ * Provided for backward compatibility, use Chart.helpers.canvas instead.
+ * @namespace Chart.canvasHelpers
+ * @deprecated since version 2.6.0
+ * @todo remove at version 3
+ * @private
+ */
+Chart.canvasHelpers = Chart.helpers.canvas;
index c89631cb43d2c6a5a57f332c32435044d59a59e7..93d285323c3be357caf8fde41103c9d5b9403b6b 100644 (file)
@@ -1,8 +1,8 @@
 'use strict';
 
-module.exports = function(Chart) {
+var helpers = require('../helpers/index');
 
-       var helpers = Chart.helpers;
+module.exports = function(Chart) {
 
        Chart.defaults.bar = {
                hover: {
index 3152cd09cfb393d8fb836dbc37c629e3c61b33ae..b91b15f1277fc1a7a760144975361c1eb0df5a4d 100644 (file)
@@ -1,8 +1,8 @@
 'use strict';
 
-module.exports = function(Chart) {
+var helpers = require('../helpers/index');
 
-       var helpers = Chart.helpers;
+module.exports = function(Chart) {
 
        Chart.defaults.bubble = {
                hover: {
index e86eea26e16a3ef8c766dc6a4a0669c10f66dd13..c87c59bbcb08feb9e7f97e75dec9179cbdf1ca1d 100644 (file)
@@ -1,9 +1,10 @@
 'use strict';
 
+var helpers = require('../helpers/index');
+
 module.exports = function(Chart) {
 
-       var helpers = Chart.helpers,
-               defaults = Chart.defaults;
+       var defaults = Chart.defaults;
 
        defaults.doughnut = {
                animation: {
index 97982bded7cad8096b36a1a2f3db0eda5a1d0bd8..c31e73f23d44a8709968c8c229e55b402b1ec155 100644 (file)
@@ -1,8 +1,8 @@
 'use strict';
 
-module.exports = function(Chart) {
+var helpers = require('../helpers/index');
 
-       var helpers = Chart.helpers;
+module.exports = function(Chart) {
 
        Chart.defaults.line = {
                showLines: true,
@@ -285,13 +285,13 @@ module.exports = function(Chart) {
                        var ilen = points.length;
                        var i = 0;
 
-                       Chart.helpers.canvas.clipArea(chart.ctx, area);
+                       helpers.canvas.clipArea(chart.ctx, area);
 
                        if (lineEnabled(me.getDataset(), chart.options)) {
                                meta.dataset.draw();
                        }
 
-                       Chart.helpers.canvas.unclipArea(chart.ctx);
+                       helpers.canvas.unclipArea(chart.ctx);
 
                        // Draw the points
                        for (; i<ilen; ++i) {
index b9123fa7262442e9adfecc51beba3ae521625f41..bf2cd6b41bf5aac9a3a09379969e7da899b184d4 100644 (file)
@@ -1,8 +1,8 @@
 'use strict';
 
-module.exports = function(Chart) {
+var helpers = require('../helpers/index');
 
-       var helpers = Chart.helpers;
+module.exports = function(Chart) {
 
        Chart.defaults.polarArea = {
 
index 42861d07a2ede5e6fd0defa69443259e6ad2c5cf..24c83b4631833130ab4dadfcbac1db5cb5bfe2d3 100644 (file)
@@ -1,8 +1,8 @@
 'use strict';
 
-module.exports = function(Chart) {
+var helpers = require('../helpers/index');
 
-       var helpers = Chart.helpers;
+module.exports = function(Chart) {
 
        Chart.defaults.radar = {
                scale: {
index ad450df8e2a19d157f7a0fbfcb9df8473946c0ee..40208916a6644260c404e6f796a5f4c6a7ba7d4f 100644 (file)
@@ -1,9 +1,9 @@
 /* global window: false */
 'use strict';
 
-module.exports = function(Chart) {
+var helpers = require('../helpers/index');
 
-       var helpers = Chart.helpers;
+module.exports = function(Chart) {
 
        Chart.defaults.global.animation = {
                duration: 1000,
index c367c36ae9f843c67e6b6d55a51d18f579ddefdb..c8578a9373791927f3fba82c5dbec0fc82285370 100644 (file)
@@ -1,8 +1,8 @@
 'use strict';
 
-module.exports = function(Chart) {
+var helpers = require('../helpers/index');
 
-       var helpers = Chart.helpers;
+module.exports = function(Chart) {
        var plugins = Chart.plugins;
        var platform = Chart.platform;
 
index 4fb207b689f580c25237b1cf323b3f350a17b024..a74612421ee72e3a95dd816bd33b30375445abfd 100644 (file)
@@ -1,8 +1,8 @@
 'use strict';
 
-module.exports = function(Chart) {
+var helpers = require('../helpers/index');
 
-       var helpers = Chart.helpers;
+module.exports = function(Chart) {
 
        var arrayEvents = ['push', 'pop', 'shift', 'splice', 'unshift'];
 
index 4fecfb33887f01dce77957142dfdd3d54449a618..ba508fddcda7f959d63f9cde04f07e546cb5a986 100644 (file)
@@ -1,11 +1,10 @@
 'use strict';
 
 var color = require('chartjs-color');
+var helpers = require('../helpers/index');
 
 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;
index 854a55575d531e1710c2b87bf9fee293419d2149..8896e232aad1d02ad8e1a83d8d922c0284571e9f 100644 (file)
@@ -3,9 +3,9 @@
 'use strict';
 
 var color = require('chartjs-color');
+var helpers = require('../helpers/index');
 
 module.exports = function(Chart) {
-       var helpers = Chart.helpers;
 
        // -- Basic js utility methods
 
index c2c4ffcbf91390fc64e5127ed87fa28e0c3c5c55..6e35bd950e851ff88e4951f74b8d580800096142 100644 (file)
@@ -1,7 +1,8 @@
 'use strict';
 
+var helpers = require('../helpers/index');
+
 module.exports = function(Chart) {
-       var helpers = Chart.helpers;
 
        /**
         * Helper function to get relative position for an event
index 8d50db80a9984866a4b1bfdb75854be944241b3a..65adac88f2f0dd18bbaeb1117413b227e9fb1d97 100644 (file)
@@ -1,8 +1,8 @@
 'use strict';
 
-module.exports = function(Chart) {
+var helpers = require('../helpers/index');
 
-       var helpers = Chart.helpers;
+module.exports = function(Chart) {
 
        function filterByPosition(array, position) {
                return helpers.where(array, function(v) {
index 164e5d4c94882a41a8f88fa0a45dfdb8d36eff25..92761158033d9d5780c2c5ac23fb2c49cbc6b40d 100644 (file)
@@ -1,8 +1,8 @@
 'use strict';
 
-module.exports = function(Chart) {
+var helpers = require('../helpers/index');
 
-       var helpers = Chart.helpers;
+module.exports = function(Chart) {
 
        Chart.defaults.global.plugins = {};
 
index 2938385cdc16c85226e17d3fda258707e0b75c88..38d1d10ac5a86a985e9d593f7069d2eb2e1b2fb7 100644 (file)
@@ -1,8 +1,8 @@
 'use strict';
 
-module.exports = function(Chart) {
+var helpers = require('../helpers/index');
 
-       var helpers = Chart.helpers;
+module.exports = function(Chart) {
 
        Chart.defaults.scale = {
                display: true,
index 58eafc9cbb111a2d37d73bd9da6f1e7de85f60e1..e903b701b087f0c98fa27f36077939f4ab37c910 100644 (file)
@@ -1,8 +1,8 @@
 'use strict';
 
-module.exports = function(Chart) {
+var helpers = require('../helpers/index');
 
-       var helpers = Chart.helpers;
+module.exports = function(Chart) {
 
        Chart.scaleService = {
                // Scale registration object. Extensions can register new scale types (such as log or DB scales) and then
index 8e4cc034c7274675ecba7173cc2d0a0a60ab79f0..a3b721164bacc284ac372dc8d19edf88de75d337 100644 (file)
@@ -1,8 +1,8 @@
 'use strict';
 
-module.exports = function(Chart) {
+var helpers = require('../helpers/index');
 
-       var helpers = Chart.helpers;
+module.exports = function(Chart) {
 
        /**
         * Namespace to hold static tick generation functions
index e54ab019202e0836a5b3ee648d567c66e3ab3bdc..6794320511f88b27585855d7748ed278f795bb1b 100644 (file)
@@ -1,8 +1,8 @@
 'use strict';
 
-module.exports = function(Chart) {
+var helpers = require('../helpers/index');
 
-       var helpers = Chart.helpers;
+module.exports = function(Chart) {
 
        /**
         * Helper method to merge the opacity into a color
index a61d19a3a5ee7066e6c44ec335769123817842f6..8604dfaea269554e5b6f2519c6f4fef9cb875575 100644 (file)
@@ -1,9 +1,10 @@
 'use strict';
 
+var helpers = require('../helpers/index');
+
 module.exports = function(Chart) {
 
-       var helpers = Chart.helpers,
-               globalOpts = Chart.defaults.global;
+       var globalOpts = Chart.defaults.global;
 
        globalOpts.elements.arc = {
                backgroundColor: globalOpts.defaultColor,
index 1718331d5f29104a03672c698fde6e324321540d..5a21fafb20b8f1c03fd2682e59c01e6b16e057b9 100644 (file)
@@ -1,8 +1,9 @@
 'use strict';
 
+var helpers = require('../helpers/index');
+
 module.exports = function(Chart) {
 
-       var helpers = Chart.helpers;
        var globalDefaults = Chart.defaults.global;
 
        Chart.defaults.global.elements.line = {
index b10132fcd07b62bc73433002bc16d68d54c4f64d..c09329b1737753a760b61202640d706d988acaae 100644 (file)
@@ -1,9 +1,10 @@
 'use strict';
 
+var helpers = require('../helpers/index');
+
 module.exports = function(Chart) {
 
-       var helpers = Chart.helpers,
-               globalOpts = Chart.defaults.global,
+       var globalOpts = Chart.defaults.global,
                defaultColor = globalOpts.defaultColor;
 
        globalOpts.elements.point = {
@@ -64,7 +65,7 @@ module.exports = function(Chart) {
                        var radius = vm.radius;
                        var x = vm.x;
                        var y = vm.y;
-                       var color = Chart.helpers.color;
+                       var color = helpers.color;
                        var errMargin = 1.01; // 1.01 is margin for Accumulated error. (Especially Edge, IE.)
                        var ratio = 0;
 
@@ -94,7 +95,7 @@ module.exports = function(Chart) {
                                ctx.fillStyle = color(ctx.fillStyle).alpha(ratio).rgbString();
                        }
 
-                       Chart.helpers.canvas.drawPoint(ctx, pointStyle, radius, x, y);
+                       helpers.canvas.drawPoint(ctx, pointStyle, radius, x, y);
                }
        });
 };
index 22bf58f312bdccfc8d052cbb40d2e1e963633b8e..bf508dc7f2c2708de2d961acd919006559c31f23 100644 (file)
@@ -1,58 +1,56 @@
 'use strict';
 
-module.exports = function(Chart) {
-       var helpers = Chart.helpers;
+var helpers = require('./helpers.core');
 
+/**
+ * @namespace Chart.helpers.canvas
+ */
+var exports = module.exports = {
        /**
-        * @namespace Chart.helpers.canvas
+        * Clears the entire canvas associated to the given `chart`.
+        * @param {Chart} chart - The chart for which to clear the canvas.
         */
-       helpers.canvas = {
-               /**
-                * Clears the entire canvas associated to the given `chart`.
-                * @param {Chart} chart - The chart for which to clear the canvas.
-                */
-               clear: function(chart) {
-                       chart.ctx.clearRect(0, 0, chart.width, chart.height);
-               },
-
-               /**
-                * Creates a "path" for a rectangle with rounded corners at position (x, y) with a
-                * given size (width, height) and the same `radius` for all corners.
-                * @param {CanvasRenderingContext2D} ctx - The canvas 2D Context.
-                * @param {Number} x - The x axis of the coordinate for the rectangle starting point.
-                * @param {Number} y - The y axis of the coordinate for the rectangle starting point.
-                * @param {Number} width - The rectangle's width.
-                * @param {Number} height - The rectangle's height.
-                * @param {Number} radius - The rounded amount (in pixels) for the four corners.
-                * @todo handle `radius` as top-left, top-right, bottom-right, bottom-left array/object?
-                */
-               roundedRect: function(ctx, x, y, width, height, radius) {
-                       if (radius) {
-                               var rx = Math.min(radius, width/2);
-                               var ry = Math.min(radius, height/2);
-
-                               ctx.moveTo(x + rx, y);
-                               ctx.lineTo(x + width - rx, y);
-                               ctx.quadraticCurveTo(x + width, y, x + width, y + ry);
-                               ctx.lineTo(x + width, y + height - ry);
-                               ctx.quadraticCurveTo(x + width, y + height, x + width - rx, y + height);
-                               ctx.lineTo(x + rx, y + height);
-                               ctx.quadraticCurveTo(x, y + height, x, y + height - ry);
-                               ctx.lineTo(x, y + ry);
-                               ctx.quadraticCurveTo(x, y, x + rx, y);
-                       } else {
-                               ctx.rect(x, y, width, height);
-                       }
+       clear: function(chart) {
+               chart.ctx.clearRect(0, 0, chart.width, chart.height);
+       },
+
+       /**
+        * Creates a "path" for a rectangle with rounded corners at position (x, y) with a
+        * given size (width, height) and the same `radius` for all corners.
+        * @param {CanvasRenderingContext2D} ctx - The canvas 2D Context.
+        * @param {Number} x - The x axis of the coordinate for the rectangle starting point.
+        * @param {Number} y - The y axis of the coordinate for the rectangle starting point.
+        * @param {Number} width - The rectangle's width.
+        * @param {Number} height - The rectangle's height.
+        * @param {Number} radius - The rounded amount (in pixels) for the four corners.
+        * @todo handle `radius` as top-left, top-right, bottom-right, bottom-left array/object?
+        */
+       roundedRect: function(ctx, x, y, width, height, radius) {
+               if (radius) {
+                       var rx = Math.min(radius, width/2);
+                       var ry = Math.min(radius, height/2);
+
+                       ctx.moveTo(x + rx, y);
+                       ctx.lineTo(x + width - rx, y);
+                       ctx.quadraticCurveTo(x + width, y, x + width, y + ry);
+                       ctx.lineTo(x + width, y + height - ry);
+                       ctx.quadraticCurveTo(x + width, y + height, x + width - rx, y + height);
+                       ctx.lineTo(x + rx, y + height);
+                       ctx.quadraticCurveTo(x, y + height, x, y + height - ry);
+                       ctx.lineTo(x, y + ry);
+                       ctx.quadraticCurveTo(x, y, x + rx, y);
+               } else {
+                       ctx.rect(x, y, width, height);
                }
-       };
+       },
 
-       helpers.canvas.drawPoint = function(ctx, pointStyle, radius, x, y) {
+       drawPoint: function(ctx, style, radius, x, y) {
                var type, edgeLength, xOffset, yOffset, height, size;
 
-               if (typeof pointStyle === 'object') {
-                       type = pointStyle.toString();
+               if (typeof style === 'object') {
+                       type = style.toString();
                        if (type === '[object HTMLImageElement]' || type === '[object HTMLCanvasElement]') {
-                               ctx.drawImage(pointStyle, x - pointStyle.width / 2, y - pointStyle.height / 2, pointStyle.width, pointStyle.height);
+                               ctx.drawImage(style, x - style.width / 2, y - style.height / 2, style.width, style.height);
                                return;
                        }
                }
@@ -61,7 +59,7 @@ module.exports = function(Chart) {
                        return;
                }
 
-               switch (pointStyle) {
+               switch (style) {
                // Default includes circle
                default:
                        ctx.beginPath();
@@ -152,20 +150,20 @@ module.exports = function(Chart) {
                }
 
                ctx.stroke();
-       };
+       },
 
-       helpers.canvas.clipArea = function(ctx, clipArea) {
+       clipArea: function(ctx, area) {
                ctx.save();
                ctx.beginPath();
-               ctx.rect(clipArea.left, clipArea.top, clipArea.right - clipArea.left, clipArea.bottom - clipArea.top);
+               ctx.rect(area.left, area.top, area.right - area.left, area.bottom - area.top);
                ctx.clip();
-       };
+       },
 
-       helpers.canvas.unclipArea = function(ctx) {
+       unclipArea: function(ctx) {
                ctx.restore();
-       };
+       },
 
-       helpers.canvas.lineTo = function(ctx, previous, target, flip) {
+       lineTo: function(ctx, previous, target, flip) {
                if (target.steppedLine) {
                        if (target.steppedLine === 'after') {
                                ctx.lineTo(previous.x, target.y);
@@ -188,36 +186,29 @@ module.exports = function(Chart) {
                        flip? target.controlPointNextY : target.controlPointPreviousY,
                        target.x,
                        target.y);
-       };
-
-       /**
-        * Provided for backward compatibility, use Chart.helpers.canvas instead.
-        * @namespace Chart.canvasHelpers
-        * @deprecated since version 2.6.0
-        * @todo remove at version 3
-        * @private
-        */
-       Chart.canvasHelpers = helpers.canvas;
-
-       /**
-        * Provided for backward compatibility, use Chart.helpers.canvas.clear instead.
-        * @namespace Chart.helpers.clear
-        * @deprecated since version 2.7.0
-        * @todo remove at version 3
-        * @private
-        */
-       helpers.clear = helpers.canvas.clear;
+       }
+};
 
-       /**
-        * Provided for backward compatibility, use Chart.helpers.canvas.roundedRect instead.
-        * @namespace Chart.helpers.drawRoundedRectangle
-        * @deprecated since version 2.7.0
-        * @todo remove at version 3
-        * @private
-        */
-       helpers.drawRoundedRectangle = function(ctx) {
-               ctx.beginPath();
-               helpers.canvas.roundedRect.apply(this, arguments);
-               ctx.closePath();
-       };
+// DEPRECATIONS
+
+/**
+ * Provided for backward compatibility, use Chart.helpers.canvas.clear instead.
+ * @namespace Chart.helpers.clear
+ * @deprecated since version 2.7.0
+ * @todo remove at version 3
+ * @private
+ */
+helpers.clear = exports.clear;
+
+/**
+ * Provided for backward compatibility, use Chart.helpers.canvas.roundedRect instead.
+ * @namespace Chart.helpers.drawRoundedRectangle
+ * @deprecated since version 2.7.0
+ * @todo remove at version 3
+ * @private
+ */
+helpers.drawRoundedRectangle = function(ctx) {
+       ctx.beginPath();
+       exports.roundedRect.apply(exports, arguments);
+       ctx.closePath();
 };
index d0e4b14267c6995cf33b3a5f7fb4bf8100219bd7..0a603a28261470145174443b2b72d39151715d6f 100644 (file)
 'use strict';
 
-module.exports = function(Chart) {
+/**
+ * @namespace Chart.helpers
+ */
+var helpers = {
        /**
-        * @namespace Chart.helpers
+        * An empty function that can be used, for example, for optional callback.
         */
-       var helpers = Chart.helpers = {
-               /**
-                * An empty function that can be used, for example, for optional callback.
-                */
-               noop: function() {},
-
-               /**
-                * Returns a unique id, sequentially generated from a global variable.
-                * @returns {Number}
-                * @function
-                */
-               uid: (function() {
-                       var id = 0;
-                       return function() {
-                               return id++;
-                       };
-               }()),
-
-               /**
-                * Returns true if `value` is neither null nor undefined, else returns false.
-                * @param {*} value - The value to test.
-                * @returns {Boolean}
-                * @since 2.7.0
-                */
-               isNullOrUndef: function(value) {
-                       return value === null || typeof value === 'undefined';
-               },
-
-               /**
-                * Returns true if `value` is an array, else returns false.
-                * @param {*} value - The value to test.
-                * @returns {Boolean}
-                * @function
-                */
-               isArray: Array.isArray? Array.isArray : function(value) {
-                       return Object.prototype.toString.call(value) === '[object Array]';
-               },
-
-               /**
-                * Returns true if `value` is an object (excluding null), else returns false.
-                * @param {*} value - The value to test.
-                * @returns {Boolean}
-                * @since 2.7.0
-                */
-               isObject: function(value) {
-                       return value !== null && Object.prototype.toString.call(value) === '[object Object]';
-               },
-
-               /**
-                * Returns `value` if defined, else returns `defaultValue`.
-                * @param {*} value - The value to return if defined.
-                * @param {*} defaultValue - The value to return if `value` is undefined.
-                * @returns {*}
-                */
-               valueOrDefault: function(value, defaultValue) {
-                       return typeof value === 'undefined'? defaultValue : value;
-               },
-
-               /**
-                * Returns value at the given `index` in array if defined, else returns `defaultValue`.
-                * @param {Array} value - The array to lookup for value at `index`.
-                * @param {Number} index - The index in `value` to lookup for value.
-                * @param {*} defaultValue - The value to return if `value[index]` is undefined.
-                * @returns {*}
-                */
-               valueAtIndexOrDefault: function(value, index, defaultValue) {
-                       return helpers.valueOrDefault(helpers.isArray(value)? value[index] : value, defaultValue);
-               },
-
-               /**
-                * Calls `fn` with the given `args` in the scope defined by `thisArg` and returns the
-                * value returned by `fn`. If `fn` is not a function, this method returns undefined.
-                * @param {Function} fn - The function to call.
-                * @param {Array|undefined|null} args - The arguments with which `fn` should be called.
-                * @param {Object} [thisArg] - The value of `this` provided for the call to `fn`.
-                * @returns {*}
-                */
-               callback: function(fn, args, thisArg) {
-                       if (fn && typeof fn.call === 'function') {
-                               return fn.apply(thisArg, args);
-                       }
-               },
-
-               /**
-                * Note(SB) for performance sake, this method should only be used when loopable type
-                * is unknown or in none intensive code (not called often and small loopable). Else
-                * it's preferable to use a regular for() loop and save extra function calls.
-                * @param {Object|Array} loopable - The object or array to be iterated.
-                * @param {Function} fn - The function to call for each item.
-                * @param {Object} [thisArg] - The value of `this` provided for the call to `fn`.
-                * @param {Boolean} [reverse] - If true, iterates backward on the loopable.
-                */
-               each: function(loopable, fn, thisArg, reverse) {
-                       var i, len, keys;
-                       if (helpers.isArray(loopable)) {
-                               len = loopable.length;
-                               if (reverse) {
-                                       for (i = len - 1; i >= 0; i--) {
-                                               fn.call(thisArg, loopable[i], i);
-                                       }
-                               } else {
-                                       for (i = 0; i < len; i++) {
-                                               fn.call(thisArg, loopable[i], i);
-                                       }
-                               }
-                       } else if (helpers.isObject(loopable)) {
-                               keys = Object.keys(loopable);
-                               len = keys.length;
-                               for (i = 0; i < len; i++) {
-                                       fn.call(thisArg, loopable[keys[i]], keys[i]);
-                               }
-                       }
-               },
-
-               /**
-                * Returns true if the `a0` and `a1` arrays have the same content, else returns false.
-                * @see http://stackoverflow.com/a/14853974
-                * @param {Array} a0 - The array to compare
-                * @param {Array} a1 - The array to compare
-                * @returns {Boolean}
-                */
-               arrayEquals: function(a0, a1) {
-                       var i, ilen, v0, v1;
-
-                       if (!a0 || !a1 || a0.length !== a1.length) {
-                               return false;
-                       }
+       noop: function() {},
 
-                       for (i = 0, ilen=a0.length; i < ilen; ++i) {
-                               v0 = a0[i];
-                               v1 = a1[i];
-
-                               if (v0 instanceof Array && v1 instanceof Array) {
-                                       if (!helpers.arrayEquals(v0, v1)) {
-                                               return false;
-                                       }
-                               } else if (v0 !== v1) {
-                                       // NOTE: two different object instances will never be equal: {x:20} != {x:20}
-                                       return false;
-                               }
-                       }
+       /**
+        * Returns a unique id, sequentially generated from a global variable.
+        * @returns {Number}
+        * @function
+        */
+       uid: (function() {
+               var id = 0;
+               return function() {
+                       return id++;
+               };
+       }()),
 
-                       return true;
-               },
-
-               /**
-                * Returns a deep copy of `source` without keeping references on objects and arrays.
-                * @param {*} source - The value to clone.
-                * @returns {*}
-                */
-               clone: function(source) {
-                       if (helpers.isArray(source)) {
-                               return source.map(helpers.clone);
-                       }
+       /**
+        * Returns true if `value` is neither null nor undefined, else returns false.
+        * @param {*} value - The value to test.
+        * @returns {Boolean}
+        * @since 2.7.0
+        */
+       isNullOrUndef: function(value) {
+               return value === null || typeof value === 'undefined';
+       },
 
-                       if (helpers.isObject(source)) {
-                               var target = {};
-                               var keys = Object.keys(source);
-                               var klen = keys.length;
-                               var k = 0;
+       /**
+        * Returns true if `value` is an array, else returns false.
+        * @param {*} value - The value to test.
+        * @returns {Boolean}
+        * @function
+        */
+       isArray: Array.isArray? Array.isArray : function(value) {
+               return Object.prototype.toString.call(value) === '[object Array]';
+       },
 
-                               for (; k<klen; ++k) {
-                                       target[keys[k]] = helpers.clone(source[keys[k]]);
-                               }
+       /**
+        * Returns true if `value` is an object (excluding null), else returns false.
+        * @param {*} value - The value to test.
+        * @returns {Boolean}
+        * @since 2.7.0
+        */
+       isObject: function(value) {
+               return value !== null && Object.prototype.toString.call(value) === '[object Object]';
+       },
 
-                               return target;
-                       }
+       /**
+        * Returns `value` if defined, else returns `defaultValue`.
+        * @param {*} value - The value to return if defined.
+        * @param {*} defaultValue - The value to return if `value` is undefined.
+        * @returns {*}
+        */
+       valueOrDefault: function(value, defaultValue) {
+               return typeof value === 'undefined'? defaultValue : value;
+       },
 
-                       return source;
-               },
+       /**
+        * Returns value at the given `index` in array if defined, else returns `defaultValue`.
+        * @param {Array} value - The array to lookup for value at `index`.
+        * @param {Number} index - The index in `value` to lookup for value.
+        * @param {*} defaultValue - The value to return if `value[index]` is undefined.
+        * @returns {*}
+        */
+       valueAtIndexOrDefault: function(value, index, defaultValue) {
+               return helpers.valueOrDefault(helpers.isArray(value)? value[index] : value, defaultValue);
+       },
 
-               /**
-                * The default merger when Chart.helpers.merge is called without merger option.
-                * Note(SB): this method is also used by configMerge and scaleMerge as fallback.
-                * @private
-                */
-               _merger: function(key, target, source, options) {
-                       var tval = target[key];
-                       var sval = source[key];
+       /**
+        * Calls `fn` with the given `args` in the scope defined by `thisArg` and returns the
+        * value returned by `fn`. If `fn` is not a function, this method returns undefined.
+        * @param {Function} fn - The function to call.
+        * @param {Array|undefined|null} args - The arguments with which `fn` should be called.
+        * @param {Object} [thisArg] - The value of `this` provided for the call to `fn`.
+        * @returns {*}
+        */
+       callback: function(fn, args, thisArg) {
+               if (fn && typeof fn.call === 'function') {
+                       return fn.apply(thisArg, args);
+               }
+       },
 
-                       if (helpers.isObject(tval) && helpers.isObject(sval)) {
-                               helpers.merge(tval, sval, options);
+       /**
+        * Note(SB) for performance sake, this method should only be used when loopable type
+        * is unknown or in none intensive code (not called often and small loopable). Else
+        * it's preferable to use a regular for() loop and save extra function calls.
+        * @param {Object|Array} loopable - The object or array to be iterated.
+        * @param {Function} fn - The function to call for each item.
+        * @param {Object} [thisArg] - The value of `this` provided for the call to `fn`.
+        * @param {Boolean} [reverse] - If true, iterates backward on the loopable.
+        */
+       each: function(loopable, fn, thisArg, reverse) {
+               var i, len, keys;
+               if (helpers.isArray(loopable)) {
+                       len = loopable.length;
+                       if (reverse) {
+                               for (i = len - 1; i >= 0; i--) {
+                                       fn.call(thisArg, loopable[i], i);
+                               }
                        } else {
-                               target[key] = helpers.clone(sval);
-                       }
-               },
-
-               /**
-                * Merges source[key] in target[key] only if target[key] is undefined.
-                * @private
-                */
-               _mergerIf: function(key, target, source) {
-                       var tval = target[key];
-                       var sval = source[key];
-
-                       if (helpers.isObject(tval) && helpers.isObject(sval)) {
-                               helpers.mergeIf(tval, sval);
-                       } else if (!target.hasOwnProperty(key)) {
-                               target[key] = helpers.clone(sval);
+                               for (i = 0; i < len; i++) {
+                                       fn.call(thisArg, loopable[i], i);
+                               }
                        }
-               },
-
-               /**
-                * Recursively deep copies `source` properties into `target` with the given `options`.
-                * IMPORTANT: `target` is not cloned and will be updated with `source` properties.
-                * @param {Object} target - The target object in which all sources are merged into.
-                * @param {Object|Array(Object)} source - Object(s) to merge into `target`.
-                * @param {Object} [options] - Merging options:
-                * @param {Function} [options.merger] - The merge method (key, target, source, options)
-                * @returns {Object} The `target` object.
-                */
-               merge: function(target, source, options) {
-                       var sources = helpers.isArray(source)? source : [source];
-                       var ilen = sources.length;
-                       var merge, i, keys, klen, k;
-
-                       if (!helpers.isObject(target)) {
-                               return target;
+               } else if (helpers.isObject(loopable)) {
+                       keys = Object.keys(loopable);
+                       len = keys.length;
+                       for (i = 0; i < len; i++) {
+                               fn.call(thisArg, loopable[keys[i]], keys[i]);
                        }
+               }
+       },
 
-                       options = options || {};
-                       merge = options.merger || helpers._merger;
+       /**
+        * Returns true if the `a0` and `a1` arrays have the same content, else returns false.
+        * @see http://stackoverflow.com/a/14853974
+        * @param {Array} a0 - The array to compare
+        * @param {Array} a1 - The array to compare
+        * @returns {Boolean}
+        */
+       arrayEquals: function(a0, a1) {
+               var i, ilen, v0, v1;
 
-                       for (i=0; i<ilen; ++i) {
-                               source = sources[i];
-                               if (!helpers.isObject(source)) {
-                                       continue;
-                               }
+               if (!a0 || !a1 || a0.length !== a1.length) {
+                       return false;
+               }
 
-                               keys = Object.keys(source);
-                               for (k=0, klen = keys.length; k<klen; ++k) {
-                                       merge(keys[k], target, source, options);
+               for (i = 0, ilen=a0.length; i < ilen; ++i) {
+                       v0 = a0[i];
+                       v1 = a1[i];
+
+                       if (v0 instanceof Array && v1 instanceof Array) {
+                               if (!helpers.arrayEquals(v0, v1)) {
+                                       return false;
                                }
+                       } else if (v0 !== v1) {
+                               // NOTE: two different object instances will never be equal: {x:20} != {x:20}
+                               return false;
+                       }
+               }
+
+               return true;
+       },
+
+       /**
+        * Returns a deep copy of `source` without keeping references on objects and arrays.
+        * @param {*} source - The value to clone.
+        * @returns {*}
+        */
+       clone: function(source) {
+               if (helpers.isArray(source)) {
+                       return source.map(helpers.clone);
+               }
+
+               if (helpers.isObject(source)) {
+                       var target = {};
+                       var keys = Object.keys(source);
+                       var klen = keys.length;
+                       var k = 0;
+
+                       for (; k<klen; ++k) {
+                               target[keys[k]] = helpers.clone(source[keys[k]]);
                        }
 
                        return target;
-               },
-
-               /**
-                * Recursively deep copies `source` properties into `target` *only* if not defined in target.
-                * IMPORTANT: `target` is not cloned and will be updated with `source` properties.
-                * @param {Object} target - The target object in which all sources are merged into.
-                * @param {Object|Array(Object)} source - Object(s) to merge into `target`.
-                * @returns {Object} The `target` object.
-                */
-               mergeIf: function(target, source) {
-                       return helpers.merge(target, source, {merger: helpers._mergerIf});
                }
-       };
+
+               return source;
+       },
 
        /**
-        * Provided for backward compatibility, use Chart.helpers.callback instead.
-        * @function Chart.helpers.callCallback
-        * @deprecated since version 2.6.0
-        * @todo remove at version 3
+        * The default merger when Chart.helpers.merge is called without merger option.
+        * Note(SB): this method is also used by configMerge and scaleMerge as fallback.
         * @private
         */
-       helpers.callCallback = helpers.callback;
+       _merger: function(key, target, source, options) {
+               var tval = target[key];
+               var sval = source[key];
+
+               if (helpers.isObject(tval) && helpers.isObject(sval)) {
+                       helpers.merge(tval, sval, options);
+               } else {
+                       target[key] = helpers.clone(sval);
+               }
+       },
 
        /**
-        * Provided for backward compatibility, use Array.prototype.indexOf instead.
-        * Array.prototype.indexOf compatibility: Chrome, Opera, Safari, FF1.5+, IE9+
-        * @function Chart.helpers.indexOf
-        * @deprecated since version 2.7.0
-        * @todo remove at version 3
+        * Merges source[key] in target[key] only if target[key] is undefined.
         * @private
         */
-       helpers.indexOf = function(array, item, fromIndex) {
-               return Array.prototype.indexOf.call(array, item, fromIndex);
-       };
+       _mergerIf: function(key, target, source) {
+               var tval = target[key];
+               var sval = source[key];
+
+               if (helpers.isObject(tval) && helpers.isObject(sval)) {
+                       helpers.mergeIf(tval, sval);
+               } else if (!target.hasOwnProperty(key)) {
+                       target[key] = helpers.clone(sval);
+               }
+       },
 
        /**
-        * Provided for backward compatibility, use Chart.helpers.valueOrDefault instead.
-        * @function Chart.helpers.getValueOrDefault
-        * @deprecated since version 2.7.0
-        * @todo remove at version 3
-        * @private
+        * Recursively deep copies `source` properties into `target` with the given `options`.
+        * IMPORTANT: `target` is not cloned and will be updated with `source` properties.
+        * @param {Object} target - The target object in which all sources are merged into.
+        * @param {Object|Array(Object)} source - Object(s) to merge into `target`.
+        * @param {Object} [options] - Merging options:
+        * @param {Function} [options.merger] - The merge method (key, target, source, options)
+        * @returns {Object} The `target` object.
         */
-       helpers.getValueOrDefault = helpers.valueOrDefault;
+       merge: function(target, source, options) {
+               var sources = helpers.isArray(source)? source : [source];
+               var ilen = sources.length;
+               var merge, i, keys, klen, k;
+
+               if (!helpers.isObject(target)) {
+                       return target;
+               }
+
+               options = options || {};
+               merge = options.merger || helpers._merger;
+
+               for (i=0; i<ilen; ++i) {
+                       source = sources[i];
+                       if (!helpers.isObject(source)) {
+                               continue;
+                       }
+
+                       keys = Object.keys(source);
+                       for (k=0, klen = keys.length; k<klen; ++k) {
+                               merge(keys[k], target, source, options);
+                       }
+               }
+
+               return target;
+       },
 
        /**
-        * Provided for backward compatibility, use Chart.helpers.valueAtIndexOrDefault instead.
-        * @function Chart.helpers.getValueAtIndexOrDefault
-        * @deprecated since version 2.7.0
-        * @todo remove at version 3
-        * @private
+        * Recursively deep copies `source` properties into `target` *only* if not defined in target.
+        * IMPORTANT: `target` is not cloned and will be updated with `source` properties.
+        * @param {Object} target - The target object in which all sources are merged into.
+        * @param {Object|Array(Object)} source - Object(s) to merge into `target`.
+        * @returns {Object} The `target` object.
         */
-       helpers.getValueAtIndexOrDefault = helpers.valueAtIndexOrDefault;
+       mergeIf: function(target, source) {
+               return helpers.merge(target, source, {merger: helpers._mergerIf});
+       }
+};
+
+module.exports = helpers;
+
+// DEPRECATIONS
+
+/**
+ * Provided for backward compatibility, use Chart.helpers.callback instead.
+ * @function Chart.helpers.callCallback
+ * @deprecated since version 2.6.0
+ * @todo remove at version 3
+ * @private
+ */
+helpers.callCallback = helpers.callback;
+
+/**
+ * Provided for backward compatibility, use Array.prototype.indexOf instead.
+ * Array.prototype.indexOf compatibility: Chrome, Opera, Safari, FF1.5+, IE9+
+ * @function Chart.helpers.indexOf
+ * @deprecated since version 2.7.0
+ * @todo remove at version 3
+ * @private
+ */
+helpers.indexOf = function(array, item, fromIndex) {
+       return Array.prototype.indexOf.call(array, item, fromIndex);
 };
+
+/**
+ * Provided for backward compatibility, use Chart.helpers.valueOrDefault instead.
+ * @function Chart.helpers.getValueOrDefault
+ * @deprecated since version 2.7.0
+ * @todo remove at version 3
+ * @private
+ */
+helpers.getValueOrDefault = helpers.valueOrDefault;
+
+/**
+ * Provided for backward compatibility, use Chart.helpers.valueAtIndexOrDefault instead.
+ * @function Chart.helpers.getValueAtIndexOrDefault
+ * @deprecated since version 2.7.0
+ * @todo remove at version 3
+ * @private
+ */
+helpers.getValueAtIndexOrDefault = helpers.valueAtIndexOrDefault;
index 23ca6fff0808c233595edb8c5f79be97d6070f5f..603e3f7f7ba2a97db4689291a09fba5f1665d302 100644 (file)
@@ -1,8 +1,11 @@
 'use strict';
 
+var helpers = require('./helpers.core');
+
 /**
  * Easing functions adapted from Robert Penner's easing equations.
- * http://www.robertpenner.com/easing/
+ * @namespace Chart.helpers.easingEffects
+ * @see http://www.robertpenner.com/easing/
  */
 var effects = {
        linear: function(t) {
@@ -231,22 +234,17 @@ var effects = {
        }
 };
 
-module.exports = function(Chart) {
-       /**
-        * @namespace Chart.helpers.easing.effects
-        */
-       Chart.helpers.easing = {
-               effects: effects
-       };
-
-       /**
-        * Provided for backward compatibility, use Chart.helpers.easing.effects instead.
-        * @function Chart.helpers.easingEffects
-        * @deprecated since version 2.7.0
-        * @todo remove at version 3
-        * @private
-        */
-       Chart.helpers.easingEffects = effects;
-
-       return Chart.helpers.easing;
+module.exports = {
+       effects: effects
 };
+
+// DEPRECATIONS
+
+/**
+ * Provided for backward compatibility, use Chart.helpers.easing.effects instead.
+ * @function Chart.helpers.easingEffects
+ * @deprecated since version 2.7.0
+ * @todo remove at version 3
+ * @private
+ */
+helpers.easingEffects = effects;
index f3e6e96b1c4995e91f1cb1596a0b520b01ba474a..f01dfaecd402d9a289e86968951ad3fe5b5d0e2f 100644 (file)
 var moment = require('moment');
 moment = typeof(moment) === 'function' ? moment : window.moment;
 
-module.exports = function(Chart) {
+var interval = {
+       millisecond: {
+               size: 1,
+               steps: [1, 2, 5, 10, 20, 50, 100, 250, 500]
+       },
+       second: {
+               size: 1000,
+               steps: [1, 2, 5, 10, 30]
+       },
+       minute: {
+               size: 60000,
+               steps: [1, 2, 5, 10, 30]
+       },
+       hour: {
+               size: 3600000,
+               steps: [1, 2, 3, 6, 12]
+       },
+       day: {
+               size: 86400000,
+               steps: [1, 2, 5]
+       },
+       week: {
+               size: 604800000,
+               maxStep: 4
+       },
+       month: {
+               size: 2.628e9,
+               maxStep: 3
+       },
+       quarter: {
+               size: 7.884e9,
+               maxStep: 4
+       },
+       year: {
+               size: 3.154e10,
+               maxStep: false
+       }
+};
 
-       var interval = {
-               millisecond: {
-                       size: 1,
-                       steps: [1, 2, 5, 10, 20, 50, 100, 250, 500]
-               },
-               second: {
-                       size: 1000,
-                       steps: [1, 2, 5, 10, 30]
-               },
-               minute: {
-                       size: 60000,
-                       steps: [1, 2, 5, 10, 30]
-               },
-               hour: {
-                       size: 3600000,
-                       steps: [1, 2, 3, 6, 12]
-               },
-               day: {
-                       size: 86400000,
-                       steps: [1, 2, 5]
-               },
-               week: {
-                       size: 604800000,
-                       maxStep: 4
-               },
-               month: {
-                       size: 2.628e9,
-                       maxStep: 3
-               },
-               quarter: {
-                       size: 7.884e9,
-                       maxStep: 4
-               },
-               year: {
-                       size: 3.154e10,
-                       maxStep: false
+/**
+ * Helper for generating axis labels.
+ * @param options {ITimeGeneratorOptions} the options for generation
+ * @param dataRange {IRange} the data range
+ * @param niceRange {IRange} the pretty range to display
+ * @return {Number[]} ticks
+ */
+function generateTicksNiceRange(options, dataRange, niceRange) {
+       var ticks = [];
+       if (options.maxTicks) {
+               var stepSize = options.stepSize;
+               var startTick = options.min !== undefined ? options.min : niceRange.min;
+               var majorUnit = options.majorUnit;
+               var majorUnitStart = majorUnit ? moment(startTick).add(1, majorUnit).startOf(majorUnit) : startTick;
+               var startRange = majorUnitStart.valueOf() - startTick;
+               var stepValue = interval[options.unit].size * stepSize;
+               var startFraction = startRange % stepValue;
+               var alignedTick = startTick;
+               if (startFraction && majorUnit && !options.timeOpts.round && !options.timeOpts.isoWeekday) {
+                       alignedTick += startFraction - stepValue;
+                       ticks.push(alignedTick);
+               } else {
+                       ticks.push(startTick);
                }
-       };
-
-       /**
-        * Helper for generating axis labels.
-        * @param options {ITimeGeneratorOptions} the options for generation
-        * @param dataRange {IRange} the data range
-        * @param niceRange {IRange} the pretty range to display
-        * @return {Number[]} ticks
-        */
-       function generateTicksNiceRange(options, dataRange, niceRange) {
-               var ticks = [];
-               if (options.maxTicks) {
-                       var stepSize = options.stepSize;
-                       var startTick = options.min !== undefined ? options.min : niceRange.min;
-                       var majorUnit = options.majorUnit;
-                       var majorUnitStart = majorUnit ? moment(startTick).add(1, majorUnit).startOf(majorUnit) : startTick;
-                       var startRange = majorUnitStart.valueOf() - startTick;
-                       var stepValue = interval[options.unit].size * stepSize;
-                       var startFraction = startRange % stepValue;
-                       var alignedTick = startTick;
-                       if (startFraction && majorUnit && !options.timeOpts.round && !options.timeOpts.isoWeekday) {
-                               alignedTick += startFraction - stepValue;
-                               ticks.push(alignedTick);
-                       } else {
-                               ticks.push(startTick);
-                       }
-                       var cur = moment(alignedTick);
-                       var realMax = options.max || niceRange.max;
-                       while (cur.add(stepSize, options.unit).valueOf() < realMax) {
-                               ticks.push(cur.valueOf());
-                       }
+               var cur = moment(alignedTick);
+               var realMax = options.max || niceRange.max;
+               while (cur.add(stepSize, options.unit).valueOf() < realMax) {
                        ticks.push(cur.valueOf());
                }
-               return ticks;
+               ticks.push(cur.valueOf());
        }
+       return ticks;
+}
 
-       Chart.helpers = Chart.helpers || {};
-
-       Chart.helpers.time = {
+/**
+ * @namespace Chart.helpers.time;
+ */
+module.exports = {
+       /**
+        * Helper function to parse time to a moment object
+        * @param axis {TimeAxis} the time axis
+        * @param label {Date|string|number|Moment} The thing to parse
+        * @return {Moment} parsed time
+        */
+       parseTime: function(axis, label) {
+               var timeOpts = axis.options.time;
+               if (typeof timeOpts.parser === 'string') {
+                       return moment(label, timeOpts.parser);
+               }
+               if (typeof timeOpts.parser === 'function') {
+                       return timeOpts.parser(label);
+               }
+               if (typeof label.getMonth === 'function' || typeof label === 'number') {
+                       // Date objects
+                       return moment(label);
+               }
+               if (label.isValid && label.isValid()) {
+                       // Moment support
+                       return label;
+               }
+               var format = timeOpts.format;
+               if (typeof format !== 'string' && format.call) {
+                       // Custom parsing (return an instance of moment)
+                       console.warn('options.time.format is deprecated and replaced by options.time.parser.');
+                       return format(label);
+               }
+               // Moment format parsing
+               return moment(label, format);
+       },
 
-               /**
-                * Helper function to parse time to a moment object
-                * @param axis {TimeAxis} the time axis
-                * @param label {Date|string|number|Moment} The thing to parse
-                * @return {Moment} parsed time
-                */
-               parseTime: function(axis, label) {
-                       var timeOpts = axis.options.time;
-                       if (typeof timeOpts.parser === 'string') {
-                               return moment(label, timeOpts.parser);
-                       }
-                       if (typeof timeOpts.parser === 'function') {
-                               return timeOpts.parser(label);
-                       }
-                       if (typeof label.getMonth === 'function' || typeof label === 'number') {
-                               // Date objects
-                               return moment(label);
-                       }
-                       if (label.isValid && label.isValid()) {
-                               // Moment support
-                               return label;
-                       }
-                       var format = timeOpts.format;
-                       if (typeof format !== 'string' && format.call) {
-                               // Custom parsing (return an instance of moment)
-                               console.warn('options.time.format is deprecated and replaced by options.time.parser.');
-                               return format(label);
+       /**
+        * Figure out which is the best unit for the scale
+        * @param minUnit {String} minimum unit to use
+        * @param min {Number} scale minimum
+        * @param max {Number} scale maximum
+        * @return {String} the unit to use
+        */
+       determineUnit: function(minUnit, min, max, maxTicks) {
+               var units = Object.keys(interval);
+               var unit;
+               var numUnits = units.length;
+
+               for (var i = units.indexOf(minUnit); i < numUnits; i++) {
+                       unit = units[i];
+                       var unitDetails = interval[unit];
+                       var steps = (unitDetails.steps && unitDetails.steps[unitDetails.steps.length - 1]) || unitDetails.maxStep;
+                       if (steps === undefined || Math.ceil((max - min) / (steps * unitDetails.size)) <= maxTicks) {
+                               break;
                        }
-                       // Moment format parsing
-                       return moment(label, format);
-               },
+               }
 
-               /**
-                * Figure out which is the best unit for the scale
-                * @param minUnit {String} minimum unit to use
-                * @param min {Number} scale minimum
-                * @param max {Number} scale maximum
-                * @return {String} the unit to use
-                */
-               determineUnit: function(minUnit, min, max, maxTicks) {
-                       var units = Object.keys(interval);
-                       var unit;
-                       var numUnits = units.length;
+               return unit;
+       },
 
-                       for (var i = units.indexOf(minUnit); i < numUnits; i++) {
-                               unit = units[i];
-                               var unitDetails = interval[unit];
-                               var steps = (unitDetails.steps && unitDetails.steps[unitDetails.steps.length - 1]) || unitDetails.maxStep;
-                               if (steps === undefined || Math.ceil((max - min) / (steps * unitDetails.size)) <= maxTicks) {
-                                       break;
-                               }
+       /**
+        * Determine major unit accordingly to passed unit
+        * @param unit {String} relative unit
+        * @return {String} major unit
+        */
+       determineMajorUnit: function(unit) {
+               var units = Object.keys(interval);
+               var unitIndex = units.indexOf(unit);
+               while (unitIndex < units.length) {
+                       var majorUnit = units[++unitIndex];
+                       // exclude 'week' and 'quarter' units
+                       if (majorUnit !== 'week' && majorUnit !== 'quarter') {
+                               return majorUnit;
                        }
+               }
 
-                       return unit;
-               },
+               return null;
+       },
 
-               /**
-                * Determine major unit accordingly to passed unit
-                * @param unit {String} relative unit
-                * @return {String} major unit
-                */
-               determineMajorUnit: function(unit) {
-                       var units = Object.keys(interval);
-                       var unitIndex = units.indexOf(unit);
-                       while (unitIndex < units.length) {
-                               var majorUnit = units[++unitIndex];
-                               // exclude 'week' and 'quarter' units
-                               if (majorUnit !== 'week' && majorUnit !== 'quarter') {
-                                       return majorUnit;
-                               }
+       /**
+        * Determines how we scale the unit
+        * @param min {Number} the scale minimum
+        * @param max {Number} the scale maximum
+        * @param unit {String} the unit determined by the {@see determineUnit} method
+        * @return {Number} the axis step size as a multiple of unit
+        */
+       determineStepSize: function(min, max, unit, maxTicks) {
+               // Using our unit, figure out what we need to scale as
+               var unitDefinition = interval[unit];
+               var unitSizeInMilliSeconds = unitDefinition.size;
+               var sizeInUnits = Math.ceil((max - min) / unitSizeInMilliSeconds);
+               var multiplier = 1;
+               var range = max - min;
+
+               if (unitDefinition.steps) {
+                       // Have an array of steps
+                       var numSteps = unitDefinition.steps.length;
+                       for (var i = 0; i < numSteps && sizeInUnits > maxTicks; i++) {
+                               multiplier = unitDefinition.steps[i];
+                               sizeInUnits = Math.ceil(range / (unitSizeInMilliSeconds * multiplier));
                        }
-
-                       return null;
-               },
-
-               /**
-                * Determines how we scale the unit
-                * @param min {Number} the scale minimum
-                * @param max {Number} the scale maximum
-                * @param unit {String} the unit determined by the {@see determineUnit} method
-                * @return {Number} the axis step size as a multiple of unit
-                */
-               determineStepSize: function(min, max, unit, maxTicks) {
-                       // Using our unit, figure out what we need to scale as
-                       var unitDefinition = interval[unit];
-                       var unitSizeInMilliSeconds = unitDefinition.size;
-                       var sizeInUnits = Math.ceil((max - min) / unitSizeInMilliSeconds);
-                       var multiplier = 1;
-                       var range = max - min;
-
-                       if (unitDefinition.steps) {
-                               // Have an array of steps
-                               var numSteps = unitDefinition.steps.length;
-                               for (var i = 0; i < numSteps && sizeInUnits > maxTicks; i++) {
-                                       multiplier = unitDefinition.steps[i];
-                                       sizeInUnits = Math.ceil(range / (unitSizeInMilliSeconds * multiplier));
-                               }
-                       } else {
-                               while (sizeInUnits > maxTicks && maxTicks > 0) {
-                                       ++multiplier;
-                                       sizeInUnits = Math.ceil(range / (unitSizeInMilliSeconds * multiplier));
-                               }
+               } else {
+                       while (sizeInUnits > maxTicks && maxTicks > 0) {
+                               ++multiplier;
+                               sizeInUnits = Math.ceil(range / (unitSizeInMilliSeconds * multiplier));
                        }
+               }
 
-                       return multiplier;
-               },
+               return multiplier;
+       },
 
-               /**
-                * @function generateTicks
-                * @param options {ITimeGeneratorOptions} the options for generation
-                * @param dataRange {IRange} the data range
-                * @return {Number[]} ticks
-                */
-               generateTicks: function(options, dataRange) {
-                       var niceMin;
-                       var niceMax;
-                       var isoWeekday = options.timeOpts.isoWeekday;
-                       if (options.unit === 'week' && isoWeekday !== false) {
-                               niceMin = moment(dataRange.min).startOf('isoWeek').isoWeekday(isoWeekday).valueOf();
-                               niceMax = moment(dataRange.max).startOf('isoWeek').isoWeekday(isoWeekday);
-                               if (dataRange.max - niceMax > 0) {
-                                       niceMax.add(1, 'week');
-                               }
-                               niceMax = niceMax.valueOf();
-                       } else {
-                               niceMin = moment(dataRange.min).startOf(options.unit).valueOf();
-                               niceMax = moment(dataRange.max).startOf(options.unit);
-                               if (dataRange.max - niceMax > 0) {
-                                       niceMax.add(1, options.unit);
-                               }
-                               niceMax = niceMax.valueOf();
+       /**
+        * @function generateTicks
+        * @param options {ITimeGeneratorOptions} the options for generation
+        * @param dataRange {IRange} the data range
+        * @return {Number[]} ticks
+        */
+       generateTicks: function(options, dataRange) {
+               var niceMin;
+               var niceMax;
+               var isoWeekday = options.timeOpts.isoWeekday;
+               if (options.unit === 'week' && isoWeekday !== false) {
+                       niceMin = moment(dataRange.min).startOf('isoWeek').isoWeekday(isoWeekday).valueOf();
+                       niceMax = moment(dataRange.max).startOf('isoWeek').isoWeekday(isoWeekday);
+                       if (dataRange.max - niceMax > 0) {
+                               niceMax.add(1, 'week');
+                       }
+                       niceMax = niceMax.valueOf();
+               } else {
+                       niceMin = moment(dataRange.min).startOf(options.unit).valueOf();
+                       niceMax = moment(dataRange.max).startOf(options.unit);
+                       if (dataRange.max - niceMax > 0) {
+                               niceMax.add(1, options.unit);
                        }
-                       return generateTicksNiceRange(options, dataRange, {
-                               min: niceMin,
-                               max: niceMax
-                       });
+                       niceMax = niceMax.valueOf();
                }
-
-       };
-
+               return generateTicksNiceRange(options, dataRange, {
+                       min: niceMin,
+                       max: niceMax
+               });
+       }
 };
diff --git a/src/helpers/index.js b/src/helpers/index.js
new file mode 100644 (file)
index 0000000..a21c99a
--- /dev/null
@@ -0,0 +1,6 @@
+'use strict';
+
+module.exports = require('./helpers.core');
+module.exports.easing = require('./helpers.easing');
+module.exports.canvas = require('./helpers.canvas');
+module.exports.time = require('./helpers.time');
index a5345d1e76d337540d97bffdebc3b36d727f7326..f8e328954bce471eab7f8e102640674d109bb0f4 100644 (file)
@@ -1,8 +1,9 @@
 'use strict';
 
+var helpers = require('../helpers/index');
+
 // Chart.Platform implementation for targeting a web browser
-module.exports = function(Chart) {
-       var helpers = Chart.helpers;
+module.exports = function() {
 
        // DOM event types -> Chart.js event types.
        // Note: only events with different types are mapped.
index 0f27e5868a60f95c32a2ce2f4502efa1a3ced624..3464d5ff59c42949aa8f5075d0a4d1700a00e089 100644 (file)
@@ -1,8 +1,10 @@
 'use strict';
 
+var helpers = require('../helpers/index');
+
 // By default, select the browser (DOM) platform.
 // @TODO Make possible to select another platform at build time.
-var implementation = require('./platform.dom.js');
+var implementation = require('./platform.dom');
 
 module.exports = function(Chart) {
        /**
@@ -65,5 +67,5 @@ module.exports = function(Chart) {
         * @prop {Number} y - The mouse y position, relative to the canvas (null for incompatible events)
         */
 
-       Chart.helpers.extend(Chart.platform, implementation(Chart));
+       helpers.extend(Chart.platform, implementation(Chart));
 };
index 2a91d38e81483c3dfb723c199a9d3a9106c19fe9..4f49064f084b459360e8e53a0ea3141ecfd53126 100644 (file)
@@ -1,5 +1,7 @@
 'use strict';
 
+var helpers = require('../helpers/index');
+
 module.exports = function(Chart) {
        /**
         * Plugin based on discussion from the following Chart.js issues:
@@ -11,7 +13,6 @@ module.exports = function(Chart) {
        };
 
        var defaults = Chart.defaults;
-       var helpers = Chart.helpers;
        var mappers = {
                dataset: function(source) {
                        var index = source.fill;
index 0e3b1e66530dc16696569208801847c4ac2087c2..3eb0f57dfcba3e21b111629fe43cd0e6ae7ed038 100644 (file)
@@ -1,8 +1,9 @@
 'use strict';
 
+var helpers = require('../helpers/index');
+
 module.exports = function(Chart) {
 
-       var helpers = Chart.helpers;
        var layout = Chart.layoutService;
        var noop = helpers.noop;
 
@@ -360,7 +361,7 @@ module.exports = function(Chart) {
                                                var centerY = y + offSet;
 
                                                // Draw pointStyle as legend symbol
-                                               Chart.helpers.canvas.drawPoint(ctx, legendItem.pointStyle, radius, centerX, centerY);
+                                               helpers.canvas.drawPoint(ctx, legendItem.pointStyle, radius, centerX, centerY);
                                        } else {
                                                // Draw box as legend symbol
                                                if (!isLineWidthZero) {
index c8f815d763ecfdf92937f625c6e180fd31459c02..42ad1b0d3dbe1284b4f493d19c554d90af417031 100644 (file)
@@ -1,8 +1,9 @@
 'use strict';
 
+var helpers = require('../helpers/index');
+
 module.exports = function(Chart) {
 
-       var helpers = Chart.helpers;
        var layout = Chart.layoutService;
        var noop = helpers.noop;
 
index c9a6af41ed3b4b3d790583380b91e05b94335dc4..34223c283838d02a45e326b2dc5f2bfdba1b9534 100644 (file)
@@ -1,8 +1,8 @@
 'use strict';
 
-module.exports = function(Chart) {
+var helpers = require('../helpers/index');
 
-       var helpers = Chart.helpers;
+module.exports = function(Chart) {
 
        var defaultConfig = {
                position: 'left',
index 28cde52d6559db7d82fab1511e594dca746e9d8c..33bc22517bf91822c53f1a38d4bb14006422d53b 100644 (file)
@@ -1,9 +1,10 @@
 'use strict';
 
+var helpers = require('../helpers/index');
+
 module.exports = function(Chart) {
 
-       var helpers = Chart.helpers,
-               noop = helpers.noop;
+       var noop = helpers.noop;
 
        Chart.LinearScaleBase = Chart.Scale.extend({
                handleTickRangeOptions: function() {
index a343aaf73b0f2f7c04eebc0d40feaabde79db64d..a5c5fa918a28ebc05bdcf7d60b9080c14396b3c2 100644 (file)
@@ -1,8 +1,8 @@
 'use strict';
 
-module.exports = function(Chart) {
+var helpers = require('../helpers/index');
 
-       var helpers = Chart.helpers;
+module.exports = function(Chart) {
 
        var defaultConfig = {
                position: 'left',
index 90cb52cd09024b456d23cb1f1d606c5da976254c..93036c691e53b268f7a9e29cb63e3ef2911ae58f 100644 (file)
@@ -1,8 +1,9 @@
 'use strict';
 
+var helpers = require('../helpers/index');
+
 module.exports = function(Chart) {
 
-       var helpers = Chart.helpers;
        var globalDefaults = Chart.defaults.global;
 
        var defaultConfig = {
index 14621ba7a8b0ba76f0f10f4e8e6865d282fecc43..fab5ccd64160c64449929f54484b8264c64a640e 100644 (file)
@@ -4,9 +4,10 @@
 var moment = require('moment');
 moment = typeof(moment) === 'function' ? moment : window.moment;
 
+var helpers = require('../helpers/index');
+
 module.exports = function(Chart) {
 
-       var helpers = Chart.helpers;
        var timeHelpers = helpers.time;
 
        var defaultConfig = {