/****************************************************************************** * * jquery.graphTable-0.1.js * by rebecca murphey * http://blog.rebeccamurphey.com * rmurphey gmail com * License: GPL * 17 December 2007 * * requires: * * - jquery.js (http://jquery.com) -- tested with 1.2.1 * - jquery.flot.js (http://code.google.com/p/flot/) * * usage: * * $('#myTable').graphTable(graphTableOptionsObject,flotOptionsObject); * * - both arguments are optional; defaults will work in most cases * but you'll need to include {series: 'columns'} if your data is * in columns. * - for details on graphTable options and defaults, see below. * - for details on flot options and defaults, see * http://code.google.com/p/flot/ * * notes: * * - this isn't going to work well with tables that use rowspan or colspan * - make sure to use the transform args to transform your cell contents into * something flot can understand -- especially important if your cells * contain currency or dates * ******************************************************************************/ (function($) { $.fn.graphTable = function(graphArgs_,flotArgs_) { var args = { /* * options for reading the table -- defaults will work in most cases except * you'll want to override the default args.series if your series are in columns * * note that anywhere the word "index" is used, the count starts from 0 at * the top left of the table * */ series: 'rows', // are the series in rows or columns? labels: 0, // index of the cell in the series row/column that contains the label for the series xaxis: 0, // index of the row/column (whatever args.series is) that contains the x values firstSeries: 1, // index of the row/column containing the first series lastSeries: null, // index of the row/column containing the last series; will use the last cell in the row/col if not set dataStart: 1, // index of the first cell in the series containing data dataEnd: null, // index of the last cell in the series containing data; will use the last cell in the row/col if not set /* graph size and position */ position: 'after', // before the table, after the table, or replace the table width: null, // set to null to use the width of the table height: null, // set to null to use the height of the table min: 0, // defaults to minimum y value in the table max: 0, // defaults to maximum y value in the table /* data transformation before plotting */ dataTransform: null, // function to run on cell contents before passing to flot; string -> string labelTransform: null, // function to run on cell contents before passing to flot; string -> string xaxisTransform: null // function to run on cell contents before passing to flot; string -> string } // override defaults with user args $.extend(true,args,graphArgs_); /* default to last cell in the row/col for * lastSeries and dataEnd if they haven't been set yet */ // index of the row/column containing the last series if (! args.lastSeries) { args.lastSeries = (args.series == 'columns') ? $('tr',$(this)).eq(args.labels).find('th,td').length - 1 : $('tr',$(this)).length - 1; } // index of the last cell in the series containing data if (! args.dataEnd) { args.dataEnd = (args.series == 'rows') ? $('tr',$(this)).eq(args.firstSeries).find('th,td').length - 1: $('tr',$(this)).length - 1; } return $(this).each(function() { // use local min/max for y of each graph, based on initial args var $table = $(this); // make sure the table is a table! if (! $table.is('table')) { return; } // if no height and width have been set, then set // width and height based on the width and height of the table if (! args.width) { args.width = $table.width(); } if (! args.height) { args.height = $table.height(); } var min = args.min; var max = args.max; var $rows = $('tr',$table); var tableData = new Array(); switch (args.series) { case 'rows': var $xaxisRow = $rows.eq(args.xaxis); // iterate over each of the rows in the series for (i=args.firstSeries;i<=args.lastSeries;i++) { var rowData = new Array(); $dataRow = $('tr',$table).eq(i); // get the label for the whole row var label = $('th,td',$dataRow).eq(args.labels).text(); if (args.labelTransform) { label = args.labelTransform(label); } for (j=args.dataStart;j<=args.dataEnd;j++) { var x = $('th,td',$xaxisRow).eq(j).text(); var y = $('th,td',$dataRow).eq(j).text(); if (args.dataTransform) { y = args.dataTransform(y); } if (args.xaxisTransform) { x = args.xaxisTransform(x); } test_x = parseFloat(x); test_y = parseFloat(y); if (test_y < min) { min = test_y; } else if (test_y > max) { max = test_y; } rowData[rowData.length] = [x,y]; } tableData[tableData.length] = { label: label, data: rowData }; } break; case 'columns': // iterate over each of the columns in the series var $labelRow = $rows.eq(args.labels); for (j=args.firstSeries;j<=args.lastSeries;j++) { // j designates the column var colData = new Array(); var label = $labelRow.find('th,td').eq(j).text(); if (args.labelTransform) { label = args.labelTransform(label); } for (i=args.dataStart;i<=args.dataEnd;i++) { // i designates the row $cell = $rows.eq(i).find('th,td').eq(j); var y = $cell.text(); var x = $rows.eq(i).find('th,td').eq(args.xaxis).text(); if (args.dataTransform) { y = args.dataTransform(y); } if (args.xaxisTransform) { x = args.xaxisTransform(y); } test_x = parseFloat(x); test_y = parseFloat(y); if (test_y < min) { min = test_y; } else if (test_y > max) { max = test_y; } colData[colData.length] = [x,y]; } tableData[tableData.length] = { label: label, data: colData }; } break; } switch (args.position) { case 'after': $div = $table.after('
').next('div'); break; case 'replace': $div = $table.after('
').next('div'); $table.remove(); break; default: $div = $table.before('
').prev('div'); break; } var flotArgs = { yaxis: { min: min, max: max }, title: 'foo' }; $div.width(args.width).height(args.height); $.extend(true,flotArgs,flotArgs_); $.plot($div, tableData, flotArgs); console.log(tableData); }); }; })(jQuery);