Commits

Chris Leonello committed 315ad0b

Mainly working on log axes.
Also investigating AxisTick object, although not used yet.

  • Participants
  • Parent commits 9c9d8e4

Comments (0)

Files changed (3)

         chart1 = $.jqplot('chartdiv1', [[[1,1],[2,4], [4,5], [5,3], null, [7,8]], [[6,10],[10,7.7],[14,10],[18,15]]]);
         chart2 = $.jqplot('chartdiv2', [[[1,1],[2,4], [4,5], [5,3], null, [7,8]], [[2,35],[5,30],[9,18],[11,21]]], {title:'Sample #2', series:[{}, {yaxis:'y2axis'}]});
 */
+				var data = [];
+				var temp = [];
+				var d = 1.00;
+				var g = 1.01;
+				for (var i=1; i<11; i++) {
+					temp.push([i, d]);
+					d *= g;
+				}
+				data.push(temp);
         chart = $.jqplot('chartdiv', 
-            [[[1,1],[2,4],[3,5],[4,1],[5,4],[6,10]], [[1,11],[2,18],[3,4],[4,50],[5,-5],[6,41]]], 
+            //[[[1,1],[2,4],[3,5],[4,1],[5,4],[6,10]], [[21,1],[32,313],[43,752],[54,3081],[65,6472],[76,10000]]],
+            //[[[1,1.1],[2,1.4],[3,1.6],[4,2],[5,2.45],[6,2.8],[7,3.4],[8,4.4],[9,4.8],[10,5.4]]], 
+						data,
             {
-                title:{text:'Dual Axis With Title and Trend Line'}, 
+                title:{text:'dP increase'}, 
                 legend:{textColor:'', fontSize:'0.8em', location:'nw', rowSpacing:'0.2em'}, 
                 grid:{borderShadow:true, drawGridlines:true, background: '#ffffe0'}, 
                 axesDefaults:{ticks:{mark:'cross', showLabels:true, size:6, fontSize:'0.75em'}}, 
-                series:[{trendLines:{show:true, label:'Line 1 Trend'}, label:'Line 1'}, {label:'Line 2', xaxis:'x2axis', yaxis:'y2axis'}],
-                axes:{y2axis:{min:0, max:42}},
-								seriesDefaults:{rendererOptions:{marker:{style:'circle'}}}
+                //series:[{show:false, trendLines:{show:false, label:'Line 1 Trend'}, label:'Line 1'}, {label:'Line 2', xaxis:'xaxis', yaxis:'yaxis'}],
+								series:[{label:'Line 2', xaxis:'xaxis', yaxis:'yaxis'}],
+                axes:{yaxis:{pad:1, type:'log'}},
+        				seriesDefaults:{rendererOptions:{marker:{style:'filledCircle'}}}
             });
+
+        // chart = $.jqplot('chartdiv', 
+        //     [[[1,87],[2,313],[3,752],[4,3081],[5,6472],[6,10355]]], 
+        //     {
+        //         title:{text:'Dual Axis With Title and Trend Line'}, 
+        //         legend:{textColor:'', fontSize:'0.8em', location:'nw', rowSpacing:'0.2em'}, 
+        //         grid:{borderShadow:true, drawGridlines:true, background: '#ffffe0'}, 
+        //         axesDefaults:{ticks:{mark:'cross', showLabels:true, size:6, fontSize:'0.75em'}}, 
+        //         series:[{label:'Line 2', xaxis:'xaxis', yaxis:'yaxis'}],
+        //         axes:{yaxis:{type:'log', pad:2}},
+        // 								seriesDefaults:{rendererOptions:{marker:{style:'circle'}}}
+        //     });
 		});
 		</script>
 		<style type="text/css">

File jqplot.lineAxisRenderer.js

 (function($) {
+    var debug = 1;
+        
+	// Convienence function that won't hang IE.
+	function log() {
+	    if (window.console && debug) {
+	       if (arguments.length == 1) console.log (arguments[0]);
+	       else console.log(arguments);
+	    }
+	};
+	
     $.jqplot.lineAxisRenderer = function() {
     };
     
             // if 2-D array, match them up
             if (temp[0].lenth) {
                 for (var i=0; i< temp; i++) {
+                    var t = new AxisTick();
+                    axis._ticks.push($.extend(true, t, {label:temp[i][1].toString(), value:temp[i][0]}));
                     axis.ticks.labels.push(temp[i][1].toString());
                     axis.ticks.values.push(parseFloat(temp[i][0]));
                 }
             // else 1-D array
             else {
                 for (var i=0; i< temp; i++) {
-                    axis.ticks.labels.push(temp[i].toString());
-                    axis.ticks.values.push(parseFloat(temp[i]));
+                    var t = new AxisTick();
+                    if (typeof(temp[i]) == 'number') axis._ticks.push($.extend(true, t, {label:temp[i].toString(), value:temp[i]}));
+                    else  axis._ticks.push($.extend(true, t, {label:temp[i].toString(), value:i+1}));
+                    if (typeof(temp[i]) == 'number') {
+                        axis.ticks.labels.push(temp[i].toString());
+                        axis.ticks.values.push(parseFloat(temp[i]));
+                    }
+                    else {
+                        axis.ticks.labels.push(temp[i].toString());
+                        axis.ticks.values.push(i+1);
+                    }
                 }
             }
         }
     
     $.jqplot.lineAxisRenderer.prototype.fill = function() {
         var name = this.name;
+        log('render axis ', name);
         var db = this._dataBounds;
         var dim, interval;
         var min, max;
         var pos1, pos2;
+        var tt;
         if (name == 'xaxis' || name == 'x2axis') {
             dim = this._canvasWidth;
         }
         else {
             dim = this._canvasHeight;
         }
-        if (this.numberTicks == null){
-            if (dim > 100) {
-                this.numberTicks = parseInt(3+(dim-100)/75);
-            }
-            else this.numberTicks = 3;
-        }
-        
         
         min = ((this.min != null) ? this.min : db.min);
         max = ((this.max != null) ? this.max : db.max);
         var range = max - min;
-        var rmin = min - (this.min != null ? 0 : range/2*(this.scale - 1));
-        var rmax = max + (this.max != null ? 0 : range/2*(this.scale - 1));
-        this.min = rmin;
-        this.max = rmax;
-        this.tickInterval = (rmax - rmin)/(this.numberTicks-1);
-        for (var i=0; i<this.numberTicks; i++){
-            var tt = rmin + i*this.tickInterval
-            this.ticks.labels.push(this.tickFormatter(this.ticks.formatString, tt));
-            this.ticks.values.push(rmin + i*this.tickInterval);
-            var pox = i*15+'px';
-            switch (name) {
-                case 'xaxis':
-                    this.ticks.styles.push({position:'absolute', top:'0px', left:pox, paddingTop:'10px'});
-                    break;
-                case 'x2axis':
-                    this.ticks.styles.push({position:'absolute', bottom:'0px', left:pox, paddingBottom:'10px'});
-                    break;
-                case 'yaxis':
-                    this.ticks.styles.push({position:'absolute', right:'0px', top:pox, paddingRight:'10px'});
-                    break;
-                case 'y2axis':
-                    this.ticks.styles.push({position:'absolute', left:'0px', top:pox, paddingLeft:'10px'});
-                    break;
+        var rmin, rmax;
+        log('min and max: ', min, max);
+        log('type of axis: ', this.type);
+
+        if (this.type == 'log' || this.type == 'logarithmic') {
+            // for log axes, open up range to get a nice power of 10.
+            rmin = Math.pow(10, Math.ceil(Math.log(min*(2-this.pad))/Math.LN10)-1);
+            rmax = Math.pow(10, Math.floor(Math.log(max*this.pad)/Math.LN10)+1);
+            // rmin = min - min*((this.pad-1)/2);
+            // if (rmin <= 0) rmin = .01;
+            // rmax = max + max*((this.pad-1)/2);
+            log('rmin and rmax, ', rmin, rmax);
+            this.min = rmin;
+            this.max = rmax;
+            range = this.max - this.min;
+            var fittedTicks = 0;
+            var minorTicks = 0;
+            if (this.numberTicks == null){
+                if (dim > 100) {
+                    this.numberTicks = Math.log(this.max/this.min)/Math.LN10 + 1;
+                    //this.numberTicks = Math.ceil(Math.log(range)/Math.LN10 + 1);
+                    if (this.numberTicks < 2) this.numberTicks = 2;
+                    fittedTicks = parseInt(3+(dim-100)/75);
+                }
+                else {
+                    this.numberTicks = 2;
+                    fittedTicks = 2;
+                }
+                // if we don't have enough ticks, add some minor ticks
+                // how many to have between major ticks.
+                if (this.numberTicks < fittedTicks-1) {
+                    minorTicks = 1 + Math.floor(fittedTicks/this.numberTicks);
+                }
+            }
+            log('numberticks, fittedticks: ', this.numberticks, fittedTicks);
+            
+            function fillTick(tt) {
+                this.ticks.labels.push(this.tickFormatter(this.ticks.formatString, tt));
+                this.ticks.values.push(tt);
+                var pox = i*15+'px';
+                switch (name) {
+                    case 'xaxis':
+                        this.ticks.styles.push({position:'absolute', top:'0px', left:pox, paddingTop:'10px'});
+                        break;
+                    case 'x2axis':
+                        this.ticks.styles.push({position:'absolute', bottom:'0px', left:pox, paddingBottom:'10px'});
+                        break;
+                    case 'yaxis':
+                        this.ticks.styles.push({position:'absolute', right:'0px', top:pox, paddingRight:'10px'});
+                        break;
+                    case 'y2axis':
+                        this.ticks.styles.push({position:'absolute', left:'0px', top:pox, paddingLeft:'10px'});
+                        break;
+                }
+            };
+        
+            log('number of ticks ', this.numberTicks);
+            this.tickInterval = range / (this.numberTicks-1);
+            for (var i=0; i<this.numberTicks; i++){
+                // if (i == 0) tt = this.min;
+                // else tt = Math.pow(10, i - this.numberTicks + 1) * this.max;
+                tt = Math.pow(10, i - this.numberTicks + 1) * this.max
+                
+                // tt = this.min + i * range / (this.numberTicks-1);
+                log('tick value ', tt);
+                fillTick.call(this, tt);
+                
+                if (minorTicks) {
+                    var tt1 = Math.pow(10, i - this.numberTicks + 2) * this.max;
+                    var spread = tt1 - tt;
+                    var interval = spread / (minorTicks+1);
+                    for (var j=0; j<minorTicks; j++) {
+                        fillTick.call(this, tt+interval*(j+1));
+                    }
+                }       
+            }
+        }
+        
+        else {
+            rmin = min - range/2*(this.pad - 1);
+            rmax = max + range/2*(this.pad - 1);
+            this.min = rmin;
+            this.max = rmax;
+            range = this.max - this.min;
+        
+            if (this.numberTicks == null){
+                if (dim > 100) {
+                    this.numberTicks = parseInt(3+(dim-100)/75);
+                }
+                else this.numberTicks = 2;
+            }
+        
+            this.tickInterval = range / (this.numberTicks-1);
+            for (var i=0; i<this.numberTicks; i++){
+                tt = this.min + i * range / (this.numberTicks-1);
+                this.ticks.labels.push(this.tickFormatter(this.ticks.formatString, tt));
+                this.ticks.values.push(tt);
+                var pox = i*15+'px';
+                switch (name) {
+                    case 'xaxis':
+                        this.ticks.styles.push({position:'absolute', top:'0px', left:pox, paddingTop:'10px'});
+                        break;
+                    case 'x2axis':
+                        this.ticks.styles.push({position:'absolute', bottom:'0px', left:pox, paddingBottom:'10px'});
+                        break;
+                    case 'yaxis':
+                        this.ticks.styles.push({position:'absolute', right:'0px', top:pox, paddingRight:'10px'});
+                        break;
+                    case 'y2axis':
+                        this.ticks.styles.push({position:'absolute', left:'0px', top:pox, paddingLeft:'10px'});
+                        break;
                     
+                }
             }
         }
         if (name == 'yaxis' || name == 'y2axis') this.ticks.styles.reverse();
     $.jqplot.lineAxisRenderer.prototype.pack = function(offsets, gridwidth, gridheight) {
         var ticks = this.ticks;
         var tickdivs = $(this._elem).children('div');
+        // linear or log axis.  All it changes is the transformation functions from units to coordinates
+        var trans = function(v) { return v };
+        var logtrans = function (v) { return Math.log(v)/Math.LN10; };
+        var max = this.max;
+        var min = this.min;
+        if (this.type == 'log' || this.type == 'logarithmic') {
+            // trans = logtrans;
+            // max = Math.log(this.max)/Math.LN10;
+            // min = Math.log(this.min)/Math.LN10;
+            trans = Math.log;
+            max = Math.log(this.max);
+            min = Math.log(this.min);
+        }
+        
         if (this.name == 'xaxis' || this.name == 'x2axis') {
             this._offsets = {min:offsets.left, max:offsets.right};
             
             this._offsets = {min:offsets.bottom, max:offsets.top};
             
             this.p2u = function(p) {
-                return (p - this._canvasHeight + this._offsets.min)*(this.max - this.min)/(this._canvasHeight - this._offsets.min - this._offsets.max) + this.min;
+                return (trans(p) - this._canvasHeight + this._offsets.min)*(max - min)/(this._canvasHeight - this._offsets.min - this._offsets.max) + min;
             }
             
             this.u2p = function(u) {
-                return -(u - this.min) * (this._canvasHeight - this._offsets.min - this._offsets.max) / (this.max - this.min) + this._canvasHeight - this._offsets.min;
+                return -(trans(u) - min) * (this._canvasHeight - this._offsets.min - this._offsets.max) / (max - min) + this._canvasHeight - this._offsets.min;
             }
             
             this.series_u2p = function(u) {
-                return (this.max - u) * gridheight /(this.max - this.min);
+                return (max - trans(u)) * gridheight /(max - min);
             }
             
             this.series_p2u = function(p) {
-                return -p * (this.max - this.min) / gridheight + this.max;
+                return -trans(p) * (max - min) / gridheight + max;
             }
             
             if (this.show) {

File jquery.jqplot.js

         Class: Axis
         (Private) An individual axis object.  Cannot be instantiated directly, but created
         by the Plot oject.  Axis properties can be set or overriden by the 
-        options passed in from the user.
+        options passed in from the user.  As currently implemented, the axis and 
+        the lineAxisRenderer are tightly integrated.  Options are assigned to the
+        Axis object itself, and not the renderer.
         
         Parameters:
             name - Axis name (identifier).  One of 'xaxis', 'yaxis', 'x2axis' or 'y2axis'.
         // prop: show
         // Wether to display the axis on the graph.
         this.show = false;
-        // prop: scale
+        // prop: pad
+        // Padding to extend the range above and below the data bounds.
         // Factor to multiply by the data range when setting the axis bounds
-        this.scale = 1.2;
+        this.pad = 1.2;
+        // prop: type
+        // Type of axis, linear or log
+        this.type = 'linear';
         // prop: numberTicks
         // Desired number of ticks.  Computed automatically by default
         this.numberTicks;
         this.label = {text:null, fontFamily:null, fontSize:null, align:null};
         /*  
             prop: ticks
-            Container for axis ticks and their properties.
+            Container for axis tick properties.
         
             Properties:
           
         // prop: _canvasHeight
         // height of the grid canvas, total DOM element height.
         this._canvasHeight;
+        this._ticks=[];
+    };
+    
+    function AxisTick() {
+        this.mark = 'outside';
+        this.isMinorTick = false;
+        this.size = 4;
+        this.show = true;
+        this.showLabel = true;
+        this.label = '';
+        this.value;
+        this.styles = {};
+        this.formatString;
+        this.fontFamily='';
+        this.fontSize = '0.75em';
+        this.textColor = '';
+        this._elem;
     };
     
     /* 
         this.equalYTicks = true;
         // borrowed colors from Flot.
         this.seriesColors = ["#edc240", "#afd8f8", "#cb4b4b", "#4da74d", "#9440ed"];
+        this.seriesColorsIndex = 0;
         // Default font characteristics which can be overriden by individual 
         // plot elements.  All are css specs.
         this.textColor = '#666666';
             
             // set the dataBounds (min and max) for each axis
             for (var i=0; i<this.series.length; i++) {
-                this.series[i].renderer.processData.call(this.series[i]);
+                if (this.series[i].show) this.series[i].renderer.processData.call(this.series[i]);
+                //this.series[i].renderer.processData.call(this.series[i]);
             }
         }
+        
+        this.getNextSeriesColor = function() {
+            var c = this.seriesColors[this.seriesColorsIndex];
+            this.seriesColorsIndex++;
+            return c;
+        }
     
         // Function: parseOptions
         //  Parses the user's options overriding defaults.
                 }
                 
                 // parse the renderer options and apply default colors if not provided
-                if (!temp.rendererOptions.color) temp.rendererOptions.color = this.seriesColors[i];
+                if (!temp.rendererOptions.color && temp.show != false) {
+                    temp.rendererOptions.color = this.getNextSeriesColor();
+                }
+                // temp.rendererOptions.show = temp.show;
                 temp.renderer.init(temp.rendererOptions);
                 // $.extend(true, temp.renderer, {color:this.seriesColors[i]}, this.rendererOptions);
                 this.series.push(temp);
                 var pad = false;
                 for (var i = 0; i< series.length; i++) {
                     s = series[i];
-                    var lt = s.label.toString();
-                    if (lt) {
-                        addrow(lt, s.renderer.color, pad);
-                        pad = true;
-                    }
-                    for (var j=0; j<$.jqplot.drawLegendHooks.length; j++) {
-                        var item = $.jqplot.drawLegendHooks[j].call(legend, s);
-                        if (item) {
-                            addrow(item.label, item.color, pad);
+                    if (s.show) {
+                        var lt = s.label.toString();
+                        if (lt) {
+                            addrow(lt, s.renderer.color, pad);
                             pad = true;
-                        } 
+                        }
+                        for (var j=0; j<$.jqplot.drawLegendHooks.length; j++) {
+                            var item = $.jqplot.drawLegendHooks[j].call(legend, s);
+                            if (item) {
+                                addrow(item.label, item.color, pad);
+                                pad = true;
+                            } 
+                        }
                     }
                 }
             }
         // of the individual series.
         this.drawSeries = function(){
             for (var i=0; i<this.series.length; i++) {
-                this.series[i].renderer.draw.call(this.series[i].renderer, this.series[i], this.grid, this.sctx);
-                for (var j=0; j<$.jqplot.postDrawSeriesHooks.length; j++) {
-                    $.jqplot.postDrawSeriesHooks[j].call(this.series[i], this.grid, this.sctx);
+                if (this.series[i].show) {
+                    this.series[i].renderer.draw.call(this.series[i].renderer, this.series[i], this.grid, this.sctx);
+                    for (var j=0; j<$.jqplot.postDrawSeriesHooks.length; j++) {
+                        $.jqplot.postDrawSeriesHooks[j].call(this.series[i], this.grid, this.sctx);
+                    }
                 }
             }
         };