mirror of
https://github.com/chartjs/Chart.js.git
synced 2025-12-08 20:36:08 +00:00
Make Chart.helpers importable (#4479)
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`).
This commit is contained in:
parent
b03ab1ca45
commit
717e8d950a
18
src/chart.js
18
src/chart.js
@ -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;
|
||||
|
||||
@ -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: {
|
||||
|
||||
@ -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: {
|
||||
|
||||
@ -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: {
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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 = {
|
||||
|
||||
|
||||
@ -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: {
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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;
|
||||
|
||||
|
||||
@ -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'];
|
||||
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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 = {};
|
||||
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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 = {
|
||||
|
||||
@ -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);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
@ -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 = {
|
||||
/**
|
||||
* 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);
|
||||
},
|
||||
|
||||
/**
|
||||
* @namespace Chart.helpers.canvas
|
||||
* 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?
|
||||
*/
|
||||
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);
|
||||
},
|
||||
roundedRect: function(ctx, x, y, width, height, radius) {
|
||||
if (radius) {
|
||||
var rx = Math.min(radius, width/2);
|
||||
var ry = Math.min(radius, height/2);
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
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();
|
||||
};
|
||||
|
||||
@ -1,295 +1,297 @@
|
||||
'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() {},
|
||||
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 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 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 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 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` 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);
|
||||
},
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
},
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
/**
|
||||
* 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 if (helpers.isObject(loopable)) {
|
||||
keys = Object.keys(loopable);
|
||||
len = keys.length;
|
||||
} else {
|
||||
for (i = 0; i < len; i++) {
|
||||
fn.call(thisArg, loopable[keys[i]], keys[i]);
|
||||
fn.call(thisArg, loopable[i], 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;
|
||||
} 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]);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
for (i = 0, ilen=a0.length; i < ilen; ++i) {
|
||||
v0 = a0[i];
|
||||
v1 = a1[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 (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}
|
||||
if (!a0 || !a1 || a0.length !== a1.length) {
|
||||
return false;
|
||||
}
|
||||
|
||||
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;
|
||||
},
|
||||
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 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;
|
||||
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;
|
||||
}
|
||||
|
||||
return source;
|
||||
},
|
||||
|
||||
/**
|
||||
* 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];
|
||||
|
||||
if (helpers.isObject(tval) && helpers.isObject(sval)) {
|
||||
helpers.merge(tval, sval, options);
|
||||
} 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);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
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;
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -3,223 +3,218 @@
|
||||
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 || {};
|
||||
/**
|
||||
* @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);
|
||||
},
|
||||
|
||||
Chart.helpers.time = {
|
||||
/**
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* 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);
|
||||
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;
|
||||
}
|
||||
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);
|
||||
},
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
}
|
||||
|
||||
return unit;
|
||||
},
|
||||
|
||||
/**
|
||||
* 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 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));
|
||||
}
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
return generateTicksNiceRange(options, dataRange, {
|
||||
min: niceMin,
|
||||
max: niceMax
|
||||
});
|
||||
}
|
||||
|
||||
};
|
||||
return unit;
|
||||
},
|
||||
|
||||
/**
|
||||
* 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 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));
|
||||
}
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
return generateTicksNiceRange(options, dataRange, {
|
||||
min: niceMin,
|
||||
max: niceMax
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
6
src/helpers/index.js
Normal file
6
src/helpers/index.js
Normal file
@ -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');
|
||||
@ -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.
|
||||
|
||||
@ -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));
|
||||
};
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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;
|
||||
|
||||
|
||||
@ -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',
|
||||
|
||||
@ -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() {
|
||||
|
||||
@ -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',
|
||||
|
||||
@ -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 = {
|
||||
|
||||
@ -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 = {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user