'./src/scales/**',
'./src/elements/**',
'./src/charts/**',
- './src/**',
'./node_modules/color/dist/color.min.js'
],
isCustom = !!(util.env.types),
};
window.onload = function() {
var ctx = document.getElementById("canvas").getContext("2d");
- window.myBar = new Chart(ctx).Bar({
+ window.myBar = new Chart(ctx, {
data: barChartData,
options: {
responsive: true,
type: "linear",
}],
},
-
};
Chart = root.Chart,
helpers = Chart.helpers;
- Chart.RectangularCanvasController = function(chart, elementController) {
- this.chartInstance = chart;
- this.elementController = elementController;
- };
- Chart.RectangularCanvasController.prototype.initialize = function() {
- this.bindEvents();
- this.buildScales();
-
- // Need to fit scales before we reset elements.
- Chart.scaleService.fitScalesForChart(this.chartInstance, this.chartInstance.chart.width, this.chartInstance.chart.height);
- this.elementController.resetElements();
-
- this.initToolTip();
-
- this.chartInstance.update();
- };
-
- Chart.RectangularCanvasController.prototype.bindEvents = function() {
- helpers.bindEvents(this.chartInstance, this.chartInstance.options.events, function(evt) {
- // this will be the chart instance
- this.canvasController.eventHandler(evt);
- });
- };
-
- Chart.RectangularCanvasController.prototype.eventHandler = function(e) {
- this.lastActive = this.lastActive || [];
-
- // Find Active Elements
- if (e.type == 'mouseout') {
- this.active = [];
- } else {
- this.active = function() {
- switch (this.chartInstance.options.hover.mode) {
- case 'single':
- return this.elementController.getElementAtEvent(e);
- case 'label':
- return this.elementController.getElementsAtEvent(e);
- case 'dataset':
- return this.elementController.getDatasetAtEvent(e);
- default:
- return e;
- }
- }.call(this);
- }
-
- // On Hover hook
- if (this.chartInstance.options.hover.onHover) {
- this.chartInstance.options.hover.onHover.call(this.chartInstance, this.active);
- }
-
- if (e.type == 'mouseup' || e.type == 'click') {
- if (this.chartInstance.options.onClick) {
- this.chartInstance.options.onClick.call(this, e, this.active);
- }
- }
-
- var dataset;
- var index;
- // Remove styling for last active (even if it may still be active)
- if (this.lastActive.length) {
- switch (this.chartInstance.options.hover.mode) {
- case 'single':
- this.elementController.resetElementAppearance(this.lastActive[0], this.lastActive[0]._datasetIndex, this.lastActive[0]._index);
- break;
- case 'label':
- for (var i = 0; i < this.lastActive.length; i++) {
- this.elementController.resetElementAppearance(this.lastActive[i], this.lastActive[i]._datasetIndex, this.lastActive[i]._index);
- }
- break;
- case 'dataset':
- break;
- default:
- // Don't change anything
- }
- }
-
- // Built in hover styling
- if (this.active.length && this.chartInstance.options.hover.mode) {
- switch (this.chartInstance.options.hover.mode) {
- case 'single':
- this.elementController.setElementHoverStyle(this.active[0]);
- break;
- case 'label':
- for (var i = 0; i < this.active.length; i++) {
- this.elementController.setElementHoverStyle(this.active[i]);
- }
- break;
- case 'dataset':
- break;
- default:
- // Don't change anything
- }
- }
-
-
- // Built in Tooltips
- if (this.chartInstance.options.tooltips.enabled) {
-
- // The usual updates
- this.chartInstance.tooltip.initialize();
-
- // Active
- if (this.active.length) {
- this.chartInstance.tooltip._model.opacity = 1;
-
- helpers.extend(this.chartInstance.tooltip, {
- _active: this.active,
- });
-
- this.chartInstance.tooltip.update();
- } else {
- // Inactive
- this.chartInstance.tooltip._model.opacity = 0;
- }
- }
-
- // Hover animations
- this.chartInstance.tooltip.pivot();
-
- if (!this.chartInstance.animating) {
- var changed;
-
- helpers.each(this.active, function(element, index) {
- if (element !== this.lastActive[index]) {
- changed = true;
- }
- }, this);
-
- // If entering, leaving, or changing elements, animate the change via pivot
- if ((!this.lastActive.length && this.active.length) ||
- (this.lastActive.length && !this.active.length) ||
- (this.lastActive.length && this.active.length && changed)) {
-
- this.chartInstance.stop();
- this.chartInstance.render(this.chartInstance.options.hover.animationDuration);
- }
- }
-
- // Remember Last Active
- this.lastActive = this.active;
- return this;
- };
-
- Chart.RectangularCanvasController.prototype.initToolTip = function() {
- this.chartInstance.tooltip = new Chart.Tooltip({
- _chart: this.chartInstance.chart,
- _data: this.chartInstance.data,
- _options: this.chartInstance.options,
- }, this);
- };
-
- Chart.RectangularCanvasController.prototype.buildScales = function() {
- // Map of scale ID to scale object so we can lookup later
- this.chartInstance.scales = {};
-
- // Build the x axes
- helpers.each(this.chartInstance.options.scales.xAxes, function(xAxisOptions) {
- var ScaleClass = Chart.scaleService.getScaleConstructor(xAxisOptions.type);
- var scale = new ScaleClass({
- ctx: this.chartInstance.chart.ctx,
- options: xAxisOptions,
- data: this.chartInstance.data,
- id: xAxisOptions.id,
- });
-
- this.chartInstance.scales[scale.id] = scale;
- }, this);
-
- // Build the y axes
- helpers.each(this.chartInstance.options.scales.yAxes, function(yAxisOptions) {
- var ScaleClass = Chart.scaleService.getScaleConstructor(yAxisOptions.type);
- var scale = new ScaleClass({
- ctx: this.chartInstance.chart.ctx,
- options: yAxisOptions,
- data: this.chartInstance.data,
- id: yAxisOptions.id,
- });
-
- this.chartInstance.scales[scale.id] = scale;
- }, this);
- };
-
- Chart.RectangularCanvasController.prototype.update = function() {
- Chart.scaleService.fitScalesForChart(this.chartInstance, this.chartInstance.chart.width, this.chartInstance.chart.height);
- this.elementController.updateElements();
- };
}).call(this);
+++ /dev/null
-(function() {
-
- "use strict";
-
- //Declare root variable - window in the browser, global on the server
- var root = this,
- previous = root.Chart,
- helpers = Chart.helpers;
-
-
- //Create a dictionary of chart types, to allow for extension of existing types
- Chart.types = {};
-
- //Store a reference to each instance - allowing us to globally resize chart instances on window resize.
- //Destroy method on the chart will remove the instance of the chart from this reference.
- Chart.instances = {};
-
- Chart.Type = function(config, instance) {
- this.data = config.data;
- this.options = config.options;
- this.chart = instance;
- this.id = helpers.uid();
- //Add the chart instance to the global namespace
- Chart.instances[this.id] = this;
-
- // Initialize is always called when a chart type is created
- // By default it is a no op, but it should be extended
- if (this.options.responsive) {
- this.resize();
- }
- this.initialize.call(this);
- };
-
- //Core methods that'll be a part of every chart type
- helpers.extend(Chart.Type.prototype, {
- initialize: function() {
- return this;
- },
- clear: function() {
- helpers.clear(this.chart);
- return this;
- },
- stop: function() {
- // Stops any current animation loop occuring
- Chart.animationService.cancelAnimation(this);
- return this;
- },
- resize: function() {
- this.stop();
- var canvas = this.chart.canvas,
- newWidth = helpers.getMaximumWidth(this.chart.canvas),
- newHeight = this.options.maintainAspectRatio ? newWidth / this.chart.aspectRatio : getMaximumHeight(this.chart.canvas);
-
- canvas.width = this.chart.width = newWidth;
- canvas.height = this.chart.height = newHeight;
-
- helpers.retinaScale(this.chart);
-
- return this;
- },
- update: function(animationDuration) {
- this.canvasController.update();
- this.render(animationDuration);
- },
- render: function(duration) {
-
- if (this.options.animation.duration !== 0 || duration) {
- var animation = new Chart.Animation();
- animation.numSteps = (duration || this.options.animation.duration) / 16.66; //60 fps
- animation.easing = this.options.animation.easing;
-
- // render function
- animation.render = function(chartInstance, animationObject) {
- var easingFunction = helpers.easingEffects[animationObject.easing];
- var stepDecimal = animationObject.currentStep / animationObject.numSteps;
- var easeDecimal = easingFunction(stepDecimal);
-
- chartInstance.draw(easeDecimal, stepDecimal, animationObject.currentStep);
- };
-
- // user events
- animation.onAnimationProgress = this.options.onAnimationProgress;
- animation.onAnimationComplete = this.options.onAnimationComplete;
-
- Chart.animationService.addAnimation(this, animation, duration);
- } else {
- this.draw();
- this.options.onAnimationComplete.call(this);
- }
- return this;
- },
- eachElement: function(callback) {
- helpers.each(this.data.datasets, function(dataset, datasetIndex) {
- helpers.each(dataset.metaData, callback, this, dataset.metaData, datasetIndex);
- }, this);
- },
- eachValue: function(callback) {
- helpers.each(this.data.datasets, function(dataset, datasetIndex) {
- helpers.each(dataset.data, callback, this, datasetIndex);
- }, this);
- },
- eachDataset: function(callback) {
- helpers.each(this.data.datasets, callback, this);
- },
- getElementsAtEvent: function(e) {
- var elementsArray = [],
- eventPosition = helpers.getRelativePosition(e),
- datasetIterator = function(dataset) {
- elementsArray.push(dataset.metaData[elementIndex]);
- },
- elementIndex;
-
- for (var datasetIndex = 0; datasetIndex < this.data.datasets.length; datasetIndex++) {
- for (elementIndex = 0; elementIndex < this.data.datasets[datasetIndex].metaData.length; elementIndex++) {
- if (this.data.datasets[datasetIndex].metaData[elementIndex].inGroupRange(eventPosition.x, eventPosition.y)) {
- helpers.each(this.data.datasets, datasetIterator);
- }
- }
- }
-
- return elementsArray.length ? elementsArray : [];
- },
- // Get the single element that was clicked on
- // @return : An object containing the dataset index and element index of the matching element. Also contains the rectangle that was drawn
- getElementAtEvent: function(e) {
- var element = [];
- var eventPosition = helpers.getRelativePosition(e);
-
- for (var datasetIndex = 0; datasetIndex < this.data.datasets.length; ++datasetIndex) {
- for (var elementIndex = 0; elementIndex < this.data.datasets[datasetIndex].metaData.length; ++elementIndex) {
- if (this.data.datasets[datasetIndex].metaData[elementIndex].inRange(eventPosition.x, eventPosition.y)) {
- element.push(this.data.datasets[datasetIndex].metaData[elementIndex]);
- return element;
- }
- }
- }
-
- return [];
- },
- generateLegend: function() {
- return template(this.options.legendTemplate, this);
- },
- destroy: function() {
- this.clear();
- unbindEvents(this, this.events);
- var canvas = this.chart.canvas;
-
- // Reset canvas height/width attributes starts a fresh with the canvas context
- canvas.width = this.chart.width;
- canvas.height = this.chart.height;
-
- // < IE9 doesn't support removeProperty
- if (canvas.style.removeProperty) {
- canvas.style.removeProperty('width');
- canvas.style.removeProperty('height');
- } else {
- canvas.style.removeAttribute('width');
- canvas.style.removeAttribute('height');
- }
-
- delete Chart.instances[this.id];
- },
- toBase64Image: function() {
- return this.chart.canvas.toDataURL.apply(this.chart.canvas, arguments);
- }
- });
-
- Chart.Type.extend = function(extensions) {
-
- var parent = this;
-
- var ChartType = function() {
- return parent.apply(this, arguments);
- };
-
- //Copy the prototype object of the this class
- ChartType.prototype = helpers.clone(parent.prototype);
-
- //Now overwrite some of the properties in the base class with the new extensions
- helpers.extend(ChartType.prototype, extensions);
- ChartType.extend = Chart.Type.extend;
-
- if (extensions.name || parent.prototype.name) {
-
- var chartName = extensions.name || parent.prototype.name;
- //Assign any potential default values of the new chart type
-
- //If none are defined, we'll use a clone of the chart type this is being extended from.
- //I.e. if we extend a line chart, we'll use the defaults from the line chart if our new chart
- //doesn't define some defaults of their own.
-
- var baseDefaults = (Chart.defaults[parent.prototype.name]) ? helpers.clone(Chart.defaults[parent.prototype.name]) : {};
-
- Chart.defaults[chartName] = helpers.configMerge(baseDefaults, extensions.defaults);
-
- Chart.types[chartName] = ChartType;
-
- //Register this new chart type in the Chart prototype
- Chart.prototype[chartName] = function(config) {
- config.options = helpers.configMerge(Chart.defaults.global, Chart.defaults[chartName], config.options || {});
- return new ChartType(config, this);
- };
- } else {
- warn("Name not provided for this chart, so it hasn't been registered");
- }
- return parent;
- };
-
-}).call(this);
--- /dev/null
+(function() {
+
+ "use strict";
+
+ //Declare root variable - window in the browser, global on the server
+ var root = this,
+ previous = root.Chart,
+ helpers = Chart.helpers;
+
+
+ //Create a dictionary of chart types, to allow for extension of existing types
+ Chart.types = {};
+
+ //Store a reference to each instance - allowing us to globally resize chart instances on window resize.
+ //Destroy method on the chart will remove the instance of the chart from this reference.
+ Chart.instances = {};
+
+ Chart.Controller = function(instance) {
+
+ this.chart = instance;
+ var config = instance.config;
+ this.data = config.data;
+ this.options = config.options = helpers.configMerge(Chart.defaults.global, Chart.defaults[config.type], config.options || {});
+ this.id = helpers.uid();
+
+ console.log(this.options);
+
+ //Add the chart instance to the global namespace
+ Chart.instances[this.id] = this;
+
+ // Initialize is always called when a chart type is created
+ // By default it is a no op, but it should be extended
+
+ if (this.options.responsive) {
+ this.resize();
+ }
+
+ this.initialize.call(this);
+
+ return this;
+ };
+
+ helpers.extend(Chart.Controller.prototype, {
+
+ initialize: function initialize() {
+ return this;
+ },
+
+ clear: function clear() {
+ helpers.clear(this.chart);
+ return this;
+ },
+
+ stop: function stop() {
+ // Stops any current animation loop occuring
+ Chart.animationService.cancelAnimation(this);
+ return this;
+ },
+
+ resize: function resize() {
+ this.stop();
+ var canvas = this.chart.canvas,
+ newWidth = helpers.getMaximumWidth(this.chart.canvas),
+ newHeight = this.options.maintainAspectRatio ? newWidth / this.chart.aspectRatio : getMaximumHeight(this.chart.canvas);
+
+ canvas.width = this.chart.width = newWidth;
+ canvas.height = this.chart.height = newHeight;
+
+ helpers.retinaScale(this.chart);
+
+ return this;
+ },
+
+ update: function update(animationDuration) {
+ this.canvasController.update();
+ this.render(animationDuration);
+ },
+
+ render: function render(duration) {
+
+ if (this.options.animation.duration !== 0 || duration) {
+ var animation = new Chart.Animation();
+ animation.numSteps = (duration || this.options.animation.duration) / 16.66; //60 fps
+ animation.easing = this.options.animation.easing;
+
+ // render function
+ animation.render = function(chartInstance, animationObject) {
+ var easingFunction = helpers.easingEffects[animationObject.easing];
+ var stepDecimal = animationObject.currentStep / animationObject.numSteps;
+ var easeDecimal = easingFunction(stepDecimal);
+
+ chartInstance.draw(easeDecimal, stepDecimal, animationObject.currentStep);
+ };
+
+ // user events
+ animation.onAnimationProgress = this.options.onAnimationProgress;
+ animation.onAnimationComplete = this.options.onAnimationComplete;
+
+ Chart.animationService.addAnimation(this, animation, duration);
+ } else {
+ this.draw();
+ this.options.onAnimationComplete.call(this);
+ }
+ return this;
+ },
+
+ eachElement: function eachElement(callback) {
+ helpers.each(this.data.datasets, function(dataset, datasetIndex) {
+ helpers.each(dataset.metaData, callback, this, dataset.metaData, datasetIndex);
+ }, this);
+ },
+
+ eachValue: function eachValue(callback) {
+ helpers.each(this.data.datasets, function(dataset, datasetIndex) {
+ helpers.each(dataset.data, callback, this, datasetIndex);
+ }, this);
+ },
+
+ eachDataset: function eachDataset(callback) {
+ helpers.each(this.data.datasets, callback, this);
+ },
+
+ getElementsAtEvent: function getElementsAtEvent(e) {
+ var elementsArray = [],
+ eventPosition = helpers.getRelativePosition(e),
+ datasetIterator = function(dataset) {
+ elementsArray.push(dataset.metaData[elementIndex]);
+ },
+ elementIndex;
+
+ for (var datasetIndex = 0; datasetIndex < this.data.datasets.length; datasetIndex++) {
+ for (elementIndex = 0; elementIndex < this.data.datasets[datasetIndex].metaData.length; elementIndex++) {
+ if (this.data.datasets[datasetIndex].metaData[elementIndex].inGroupRange(eventPosition.x, eventPosition.y)) {
+ helpers.each(this.data.datasets, datasetIterator);
+ }
+ }
+ }
+
+ return elementsArray.length ? elementsArray : [];
+ },
+
+ // Get the single element that was clicked on
+ // @return : An object containing the dataset index and element index of the matching element. Also contains the rectangle that was draw
+ getElementAtEvent: function getElementAtEvent(e) {
+ var element = [];
+ var eventPosition = helpers.getRelativePosition(e);
+
+ for (var datasetIndex = 0; datasetIndex < this.data.datasets.length; ++datasetIndex) {
+ for (var elementIndex = 0; elementIndex < this.data.datasets[datasetIndex].metaData.length; ++elementIndex) {
+ if (this.data.datasets[datasetIndex].metaData[elementIndex].inRange(eventPosition.x, eventPosition.y)) {
+ element.push(this.data.datasets[datasetIndex].metaData[elementIndex]);
+ return element;
+ }
+ }
+ }
+
+ return [];
+ },
+
+ generateLegend: function generateLegend() {
+ return template(this.options.legendTemplate, this);
+ },
+
+ destroy: function destroy() {
+ this.clear();
+ unbindEvents(this, this.events);
+ var canvas = this.chart.canvas;
+
+ // Reset canvas height/width attributes starts a fresh with the canvas context
+ canvas.width = this.chart.width;
+ canvas.height = this.chart.height;
+
+ // < IE9 doesn't support removeProperty
+ if (canvas.style.removeProperty) {
+ canvas.style.removeProperty('width');
+ canvas.style.removeProperty('height');
+ } else {
+ canvas.style.removeAttribute('width');
+ canvas.style.removeAttribute('height');
+ }
+
+ delete Chart.instances[this.id];
+ },
+
+ toBase64Image: function toBase64Image() {
+ return this.chart.canvas.toDataURL.apply(this.chart.canvas, arguments);
+ },
+ initialize: function initialize() {
+ this.bindEvents();
+ this.buildScales();
+
+ // Need to fit scales before we reset elements.
+ Chart.scaleService.fitScalesForChart(this, this.chart.width, this.chart.height);
+ this.elementController.resetElements();
+
+ this.initToolTip();
+
+ this.update();
+ },
+
+ bindEvents: function bindEvents() {
+ helpers.bindEvents(this, this.options.events, function(evt) {
+ // this will be the chart instance
+ this.canvasController.eventHandler(evt);
+ });
+ },
+
+ eventHandler: function eventHandler(e) {
+ this.lastActive = this.lastActive || [];
+
+ // Find Active Elements
+ if (e.type == 'mouseout') {
+ this.active = [];
+ } else {
+ this.active = function() {
+ switch (this.options.hover.mode) {
+ case 'single':
+ return this.elementController.getElementAtEvent(e);
+ case 'label':
+ return this.elementController.getElementsAtEvent(e);
+ case 'dataset':
+ return this.elementController.getDatasetAtEvent(e);
+ default:
+ return e;
+ }
+ }.call(this);
+ }
+
+ // On Hover hook
+ if (this.options.hover.onHover) {
+ this.options.hover.onHover.call(this, this.active);
+ }
+
+ if (e.type == 'mouseup' || e.type == 'click') {
+ if (this.options.onClick) {
+ this.options.onClick.call(this, e, this.active);
+ }
+ }
+
+ var dataset;
+ var index;
+ // Remove styling for last active (even if it may still be active)
+ if (this.lastActive.length) {
+ switch (this.options.hover.mode) {
+ case 'single':
+ this.elementController.resetElementAppearance(this.lastActive[0], this.lastActive[0]._datasetIndex, this.lastActive[0]._index);
+ break;
+ case 'label':
+ for (var i = 0; i < this.lastActive.length; i++) {
+ this.elementController.resetElementAppearance(this.lastActive[i], this.lastActive[i]._datasetIndex, this.lastActive[i]._index);
+ }
+ break;
+ case 'dataset':
+ break;
+ default:
+ // Don't change anything
+ }
+ }
+
+ // Built in hover styling
+ if (this.active.length && this.options.hover.mode) {
+ switch (this.options.hover.mode) {
+ case 'single':
+ this.elementController.setElementHoverStyle(this.active[0]);
+ break;
+ case 'label':
+ for (var i = 0; i < this.active.length; i++) {
+ this.elementController.setElementHoverStyle(this.active[i]);
+ }
+ break;
+ case 'dataset':
+ break;
+ default:
+ // Don't change anything
+ }
+ }
+
+
+ // Built in Tooltips
+ if (this.options.tooltips.enabled) {
+
+ // The usual updates
+ this.tooltip.initialize();
+
+ // Active
+ if (this.active.length) {
+ this.tooltip._model.opacity = 1;
+
+ helpers.extend(this.tooltip, {
+ _active: this.active,
+ });
+
+ this.tooltip.update();
+ } else {
+ // Inactive
+ this.tooltip._model.opacity = 0;
+ }
+ }
+
+ // Hover animations
+ this.tooltip.pivot();
+
+ if (!this.animating) {
+ var changed;
+
+ helpers.each(this.active, function(element, index) {
+ if (element !== this.lastActive[index]) {
+ changed = true;
+ }
+ }, this);
+
+ // If entering, leaving, or changing elements, animate the change via pivot
+ if ((!this.lastActive.length && this.active.length) ||
+ (this.lastActive.length && !this.active.length) ||
+ (this.lastActive.length && this.active.length && changed)) {
+
+ this.stop();
+ this.render(this.options.hover.animationDuration);
+ }
+ }
+
+ // Remember Last Active
+ this.lastActive = this.active;
+ return this;
+ },
+
+ initToolTip: function initToolTip() {
+ this.tooltip = new Chart.Tooltip({
+ _chart: this.chart,
+ _data: this.data,
+ _options: this.options,
+ }, this);
+ },
+
+ buildScales: function buildScales() {
+ // Map of scale ID to scale object so we can lookup later
+ this.scales = {};
+
+ // Build the x axes
+ helpers.each(this.options.scales.xAxes, function(xAxisOptions) {
+ var ScaleClass = Chart.scaleService.getScaleConstructor(xAxisOptions.type);
+ var scale = new ScaleClass({
+ ctx: this.chart.ctx,
+ options: xAxisOptions,
+ data: this.data,
+ id: xAxisOptions.id,
+ });
+
+ this.scales[scale.id] = scale;
+ }, this);
+
+ // Build the y axes
+ helpers.each(this.options.scales.yAxes, function(yAxisOptions) {
+ var ScaleClass = Chart.scaleService.getScaleConstructor(yAxisOptions.type);
+ var scale = new ScaleClass({
+ ctx: this.chart.ctx,
+ options: yAxisOptions,
+ data: this.data,
+ id: yAxisOptions.id,
+ });
+
+ this.scales[scale.id] = scale;
+ }, this);
+ },
+ update: function update() {
+ Chart.scaleService.fitScalesForChart(this, this.chart.width, this.chart.height);
+ this.elementController.updateElements();
+ }
+ });
+
+}).call(this);
previous = root.Chart;
//Occupy the global variable of Chart, and create a simple base class
- var Chart = function(context) {
+ var Chart = function(context, config) {
var chart = this;
+ this.config = config;
// Support a jQuery'd canvas element
if (context.length && context[0].getContext) {
//High pixel density displays - multiply the size of the canvas height/width by the device pixel ratio, then scale.
Chart.helpers.retinaScale(this);
- return this;
+ this.controller = new Chart.Controller(this);
+
+ return this.controller;
};
var defaultColor = 'rgba(0,0,0,0.1)';