276 lines
6.8 KiB
JavaScript
276 lines
6.8 KiB
JavaScript
/* Widget: chart (beta) - updated 10/31/2015 (v2.24.0) *//*
|
|
* Requires tablesorter v2.8+ and jQuery 1.7+
|
|
*/
|
|
/*jshint browser:true, jquery:true, unused:false */
|
|
/*global jQuery: false */
|
|
;(function($) {
|
|
'use strict';
|
|
|
|
var ts = $.tablesorter,
|
|
|
|
// temp variables
|
|
chart_cols = [],
|
|
chart_headers = [],
|
|
// google charts
|
|
chart_rows = [],
|
|
chart_data = [],
|
|
// highcharts
|
|
chart_categories = [],
|
|
chart_series = [],
|
|
// fusioncharts
|
|
chart_category = [],
|
|
chart_dataset = [],
|
|
|
|
chart = ts.chart = {
|
|
|
|
// regex used to strip out non-digit values before sending
|
|
// the string to the $.tablesorter.formatFloat function
|
|
nonDigit : /[^\d,.\-()]/g,
|
|
|
|
init: function(c, wo) {
|
|
c.$table
|
|
.off(wo.chart_event)
|
|
.on(wo.chart_event, function() {
|
|
if (this.hasInitialized) {
|
|
// refresh 'c' variable in case options are updated dynamically
|
|
var c = this.config;
|
|
chart.getCols(c, c.widgetOptions);
|
|
chart.getData(c, c.widgetOptions);
|
|
}
|
|
});
|
|
},
|
|
|
|
getCols: function(c, wo) {
|
|
var i;
|
|
chart_cols = [];
|
|
chart_series = [];
|
|
chart_dataset = [];
|
|
|
|
for ( i = 0; i < c.columns; i++ ) {
|
|
if ( wo.chart_useSelector && ts.hasWidget( c.table, 'columnSelector' ) && !c.selector.auto ) {
|
|
if ( ( c.selector.states[i] && $.inArray(i, wo.chart_ignoreColumns) < 0 ) ||
|
|
i === wo.chart_labelCol || i === wo.chart_sort[0][0] ) {
|
|
chart_cols.push(i);
|
|
}
|
|
} else {
|
|
if ( $.inArray(i, wo.chart_ignoreColumns) < 0 || i === wo.chart_labelCol || i === wo.chart_sort[0][0] ) {
|
|
chart_cols.push(i);
|
|
}
|
|
}
|
|
}
|
|
},
|
|
|
|
getData: function(c, wo) {
|
|
chart.getHeaders(c, wo);
|
|
chart.getRows(c, wo);
|
|
|
|
/* == Google data ==
|
|
array of arrays (Google charts)
|
|
[
|
|
[ "Year", "Sales", "Expenses" ],
|
|
[ "2004", 1000, 400 ],
|
|
[ "2005", 1170, 460 ],
|
|
[ "2006", 660, 1120 ],
|
|
[ "2007", 1030, 540 ]
|
|
]
|
|
|
|
== Highcharts ==
|
|
categories -> [ '2004', '2005', '2006', '2007' ]
|
|
series -> [{
|
|
name: 'Sales',
|
|
data: [ 1000, 1170, 660, 1030 ]
|
|
}, {
|
|
name: 'Expenses',
|
|
data: [ 400, 460, 1120, 540 ]
|
|
}]
|
|
|
|
== Fusioncharts
|
|
"categories": [{
|
|
"category": [
|
|
{"label": "2004"},
|
|
{"label": "2005"},
|
|
{"label": "2006"},
|
|
{"label": "2007"}
|
|
]
|
|
}],
|
|
"dataset": [
|
|
{
|
|
"seriesname": "Sales",
|
|
"data": [
|
|
{"value": "1000"},
|
|
{"value": "1170"},
|
|
{"value": "660"},
|
|
{"value": "1030"}
|
|
]
|
|
},{
|
|
"seriesname": "Expenses",
|
|
"data": [
|
|
{"value": "400"},
|
|
{"value": "600"},
|
|
{"value": "1120"},
|
|
{"value": "540"}
|
|
]
|
|
}
|
|
]
|
|
*/
|
|
|
|
chart_data = [ chart_headers ];
|
|
$.each(chart_rows, function(k, row) {
|
|
chart_data.push(row);
|
|
});
|
|
|
|
c.chart = {
|
|
// google
|
|
data: chart_data,
|
|
// highcharts
|
|
categories: chart_categories,
|
|
series: chart_series,
|
|
// FusionCharts
|
|
category: chart_category,
|
|
dataset: chart_dataset
|
|
};
|
|
},
|
|
|
|
getHeaders: function(c, wo) {
|
|
var text;
|
|
chart_headers = [];
|
|
chart_series = [];
|
|
chart_dataset = [];
|
|
chart_headers.push( c.headerContent[wo.chart_labelCol] );
|
|
$.each(chart_cols, function(k, col) {
|
|
if (col === wo.chart_labelCol) {
|
|
return true;
|
|
}
|
|
text = c.headerContent[col];
|
|
chart_headers.push( text );
|
|
chart_series.push( { name: text, data: [] } );
|
|
chart_dataset.push( { seriesname: text, data: [] } );
|
|
});
|
|
},
|
|
|
|
getRows: function(c, wo) {
|
|
var norm_rows = c.cache[0].normalized,
|
|
rows = [];
|
|
chart_rows = [];
|
|
chart_categories = [];
|
|
chart_category = [];
|
|
|
|
$.each(norm_rows, function(indx, rowVal) {
|
|
var i, txt,
|
|
$tr = rowVal[c.columns].$row,
|
|
$cells = $tr.children('th,td'),
|
|
row = [];
|
|
if (
|
|
(/v/i.test(wo.chart_incRows) && $tr.is(':visible')) ||
|
|
(/f/i.test(wo.chart_incRows) && !$tr.hasClass(wo.filter_filteredRow || 'filtered')) ||
|
|
(!/(v|f)/i.test(wo.chart_incRows))
|
|
) {
|
|
// Add all cols (don't mess up indx for sorting)
|
|
for (i = 0; i < c.columns; i++) {
|
|
if ( $.inArray(indx, wo.chart_parsed) >= 0 ) {
|
|
row.push( rowVal[i] );
|
|
} else {
|
|
txt = $cells[i].getAttribute( c.textAttribute ) || $cells[i].textContent || $cells.eq(i).text();
|
|
row.push( $.trim( txt ) );
|
|
}
|
|
}
|
|
rows.push(row);
|
|
}
|
|
});
|
|
|
|
// sort based on chart_sort
|
|
rows.sort(function(a, b) {
|
|
if ( wo.chart_sort[0][1] === 1 ) {
|
|
return ts.sortNatural( b[wo.chart_sort[0][0]], a[wo.chart_sort[0][0]] );
|
|
}
|
|
return ts.sortNatural( a[wo.chart_sort[0][0]], b[wo.chart_sort[0][0]] );
|
|
});
|
|
|
|
$.each(rows, function(i, rowVal) {
|
|
var value,
|
|
objIndex = 0,
|
|
row = [],
|
|
label = rowVal[wo.chart_labelCol];
|
|
|
|
row.push( '' + label );
|
|
|
|
$.each(rowVal, function(indx, cellValue) {
|
|
var tempVal;
|
|
if (indx === wo.chart_labelCol) {
|
|
chart_categories.push( cellValue );
|
|
chart_category.push({ 'label': cellValue });
|
|
return true;
|
|
}
|
|
value = false;
|
|
if ( wo.chart_useSelector && ts.hasWidget( c.table, 'columnSelector' ) && !c.selector.auto ) {
|
|
if ( c.selector.states[indx] && $.inArray(indx, wo.chart_ignoreColumns) < 0 ) {
|
|
value = '' + cellValue;
|
|
}
|
|
} else {
|
|
if ($.inArray(indx, wo.chart_ignoreColumns) < 0) {
|
|
value = '' + cellValue;
|
|
}
|
|
}
|
|
|
|
if (value !== false) {
|
|
if ( /s/i.test( '' + wo.chart_layout[indx] ) ) {
|
|
row.push( value );
|
|
chart_series[objIndex].data.push( value );
|
|
chart_dataset[objIndex].data.push( value );
|
|
} else {
|
|
// using format float, after stripping out all non-digit values
|
|
tempVal = ts.formatFloat( value.replace( chart.nonDigit, '' ), c.table );
|
|
tempVal = isNaN(tempVal) ? value : tempVal;
|
|
// if tempVal ends up being an empty string, fall back to value
|
|
row.push( tempVal );
|
|
chart_series[objIndex].data.push( tempVal );
|
|
chart_dataset[objIndex].data.push( { value : tempVal } );
|
|
}
|
|
objIndex++;
|
|
}
|
|
});
|
|
chart_rows.push(row);
|
|
});
|
|
},
|
|
|
|
remove: function(c, wo) {
|
|
c.$table.off(wo.chart_event);
|
|
}
|
|
|
|
};
|
|
|
|
ts.addWidget({
|
|
id: 'chart',
|
|
options: {
|
|
// (a)ll, (v)isible or (f)iltered - only the first letter is needed
|
|
chart_incRows: 'filtered',
|
|
// prefer columnSelector for ignoreColumns
|
|
chart_useSelector: false,
|
|
// columns to ignore [0, 1,... ] (zero-based index)
|
|
chart_ignoreColumns: [],
|
|
// Use parsed data instead of cell.text()
|
|
chart_parsed: [],
|
|
// data output layout, float is default
|
|
chart_layout: {
|
|
// first element is a string, all others will be float
|
|
0: 'string'
|
|
},
|
|
// Set the label column
|
|
chart_labelCol: 0,
|
|
// data sort, should always be first row, might want [[0,1]]
|
|
chart_sort: [ [ 0, 0 ] ],
|
|
// event to trigger get updated data
|
|
chart_event: 'chartData'
|
|
},
|
|
|
|
init: function(table, thisWidget, c, wo) {
|
|
chart.init(c, wo);
|
|
},
|
|
|
|
remove: function(table, c, wo) {
|
|
chart.remove(c, wo);
|
|
}
|
|
});
|
|
|
|
})(jQuery);
|