Mercurial > repos > bcclaywell > microbiome_pplacer_suite
comparison render_datatable.py @ 0:d4690e65afcd draft
Uploaded
| author | bcclaywell |
|---|---|
| date | Thu, 26 Feb 2015 18:16:36 -0500 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| -1:000000000000 | 0:d4690e65afcd |
|---|---|
| 1 #!/usr/bin/env python | |
| 2 | |
| 3 import csv | |
| 4 import itertools | |
| 5 import string | |
| 6 import sys | |
| 7 | |
| 8 input = sys.stdin | |
| 9 start_lines = input.readlines(10) | |
| 10 all_input = itertools.chain(iter(start_lines), input) | |
| 11 | |
| 12 def detect_delimiter(iterable, char_set): | |
| 13 matches = (c for c in char_set if c in iterable) | |
| 14 return next(matches, None) | |
| 15 | |
| 16 def detect_csv_dialect(sample): | |
| 17 try: | |
| 18 return csv.Sniffer().sniff(sample) | |
| 19 except: | |
| 20 return None | |
| 21 | |
| 22 delimiter = detect_delimiter(start_lines[0], list('\t, ')) | |
| 23 reader = None | |
| 24 | |
| 25 if delimiter in list('\t,'): | |
| 26 # try to detect csv dialect, which should neatly handle quoted separators and stuff | |
| 27 dialect = detect_csv_dialect(''.join(start_lines)) | |
| 28 if dialect: | |
| 29 reader = csv.reader(all_input, dialect) | |
| 30 | |
| 31 if not reader: | |
| 32 if delimiter in list(string.whitespace): | |
| 33 # use str.split() with no arguments to split on arbitrary whitespace strings | |
| 34 reader = (line.strip().split() for line in all_input) | |
| 35 else: | |
| 36 reader = all_input | |
| 37 | |
| 38 print """\ | |
| 39 <!DOCTYPE html> | |
| 40 <html lang="en"> | |
| 41 <head> | |
| 42 <meta http-equiv="content-type" content="text/html; charset=UTF-8"></meta> | |
| 43 <link href="http://netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/css/bootstrap-combined.no-icons.min.css" rel="stylesheet"> | |
| 44 <style> | |
| 45 div.dataTables_length label { | |
| 46 float: left; | |
| 47 text-align: left; | |
| 48 } | |
| 49 | |
| 50 div.dataTables_length select { | |
| 51 width: 75px; | |
| 52 } | |
| 53 | |
| 54 div.dataTables_filter label { | |
| 55 float: right; | |
| 56 } | |
| 57 | |
| 58 div.dataTables_info { | |
| 59 padding-top: 8px; | |
| 60 } | |
| 61 | |
| 62 div.dataTables_paginate { | |
| 63 float: right; | |
| 64 margin: 0; | |
| 65 } | |
| 66 | |
| 67 table.table { | |
| 68 clear: both; | |
| 69 margin-bottom: 6px !important; | |
| 70 max-width: none !important; | |
| 71 } | |
| 72 | |
| 73 table.table thead .sorting, | |
| 74 table.table thead .sorting_asc, | |
| 75 table.table thead .sorting_desc, | |
| 76 table.table thead .sorting_asc_disabled, | |
| 77 table.table thead .sorting_desc_disabled { | |
| 78 cursor: pointer; | |
| 79 *cursor: hand; | |
| 80 } | |
| 81 | |
| 82 | |
| 83 table.table thead .sorting { background: url('images/sort_both.png') no-repeat center right; } | |
| 84 | |
| 85 //table.table thead .sorting_asc { background: url('images/sort_asc.png') no-repeat center right; } | |
| 86 //table.table thead .sorting_desc { background: url('images/sort_desc.png') no-repeat center right; } | |
| 87 table.table thead .sorting_asc { background: url('http://cdn3.iconfinder.com/data/icons/fatcow/16x16_0140/bullet_arrow_up.png') no-repeat center right; } | |
| 88 table.table thead .sorting_desc { background: url('http://cdn3.iconfinder.com/data/icons/fatcow/16x16_0140/bullet_arrow_down.png') no-repeat center right; } | |
| 89 | |
| 90 table.table thead .sorting_asc_disabled { background: url('images/sort_asc_disabled.png') no-repeat center right; } | |
| 91 table.table thead .sorting_desc_disabled { background: url('images/sort_desc_disabled.png') no-repeat center right; } | |
| 92 | |
| 93 table.dataTable th:active { | |
| 94 outline: none; | |
| 95 } | |
| 96 | |
| 97 /* Scrolling */ | |
| 98 div.dataTables_scrollHead table { | |
| 99 margin-bottom: 0 !important; | |
| 100 border-bottom-left-radius: 0; | |
| 101 border-bottom-right-radius: 0; | |
| 102 } | |
| 103 | |
| 104 div.dataTables_scrollHead table thead tr:last-child th:first-child, | |
| 105 div.dataTables_scrollHead table thead tr:last-child td:first-child { | |
| 106 border-bottom-left-radius: 0 !important; | |
| 107 border-bottom-right-radius: 0 !important; | |
| 108 } | |
| 109 | |
| 110 div.dataTables_scrollBody table { | |
| 111 border-top: none; | |
| 112 margin-bottom: 0 !important; | |
| 113 } | |
| 114 | |
| 115 div.dataTables_scrollBody tbody tr:first-child th, | |
| 116 div.dataTables_scrollBody tbody tr:first-child td { | |
| 117 border-top: none; | |
| 118 } | |
| 119 | |
| 120 div.dataTables_scrollFoot table { | |
| 121 border-top: none; | |
| 122 } | |
| 123 | |
| 124 | |
| 125 | |
| 126 | |
| 127 /* | |
| 128 * TableTools styles | |
| 129 */ | |
| 130 .table tbody tr.active td, | |
| 131 .table tbody tr.active th { | |
| 132 background-color: #08C; | |
| 133 color: white; | |
| 134 } | |
| 135 | |
| 136 .table tbody tr.active:hover td, | |
| 137 .table tbody tr.active:hover th { | |
| 138 background-color: #0075b0 !important; | |
| 139 } | |
| 140 | |
| 141 .table-striped tbody tr.active:nth-child(odd) td, | |
| 142 .table-striped tbody tr.active:nth-child(odd) th { | |
| 143 background-color: #017ebc; | |
| 144 } | |
| 145 | |
| 146 table.DTTT_selectable tbody tr { | |
| 147 cursor: pointer; | |
| 148 *cursor: hand; | |
| 149 } | |
| 150 | |
| 151 div.DTTT .btn { | |
| 152 color: #333 !important; | |
| 153 font-size: 12px; | |
| 154 } | |
| 155 | |
| 156 div.DTTT .btn:hover { | |
| 157 text-decoration: none !important; | |
| 158 } | |
| 159 | |
| 160 | |
| 161 ul.DTTT_dropdown.dropdown-menu a { | |
| 162 color: #333 !important; /* needed only when demo_page.css is included */ | |
| 163 } | |
| 164 | |
| 165 ul.DTTT_dropdown.dropdown-menu li:hover a { | |
| 166 background-color: #0088cc; | |
| 167 color: white !important; | |
| 168 } | |
| 169 | |
| 170 /* TableTools information display */ | |
| 171 div.DTTT_print_info.modal { | |
| 172 height: 150px; | |
| 173 margin-top: -75px; | |
| 174 text-align: center; | |
| 175 } | |
| 176 | |
| 177 div.DTTT_print_info h6 { | |
| 178 font-weight: normal; | |
| 179 font-size: 28px; | |
| 180 line-height: 28px; | |
| 181 margin: 1em; | |
| 182 } | |
| 183 | |
| 184 div.DTTT_print_info p { | |
| 185 font-size: 14px; | |
| 186 line-height: 20px; | |
| 187 } | |
| 188 | |
| 189 | |
| 190 | |
| 191 /* | |
| 192 * FixedColumns styles | |
| 193 */ | |
| 194 div.DTFC_LeftHeadWrapper table, | |
| 195 div.DTFC_LeftFootWrapper table, | |
| 196 table.DTFC_Cloned tr.even { | |
| 197 background-color: white; | |
| 198 } | |
| 199 | |
| 200 div.DTFC_LeftHeadWrapper table { | |
| 201 margin-bottom: 0 !important; | |
| 202 border-top-right-radius: 0 !important; | |
| 203 border-bottom-left-radius: 0 !important; | |
| 204 border-bottom-right-radius: 0 !important; | |
| 205 } | |
| 206 | |
| 207 div.DTFC_LeftHeadWrapper table thead tr:last-child th:first-child, | |
| 208 div.DTFC_LeftHeadWrapper table thead tr:last-child td:first-child { | |
| 209 border-bottom-left-radius: 0 !important; | |
| 210 border-bottom-right-radius: 0 !important; | |
| 211 } | |
| 212 | |
| 213 div.DTFC_LeftBodyWrapper table { | |
| 214 border-top: none; | |
| 215 margin-bottom: 0 !important; | |
| 216 } | |
| 217 | |
| 218 div.DTFC_LeftBodyWrapper tbody tr:first-child th, | |
| 219 div.DTFC_LeftBodyWrapper tbody tr:first-child td { | |
| 220 border-top: none; | |
| 221 } | |
| 222 | |
| 223 div.DTFC_LeftFootWrapper table { | |
| 224 border-top: none; | |
| 225 } | |
| 226 </style> | |
| 227 <script type="text/javascript" language="javascript" src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-2.0.0.min.js"></script> | |
| 228 <script type="text/javascript" language="javascript" src="http://ajax.aspnetcdn.com/ajax/jquery.dataTables/1.9.4/jquery.dataTables.min.js"></script> | |
| 229 <script type="text/javascript" charset="utf-8"> | |
| 230 /* Set the defaults for DataTables initialisation */ | |
| 231 $.extend( true, $.fn.dataTable.defaults, { | |
| 232 "sDom": "<'row-fluid'<'span6'l><'span6'f>r>t<'row-fluid'<'span6'i><'span6'p>>", | |
| 233 "sPaginationType": "bootstrap", | |
| 234 "oLanguage": { | |
| 235 "sLengthMenu": "_MENU_ records per page" | |
| 236 } | |
| 237 } ); | |
| 238 | |
| 239 | |
| 240 /* Default class modification */ | |
| 241 $.extend( $.fn.dataTableExt.oStdClasses, { | |
| 242 "sWrapper": "dataTables_wrapper form-inline" | |
| 243 } ); | |
| 244 | |
| 245 | |
| 246 /* API method to get paging information */ | |
| 247 $.fn.dataTableExt.oApi.fnPagingInfo = function ( oSettings ) | |
| 248 { | |
| 249 return { | |
| 250 "iStart": oSettings._iDisplayStart, | |
| 251 "iEnd": oSettings.fnDisplayEnd(), | |
| 252 "iLength": oSettings._iDisplayLength, | |
| 253 "iTotal": oSettings.fnRecordsTotal(), | |
| 254 "iFilteredTotal": oSettings.fnRecordsDisplay(), | |
| 255 "iPage": oSettings._iDisplayLength === -1 ? | |
| 256 0 : Math.ceil( oSettings._iDisplayStart / oSettings._iDisplayLength ), | |
| 257 "iTotalPages": oSettings._iDisplayLength === -1 ? | |
| 258 0 : Math.ceil( oSettings.fnRecordsDisplay() / oSettings._iDisplayLength ) | |
| 259 }; | |
| 260 }; | |
| 261 | |
| 262 | |
| 263 /* Bootstrap style pagination control */ | |
| 264 $.extend( $.fn.dataTableExt.oPagination, { | |
| 265 "bootstrap": { | |
| 266 "fnInit": function( oSettings, nPaging, fnDraw ) { | |
| 267 var oLang = oSettings.oLanguage.oPaginate; | |
| 268 var fnClickHandler = function ( e ) { | |
| 269 e.preventDefault(); | |
| 270 if ( oSettings.oApi._fnPageChange(oSettings, e.data.action) ) { | |
| 271 fnDraw( oSettings ); | |
| 272 } | |
| 273 }; | |
| 274 | |
| 275 $(nPaging).addClass('pagination').append( | |
| 276 '<ul>'+ | |
| 277 '<li class="prev disabled"><a href="#">← '+oLang.sPrevious+'</a></li>'+ | |
| 278 '<li class="next disabled"><a href="#">'+oLang.sNext+' → </a></li>'+ | |
| 279 '</ul>' | |
| 280 ); | |
| 281 var els = $('a', nPaging); | |
| 282 $(els[0]).bind( 'click.DT', { action: "previous" }, fnClickHandler ); | |
| 283 $(els[1]).bind( 'click.DT', { action: "next" }, fnClickHandler ); | |
| 284 }, | |
| 285 | |
| 286 "fnUpdate": function ( oSettings, fnDraw ) { | |
| 287 var iListLength = 5; | |
| 288 var oPaging = oSettings.oInstance.fnPagingInfo(); | |
| 289 var an = oSettings.aanFeatures.p; | |
| 290 var i, ien, j, sClass, iStart, iEnd, iHalf=Math.floor(iListLength/2); | |
| 291 | |
| 292 if ( oPaging.iTotalPages < iListLength) { | |
| 293 iStart = 1; | |
| 294 iEnd = oPaging.iTotalPages; | |
| 295 } | |
| 296 else if ( oPaging.iPage <= iHalf ) { | |
| 297 iStart = 1; | |
| 298 iEnd = iListLength; | |
| 299 } else if ( oPaging.iPage >= (oPaging.iTotalPages-iHalf) ) { | |
| 300 iStart = oPaging.iTotalPages - iListLength + 1; | |
| 301 iEnd = oPaging.iTotalPages; | |
| 302 } else { | |
| 303 iStart = oPaging.iPage - iHalf + 1; | |
| 304 iEnd = iStart + iListLength - 1; | |
| 305 } | |
| 306 | |
| 307 for ( i=0, ien=an.length ; i<ien ; i++ ) { | |
| 308 // Remove the middle elements | |
| 309 $('li:gt(0)', an[i]).filter(':not(:last)').remove(); | |
| 310 | |
| 311 // Add the new list items and their event handlers | |
| 312 for ( j=iStart ; j<=iEnd ; j++ ) { | |
| 313 sClass = (j==oPaging.iPage+1) ? 'class="active"' : ''; | |
| 314 $('<li '+sClass+'><a href="#">'+j+'</a></li>') | |
| 315 .insertBefore( $('li:last', an[i])[0] ) | |
| 316 .bind('click', function (e) { | |
| 317 e.preventDefault(); | |
| 318 oSettings._iDisplayStart = (parseInt($('a', this).text(),10)-1) * oPaging.iLength; | |
| 319 fnDraw( oSettings ); | |
| 320 } ); | |
| 321 } | |
| 322 | |
| 323 // Add / remove disabled classes from the static elements | |
| 324 if ( oPaging.iPage === 0 ) { | |
| 325 $('li:first', an[i]).addClass('disabled'); | |
| 326 } else { | |
| 327 $('li:first', an[i]).removeClass('disabled'); | |
| 328 } | |
| 329 | |
| 330 if ( oPaging.iPage === oPaging.iTotalPages-1 || oPaging.iTotalPages === 0 ) { | |
| 331 $('li:last', an[i]).addClass('disabled'); | |
| 332 } else { | |
| 333 $('li:last', an[i]).removeClass('disabled'); | |
| 334 } | |
| 335 } | |
| 336 } | |
| 337 } | |
| 338 } ); | |
| 339 | |
| 340 | |
| 341 /* | |
| 342 * TableTools Bootstrap compatibility | |
| 343 * Required TableTools 2.1+ | |
| 344 */ | |
| 345 if ( $.fn.DataTable.TableTools ) { | |
| 346 // Set the classes that TableTools uses to something suitable for Bootstrap | |
| 347 $.extend( true, $.fn.DataTable.TableTools.classes, { | |
| 348 "container": "DTTT btn-group", | |
| 349 "buttons": { | |
| 350 "normal": "btn", | |
| 351 "disabled": "disabled" | |
| 352 }, | |
| 353 "collection": { | |
| 354 "container": "DTTT_dropdown dropdown-menu", | |
| 355 "buttons": { | |
| 356 "normal": "", | |
| 357 "disabled": "disabled" | |
| 358 } | |
| 359 }, | |
| 360 "print": { | |
| 361 "info": "DTTT_print_info modal" | |
| 362 }, | |
| 363 "select": { | |
| 364 "row": "active" | |
| 365 } | |
| 366 } ); | |
| 367 | |
| 368 // Have the collection use a bootstrap compatible dropdown | |
| 369 $.extend( true, $.fn.DataTable.TableTools.DEFAULTS.oTags, { | |
| 370 "collection": { | |
| 371 "container": "ul", | |
| 372 "button": "li", | |
| 373 "liner": "a" | |
| 374 } | |
| 375 } ); | |
| 376 } | |
| 377 | |
| 378 | |
| 379 /* Table initialisation */ | |
| 380 $(document).ready(function() { | |
| 381 $('#from_csv').dataTable( { | |
| 382 "sDom": "<'row'<'span6'l><'span6'f>r>t<'row'<'span6'i><'span6'p>>", | |
| 383 "sPaginationType": "bootstrap", | |
| 384 "oLanguage": { | |
| 385 "sLengthMenu": "_MENU_ records per page" | |
| 386 } | |
| 387 } ); | |
| 388 } ); | |
| 389 </script> | |
| 390 </head> | |
| 391 <body> | |
| 392 <div class="container" style="margin-top: 10px"> | |
| 393 <table cellpadding="0" cellspacing="0" border="0" class="table table-striped table-bordered" id="from_csv"> | |
| 394 <thead>\ | |
| 395 """ | |
| 396 | |
| 397 for i, row in enumerate(reader): | |
| 398 if i == 0: | |
| 399 print "<tr><th>" + "</th><th>".join(row) + "</th></tr>" | |
| 400 else: | |
| 401 print "<tr><td>" + "</td><td>".join(row) + "</td></tr>" | |
| 402 | |
| 403 if i == 0: | |
| 404 print "</thead><tbody>" | |
| 405 | |
| 406 print """\ | |
| 407 </tbody> | |
| 408 </table> | |
| 409 </div> | |
| 410 </body> | |
| 411 </html>\ | |
| 412 """ |
