]> git.ipfire.org Git - thirdparty/Chart.js.git/commitdiff
Stable Bar Chart, DRY core functions
authorTanner Linsley <tannerlinsley@gmail.com>
Fri, 15 May 2015 06:04:42 +0000 (00:04 -0600)
committerTanner Linsley <tannerlinsley@gmail.com>
Fri, 15 May 2015 06:04:42 +0000 (00:04 -0600)
src/Chart.Bar.js
src/Chart.Core.js

index 5ccdcba3f700b6fa8f588e0efda6496c06f0c3b3..6699924d733950702779469405b18d9232f4f01f 100644 (file)
                        },this);
 
                        // Set defaults for bars
-                       this.eachBars(function(bar, index, datasetIndex){
+                       this.eachElement(function(bar, index, datasetIndex){
                                helpers.extend(bar, {
                                        width : this.scale.calculateBarWidth(this.data.datasets.length),
                                        x: this.scale.calculateBarX(this.data.datasets.length, datasetIndex, index),
-                                       y: this.calculateBarBase(),
+                                       y: this.calculateBaseY(),
                                        _datasetIndex: datasetIndex,
                                        _index: index,
                                });
 
                        // If exiting chart
                        if(e.type == 'mouseout'){
-                               return false;
+                               return this;
                        }
 
                        this.lastActive = this.lastActive || [];
                        this.active = function(){
                                switch(this.options.hoverMode){
                                        case 'single':
-                                               return this.getBarAtEvent(e);
+                                               return this.getElementAtEvent(e);
                                        case 'label':
-                                               return this.getBarsAtEvent(e);
+                                               return this.getElementsAtEvent(e);
                                        case 'dataset':
                                                return this.getDatasetAtEvent(e);
                                        default:
                        }
 
                        // Remove styling for last active (even if it may still be active)
-                       if(this.lastActive){
+                       if(this.lastActive.length){
                                switch(this.options.hoverMode){
                                        case 'single':
                                                this.lastActive[0].backgroundColor = this.data.datasets[this.lastActive[0]._datasetIndex].backgroundColor;
                                        case 'dataset':
                                                break;
                                        default:
-                                               // do nothing
+                                               // Don't change anything
                                }
                        }
                        
-                       // Built in hover actions
+                       // Built in hover styling
                        if(this.active.length && this.options.hoverMode){
                                switch(this.options.hoverMode){
                                        case 'single':
                                        case 'dataset':
                                                break;
                                        default:
-                                               // do nothing
+                                               // Don't change anything
                                }
                        }
 
                        }
 
 
+                       // Hover animations
                        if(!this.animating){
-
-                               // If entering
-                               if(!this.lastActive.length && this.active.length){
-                                       console.log('entering');
-                                       this.tooltip.pivot();
-                                       this.stop();
-                                       this.render(false, this.options.hoverAnimationDuration);
-                               }
-
                                var changed;
                                
                                helpers.each(this.active, function(element, index){
                                        }
                                }, this);
 
-                               // If different element
-                               if(this.lastActive.length && this.active.length && changed){
-                                       console.log('changing');
-                                       this.tooltip.pivot();
-                                       this.stop();
-                                       this.render(false, this.options.hoverAnimationDuration);
-                               }
+                               // 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)){
 
-                               // if Leaving
-                               if (this.lastActive.length && !this.active.length){
-                                       console.log('leaving');
                                        this.tooltip.pivot();
-                                       this.stop();
-                                       this.render(false, this.options.hoverAnimationDuration);
+                                       this.render(this.options.hoverAnimationDuration);
                                }
-
                        }       
 
                        // Remember Last Active
-                       
                        this.lastActive = this.active;
+                       return this;
                },
                // Calculate the base point for the bar.
-               // If the scale has a 0 point, use that as the base
-               // If the scale min and max are both positive, use the bottom as a base
-               // If the scale min and max are both negative, use the top as a base
-               calculateBarBase: function() {
+               calculateBaseY: function() {
                        var base = this.scale.endPoint;
                        
                        if (this.scale.beginAtZero || ((this.scale.min <= 0 && this.scale.max >= 0) || (this.scale.min >= 0 && this.scale.max <= 0)))
 
                        this.scale.update();
 
-                       this.eachBars(function(bar, index, datasetIndex){
+                       this.eachElement(function(bar, index, datasetIndex){
                                helpers.extend(bar, {
                                        width : this.scale.calculateBarWidth(this.data.datasets.length),
                                        x: this.scale.calculateBarX(this.data.datasets.length, datasetIndex, index),
 
                        this.render();
                },
-               eachBars : function(callback){
-                       helpers.each(this.data.datasets,function(dataset, datasetIndex){
-                               helpers.each(dataset.metaData, callback, this, datasetIndex);
-                       },this);
-               },
-               eachValue : function(callback){
-                       helpers.each(this.data.datasets,function(dataset, datasetIndex){
-                               helpers.each(dataset.data, callback, this, datasetIndex);
-                       },this);
-               },
-               getBarsAtEvent : function(e){
-                       var barsArray = [],
-                               eventPosition = helpers.getRelativePosition(e),
-                               datasetIterator = function(dataset){
-                                       barsArray.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].inRange(eventPosition.x,eventPosition.y)){
-                                               helpers.each(this.data.datasets, datasetIterator);
-                                       }
-                               }
-                       }
-
-                       return barsArray.length ? barsArray : [];
-               },
-               // Get the single bar that was clicked on
-               // @return : An object containing the dataset index and bar index of the matching bar. Also contains the rectangle that was drawn
-               getBarAtEvent : function(e) {
-                       var bar = [];
-                       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)) {
-                                               bar.push(this.data.datasets[datasetIndex].metaData[elementIndex]);
-                                               return bar;
-                                       }
-                               }
-                       }
-                       
-                       return [];
-               },
                buildScale : function(labels){
                        var self = this;
 
                        this.scale = new this.ScaleClass(scaleOptions);
                },
                // This should be incorportated into the init as something like a default value. "Reflow" seems like a weird word for a fredraw function
-               /*reflow : function(){
-                       helpers.extend(this.BarClass.prototype,{
-                               y: this.calculateBarBase(), // so that we animate from the baseline
-                               base : this.calculateBarBase()
-                       });
-                       var newScaleProps = helpers.extend({
-                               height : this.chart.height,
-                               width : this.chart.width
+               redraw : function(){
+                       var base = this.calculateBaseY();
+                       this.eachElement(function(element, index, datasetIndex){
+                               helpers.extend(element,{
+                                       y: base,
+                                       base : base
+                               });
                        });
-                       this.scale.update(newScaleProps);
-               },*/
+                       render();
+               },
                draw : function(ease){
 
                        var easingDecimal = ease || 1;
                        this.scale.draw(easingDecimal);
 
                        //Draw all the bars for each dataset
-                       this.eachBars(function(bar, index, datasetIndex){
+                       this.eachElement(function(bar, index, datasetIndex){
                                if (bar.hasValue()){
                                        // Update the bar basepoint
-                                       bar.base = this.calculateBarBase();
+                                       bar.base = this.calculateBaseY();
                                        //Transition 
                                        bar.transition(easingDecimal).draw();
                                }
index 6c5c4f2851774da221050bbce24e7e4668fddf0b..a038299ad5cb133e0d4eb1e64e4d3da79f2c8754 100755 (executable)
                        }
                        return this;
                },
-               reflow : noop,
-               render : function(reflow, customDuration){
-                       if (reflow){
-                               this.reflow();
-                       }
+               redraw : noop,
+               render : function(duration){
                        
-                       if (this.options.animation && !reflow){
+                       if (this.options.animation){
                                var animation = new Chart.Animation();
-                               animation.numSteps = (customDuration || this.options.animationDuration) / 16.66; //60 fps
+                               animation.numSteps = (duration || this.options.animationDuration) / 16.66; //60 fps
                                animation.easing = this.options.animationEasing;
                                
                                // render function
                                animation.onAnimationProgress = this.options.onAnimationProgress;
                                animation.onAnimationComplete = this.options.onAnimationComplete;
                                
-                               Chart.animationService.addAnimation(this, animation, customDuration);
+                               Chart.animationService.addAnimation(this, animation, duration);
                        }
                        else{
                                this.draw();
                        }
                        return this;
                },
+               eachElement : function(callback){
+                       helpers.each(this.data.datasets,function(dataset, datasetIndex){
+                               helpers.each(dataset.metaData, callback, this, datasetIndex);
+                       },this);
+               },
+               eachValue : function(callback){
+                       helpers.each(this.data.datasets,function(dataset, datasetIndex){
+                               helpers.each(dataset.data, callback, this, datasetIndex);
+                       },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].inRange(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);
                },
                        switch(this._options.hoverMode){
                                case 'single':
                                        helpers.extend(this, {
-                                               text: template(this._options.tooltipTemplate, this._active),
+                                               text: template(this._options.tooltipTemplate, this._active[0]),
                                        });
                                        var tooltipPosition = this._active[0].tooltipPosition();
-                                       helpers.extend(this.tooltip, {
+                                       helpers.extend(this, {
                                                x: Math.round(tooltipPosition.x),
                                                y: Math.round(tooltipPosition.y),
                                        });
                frameDuration: 17,
                animations: [],
                dropFrames: 0,
-               addAnimation: function(chartInstance, animationObject, customDuration) {
+               addAnimation: function(chartInstance, animationObject, duration) {
 
-                       if(!customDuration){
+                       if(!duration){
                                chartInstance.animating = true;
                        }