google.charts.load('current', {packages: ['corechart', 'bar', 'gauge', 'scatter']});
var wpDataTablesGoogleChart = function(){
var obj = {
rows: [],
columns: [],
type: 'column',
containerId: 'google-chart-container',
columnIndexes: [],
connectedWPDataTable: null,
chart: null,
googleDataTable: null,
renderCallback: null,
options: {
animation: {
duration: 1000,
easing: 'out',
startup: true
},
backgroundColor: {
fill: '#FFFFFF',
strokeWidth: 0,
stroke: '#666',
rx: 0
},
chartArea: {
backgroundColor: {
}
},
crosshair: {
},
curveType: 'none',
fontName: 'Arial',
fontSize: null,
hAxis: {
direction: 1
},
height: 400,
legend: {
position: 'right'
},
orientation: 'horizontal',
titlePosition: 'out',
tooltip: {
trigger: 'focus'
},
vAxis: {
direction: 1,
viewWindow: {
}
}
},
setRows: function( rows ){
this.rows = rows;
},
enableDateTimeAxis: function(){
this.options.hAxis.gridlines = {
count: -1,
units: {
days: {format: ['MMM dd']},
hours: {format: ['HH:mm', 'ha']}
}
}
},
detectDates: function(){
for( var i in this.columns ){
if( this.columns[i].type == 'date' || this.columns[i].type == 'datetime' ){
for( var j in this.rows ){
var remDate = Date.parse( this.rows[j][i] );
if( isNaN(remDate) ){
this.rows[j][i] = new Date();
}else{
this.rows[j][i] = new Date(remDate);
if( this.connectedWPDataTable == null ){
var timeVal = this.rows[j][i].getTime();
if( this.columns[i].type == 'datetime' ){
timeVal += this.rows[j][i].getTimezoneOffset()*60*1000;
}
this.rows[j][i].setTime( timeVal );
} else {
this.rows[j][i].setTime( this.rows[j][i].getTime() );
}
}
if( this.columns[i].type == 'datetime' ){
this.enableDateTimeAxis();
}
}
}
}
},
setColumns: function( columns ){
this.columns = columns;
},
getColumns: function(){
return this.columns;
},
setOptions: function( options ){
for( var i in options ){
if( i == 'responsive_width' && options[i] == '1' ){
obj.options.animation = false;
jQuery(window).resize(function(){
obj.chart.draw( obj.googleDataTable, obj.options );
});
continue;
}
this.options[i] = options[i];
}
},
getOptions: function(){
return this.options;
},
setType: function( type ){
this.type = type;
},
getType: function(){
return this.type;
},
setGrouping: function( group_chart ){
this.group_chart = group_chart;
},
setContainer: function( containerId ){
this.containerId = containerId;
},
getContainer: function(){
return this.containerId;
},
setRenderCallback: function( callback ){
this.renderCallback = callback;
},
render: function(){
if( typeof google.visualization !== 'undefined' && typeof google.visualization.DataTable !== 'undefined') {
this.googleDataTable = new google.visualization.DataTable();
for (var i in this.columns) {
if (!isNaN(i))
this.googleDataTable.addColumn(this.columns[i]);
}
this.detectDates();
this.googleDataTable.addRows(this.rows);
switch (this.type) {
case 'google_column_chart':
this.chart = new google.visualization.ColumnChart(document.getElementById(this.containerId));
break;
case 'google_histogram':
this.chart = new google.visualization.Histogram(document.getElementById(this.containerId));
break;
case 'google_bar_chart':
this.options.orientation = 'vertical';
this.chart = new google.visualization.BarChart(document.getElementById(this.containerId));
break;
case 'google_stacked_bar_chart':
this.options.orientation = 'vertical';
this.options.isStacked = true;
this.chart = new google.visualization.BarChart(document.getElementById(this.containerId));
break;
case 'google_area_chart':
this.chart = new google.visualization.AreaChart(document.getElementById(this.containerId));
break;
case 'google_stepped_area_chart':
this.options.isStacked = true;
this.chart = new google.visualization.SteppedAreaChart(document.getElementById(this.containerId));
break;
case 'google_line_chart':
this.chart = new google.visualization.LineChart(document.getElementById(this.containerId));
break;
case 'google_pie_chart':
this.chart = new google.visualization.PieChart(document.getElementById(this.containerId));
break;
case 'google_bubble_chart':
this.chart = new google.visualization.BubbleChart(document.getElementById(this.containerId));
break;
case 'google_donut_chart':
this.options.pieHole = 0.4;
this.chart = new google.visualization.PieChart(document.getElementById(this.containerId));
break;
case 'google_gauge_chart':
this.options.redFrom = 90;
this.options.redTo = 100;
this.options.yellowFrom = 75;
this.options.yellowTo = 90;
this.options.minorTicks = 5;
this.chart = new google.visualization.Gauge(document.getElementById(this.containerId));
break;
case 'google_scatter_chart':
this.chart = new google.visualization.ScatterChart(document.getElementById(this.containerId));
break;
case 'google_candlestick_chart':
this.options.legend = 'none';
this.chart = new google.visualization.CandlestickChart(document.getElementById(this.containerId));
break;
case 'google_waterfall_chart':
this.options.legend = 'none';
this.options.bar = {groupWidth: '100%'};
this.options.candlestick = {
fallingColor: {strokeWidth: 0, fill: '#a52714'}, // red
risingColor: {strokeWidth: 0, fill: '#0f9d58'} // green
};
this.chart = new google.visualization.CandlestickChart(document.getElementById(this.containerId));
break;
}
if (this.renderCallback !== null) {
this.renderCallback(this);
}
this.chart.draw(this.googleDataTable, this.options);
}
},
refresh: function(){
if( typeof google.visualization !== 'undefined' && typeof google.visualization.DataTable !== 'undefined' && this.chart != null ){
this.googleDataTable = new google.visualization.DataTable();
for( var i in this.columns ){
if (!isNaN(i))
this.googleDataTable.addColumn( this.columns[i] );
}
this.detectDates();
this.googleDataTable.addRows( this.rows );
if( this.renderCallback !== null ){
this.renderCallback( this );
}
this.chart.draw( this.googleDataTable, this.options );
}
},
setConnectedWPDataTable: function( wpDataTable ){
this.connectedWPDataTable = wpDataTable;
},
getConnectedWPDataTable: function(){
return this.connectedWPDataTable;
},
setChartConfig: function(chartConfig) {
// Chart
if (chartConfig.responsive_width == 1) {
this.options.animation = false;
delete this.options.width;
jQuery(window).resize(function(){
obj.chart.draw( obj.googleDataTable, obj.options );
});
} else {
this.options.width = chartConfig.width;
}
chartConfig.height ? this.options.height = chartConfig.height : null;
this.options.backgroundColor.fill = chartConfig.background_color;
chartConfig.border_width ? this.options.backgroundColor.strokeWidth = chartConfig.border_width : null;
this.options.backgroundColor.stroke = chartConfig.border_color;
chartConfig.border_radius ? this.options.backgroundColor.rx = chartConfig.border_radius : null;
chartConfig.border_radius ? this.options.backgroundColor.rx = chartConfig.border_radius : null;
this.options.chartArea.backgroundColor.fill = chartConfig.plot_background_color;
chartConfig.plot_border_width ? this.options.chartArea.backgroundColor.strokeWidth = chartConfig.plot_border_width : null;
this.options.chartArea.backgroundColor.stroke = chartConfig.plot_border_color;
chartConfig.font_size ? this.options.fontSize = chartConfig.font_size : null;
chartConfig.font_name ? this.options.fontName = chartConfig.font_name : null;
if (chartConfig.chart_type == 'google_pie_chart'){
chartConfig.three_d == 1 ? this.options.is3D = true : this.options.is3D = false;
}
// Series
var j = 0;
for (var i in chartConfig.series_data) {
this.columns[j+1].label = chartConfig.series_data[i].label;
if (chartConfig.series_data[i].color != ''){
this.options.series[j] = {
color: chartConfig.series_data[i].color
};
}
j++;
}
if (chartConfig.chart_type == 'google_line_chart'){
chartConfig.curve_type == 1 ? this.options.curveType = 'function' : this.options.curveType = 'none';
}
// Axes
if (chartConfig.show_grid == 0) {
this.options.hAxis.gridlines = {
color: 'transparent'
};
this.options.vAxis.gridlines = {
color: 'transparent'
};
} else {
delete this.options.hAxis.gridlines;
delete this.options.vAxis.gridlines;
}
chartConfig.horizontal_axis_label ? this.options.hAxis.title = chartConfig.horizontal_axis_label : null;
if (chartConfig.horizontal_axis_crosshair == 1 && chartConfig.vertical_axis_crosshair == 0) {
this.options.crosshair = {
trigger: 'both',
orientation: 'horizontal'
}
} else if (chartConfig.horizontal_axis_crosshair == 0 && chartConfig.vertical_axis_crosshair == 1) {
this.options.crosshair = {
trigger: 'both',
orientation: 'vertical'
}
} else if (chartConfig.horizontal_axis_crosshair == 1 && chartConfig.vertical_axis_crosshair == 1) {
this.options.crosshair = {
trigger: 'both',
orientation: 'both'
}
} else {
this.options.crosshair = {}
}
chartConfig.horizontal_axis_direction ? this.options.hAxis.direction = chartConfig.horizontal_axis_direction : null;
chartConfig.vertical_axis_label ? this.options.vAxis.title = chartConfig.vertical_axis_label : null;
chartConfig.vertical_axis_direction ? this.options.vAxis.direction = chartConfig.vertical_axis_direction : null;
this.options.vAxis.viewWindow.min = chartConfig.vertical_axis_min;
this.options.vAxis.viewWindow.max= chartConfig.vertical_axis_max;
chartConfig.inverted == 1 ? this.options.orientation = 'vertical' : this.options.orientation = 'horizontal';
// Title
chartConfig.show_title == 1 ? this.options.title = chartConfig.chart_title : this.options.title = '';
chartConfig.title_floating == 1 ? this.options.titlePosition = 'in' : this.options.titlePosition = 'out';
// Tooltip
chartConfig.tooltip_enabled == 1 ? this.options.tooltip.trigger = 'focus' : this.options.tooltip.trigger = 'none';
// Legend
chartConfig.legend_position ? this.options.legend.position = chartConfig.legend_position : null;
if (chartConfig.legend_vertical_align == 'bottom') {
this.options.legend.alignment = 'end';
} else if (chartConfig.legend_vertical_align == 'middle') {
this.options.legend.alignment = 'center';
} else {
this.options.legend.alignment = 'start';
}
},
enableFollowFiltering: function(){
if( this.connectedWPDataTable == null ){ return; }
this.connectedWPDataTable.fnSettings().aoDrawCallback.push({
sName: 'chart_filter_follow',
fn: function( oSettings ){
var rowsToRender = [];
obj.options.animation = false;
var filteredData = obj.connectedWPDataTable._('tr', {"filter": "applied"}).toArray();
var dateSettingsFormat = JSON.parse( jQuery( '#'+obj.connectedWPDataTable.data('described-by') ).val() ).datepickFormat;
var timeSettingsFormat = JSON.parse( jQuery( '#'+obj.connectedWPDataTable.data('described-by') ).val() ).timeFormat;
var momentDateFormat = dateSettingsFormat.replace('dd', 'DD').replace('M', 'MMM').replace('mm', 'MM').replace('yy', 'YYYY');
var momentTimeFormat = timeSettingsFormat.replace('H', 'H').replace('i', 'mm');
var momentDateTimeFormat = momentDateFormat + ' ' + momentTimeFormat;
var numberFormat = JSON.parse( jQuery( '#'+obj.connectedWPDataTable.data('described-by') ).val() ).number_format;
for( var i in filteredData ){
var rowEntry = [];
for( var j in obj.columnIndexes ) {
if (obj.columns[j].type == 'number') {
var value = filteredData[i][obj.columnIndexes[j]];
if (isNaN(value)) {
if (numberFormat == 1) {
var thousandsSeparator = '.';
var decimalSeparator = ',';
} else {
var thousandsSeparator = ',';
var decimalSeparator = '.';
}
value = wdtUnformatNumber(value, thousandsSeparator, decimalSeparator, true);
}
rowEntry.push(parseFloat(value));
} else if (obj.columns[j].type == 'date') {
rowEntry.push( moment( filteredData[i][obj.columnIndexes[j]], momentDateFormat ).toDate() );
} else if( obj.columns[j].type == 'datetime' ){
rowEntry.push( moment( filteredData[i][obj.columnIndexes[j]], momentDateTimeFormat ).toDate() );
obj.enableDateTimeAxis();
} else {
rowEntry.push( filteredData[i][obj.columnIndexes[j]] );
}
}
rowsToRender.push( rowEntry );
}
if ( obj.group_chart == 1 ) {
var output = [];
for (var i in rowsToRender){
if (typeof output !== 'undefined' && output.length > 0) {
var value_key = 'none';
for(var j in output){
if(value_key === 'none'){
if(output[j][0].toString() == rowsToRender[i][0].toString()){
value_key = j;
}
}
}
if (value_key === 'none') {
output.push(rowsToRender[i]);
} else {
for(var n in rowsToRender[i]) {
if( n != 0){
output[value_key][n] += rowsToRender[i][n];
}
}
}
} else {
output.push(rowsToRender[i]);
}
}
rowsToRender = output;
}
obj.rows = rowsToRender;
obj.refresh();;
}
});
},
setColumnIndexes: function( columnIndexes ){
this.columnIndexes = columnIndexes;
},
getColumnIndexes: function(){
return this.columnIndexes;
}
};
return obj;
};
|