]> git.ipfire.org Git - thirdparty/Chart.js.git/commitdiff
Doughnut and polar hovering/clicking
authorTanner Linsley <tannerlinsley@gmail.com>
Wed, 3 Jun 2015 22:31:25 +0000 (16:31 -0600)
committerTanner Linsley <tannerlinsley@gmail.com>
Wed, 3 Jun 2015 22:31:25 +0000 (16:31 -0600)
src/Chart.Core.js
src/Chart.Doughnut.js
src/Chart.PolarArea.js

index 9c91b862d8575f587cebee6be7e561b9509d1c6e..356e0dbc3e029876381392d8f82d21c15362b53a 100755 (executable)
                 xOffset: 10,
                 template: [
                     '<% if(label){ %>',
-                    '    <%=label %>:',
+                    '<%=label %>:',
                     '<% } %>',
                     '<%=value %>',
                 ].join(''),
                 multiTemplate: [
                     '<%if (datasetLabel){ %>',
-                    '   <%=datasetLabel %>:',
+                    '<%=datasetLabel %>:',
                     '<% } %>',
                     '<%=value %>'
                 ].join(''),
     });
 
     Chart.Arc = Chart.Element.extend({
+        inGroupRange: function(mouseX) {
+            var vm = this._view;
+
+            if (vm) {
+                return (Math.pow(mouseX - vm.x, 2) < Math.pow(vm.radius + vm.hoverRadius, 2));
+            } else {
+                return false;
+            }
+        },
         inRange: function(chartX, chartY) {
 
             var vm = this._view;
index a6db6cb82c3f007df6b111d66864d00eba5895d5..9ccee22afaf7ea76b6ac327ad8a2e50cbfd0a5d4 100644 (file)
             this.update();
 
         },
-        getSliceAtEvent: function(e) {
-            var elements = [];
-
-            var location = helpers.getRelativePosition(e);
 
-            helpers.each(this.data.metaData, function(slice, index) {
-                if (slice.inRange(location.x, location.y)) elements.push(slice);
-            }, this);
-            return elements;
-        },
         calculateCircumference: function(dataset, value) {
             if (dataset.total > 0) {
                 return (Math.PI * 2) * (value / dataset.total);
             this.lastActive = this.lastActive || [];
 
             // Find Active Elements
-            this.active = this.getSliceAtEvent(e);
+            this.active = function() {
+                switch (this.options.hover.mode) {
+                    case 'single':
+                        return this.getSliceAtEvent(e);
+                    case 'label':
+                        return this.getSlicesAtEvent(e);
+                    case 'dataset':
+                        return this.getDatasetAtEvent(e);
+                    default:
+                        return e;
+                }
+            }.call(this);
 
             // On Hover hook
-            if (this.options.onHover) {
-                this.options.onHover.call(this, this.active);
+            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) {
-                this.lastActive[0].backgroundColor = this.data.data[this.lastActive[0]._index].backgroundColor;
+                switch (this.options.hover.mode) {
+                    case 'single':
+                        dataset = this.data.datasets[this.lastActive[0]._datasetIndex];
+                        index = this.lastActive[0]._index;
+
+                        this.lastActive[0]._model.backgroundColor = this.lastActive[0].custom && this.lastActive[0].custom.backgroundColor ? this.lastActive[0].custom.backgroundColor : helpers.getValueAtIndexOrDefault(dataset.backgroundColor, index, this.options.elements.slice.backgroundColor);
+                        this.lastActive[0]._model.borderColor = this.lastActive[0].custom && this.lastActive[0].custom.borderColor ? this.lastActive[0].custom.borderColor : helpers.getValueAtIndexOrDefault(dataset.borderColor, index, this.options.elements.slice.borderColor);
+                        this.lastActive[0]._model.borderWidth = this.lastActive[0].custom && this.lastActive[0].custom.borderWidth ? this.lastActive[0].custom.borderWidth : helpers.getValueAtIndexOrDefault(dataset.borderWidth, index, this.options.elements.slice.borderWidth);
+                        break;
+                    case 'label':
+                        for (var i = 0; i < this.lastActive.length; i++) {
+                            dataset = this.data.datasets[this.lastActive[i]._datasetIndex];
+                            index = this.lastActive[i]._index;
+
+                            this.lastActive[i]._model.backgroundColor = this.lastActive[i].custom && this.lastActive[i].custom.backgroundColor ? this.lastActive[i].custom.backgroundColor : helpers.getValueAtIndexOrDefault(dataset.backgroundColor, index, this.options.elements.slice.backgroundColor);
+                            this.lastActive[i]._model.borderColor = this.lastActive[i].custom && this.lastActive[i].custom.borderColor ? this.lastActive[i].custom.borderColor : helpers.getValueAtIndexOrDefault(dataset.borderColor, index, this.options.elements.slice.borderColor);
+                            this.lastActive[i]._model.borderWidth = this.lastActive[i].custom && this.lastActive[i].custom.borderWidth ? this.lastActive[i].custom.borderWidth : helpers.getValueAtIndexOrDefault(dataset.borderWidth, index, this.options.elements.slice.borderWidth);
+                        }
+                        break;
+                    case 'dataset':
+                        break;
+                    default:
+                        // Don't change anything
+                }
             }
 
             // Built in hover styling
             if (this.active.length && this.options.hover.mode) {
-                this.active[0].backgroundColor = this.data.data[this.active[0]._index].hoverBackgroundColor || helpers.color(this.data.data[this.active[0]._index].backgroundColor).saturate(0.5).darken(0.35).rgbString();
+                switch (this.options.hover.mode) {
+                    case 'single':
+                        dataset = this.data.datasets[this.active[0]._datasetIndex];
+                        index = this.active[0]._index;
+
+                        this.active[0]._model.radius = this.active[0].custom && this.active[0].custom.hoverRadius ? this.active[0].custom.hoverRadius : helpers.getValueAtIndexOrDefault(dataset.pointHoverRadius, index, this.active[0]._model.radius + 2);
+                        this.active[0]._model.backgroundColor = this.active[0].custom && this.active[0].custom.hoverBackgroundColor ? this.active[0].custom.hoverBackgroundColor : helpers.getValueAtIndexOrDefault(dataset.pointHoverBackgroundColor, index, helpers.color(this.active[0]._model.backgroundColor).saturate(0.5).darken(0.35).rgbString());
+                        this.active[0]._model.borderColor = this.active[0].custom && this.active[0].custom.hoverBorderColor ? this.active[0].custom.hoverBorderColor : helpers.getValueAtIndexOrDefault(dataset.pointHoverBorderColor, index, helpers.color(this.active[0]._model.borderColor).saturate(0.5).darken(0.35).rgbString());
+                        this.active[0]._model.borderWidth = this.active[0].custom && this.active[0].custom.hoverBorderWidth ? this.active[0].custom.hoverBorderWidth : helpers.getValueAtIndexOrDefault(dataset.pointBorderWidth, index, this.active[0]._model.borderWidth + 2);
+                        break;
+                    case 'label':
+                        for (var i = 0; i < this.active.length; i++) {
+                            dataset = this.data.datasets[this.active[i]._datasetIndex];
+                            index = this.active[i]._index;
+
+                            this.active[i]._model.radius = this.active[i].custom && this.active[i].custom.hoverRadius ? this.active[i].custom.hoverRadius : helpers.getValueAtIndexOrDefault(dataset.pointHoverRadius, index, this.active[i]._model.radius + 2);
+                            this.active[i]._model.backgroundColor = this.active[i].custom && this.active[i].custom.hoverBackgroundColor ? this.active[i].custom.hoverBackgroundColor : helpers.getValueAtIndexOrDefault(dataset.pointHoverBackgroundColor, index, helpers.color(this.active[i]._model.backgroundColor).saturate(0.5).darken(0.35).rgbString());
+                            this.active[i]._model.borderColor = this.active[i].custom && this.active[i].custom.hoverBorderColor ? this.active[i].custom.hoverBorderColor : helpers.getValueAtIndexOrDefault(dataset.pointHoverBorderColor, index, helpers.color(this.active[i]._model.borderColor).saturate(0.5).darken(0.35).rgbString());
+                            this.active[i]._model.borderWidth = this.active[i].custom && this.active[i].custom.hoverBorderWidth ? this.active[i].custom.hoverBorderWidth : helpers.getValueAtIndexOrDefault(dataset.pointBorderWidth, index, this.active[i]._model.borderWidth + 2);
+                        }
+                        break;
+                    case 'dataset':
+                        break;
+                    default:
+                        // Don't change anything
+                }
             }
 
+
             // Built in Tooltips
             if (this.options.tooltips.enabled) {
 
 
                 // Active
                 if (this.active.length) {
+                    this.tooltip._model.opacity = 1;
+
                     helpers.extend(this.tooltip, {
-                        opacity: 1,
                         _active: this.active,
                     });
 
                     this.tooltip.update();
                 } else {
                     // Inactive
-                    helpers.extend(this.tooltip, {
-                        opacity: 0,
-                    });
+                    this.tooltip._model.opacity = 0;
                 }
             }
 
             // Remember Last Active
             this.lastActive = this.active;
             return this;
+        },
+        getSliceAtEvent: function(e) {
+            var elements = [];
 
+            var location = helpers.getRelativePosition(e);
+
+            this.eachElement(function(slice, index) {
+                if (slice.inRange(location.x, location.y)) {
+                    elements.push(slice);
+                }
+            }, this);
+            return elements;
         },
+        /*getSlicesAtEvent: function(e) {
+            var elements = [];
+
+            var location = helpers.getRelativePosition(e);
+
+            this.eachElement(function(slice, index) {
+                if (slice.inGroupRange(location.x, location.y)) {
+                    elements.push(slice);
+                }
+            }, this);
+            return elements;
+        },*/
     });
 
     Chart.types.Doughnut.extend({
index e11f222ea2d7f2b874af10381eff580bcd4ca570..ae4b72363611de315e6a68a0c64215f767a608ce 100644 (file)
             }, this);
 
             this.scale.draw();
+
+            this.tooltip.transition(easingDecimal).draw();
         },
         events: function(e) {
 
             this.lastActive = this.lastActive || [];
 
             // Find Active Elements
-            this.active = this.getSliceAtEvent(e);
+            this.active = function() {
+                switch (this.options.hover.mode) {
+                    case 'single':
+                        return this.getSliceAtEvent(e);
+                    case 'label':
+                        return this.getSlicesAtEvent(e);
+                    case 'dataset':
+                        return this.getDatasetAtEvent(e);
+                    default:
+                        return e;
+                }
+            }.call(this);
 
             // On Hover hook
-            if (this.options.onHover) {
-                this.options.onHover.call(this, this.active);
+            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) {
-                this.lastActive[0].backgroundColor = this.data.data[this.lastActive[0]._index].backgroundColor;
+                switch (this.options.hover.mode) {
+                    case 'single':
+                        dataset = this.data.datasets[this.lastActive[0]._datasetIndex];
+                        index = this.lastActive[0]._index;
+
+                        this.lastActive[0]._model.backgroundColor = this.lastActive[0].custom && this.lastActive[0].custom.backgroundColor ? this.lastActive[0].custom.backgroundColor : helpers.getValueAtIndexOrDefault(dataset.backgroundColor, index, this.options.elements.slice.backgroundColor);
+                        this.lastActive[0]._model.borderColor = this.lastActive[0].custom && this.lastActive[0].custom.borderColor ? this.lastActive[0].custom.borderColor : helpers.getValueAtIndexOrDefault(dataset.borderColor, index, this.options.elements.slice.borderColor);
+                        this.lastActive[0]._model.borderWidth = this.lastActive[0].custom && this.lastActive[0].custom.borderWidth ? this.lastActive[0].custom.borderWidth : helpers.getValueAtIndexOrDefault(dataset.borderWidth, index, this.options.elements.slice.borderWidth);
+                        break;
+                    case 'label':
+                        for (var i = 0; i < this.lastActive.length; i++) {
+                            dataset = this.data.datasets[this.lastActive[i]._datasetIndex];
+                            index = this.lastActive[i]._index;
+
+                            this.lastActive[i]._model.backgroundColor = this.lastActive[i].custom && this.lastActive[i].custom.backgroundColor ? this.lastActive[i].custom.backgroundColor : helpers.getValueAtIndexOrDefault(dataset.backgroundColor, index, this.options.elements.slice.backgroundColor);
+                            this.lastActive[i]._model.borderColor = this.lastActive[i].custom && this.lastActive[i].custom.borderColor ? this.lastActive[i].custom.borderColor : helpers.getValueAtIndexOrDefault(dataset.borderColor, index, this.options.elements.slice.borderColor);
+                            this.lastActive[i]._model.borderWidth = this.lastActive[i].custom && this.lastActive[i].custom.borderWidth ? this.lastActive[i].custom.borderWidth : helpers.getValueAtIndexOrDefault(dataset.borderWidth, index, this.options.elements.slice.borderWidth);
+                        }
+                        break;
+                    case 'dataset':
+                        break;
+                    default:
+                        // Don't change anything
+                }
             }
 
             // Built in hover styling
             if (this.active.length && this.options.hover.mode) {
-                this.active[0].backgroundColor = this.data.data[this.active[0]._index].hoverBackgroundColor || helpers.color(this.data.data[this.active[0]._index].backgroundColor).saturate(0.5).darken(0.35).rgbString();
+                switch (this.options.hover.mode) {
+                    case 'single':
+                        dataset = this.data.datasets[this.active[0]._datasetIndex];
+                        index = this.active[0]._index;
+
+                        this.active[0]._model.radius = this.active[0].custom && this.active[0].custom.hoverRadius ? this.active[0].custom.hoverRadius : helpers.getValueAtIndexOrDefault(dataset.pointHoverRadius, index, this.active[0]._model.radius + 2);
+                        this.active[0]._model.backgroundColor = this.active[0].custom && this.active[0].custom.hoverBackgroundColor ? this.active[0].custom.hoverBackgroundColor : helpers.getValueAtIndexOrDefault(dataset.pointHoverBackgroundColor, index, helpers.color(this.active[0]._model.backgroundColor).saturate(0.5).darken(0.35).rgbString());
+                        this.active[0]._model.borderColor = this.active[0].custom && this.active[0].custom.hoverBorderColor ? this.active[0].custom.hoverBorderColor : helpers.getValueAtIndexOrDefault(dataset.pointHoverBorderColor, index, helpers.color(this.active[0]._model.borderColor).saturate(0.5).darken(0.35).rgbString());
+                        this.active[0]._model.borderWidth = this.active[0].custom && this.active[0].custom.hoverBorderWidth ? this.active[0].custom.hoverBorderWidth : helpers.getValueAtIndexOrDefault(dataset.pointBorderWidth, index, this.active[0]._model.borderWidth + 2);
+                        break;
+                    case 'label':
+                        for (var i = 0; i < this.active.length; i++) {
+                            dataset = this.data.datasets[this.active[i]._datasetIndex];
+                            index = this.active[i]._index;
+
+                            this.active[i]._model.radius = this.active[i].custom && this.active[i].custom.hoverRadius ? this.active[i].custom.hoverRadius : helpers.getValueAtIndexOrDefault(dataset.pointHoverRadius, index, this.active[i]._model.radius + 2);
+                            this.active[i]._model.backgroundColor = this.active[i].custom && this.active[i].custom.hoverBackgroundColor ? this.active[i].custom.hoverBackgroundColor : helpers.getValueAtIndexOrDefault(dataset.pointHoverBackgroundColor, index, helpers.color(this.active[i]._model.backgroundColor).saturate(0.5).darken(0.35).rgbString());
+                            this.active[i]._model.borderColor = this.active[i].custom && this.active[i].custom.hoverBorderColor ? this.active[i].custom.hoverBorderColor : helpers.getValueAtIndexOrDefault(dataset.pointHoverBorderColor, index, helpers.color(this.active[i]._model.borderColor).saturate(0.5).darken(0.35).rgbString());
+                            this.active[i]._model.borderWidth = this.active[i].custom && this.active[i].custom.hoverBorderWidth ? this.active[i].custom.hoverBorderWidth : helpers.getValueAtIndexOrDefault(dataset.pointBorderWidth, index, this.active[i]._model.borderWidth + 2);
+                        }
+                        break;
+                    case 'dataset':
+                        break;
+                    default:
+                        // Don't change anything
+                }
             }
 
+
             // Built in Tooltips
             if (this.options.tooltips.enabled) {
 
 
                 // Active
                 if (this.active.length) {
+                    this.tooltip._model.opacity = 1;
+
                     helpers.extend(this.tooltip, {
-                        opacity: 1,
                         _active: this.active,
                     });
 
                     this.tooltip.update();
                 } else {
                     // Inactive
-                    helpers.extend(this.tooltip, {
-                        opacity: 0,
-                    });
+                    this.tooltip._model.opacity = 0;
                 }
             }
 
             // Remember Last Active
             this.lastActive = this.active;
             return this;
-
         },
         getSliceAtEvent: function(e) {
             var elements = [];
 
             var location = helpers.getRelativePosition(e);
 
-            helpers.each(this.data.metaData, function(slice, index) {
-                if (slice.inRange(location.x, location.y)) elements.push(slice);
+            this.eachElement(function(slice, index) {
+                if (slice.inRange(location.x, location.y)) {
+                    elements.push(slice);
+                }
             }, this);
             return elements;
         },
+        /*getSlicesAtEvent: function(e) {
+            var elements = [];
+
+            var location = helpers.getRelativePosition(e);
+
+            this.eachElement(function(slice, index) {
+                if (slice.inGroupRange(location.x, location.y)) {
+                    elements.push(slice);
+                }
+            }, this);
+            return elements;
+        },*/
     });
 
 }).call(this);