]> git.ipfire.org Git - thirdparty/Chart.js.git/commitdiff
No hardcoded chart type methods
authorTanner Linsley <tannerlinsley@gmail.com>
Mon, 15 Jun 2015 01:15:10 +0000 (19:15 -0600)
committerTanner Linsley <tannerlinsley@gmail.com>
Mon, 15 Jun 2015 01:15:10 +0000 (19:15 -0600)
12 files changed:
gulpfile.js
samples/bar.html
src/_charts/chart.bar.js [moved from src/charts/chart.bar.js with 99% similarity]
src/_charts/chart.doughnut.js [moved from src/charts/chart.doughnut.js with 100% similarity]
src/_charts/chart.line.js [moved from src/charts/chart.line.js with 100% similarity]
src/_charts/chart.polarArea.js [moved from src/charts/chart.polarArea.js with 100% similarity]
src/_charts/chart.radar.js [moved from src/charts/chart.radar.js with 100% similarity]
src/_charts/chart.scatter.js [moved from src/charts/chart.scatter.js with 100% similarity]
src/controllers/controller.canvas.rectangular.js
src/core/core.chart.js [deleted file]
src/core/core.controller.js [new file with mode: 0644]
src/core/core.js

index 940a97aab361b8220aab4b626b5f98103ee76984..9ce3dc3f4bb2535dccd589ae39ed1b98f18efc10 100644 (file)
@@ -33,7 +33,6 @@ gulp.task('build', function() {
             './src/scales/**',
             './src/elements/**',
             './src/charts/**',
-            './src/**',
             './node_modules/color/dist/color.min.js'
         ],
         isCustom = !!(util.env.types),
index 117c375313e6b400ead6ff6c69e256ac57105c7f..5e0018d8de28746dd4a5023324130b6f77cd446a 100644 (file)
@@ -39,7 +39,7 @@
     };
     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,
similarity index 99%
rename from src/charts/chart.bar.js
rename to src/_charts/chart.bar.js
index 4d9990b113f90e82cea9ca41b635cc91d29bf303..9154fb5445cb2ea51eb32a5fa14b502262f1d949 100644 (file)
@@ -25,7 +25,6 @@
                                type: "linear",
                        }],
                },
-
        };
 
 
index a4a75cef07b9d0ba740a8b6ab665dd6df3ddc33d..80da709a44e59620a16e2ac11aaaa702285ef545 100644 (file)
@@ -5,191 +5,5 @@
                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);
diff --git a/src/core/core.chart.js b/src/core/core.chart.js
deleted file mode 100644 (file)
index a47361d..0000000
+++ /dev/null
@@ -1,209 +0,0 @@
-(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);
diff --git a/src/core/core.controller.js b/src/core/core.controller.js
new file mode 100644 (file)
index 0000000..b52e8b0
--- /dev/null
@@ -0,0 +1,371 @@
+(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);
index 5811ba26142f01cb72c3d9e28de6204248b2b496..d8037c6111dff44ab30233288f1e842c40c75cc2 100755 (executable)
@@ -18,8 +18,9 @@
                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) {
@@ -57,7 +58,9 @@
                //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)';