]> git.ipfire.org Git - thirdparty/Chart.js.git/commitdiff
Getting into 'label' hoverMode tooltips
authorTanner Linsley <tannerlinsley@gmail.com>
Tue, 12 May 2015 23:22:47 +0000 (17:22 -0600)
committerTanner Linsley <tannerlinsley@gmail.com>
Tue, 12 May 2015 23:22:47 +0000 (17:22 -0600)
samples/bar.html
src/Chart.Bar.js
src/Chart.Core.js

index 17afaf6af0155fe85b8c18c0a515ea8dc4f9cf69..b698faf8ac6a45b12469de24dff2a021fd388c8c 100644 (file)
@@ -36,7 +36,7 @@
         var ctx = document.getElementById("canvas").getContext("2d");
         window.myBar = new Chart(ctx).Bar(barChartData, {
             responsive: true,
-            hoverMode: 'single',
+            hoverMode: 'label',
             scaleBeginAtZero: false,
         });
     }
index 386e305dcb16f4e98a3d8aa8fdb56f161567ae00..c7dde124a3159c9248a0800a2f08a9ecf230c242 100644 (file)
                                        width : this.scale.calculateBarWidth(this.data.datasets.length),
                                        x: this.scale.calculateBarX(this.data.datasets.length, datasetIndex, index),
                                        y: this.calculateBarBase(),
+                                       _datasetIndex: datasetIndex,
+                                       _index: index,
                                });
                                // Copy to view model
                                bar.save();
                        // Create tooltip instance exclusively for this chart with some defaults.
                        this.tooltip = new Chart.Tooltip({
                                _chart: this.chart,
+                               _data: this.data,
                                _options: this.options,
                                opacity:0,
                                xPadding: this.options.tooltipXPadding,
                                return false;
                        }
 
+                       // Find Active Elements
                        this.active = function(){
                                switch(this.options.hoverMode){
                                        case 'single':
                                }
                        }.call(this);
 
+                       // On Hover hook
+                       if(this.options.onHover){
+                               this.options.onHover.call(this, this.active);
+                       }
 
                        // Remove styling for last active (even if it may still be active)
                        if(this.lastActive){
                                switch(this.options.hoverMode){
                                        case 'single':
-                                               this.lastActive.element.backgroundColor = this.data.datasets[this.lastActive.datasetIndex].backgroundColor;
-                                               this.lastActive.element.borderColor = this.data.datasets[this.lastActive.datasetIndex].borderColor;
-                                               this.lastActive.element.borderWidth = 0;
+                                               this.lastActive[0].backgroundColor = this.data.datasets[this.lastActive[0]._datasetIndex].backgroundColor;
+                                               this.lastActive[0].borderColor = this.data.datasets[this.lastActive[0]._datasetIndex].borderColor;
+                                               this.lastActive[0].borderWidth = 0;
                                                break;
                                        case 'label':
                                                break;
                                                // do nothing
                                }
                        }
-
-                       // On Hover hook
-                       if(this.options.onHover){
-                               this.options.onHover.call(this, this.active);
-                       }
                        
                        // Built in hover actions
                        if(this.active && this.options.hoverMode){
                                switch(this.options.hoverMode){
                                        case 'single':
-                                               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();
+                                               this.active[0].backgroundColor = this.data.datasets[this.active[0]._datasetIndex].hoverBackgroundColor || helpers.color(this.active[0].backgroundColor).saturate(0.5).darken(0.25).rgbString();
+                                               this.active[0].borderColor = this.data.datasets[this.active[0]._datasetIndex].hoverBorderColor || helpers.color(this.active[0].borderColor).saturate(0.5).darken(0.25).rgbString();
                                                break;
                                        case 'label':
                                                break;
                        // Built in Tooltips
                        if(this.options.showTooltips){
 
-                               // The usual
+                               // The usual updates
                                this.tooltip.initialize();
 
-                               // Active Details
+                               // Active
                                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,
+                                               _active: this.active,
                                        });
-                                       this.tooltip.updateContent();
+
+                                       this.tooltip.update();
                                }
                                else{
-                                       // Inactive Details
+                                       // Inactive
                                        helpers.extend(this.tooltip, {
                                                opacity: 0,
                                                _active: false,
                        if(!this.animating){
                                // If entering
                                if(!this.lastActive && this.active){
+                                       console.log('entering');
                                        this.render(false, this.options.hoverAnimationDuration);
                                }
 
+                               var changed = false;
+
+                               if (this.active.length !== this.lastActive.length){
+                                               changed = true;
+                               }
+                               
+                               helpers.each(this.active, function(element, index){
+                                       if (element !== this.lastActive[index]){
+                                               changed = true;
+                                       }
+                               }, this);
+
                                // If different element
-                               if(this.lastActive && this.active && this.lastActive.element !== this.active.element){
+                               if(this.lastActive && this.active && changed){
+                                       console.log('changing');
                                        this.render(false, this.options.hoverAnimationDuration);
                                }
 
                                // if Leaving
                                if (this.lastActive && !this.active){
+                                       console.log('leaving');
                                        this.render(false, this.options.hoverAnimationDuration);
                                }
                        }
                                        borderColor : this.data.datasets[datasetIndex].borderColor,
                                        borderWidth : this.data.datasets[datasetIndex].borderWidth,
                                        backgroundColor : this.data.datasets[datasetIndex].backgroundColor,
+                                       _datasetIndex: datasetIndex,
+                                       _index: index,
                                        _start: undefined
                                });
                        }, this);
                                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;
                                        }
                                }
                        }
 
-                       return barsArray;
+                       return barsArray.length ? barsArray : false;
                },
                // 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 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 = {
-                                                       element : this.data.datasets[datasetIndex].metaData[elementIndex],
-                                                       datasetIndex : datasetIndex,
-                                                       elementIndex : elementIndex,
-                                               };
+                                               bar.push(this.data.datasets[datasetIndex].metaData[elementIndex]);
                                                return bar;
                                        }
                                }
                        }
                        
-                       return bar;
+                       return false;
                },
                buildScale : function(labels){
                        var self = this;
index db7d16da42f8214a5c072f6ea71b0b11c5e5711c..9f80f2fa6433afff0f17a3d761ab37f82bb2c791 100755 (executable)
        });
        
        Chart.Tooltip = Chart.Element.extend({
-               updateContent: function(){
-
+               update: function(){
                        switch(this._options.hoverMode){
                                case 'single':
                                        helpers.extend(this, {
-                                               text: template(this._options.tooltipTemplate, this._active)
+                                               text: template(this._options.tooltipTemplate, this._active),
+                                       });
+                                       var tooltipPosition = this._active[0].tooltipPosition();
+                                       helpers.extend(this.tooltip, {
+                                               x: Math.round(tooltipPosition.x),
+                                               y: Math.round(tooltipPosition.y),
                                        });
                                        return this;
+                               case 'label':
 
-                       }
+                                       var dataArray,
+                                               dataIndex;
 
-                       return;
+                                       var tooltipLabels = [],
+                                               tooltipColors = [];
 
+                                       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 dataArray,
-                               dataIndex;
+                                       var 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]);
+                                                       }
+                                               });
 
-                       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._vm.x);
+                                                       yPositions.push(element._vm.y);
 
-                                       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,
+                                                               stroke: element._vm.borderColor
+                                                       });
 
+                                               }, this);
 
-                                               //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
-                                               });
+                                               yMin = min(yPositions);
+                                               yMax = max(yPositions);
 
-                                       }, 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();
+                                               xMin = min(xPositions);
+                                               xMax = max(xPositions);
 
-                       return this;
+                                               return {
+                                                       x: (xMin > this._chart.width/2) ? xMin : xMax,
+                                                       y: (yMin + yMax)/2
+                                               };
+                                       }).call(this, dataIndex);
+
+                                       helpers.extend(this, {
+                                               x: medianPosition.x,
+                                               y: medianPosition.y,
+                                       });
+                                       return this;
+                       }
                },
                draw : function(){