1/****************************************************************************** 2 * 3 * jquery.graphTable2-0.1.js 4 * by rebecca murphey 5 * http://blog.rebeccamurphey.com 6 * rmurphey gmail com 7 * License: GPL 8 * 17 December 2007 9 * 10 * table2Plot.js 11 * by tom cafferty 12 * http://www.glocalfocal.com 13 * tcafferty glocalfocal com 14 * License: GPL 15 * 03 December 2011 16 * 17 * requires: 18 * 19 * - jquery.js (http://jquery.com) -- tested with 1.4.2 20 * - jquery.jqplot (https://bitbucket.org/cleonello/jqplot/wiki/Home) 21 * 22 * usage: 23 * 24 * jQuery('#myTable').tablePlot(graphTableOptionsObject,jplotOptionsObject); 25 * 26 * - both arguments are optional; defaults will work in most cases 27 * but you'll need to include {series: 'columns'} if your data is 28 * in columns. 29 * - for details on tablePlot options and defaults, see below. 30 * - for details on jqlot options and defaults, see 31 * http://www.jqplot.com/ 32 * 33 * notes: 34 * 35 * - this isn't going to work well with tables that use rowspan or colspan 36 * - make sure to use the transform args to transform your cell contents into 37 * something flot can understand -- especially important if your cells 38 * contain currency or dates 39 * 40 ******************************************************************************/ 41 42(function($) { 43 44 jQuery.fn.tablePlot = function(graphArgs_,plotArgs_) { 45 46 var args = { 47 /* 48 * options for reading the table -- defaults will work in most cases except 49 * you'll want to override the default args.series if your series are in columns 50 * 51 * note that anywhere the word "index" is used, the count starts from 0 at 52 * the top left of the table 53 * 54 */ 55 series: 'rows', // are the series in rows or columns? 56 labels: 0, // index of the cell in the series row/column that contains the label for the series 57 xaxis: 0, // index of the row/column (whatever args.series is) that contains the x values 58 firstSeries: 1, // index of the row/column containing the first series 59 lastSeries: null, // index of the row/column containing the last series; will use the last cell in the row/col if not set 60 dataStart: 1, // index of the first cell in the series containing data 61 dataEnd: null, // index of the last cell in the series containing data; will use the last cell in the row/col if not set 62 63 /* graph size and position */ 64 position: 'after', // before the table, after the table, or replace the table 65 width: null, // set to null to use the width of the table 66 height: null, // set to null to use the height of the table 67 min: 0, // defaults to minimum y value in the table 68 max: 0, // defaults to maximum y value in the table 69 70 /* data transformation before plotting */ 71 dataTransform: null, // function to run on cell contents before passing to flot; string -> string 72 labelTransform: null, // function to run on cell contents before passing to flot; string -> string 73 xaxisTransform: null // function to run on cell contents before passing to flot; string -> string 74 } 75 76 // override defaults with user args 77 $.extend(true,args,graphArgs_); 78 79 /* default to last cell in the row/col for 80 * lastSeries and dataEnd if they haven't been set yet */ 81 82 // index of the row/column containing the last series 83 if (! args.lastSeries) { 84 args.lastSeries = (args.series == 'columns') ? 85 $('tr',$(this)).eq(args.labels).find('th,td').length - 1 : 86 $('tr',$(this)).length - 1; 87 } 88 89 // index of the last cell in the series containing data 90 if (! args.dataEnd) { 91 args.dataEnd = (args.series == 'rows') ? 92 $('tr',$(this)).eq(args.firstSeries).find('th,td').length - 1: 93 $('tr',$(this)).length - 1; 94 } 95 96 return $(this).each(function() { 97 // use local min/max for y of each graph, based on initial args 98 var $table = $(this); 99 100 // make sure the table is a table! 101 if (! $table.is('table')) { return; } 102 103 // if no height and width have been set, then set 104 // width and height based on the width and height of the table 105 if (! args.width) { args.width = $table.width(); } 106 if (! args.height) { args.height = $table.height(); } 107 108 var min = args.min; 109 var max = args.max; 110 var $rows = $('tr',$table); 111 var line1 = new Array(); 112 var line2 = new Array(args.lastSeries+1); 113 for (i=1; i <args.lastSeries+1; i++) { 114 line2[i]=new Array(); 115 } 116 var line3 = new Array(args.lastSeries); 117 for (i=0; i <args.lastSeries; i++) { 118 line3[i]=new Array(); 119 } 120 var ticks = new Array(); 121 var yVal = new Array(); 122 123 ind = 1; 124 switch (args.series) { 125 126 case 'rows': 127 var $xaxisRow = $rows.eq(args.xaxis); 128 129 // iterate over each of the rows in the series 130 for (i=args.firstSeries;i<=args.lastSeries;i++) { 131 dataIndex = i-args.firstSeries; 132 line1[dataIndex] = new Array(); 133 134 $dataRow = $('tr',$table).eq(i); 135 136 // get the label for the whole row 137 var label = $('th,td',$dataRow).eq(args.labels).text(); 138 139 if (args.labelTransform) { label = args.labelTransform(label); } 140 141 for (j=args.dataStart;j<=args.dataEnd;j++) { 142 var x = $('th,td',$xaxisRow).eq(j).text(); 143 var y = $('th,td',$dataRow).eq(j).text(); 144 145 if (args.dataTransform) { y = args.dataTransform(y); } 146 if (args.xaxisTransform) { x = args.xaxisTransform(x); } 147 148 if (args.orient == 'vertical') { 149 if (plotArgs_.stackSeries) { 150 line2[i][j-1] = parseInt(y, 10); 151 ind=ind+1; 152 } else 153 line1[dataIndex][line1[dataIndex].length] = [x, y]; 154 } else { 155 yVal[line1[dataIndex].length] = x; 156 line1[dataIndex][line1[dataIndex].length] = [y, j]; 157 } 158 } 159 } 160 break; 161 162 case 'columns': 163 // iterate over each of the columns in the series 164 var $labelRow = $rows.eq(args.labels); 165 166 for (j=args.firstSeries;j<=args.lastSeries;j++) { // j designates the column 167 dataIndex = j-args.firstSeries; 168 line1[dataIndex] = new Array(); 169 170 var label = $labelRow.find('th,td').eq(j).text(); 171 if (args.labelTransform) { label = args.labelTransform(label); } 172 173 for (i=args.dataStart;i<=args.dataEnd;i++) { // i designates the row 174 $cell = $rows.eq(i).find('th,td').eq(j); 175 var y = $cell.text(); 176 var x = $rows.eq(i).find('th,td').eq(args.xaxis).text(); 177 178 if (args.dataTransform) { y = args.dataTransform(y); } 179 if (args.xaxisTransform) { x = args.xaxisTransform(x); } 180 181 if (args.orient == 'vertical') { 182 if (plotArgs_.stackSeries) { 183 line2[j][i-1] = parseInt(y, 10); 184 ind=ind+1; 185 if (i > 0) ticks[i-1]=x; 186 } else 187 line1[dataIndex][line1[dataIndex].length] = [x, y]; 188 } else { 189 if (plotArgs_.stackSeries) { 190 line2[j][i-1] = parseInt(y, 10); 191 ind=ind+1; 192 } else { 193 yVal[line1[dataIndex].length] = x; 194 line1[dataIndex][line1[dataIndex].length] = [y, i]; 195 } 196 } 197 } 198 } 199 break; 200 } 201 202 var divid = 'chartdiv_' + args.id; 203 var divstr = '<div id="'+divid+'" style="width:'+args.width+'px; height:'+args.height+'px;" class="plot-graph"></div>'; 204 if (args.placement) { 205 $div = $("#"+args.placement); 206 } else 207 switch (args.position) { 208 case 'after': 209 $div = $table.after(divstr).next('div'); 210 break; 211 212 case 'replace': 213 $div = $table.after(divstr).next('div'); 214 $table.remove(); 215 break; 216 217 default: 218 $div = $table.before(divstr).prev('div'); 219 break; 220 } 221 var plotArgs; 222 if (args.orient == 'vertical') 223 if (plotArgs_.stackSeries) 224 var plotArgs = {axes: {xaxis: {renderer: jQuery.jqplot.CategoryAxisRenderer, tickOptions: {angle: -30}, ticks: ticks}}}; 225 else 226 var plotArgs = plotArgs_; 227 else 228 var plotArgs = plotArgs_; 229 jQuery.extend(true,plotArgs,plotArgs_); 230 231 if (plotArgs_.stackSeries) { 232 for (i=1; i<=args.lastSeries; i++) 233 line3[i-1] = line2[i]; 234 plot1 = jQuery.jqplot(divid, line3, plotArgs); 235 } 236 else 237 plot1 = jQuery.jqplot(divid, line1, plotArgs); 238 }); 239 }; 240 241})(jQuery); 242