]> git.ipfire.org Git - thirdparty/Chart.js.git/commitdiff
Mid-code commit
authorTanner Linsley <tannerlinsley@gmail.com>
Tue, 12 May 2015 21:42:20 +0000 (15:42 -0600)
committerTanner Linsley <tannerlinsley@gmail.com>
Tue, 12 May 2015 21:42:20 +0000 (15:42 -0600)
samples/bar.html
src/Chart.Bar.js
src/Chart.Core.js

index 0ddfd27408ee51eac652935c8d38575d96c7ef0b..17afaf6af0155fe85b8c18c0a515ea8dc4f9cf69 100644 (file)
@@ -49,8 +49,6 @@
         barChartData.datasets[1].data = [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()];
 
         window.myBar.update();
-
-        console.log(window.barChartData);
     });
     </script>
 </body>
index 01872dde7b725b2cf7463b53f2b8374341b1137c..386e305dcb16f4e98a3d8aa8fdb56f161567ae00 100644 (file)
@@ -87,7 +87,6 @@
                        //Declare the extension of the default point, to cater for the options passed in to the constructor
                        this.BarClass = Chart.Rectangle.extend({
                                ctx : this.chart.ctx,
-                               _vm: {}
                        });
 
                        // Build Scale
                                bar.save();
                        }, this);
 
+                       // Create tooltip instance exclusively for this chart with some defaults.
+                       this.tooltip = new Chart.Tooltip({
+                               _chart: this.chart,
+                               _options: this.options,
+                               opacity:0,
+                               xPadding: this.options.tooltipXPadding,
+                               yPadding: this.options.tooltipYPadding,
+                               xOffset: this.options.tooltipXOffset,
+                               backgroundColor: this.options.tooltipBackgroundColor,
+                               textColor: this.options.tooltipFontColor,
+                               _fontFamily: this.options.tooltipFontFamily,
+                               _fontStyle: this.options.tooltipFontStyle,
+                               fontSize: this.options.tooltipFontSize,
+                               titleTextColor: this.options.tooltipTitleFontColor,
+                               _titleFontFamily: this.options.tooltipTitleFontFamily,
+                               _titleFontStyle: this.options.tooltipTitleFontStyle,
+                               titleFontSize: this.options.tooltipTitleFontSize,
+                               caretHeight: this.options.tooltipCaretSize,
+                               cornerRadius: this.options.tooltipCornerRadius,
+                               legendColorBackground : this.options.multiTooltipKeyBackground,
+                       }, this);
+
+                       // Update the chart with the latest data.
                        this.update();
                },
                onHover: function(e){
                                return false;
                        }
 
-                       var active = function(){
+                       this.active = function(){
                                switch(this.options.hoverMode){
                                        case 'single':
                                                return this.getBarAtEvent(e);
 
                        // On Hover hook
                        if(this.options.onHover){
-                               this.options.onHover.call(this, active);
+                               this.options.onHover.call(this, this.active);
                        }
                        
                        // Built in hover actions
-                       if(active && this.options.hoverMode){
+                       if(this.active && this.options.hoverMode){
                                switch(this.options.hoverMode){
                                        case 'single':
-                                               active.element.backgroundColor = this.data.datasets[active.datasetIndex].hoverBackgroundColor || helpers.color(active.element.backgroundColor).saturate(0.5).darken(0.25).rgbString();
-                                               active.element.borderColor = this.data.datasets[active.datasetIndex].hoverBorderColor || helpers.color(active.element.borderColor).saturate(0.5).darken(0.25).rgbString();
+                                               this.active.element.backgroundColor = this.data.datasets[this.active.datasetIndex].hoverBackgroundColor || helpers.color(this.active.element.backgroundColor).saturate(0.5).darken(0.25).rgbString();
+                                               this.active.element.borderColor = this.data.datasets[this.active.datasetIndex].hoverBorderColor || helpers.color(this.active.element.borderColor).saturate(0.5).darken(0.25).rgbString();
                                                break;
                                        case 'label':
                                                break;
                                }
                        }
 
+
+                       // Built in Tooltips
+                       if(this.options.showTooltips){
+
+                               // The usual
+                               this.tooltip.initialize();
+
+                               // Active Details
+                               if(this.active){
+                                       var tooltipPosition = this.active.element.tooltipPosition();
+                                       helpers.extend(this.tooltip, {
+                                               opacity: 1,
+                                               x: Math.round(tooltipPosition.x),
+                                               y: Math.round(tooltipPosition.y),
+                                               _active: this.active.element,
+                                       });
+                                       this.tooltip.updateContent();
+                               }
+                               else{
+                                       // Inactive Details
+                                       helpers.extend(this.tooltip, {
+                                               opacity: 0,
+                                               _active: false,
+                                       });
+                               }
+                       }
+
                        // Only animate for major events
                        if(!this.animating){
                                // If entering
-                               if(!this.lastActive && active){
+                               if(!this.lastActive && this.active){
                                        this.render(false, this.options.hoverAnimationDuration);
                                }
 
                                // If different element
-                               if(this.lastActive && active && this.lastActive.element !== active.element){
+                               if(this.lastActive && this.active && this.lastActive.element !== this.active.element){
                                        this.render(false, this.options.hoverAnimationDuration);
                                }
 
                                // if Leaving
-                               if (this.lastActive && !active){
+                               if (this.lastActive && !this.active){
                                        this.render(false, this.options.hoverAnimationDuration);
                                }
                        }
 
                        // Remember Last Active
-                       this.lastActive = active;
-
-                       if (this.options.showTooltips){
-                               this.showTooltip(active, this.options.hoverMode);
-                       }
+                       this.lastActive = this.active;
                },
                // Calculate the base point for the bar.
                // If the scale has a 0 point, use that as the base
 
                        this.scale = new this.ScaleClass(scaleOptions);
                },
-               addData : function(valuesArray,label){
-                       //Map the values array for each of the datasets
-                       helpers.each(valuesArray,function(value,datasetIndex){
-                               //Add a new point for each piece of data, passing any required data to draw.
-                               this.data.datasets[datasetIndex].bars.push(new this.BarClass({
-                                       value : value,
-                                       label : label,
-                                       datasetLabel: this.data.datasets[datasetIndex].label,
-                                       x: this.scale.calculateBarX(this.data.datasets.length, datasetIndex, this.scale.valuesCount+1),
-                                       y: this.calculateBarBase(),
-                                       width : this.scale.calculateBarWidth(this.data.datasets.length),
-                                       base : this.calculateBarBase(),
-                                       borderColor : this.data.datasets[datasetIndex].borderColor,
-                                       backgroundColor : this.data.datasets[datasetIndex].backgroundColor
-                               }));
-                       },this);
-
-                       this.scale.addXLabel(label);
-                       //Then re-render the chart.
-                       this.update();
-               },
-               removeData : function(){
-                       this.scale.removeXLabel();
-                       //Then re-render the chart.
-                       helpers.each(this.data.datasets,function(dataset){
-                               dataset.bars.shift();
-                       },this);
-                       this.update();
-               },
-               reflow : function(){
+               // 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()
                                width : this.chart.width
                        });
                        this.scale.update(newScaleProps);
-               },
+               },*/
                draw : function(ease){
 
                        var easingDecimal = ease || 1;
                                        // Update the bar basepoint
                                        bar.base = this.calculateBarBase();
                                        //Transition 
-                                       bar.transition([
-                                               'x',
-                                               'y',
-                                               'width',
-                                               'backgroundColor',
-                                               'borderColor',
-                                               'borderWidth'
-                                       ], easingDecimal).draw();
+                                       bar.transition(easingDecimal).draw();
                                }
                        }, this);
+
+                       // Finally draw the tooltip
+                       this.tooltip.transition(easingDecimal).draw();
                }
        });
 
index 49e03ffc599ec6d3f32d963248dfa7a27270d2b8..f3b000806f738bcbc1eb14f4d0593c5110a8d7b2 100755 (executable)
 
                        delete Chart.instances[this.id];
                },
-               showTooltip : function(elements, hoverMode){
-
-                       // Hide if no elements
-                       if(!elements){
-                               if(this.options.customTooltips){
-                                       this.options.customTooltips(false);
-                               }
-                               if(!this.animating){    
-                                       this.render(false, this.options.hoverAnimationDuration);
-                               }
-                               return;
-                       }
-
-                       switch(hoverMode){
-                               case 'single':
-                                       var tooltipPosition = elements.element.tooltipPosition();
-                                       new Chart.Tooltip({
-                                               x: Math.round(tooltipPosition.x),
-                                               y: Math.round(tooltipPosition.y),
-                                               xPadding: this.options.tooltipXPadding,
-                                               yPadding: this.options.tooltipYPadding,
-                                               backgroundColor: this.options.tooltipBackgroundColor,
-                                               textColor: this.options.tooltipFontColor,
-                                               fontFamily: this.options.tooltipFontFamily,
-                                               fontStyle: this.options.tooltipFontStyle,
-                                               fontSize: this.options.tooltipFontSize,
-                                               caretHeight: this.options.tooltipCaretSize,
-                                               cornerRadius: this.options.tooltipCornerRadius,
-                                               text: template(this.options.tooltipTemplate, elements.element),
-                                               chart: this.chart,
-                                               custom: this.options.customTooltips
-                                       }).draw();
-                                       break;
-                               case 'label':
-                                       var dataArray,
-                                               dataIndex;
-
-                                       for (var i = this.data.datasets.length - 1; i >= 0; i--) {
-                                               dataArray = this.data.datasets[i].metaData;
-                                               dataIndex = indexOf(dataArray, elements[0]);
-                                               if (dataIndex !== -1){
-                                                       break;
-                                               }
-                                       }
-                                       var tooltipLabels = [],
-                                               tooltipColors = [],
-                                               medianPosition = (function(index) {
-
-                                                       // Get all the points at that particular index
-                                                       var Elements = [],
-                                                               dataCollection,
-                                                               xPositions = [],
-                                                               yPositions = [],
-                                                               xMax,
-                                                               yMax,
-                                                               xMin,
-                                                               yMin;
-                                                       helpers.each(this.data.datasets, function(dataset){
-                                                               dataCollection = dataset.metaData;
-                                                               if (dataCollection[dataIndex] && dataCollection[dataIndex].hasValue()){
-                                                                       Elements.push(dataCollection[dataIndex]);
-                                                               }
-                                                       });
-
-                                                       helpers.each(Elements, function(element) {
-                                                               xPositions.push(element.x);
-                                                               yPositions.push(element.y);
-
-
-                                                               //Include any colour information about the element
-                                                               tooltipLabels.push(helpers.template(this.options.multiTooltipTemplate, element));
-                                                               tooltipColors.push({
-                                                                       fill: element._vm.backgroundColor || element.backgroundColor,
-                                                                       stroke: element._vm.borderColor || element.borderColor
-                                                               });
-
-                                                       }, this);
-
-                                                       yMin = min(yPositions);
-                                                       yMax = max(yPositions);
-
-                                                       xMin = min(xPositions);
-                                                       xMax = max(xPositions);
-
-                                                       return {
-                                                               x: (xMin > this.chart.width/2) ? xMin : xMax,
-                                                               y: (yMin + yMax)/2
-                                                       };
-                                               }).call(this, dataIndex);
-
-                                       new Chart.MultiTooltip({
-                                               x: medianPosition.x,
-                                               y: medianPosition.y,
-                                               xPadding: this.options.tooltipXPadding,
-                                               yPadding: this.options.tooltipYPadding,
-                                               xOffset: this.options.tooltipXOffset,
-                                               backgroundColor: this.options.tooltipBackgroundColor,
-                                               textColor: this.options.tooltipFontColor,
-                                               fontFamily: this.options.tooltipFontFamily,
-                                               fontStyle: this.options.tooltipFontStyle,
-                                               fontSize: this.options.tooltipFontSize,
-                                               titleTextColor: this.options.tooltipTitleFontColor,
-                                               titleFontFamily: this.options.tooltipTitleFontFamily,
-                                               titleFontStyle: this.options.tooltipTitleFontStyle,
-                                               titleFontSize: this.options.tooltipTitleFontSize,
-                                               cornerRadius: this.options.tooltipCornerRadius,
-                                               labels: tooltipLabels,
-                                               legendColors: tooltipColors,
-                                               legendColorBackground : this.options.multiTooltipKeyBackground,
-                                               title: elements[0].label,
-                                               chart: this.chart,
-                                               ctx: this.chart.ctx,
-                                               custom: this.options.customTooltips
-                                       }).draw();
-                                       break;
-                               case 'dataset':
-                                       break;
-                               default:
-                       }
-
-                       return this;
-               },
                toBase64Image : function(){
                        return this.chart.canvas.toDataURL.apply(this.chart.canvas, arguments);
                }
        };
 
        Chart.Element = function(configuration){
+               extend(this,{
+                       _vm: {},
+               });
                extend(this,configuration);
                this.initialize.apply(this,arguments);
        };
                        delete this._vm._start;
                        return this;
                },
-               transition : function(props, ease){
+               transition : function(ease){
                        if(!this._start){
                                this._start = clone(this._vm);
                        }
                        each(this,function(value, key){
 
                                // Only non-vm properties
-                               if(key === '_vm' || !this.hasOwnProperty(key)){
+                               if(key[0] === '_' || !this.hasOwnProperty(key)){
                                        return;
                                }
 
                                        return;
                                }
 
-                               // If transition property, do transition with ease (no pun intended)
-                               if(props.indexOf(key) > -1){
-                                       // Color transitions if possible
-                                       if(typeof value === 'string'){
-                                               try{    
-                                                       var color = helpers.color(this._start[key]).mix(helpers.color(this[key]), ease);
-                                                       this._vm[key] = color.rgbString();
-                                               } catch(err){
-                                                       this._vm[key] = value;
-                                               }
-                                               return;
+                               // No unnecessary computations
+                               if(this[key] === this._vm[key]){
+                                       return;
+                               }
+                               
+                               // Color transitions if possible
+                               if(typeof value === 'string'){
+                                       try{    
+                                               var color = helpers.color(this._start[key]).mix(helpers.color(this[key]), ease);
+                                               this._vm[key] = color.rgbString();
+                                       } catch(err){
+                                               this._vm[key] = value;
                                        }
-                                       // Everything else, presumably numbers
+                               }
+                               // Number transitions
+                               else if(typeof value === 'number'){     
                                        this._vm[key] = ((this[key] - this._start[key]) * ease) + this._start[key];
-                                       return;
                                }
-
-                               // Non-transitionals
-                               this._vm[key] = value;
+                               // Non-transitionals or strings
+                               else{
+                                       this._vm[key] = value;
+                               }
                                
                        },this);
                        if(ease === 1){
        });
        
        Chart.Tooltip = Chart.Element.extend({
+               updateContent: function(){
+
+                       switch(this._options.hoverMode){
+                               case 'single':
+                                       helpers.extend(this, {
+                                               text: template(this._tooltipTemplate, this._active)
+                                       });
+                                       return this;
+
+                       }
+
+                       return;
+
+
+                       var dataArray,
+                               dataIndex;
+
+                       for (var i = this.data.datasets.length - 1; i >= 0; i--) {
+                               dataArray = this.data.datasets[i].metaData;
+                               dataIndex = indexOf(dataArray, this.active[0]);
+                               if (dataIndex !== -1){
+                                       break;
+                               }
+                       }
+                       var tooltipLabels = [],
+                               tooltipColors = [],
+                               medianPosition = (function(index) {
+
+                                       // Get all the points at that particular index
+                                       var Elements = [],
+                                               dataCollection,
+                                               xPositions = [],
+                                               yPositions = [],
+                                               xMax,
+                                               yMax,
+                                               xMin,
+                                               yMin;
+                                       helpers.each(this.data.datasets, function(dataset){
+                                               dataCollection = dataset.metaData;
+                                               if (dataCollection[dataIndex] && dataCollection[dataIndex].hasValue()){
+                                                       Elements.push(dataCollection[dataIndex]);
+                                               }
+                                       });
+
+                                       helpers.each(Elements, function(element) {
+                                               xPositions.push(element.x);
+                                               yPositions.push(element.y);
+
+
+                                               //Include any colour information about the element
+                                               tooltipLabels.push(helpers.template(this.multiTooltipTemplate, element));
+                                               tooltipColors.push({
+                                                       fill: element._vm.backgroundColor || element.backgroundColor,
+                                                       stroke: element._vm.borderColor || element.borderColor
+                                               });
+
+                                       }, this);
+
+                                       yMin = min(yPositions);
+                                       yMax = max(yPositions);
+
+                                       xMin = min(xPositions);
+                                       xMax = max(xPositions);
+
+                                       return {
+                                               x: (xMin > this.chart.width/2) ? xMin : xMax,
+                                               y: (yMin + yMax)/2
+                                       };
+                               }).call(this, dataIndex);
+
+                       new Chart.MultiTooltip({
+                               x: medianPosition.x,
+                               y: medianPosition.y,
+                               xPadding: this.tooltipXPadding,
+                               yPadding: this.tooltipYPadding,
+                               xOffset: this.tooltipXOffset,
+                               backgroundColor: this.tooltipBackgroundColor,
+                               textColor: this.tooltipFontColor,
+                               fontFamily: this.tooltipFontFamily,
+                               fontStyle: this.tooltipFontStyle,
+                               fontSize: this.tooltipFontSize,
+                               titleTextColor: this.tooltipTitleFontColor,
+                               titleFontFamily: this.tooltipTitleFontFamily,
+                               titleFontStyle: this.tooltipTitleFontStyle,
+                               titleFontSize: this.tooltipTitleFontSize,
+                               cornerRadius: this.tooltipCornerRadius,
+                               labels: tooltipLabels,
+                               legendColors: tooltipColors,
+                               legendColorBackground : this.multiTooltipKeyBackground,
+                               title: this.data.datasets[0].label,
+                               chart: this.chart,
+                               ctx: this.chart.ctx,
+                               custom: this.customTooltips
+                       }).draw();
+
+                       return this;
+               },
                draw : function(){
 
-                       var ctx = this.chart.ctx;
 
-                       ctx.font = fontString(this.fontSize,this.fontStyle,this.fontFamily);
+                       var ctx = this._chart.ctx;
+                       var vm = this._vm;
+
+                       ctx.font = fontString(vm.fontSize,vm.fontStyle,vm.fontFamily);
 
-                       this.xAlign = "center";
-                       this.yAlign = "above";
+                       vm.xAlign = "center";
+                       vm.yAlign = "above";
 
                        //Distance between the actual element.y position and the start of the tooltip caret
-                       var caretPadding = this.caretPadding = 2;
+                       var caretPadding = vm.caretPadding = 2;
 
-                       var tooltipWidth = ctx.measureText(this.text).width + 2*this.xPadding,
-                               tooltipRectHeight = this.fontSize + 2*this.yPadding,
-                               tooltipHeight = tooltipRectHeight + this.caretHeight + caretPadding;
+                       var tooltipWidth = ctx.measureText(vm.text).width + 2*vm.xPadding,
+                               tooltipRectHeight = vm.fontSize + 2*vm.yPadding,
+                               tooltipHeight = tooltipRectHeight + vm.caretHeight + caretPadding;
 
-                       if (this.x + tooltipWidth/2 >this.chart.width){
-                               this.xAlign = "left";
-                       } else if (this.x - tooltipWidth/2 < 0){
-                               this.xAlign = "right";
+                       if (vm.x + tooltipWidth/2 >this._chart.width){
+                               vm.xAlign = "left";
+                       } else if (vm.x - tooltipWidth/2 < 0){
+                               vm.xAlign = "right";
                        }
 
-                       if (this.y - tooltipHeight < 0){
-                               this.yAlign = "below";
+                       if (vm.y - tooltipHeight < 0){
+                               vm.yAlign = "below";
                        }
 
+                       var tooltipX = vm.x - tooltipWidth/2,
+                               tooltipY = vm.y - tooltipHeight;
 
-                       var tooltipX = this.x - tooltipWidth/2,
-                               tooltipY = this.y - tooltipHeight;
-
-                       ctx.fillStyle = this.backgroundColor;
+                       ctx.fillStyle = helpers.color(vm.backgroundColor).alpha(vm.opacity).rgbString();
 
                        // Custom Tooltips
-                       if(this.custom){
-                               this.custom(this);
+                       if(this._custom){
+                               this._custom(this._vm);
                        }
                        else{
-                               switch(this.yAlign)
-                               {
-                               case "above":
-                                       //Draw a caret above the x/y
-                                       ctx.beginPath();
-                                       ctx.moveTo(this.x,this.y - caretPadding);
-                                       ctx.lineTo(this.x + this.caretHeight, this.y - (caretPadding + this.caretHeight));
-                                       ctx.lineTo(this.x - this.caretHeight, this.y - (caretPadding + this.caretHeight));
-                                       ctx.closePath();
-                                       ctx.fill();
-                                       break;
-                               case "below":
-                                       tooltipY = this.y + caretPadding + this.caretHeight;
-                                       //Draw a caret below the x/y
-                                       ctx.beginPath();
-                                       ctx.moveTo(this.x, this.y + caretPadding);
-                                       ctx.lineTo(this.x + this.caretHeight, this.y + caretPadding + this.caretHeight);
-                                       ctx.lineTo(this.x - this.caretHeight, this.y + caretPadding + this.caretHeight);
-                                       ctx.closePath();
-                                       ctx.fill();
-                                       break;
+                               switch(vm.yAlign){
+                                       case "above":
+                                               //Draw a caret above the x/y
+                                               ctx.beginPath();
+                                               ctx.moveTo(vm.x,vm.y - caretPadding);
+                                               ctx.lineTo(vm.x + vm.caretHeight, vm.y - (caretPadding + vm.caretHeight));
+                                               ctx.lineTo(vm.x - vm.caretHeight, vm.y - (caretPadding + vm.caretHeight));
+                                               ctx.closePath();
+                                               ctx.fill();
+                                               break;
+                                       case "below":
+                                               tooltipY = vm.y + caretPadding + vm.caretHeight;
+                                               //Draw a caret below the x/y
+                                               ctx.beginPath();
+                                               ctx.moveTo(vm.x, vm.y + caretPadding);
+                                               ctx.lineTo(vm.x + vm.caretHeight, vm.y + caretPadding + vm.caretHeight);
+                                               ctx.lineTo(vm.x - vm.caretHeight, vm.y + caretPadding + vm.caretHeight);
+                                               ctx.closePath();
+                                               ctx.fill();
+                                               break;
                                }
 
-                               switch(this.xAlign)
-                               {
-                               case "left":
-                                       tooltipX = this.x - tooltipWidth + (this.cornerRadius + this.caretHeight);
-                                       break;
-                               case "right":
-                                       tooltipX = this.x - (this.cornerRadius + this.caretHeight);
-                                       break;
+                               switch(vm.xAlign){
+                                       case "left":
+                                               tooltipX = vm.x - tooltipWidth + (vm.cornerRadius + vm.caretHeight);
+                                               break;
+                                       case "right":
+                                               tooltipX = vm.x - (vm.cornerRadius + vm.caretHeight);
+                                               break;
                                }
 
-                               drawRoundedRectangle(ctx,tooltipX,tooltipY,tooltipWidth,tooltipRectHeight,this.cornerRadius);
+                               drawRoundedRectangle(ctx,tooltipX,tooltipY,tooltipWidth,tooltipRectHeight,vm.cornerRadius);
 
                                ctx.fill();
 
-                               ctx.fillStyle = this.textColor;
+                               ctx.fillStyle = helpers.color(vm.textColor).alpha(vm.opacity).rgbString();
                                ctx.textAlign = "center";
                                ctx.textBaseline = "middle";
-                               ctx.fillText(this.text, tooltipX + tooltipWidth/2, tooltipY + tooltipRectHeight/2);
+                               ctx.fillText(vm.text, tooltipX + tooltipWidth/2, tooltipY + tooltipRectHeight/2);
+
                        }
                }
        });