]> git.ipfire.org Git - thirdparty/Chart.js.git/commitdiff
Draw bar chart negative values down from the 0 point of the scale. If all values...
authorEvert Timberg <evert.timberg@gmail.com>
Sun, 15 Mar 2015 18:32:59 +0000 (14:32 -0400)
committerEvert Timberg <evert.timberg@gmail.com>
Sun, 15 Mar 2015 20:04:55 +0000 (16:04 -0400)
samples/bar.html
src/Chart.Bar.js
src/Chart.Core.js

index 5bf4b5bae3661b26f403b9a50503f995075a4761..1b1166a22066416cf1d87ab78156e688266c6347 100644 (file)
@@ -11,7 +11,7 @@
 
 
        <script>
-       var randomScalingFactor = function(){ return Math.round(Math.random()*100)};
+       var randomScalingFactor = function(){ return (Math.random() > 0.5 ? 1.0 : -1.0) * Math.round(Math.random()*100)};
 
        var barChartData = {
                labels : ["January","February","March","April","May","June","July"],
@@ -36,7 +36,8 @@
        window.onload = function(){
                var ctx = document.getElementById("canvas").getContext("2d");
                window.myBar = new Chart(ctx).Bar(barChartData, {
-                       responsive : true
+                       responsive : true,
+                       scaleBeginAtZero: false,
                });
        }
 
index 87fb26ddc405267419abcaa749b76435ee3340cc..7147c15534fab4b100f111ebe7dc204dba59c735 100644 (file)
 
                        this.buildScale(data.labels);
 
-                       this.BarClass.prototype.base = this.scale.endPoint;
+                       this.BarClass.prototype.base = this.calculateBarBase();
 
                        this.eachBars(function(bar, index, datasetIndex){
                                helpers.extend(bar, {
                                        width : this.scale.calculateBarWidth(this.datasets.length),
                                        x: this.scale.calculateBarX(this.datasets.length, datasetIndex, index),
-                                       y: this.scale.endPoint
+                                       y: this.calculateBarBase() // so that we animate from the baseline
                                });
                                bar.save();
                        }, this);
 
                        this.render();
                },
+               // 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() {
+                       var base = this.scale.endPoint;
+                       
+                       if (this.scale.beginAtZero || Math.sign(this.scale.min) != Math.sign(this.scale.max))
+                       {
+                               base = this.scale.calculateY(0);
+                       }
+                       else if (Math.sign(this.scale.min) < 0 && Math.sign(this.scale.max) < 0)
+                       {
+                               // All values are negative. Use the top as the base
+                               base = this.scale.startPoint;
+                       }
+                       
+                       return base;
+               },
                update : function(){
                        this.scale.update();
                        // Reset any highlight colours before updating.
                                        value : value,
                                        label : label,
                                        x: this.scale.calculateBarX(this.datasets.length, datasetIndex, this.scale.valuesCount+1),
-                                       y: this.scale.endPoint,
+                                       y: this.calculateBarBase(), // so that we animate from the 0 point
                                        width : this.scale.calculateBarWidth(this.datasets.length),
-                                       base : this.scale.endPoint,
+                                       base : this.calculateBarBase(),
                                        strokeColor : this.datasets[datasetIndex].strokeColor,
                                        fillColor : this.datasets[datasetIndex].fillColor
                                }));
                },
                reflow : function(){
                        helpers.extend(this.BarClass.prototype,{
-                               y: this.scale.endPoint,
-                               base : this.scale.endPoint
+                               y: this.calculateBarBase(), // so that we animate from the baseline
+                               base : this.calculateBarBase()
                        });
                        var newScaleProps = helpers.extend({
                                height : this.chart.height,
                        helpers.each(this.datasets,function(dataset,datasetIndex){
                                helpers.each(dataset.bars,function(bar,index){
                                        if (bar.hasValue()){
-                                               bar.base = this.scale.endPoint;
+                                               bar.base = this.calculateBarBase()
+                                               
                                                //Transition then draw
                                                bar.transition({
                                                        x : this.scale.calculateBarX(this.datasets.length, datasetIndex, index),
index 5dccd2ef9b1cb8d7864709f5fcb72f30d5b3d674..b05b6b9715a0ad88d5b355671a081770636e805f 100755 (executable)
                        return this.base - this.y;
                },
                inRange : function(chartX,chartY){
-                       return (chartX >= this.x - this.width/2 && chartX <= this.x + this.width/2) && (chartY >= this.y && chartY <= this.base);
+                       if (this.y < this.base)
+                       {
+                               return (chartX >= this.x - this.width/2 && chartX <= this.x + this.width/2) && (chartY >= this.y && chartY <= this.base);
+                       }
+                       else
+                       {
+                               return (chartX >= this.x - this.width / 2 && chartX <= this.x + this.width / 2) && (chartY >= this.base && chartY <= this.y);
+                       }
                }
        });