Skip to content

Instantly share code, notes, and snippets.

@son0fhobs
Last active August 29, 2015 13:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save son0fhobs/9521110 to your computer and use it in GitHub Desktop.
Save son0fhobs/9521110 to your computer and use it in GitHub Desktop.
HTML Table Data Visualization
/*
// Tabelizer for Contract Table? - http://www.jqueryrain.com/?pl_6d8jV
// CSS flow! - Snippets - http://www.cssflow.com/snippets/
// better wordcloud - https://github.com/lucaong/jQCloud
// navigation and options styles awesomeness - codepen
// Use Awesome CSS Progress bars for bars instead - animate them
// use gradients with overflow hidden?
// cookies to save options?
// export to google visualizations? - https://code.google.com/p/auto-table-to-chart/
// inspiration - http://codecanyon.net/item/graphup-jquery-plugin/108025
// CDN Libraries
// color picker - http://bgrins.github.io/spectrum/ - includes alpha though
// color library if really needed
- https://github.com/jquery/jquery-color
- https://github.com/gka/chroma.js
- http://matthewbjordan.me/Colors/
// pie, line graph, scattered, scattered pie - overlayed?
// sparklines!
// jquer knob - other radial, guages? - superpose! http://anthonyterrien.com/knob/
// gauges, ok, not stacked - http://bernii.github.io/gauge.js/, http://www.justgage.com/
// pure css radial? - http://codepen.io/jo-asakura/pen/stFHi
// bars centered
// awesome stacked bar - http://codepen.io/dweidner/pen/fEbyt
// 3d bars, progress bars, animate... editable?
// make a color heatmap based on values - gradient to select, color library to work with.
// Circle bubbles based on size and color $15! - expand on? Can I use datatables? Editable tables?
// throw in awesome css inspiration stuff
// bootstrap v datatables?
// jquery ui to click and drag modals?
// 2000 characters?
// http://www.boutell.com/newfaq/misc/urllength.html - 80,000! chrome - 2,097,152!
*/
// copy moz color palette
// other visualizations? Stacked bar graph for row, first td has div that spans entire row, then use % from there
// this is designed to highlight cells and show background bar graphs based on cell values
// bar %, bar color, user choose color? Choose which cols have visualization. Normalize vals if > 100?
// append style to header
// https://rstudio.github.io/DT/
// http://www.htmlwidgets.org/showcase_datatables.html
// http://ace.c9.io/#nav=about
var options = {
visualization_type: 'bar', // bar, full, stacked-bar - this is also the css class - default is full
style:'left', // bar: 'left', 'right', 'bottom', 'top', 'center', 'center-vertical' | colored - monochromatic, palette, gradient
color_style: 'opacity', // opacity, gradient, palette, default
color:'rgb(0, 100, 255)', // allow color selector
color_gradient:'', // css gradient? Hm...
color_palette:{}, // percent:color
vals_by:'column', // column, row, individual = for determining percent or decimal if not defined
percent_format: 'detect', // 'detect', 'percent', 'decimal'
bg_div_class: 'bg-div'
};
var selector = '#DataTables_Table_3';
var $table = $(selector);
var styles = '';
styles += selector+' td{position:relative;}';
styles += ' table .td-content{position:relative;z-index:1;}';
styles += ' .bg-div{ position:absolute; background:'+options.color+';z-index:0;}';
styles += ' .bg-div{ box-shadow:-1px 1px 1px #aaa; opacity:.6;}';
styles += ' .bar-down .bg-div{left:0; bottom:auto;top:0; width:100%;}';
styles += ' .bar-up .bg-div{left:0; bottom:0; top:auto;width:100%;}';
styles += ' .bar-right .bg-div{left:auto;right:0; top:0; width:auto; height:100%;}';
styles += ' .bar-left .bg-div{left:0; right:auto; top:0; width:auto; height:100%;}';
styles += ' .bar-center .bg-div{left:50%; right:auto; width:auto; height:100%;}';
styles += ' .bar-center-vertical .bg-div{top :50%; bottom:auto;width:100%; height:auto;}';
styles += ' .bar-circle .bg-div{left:50%; right:auto; top:50%; bottom:auto;border-radius:100%;}';
styles += ' .full .bg-div{left:0; right:auto; top:0; width:100%; height:100%; bottom:auto; }';
append_styles_to_head(styles);
// append styles with js while jquery loads
function reset_classes(prev_options){
}
function append_styles_to_head(){
var head = document.head || document.getElementsByTagName('head')[0];
var style = document.createElement('style');
style.type = 'text/css';
if (style.styleSheet){
style.styleSheet.cssText = styles;
} else {
style.appendChild(document.createTextNode(styles));
}
head.appendChild(style);
}
// run it
add_visualization_divs($table, options);
modify_visualization_by_val($table, options)
var prev_options = options; // for removing classes if things change
function add_visualization_divs($table, options, prev_options){
if(typeof prev_options === 'undefined'){ prev_options = options; }
$table.find('td').each(function(){
// don't add bg-div twice
if($(this).find('.'+options.bg_div_class).length){
// remove previous classes for visualization types?
$(this).removeClass(prev_options.visualization_type);
$(this).removeClass(prev_options.visualization_type+'-'+prev_options.style);
}else{
var content = $(this).html();
$(this).html('<div class="'+options.bg_div_class+'"></div><div class="td-content">'+content+'</div>');
}
$(this).addClass(options.visualization_type);
$(this).addClass(options.visualization_type+'-'+options.style);
});
}
function modify_visualization_by_val($table, options){
var col_percent_decimal = percent_or_decimal_by_col($table);
$table.find('tr').each(function(r){
var $tr = $(this);
$tr.find('td').each(function(i){
// i = col number
var $td = $(this);
var val = get_cell_num_val($td);
var decimal_val = (col_percent_decimal[i] === 'decimal') ? val : val/100;
var vals = get_val_variations(decimal_val); // vals.percent_val, vals.decimal_val, vals.percent_str
var class_selector = '.'+options.bg_div_class;
var $bg_div = $td.find(class_selector);
// $bg_div.css({'border':'1px solid #000', 'width':'20px', 'height':'100%'});
modify_bar_by_val(vals, $bg_div, options, $td);
modify_color_by_val(vals, $bg_div, options, $td);
});
});
}
function get_val_variations(decimal_val){
var vals = {
percent_val:decimal_val*100,
decimal_val:decimal_val,
percent_num:(decimal_val*100)+'%'
};
return vals;
}
function modify_bar_by_val(vals, $bg_div, options, $td){
var offset_padding = 0;
var margin_left = 0;
var margin_top = 0;
// remove old offsets
$bg_div.css('margin', '0px');
if(options.style === 'left' || options.style === 'right'){
/*
if(options.style === 'left'){
offset_padding = $td.css('padding-left');
$bg_div.css('margin-left', '-'+offset_padding);
}else if(options.style === 'right'){
offset_padding = $td.css('padding-right');
$bg_div.css('margin-right', '-'+offset_padding);
}
*/
$bg_div.css({'width':vals.percent_num});
}else if(options.style === 'center'){
$bg_div.css({'width':vals.percent_num});
margin_left = $bg_div.width()/2; // once width % applied, get calculated width
$bg_div.css({'margin-left':'-'+margin_left+'px'});
offset_padding = $td.css('padding-top');
$bg_div.css('margin-top', '-'+offset_padding);
}else if(options.style === 'circle'){
$bg_div.css({'width':vals.percent_num});
$bg_div.css({'height':$bg_div.width()});
margin_left = $bg_div.width()/2; // + parseInt($td.css('padding-left'));
margin_top = $bg_div.width()/2; // + parseInt($td.css('padding-top'));
$bg_div.css({'margin-left':'-'+margin_left+'px', 'margin-top':'-'+margin_top+'px'});
}else if(options.style === 'top' || options.style === 'bottom'){
/*
if(options.style === 'top'){
offset_padding = $td.css('padding-top');
$bg_div.css('margin-top', '-'+offset_padding);
}else if(options.style === 'bottom'){
offset_padding = $td.css('padding-bottom');
$bg_div.css('margin-bottom', '-'+offset_padding);
}
*/
$bg_div.css({'height':vals.percent_num});
}else if(options.style === 'center-vertical'){
$bg_div.css({'height':vals.percent_num});
margin_top = $bg_div.height()/2; // once width % applied, get calculated width
$bg_div.css({'margin-top':'-'+margin_top+'px'});
offset_padding = $td.css('padding-left');
$bg_div.css('margin-left', '-'+offset_padding);
}else if(options.style === 'opacity'){
$bg_div.css({'opacity':vals.percent_num});
}
}
function modify_color_by_val(vals, $bg_div, options, $td){
if(options.color_style === 'opacity'){
var opacity = parseInt(vals.percent_num);
if(opacity > 1){
opacity = opacity/100;
}
$bg_div.css({'opacity': opacity });
}else if(options.color_style === 'gradient'){
// how make this work?
}else if(options.color_style === 'palette'){
// user chosen color palette, divide each color into equal percent range? 10% range by default, or custom ranges?
}
/*
else{ // monochromatic - already set with css
var rgba = val_to_rgba(options.color, vals.decimal_val);
$bg_div.css({'background-color':rgba});
}
*/
}
// append class based on type
// get val, convert to percent
// modify bg_div based on percent
function percent_or_decimal_by_col($table){
// can't tell cell if decimal or percent if 1, thus compare entire column.
var col_percent_decimal = [];
var columns = get_columns($table);
var i=0;
var max = columns.length;
for(i=0;i<max;i++){
col_percent_decimal[i] = get_col_percent_or_decimal(columns[i]);
}
return col_percent_decimal;
}
function get_columns($table){
var columns = [];
$table.find('tr').each(function(i){
var $tr = $(this);
$tr.children('td').each(function(r){
var $td = $(this);
if(typeof columns[r] == 'undefined'){ columns[r] = []; }
columns[r].push($td);
});
});
return columns;
}
function get_cell_num_val($cell){
var val = $cell.text();
if(val){
var number = val.match(/[\d\.\,]+/); // only match first number? global numbers?
if(number){
number = number[0];
}else{
return 0;
}
number = parseFloat(number.replace(',',''));
return number;
}else{
return 0;
}
}
function get_col_percent_or_decimal(col){
var cells_decimal = 0;
var cells_percent = 0;
var c = 0;
var maxc = col.length;
for(c=0;c<maxc;c++){
var val = get_cell_num_val($(col[c])); // Is this correct, $(col[c]) ??? Even though already jQuery object?
if(val > 1 && val <= 100){
cells_percent++;
}else if(val <= 1){
cells_decimal++;
}
return (cells_decimal > cells_percent) ? 'decimal' : 'percent';
}
}
// get color in rgba, change a as needed
function val_to_rgba(color, decimal_percent){
// match to get 3 numbers (if four, remove 4th
if(~color.indexOf('#')){
// color is hex. Convert first or send warning
}
var rgb_vals = color.match(/\d+/g);
if(rgb_vals.length !== 3){
if(rgb_vals.length > 3){
// remove 4th val
}else if(rgb_vals.length === 1){
// probably hex, either convert or send error
}
}
var rgba = '('+rgb_vals.join(', ') + ', ' + decimal_percent + ')';
return rgba;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment