Mike Caskey
2016-08-24 16:47:59 UTC
I use a CSV file to populate a bar chart. The file has a header row and
about 80 rows of data - far too many for the bar chart to display nicely at
once. So I added pagination from this jsFiddle
<http://jsfiddle.net/6FQSJ/1/>- and it works great!
However, I also need to use a string filter ControlWrapper in order to find
data quickly. Incidentally, the 80-row CSV will likely increase to about
750, so both pagination and filtering are necessary. The filter and chart
have a bind between them and both are linked via a dashboard object.
My problem is, that when the string filter is used, it causes errors with
pagination and the chart fails to redraw. I assume that the DataTable
object is decreasing in size during the filter process, but the pagination
function doesn't get "refreshed" until I physically click the NEXT button
then the PREV button on the page, nor does the chart show the appropriate
data until pagination is clicked again and again.
Here's my code thus far (sample data attached):
<html>
<head>
<title>Embedded Charts - Ex5 (CSV array, Dashboard and String
Filter)</title>
<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
<!-- Required: Load jQuery library -->
<script src="http://code.jquery.com/jquery-1.10.1.min.js"></script>
<!-- Required: Google Visualization library -->
<script type="text/javascript" src="js/gviz-api.js"></script>
<!-- Optional: Google Geochart and Map Chart libraries -->
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
<!-- Load the AJAX API-->
<script type="text/javascript"
src="https://www.gstatic.com/charts/loader.js"></script>
<!-- Load CSV parser -->
<script type="text/javascript" src="js/jquery.csv.js"></script>
<script type="text/javascript">
// Load the Visualization API and the controls package.
google.charts.load('44', {'packages':['corechart','controls']});
// Set a callback to run when the Google Visualization API is loaded.
google.charts.setOnLoadCallback(drawChart);
// Callback that creates and populates a data table,
// instantiates a dashboard, a range slider and a pie chart,
// passes in the data and draws it.
function drawChart() {
// grab the CSV
$.get("http://localhost/dev/data/sample-data-csv.csv", function(csvString){
// transform the csv into a 2-dimmensional arrayToDataTable
var arrayData = $.csv.toArrays(csvString, {onParseValue:
$.csv.hooks.castToScalar});
// Built a new DataTable from the object arrayData
var data = new google.visualization.DataTable();
data.addColumn('string','Alias');
data.addColumn('number','Amount');
for (var i = 1; i < arrayData.length; i++) {
var v1 = arrayData[i][0];
var v2 = arrayData[i][2];
data.addRow([v1,v2]);
}
// Dashboard objects test
var dashboard = new
google.visualization.Dashboard(document.getElementById('dashboard_div'));
var rangeFilter = new google.visualization.ControlWrapper({
'controlType':'StringFilter',
'containerId':'control_div',
// set control options
'options':{
'filterColumnLabel':'Alias',
'matchType':'prefix',
'caseSensitive':false,
'useFormattedValue':false,
'ui':{
label:'Filter by Alias',
labelSeparator:':',
cssClass:'gviz-ui',
labelStacking:'horizontal'
},
}
});
var barChart = new google.visualization.ChartWrapper({
'chartType':'BarChart',
'containerId':'chart_div',
'dataTable':data,
// set chart options
'options':{
// pagination - does not work(?)
showRowNumber:true,
page:'enable',
pageSize:20,
pagingSymbols:{prev:'Prev', next:'Next'},
//pagingButtonsConfiguration:'auto',
// chart options
width:640,
height:640,
legend:'none',
//view:{'columns':[0,2]},
hAxis: {
title:data.getColumnLabel(1),
minValue:data.getColumnRange(1).min,
maxValue:data.getColumnRange(1).max
},
vAxis: {
title:data.getColumnLabel(0),
minValue:data.getColumnRange(0).min,
maxValue:data.getColumnRange(0).max
},
colors:['333333'],
title:'Amount by Alias',
titleTestStyle:{color:'#ddd', bold:true, fontSize:18},
},
});
// Pagination function binding - src: http://jsfiddle.net/6FQSJ/1/
EnablePagination(barChart, 10, document.getElementById('prevButton'),
document.getElementById('nextButton'));
// Bind wrappers and draw chart
dashboard.bind(rangeFilter, barChart);
dashboard.draw(data);
});
}
function EnablePagination(chart, ps, prevButton, nextButton) {
var currentPage = -1;
var pageSize = ps;
// pad the datatable to have an exact number of pages, otherwise the bars'
size in the
// last page will be artificially increased
var dt = chart.getDataTable();
if (dt.getNumberOfRows() % pageSize != 0) {
for (var i = pageSize - (dt.getNumberOfRows() % pageSize); i > 0; i--) {
dt.addRow(['', 0]);
}
}
var paginate = function(dir) {
var numRows = chart.getDataTable().getNumberOfRows();
currentPage += dir;
var rows = [];
for (var i = pageSize*currentPage; i < pageSize*(currentPage+1) && i <
numRows; i++) {
rows.push(i);
}
chart.setView({rows: rows});
chart.draw();
currentPage == 0 ? prevButton.setAttribute('disabled', 'disabled') :
prevButton.removeAttribute('disabled');
currentPage == numRows/pageSize-1 ? nextButton.setAttribute('disabled',
'disabled') : nextButton.removeAttribute('disabled');
}
prevButton.onclick = function() { paginate(-1) };
nextButton.onclick = function() { paginate(1) };
paginate(1);
}
</script>
<style>
.gviz-ui {font-size:10pt; vertical-align:middle;}
.gviz-ui .goog-inline-block input[id*="input"] {text-transform:uppercase
!important;}
</style>
</head>
<body>
<div id="dashboard_div">
<div id="control_div"></div>
<div id="chart_div"></div>
<button id="prevButton">Prev</button>
<button id="nextButton">Next</button>
</div>
</body>
<script>
/*$(document).ready(function() {*/
// Set input max length
jQuery('#7-input').attr('maxLength', 4).keypress(drawChart);
// Add function call on input keypress
/*$('#7-input').keypress(function(){
drawChart();
});*/
/*}); */
</script>
</html>
This screen cap is the error i see using Chrome:
<Loading Image...
>
The chart should automatically redraw and show 3 valid rows, but doesn't
until I click (unseen) "Next" button, then the "Prev" button and the chart
looks right.
<Loading Image...
>
What am I missing? I don't thin I can BIND the StringFilter control to the
pagination function. I though about having a "keypress" event call the
drawChart() function but it doesn't respond to my jQuery calls.
Thanks for any help you can provide.
about 80 rows of data - far too many for the bar chart to display nicely at
once. So I added pagination from this jsFiddle
<http://jsfiddle.net/6FQSJ/1/>- and it works great!
However, I also need to use a string filter ControlWrapper in order to find
data quickly. Incidentally, the 80-row CSV will likely increase to about
750, so both pagination and filtering are necessary. The filter and chart
have a bind between them and both are linked via a dashboard object.
My problem is, that when the string filter is used, it causes errors with
pagination and the chart fails to redraw. I assume that the DataTable
object is decreasing in size during the filter process, but the pagination
function doesn't get "refreshed" until I physically click the NEXT button
then the PREV button on the page, nor does the chart show the appropriate
data until pagination is clicked again and again.
Here's my code thus far (sample data attached):
<html>
<head>
<title>Embedded Charts - Ex5 (CSV array, Dashboard and String
Filter)</title>
<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
<!-- Required: Load jQuery library -->
<script src="http://code.jquery.com/jquery-1.10.1.min.js"></script>
<!-- Required: Google Visualization library -->
<script type="text/javascript" src="js/gviz-api.js"></script>
<!-- Optional: Google Geochart and Map Chart libraries -->
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
<!-- Load the AJAX API-->
<script type="text/javascript"
src="https://www.gstatic.com/charts/loader.js"></script>
<!-- Load CSV parser -->
<script type="text/javascript" src="js/jquery.csv.js"></script>
<script type="text/javascript">
// Load the Visualization API and the controls package.
google.charts.load('44', {'packages':['corechart','controls']});
// Set a callback to run when the Google Visualization API is loaded.
google.charts.setOnLoadCallback(drawChart);
// Callback that creates and populates a data table,
// instantiates a dashboard, a range slider and a pie chart,
// passes in the data and draws it.
function drawChart() {
// grab the CSV
$.get("http://localhost/dev/data/sample-data-csv.csv", function(csvString){
// transform the csv into a 2-dimmensional arrayToDataTable
var arrayData = $.csv.toArrays(csvString, {onParseValue:
$.csv.hooks.castToScalar});
// Built a new DataTable from the object arrayData
var data = new google.visualization.DataTable();
data.addColumn('string','Alias');
data.addColumn('number','Amount');
for (var i = 1; i < arrayData.length; i++) {
var v1 = arrayData[i][0];
var v2 = arrayData[i][2];
data.addRow([v1,v2]);
}
// Dashboard objects test
var dashboard = new
google.visualization.Dashboard(document.getElementById('dashboard_div'));
var rangeFilter = new google.visualization.ControlWrapper({
'controlType':'StringFilter',
'containerId':'control_div',
// set control options
'options':{
'filterColumnLabel':'Alias',
'matchType':'prefix',
'caseSensitive':false,
'useFormattedValue':false,
'ui':{
label:'Filter by Alias',
labelSeparator:':',
cssClass:'gviz-ui',
labelStacking:'horizontal'
},
}
});
var barChart = new google.visualization.ChartWrapper({
'chartType':'BarChart',
'containerId':'chart_div',
'dataTable':data,
// set chart options
'options':{
// pagination - does not work(?)
showRowNumber:true,
page:'enable',
pageSize:20,
pagingSymbols:{prev:'Prev', next:'Next'},
//pagingButtonsConfiguration:'auto',
// chart options
width:640,
height:640,
legend:'none',
//view:{'columns':[0,2]},
hAxis: {
title:data.getColumnLabel(1),
minValue:data.getColumnRange(1).min,
maxValue:data.getColumnRange(1).max
},
vAxis: {
title:data.getColumnLabel(0),
minValue:data.getColumnRange(0).min,
maxValue:data.getColumnRange(0).max
},
colors:['333333'],
title:'Amount by Alias',
titleTestStyle:{color:'#ddd', bold:true, fontSize:18},
},
});
// Pagination function binding - src: http://jsfiddle.net/6FQSJ/1/
EnablePagination(barChart, 10, document.getElementById('prevButton'),
document.getElementById('nextButton'));
// Bind wrappers and draw chart
dashboard.bind(rangeFilter, barChart);
dashboard.draw(data);
});
}
function EnablePagination(chart, ps, prevButton, nextButton) {
var currentPage = -1;
var pageSize = ps;
// pad the datatable to have an exact number of pages, otherwise the bars'
size in the
// last page will be artificially increased
var dt = chart.getDataTable();
if (dt.getNumberOfRows() % pageSize != 0) {
for (var i = pageSize - (dt.getNumberOfRows() % pageSize); i > 0; i--) {
dt.addRow(['', 0]);
}
}
var paginate = function(dir) {
var numRows = chart.getDataTable().getNumberOfRows();
currentPage += dir;
var rows = [];
for (var i = pageSize*currentPage; i < pageSize*(currentPage+1) && i <
numRows; i++) {
rows.push(i);
}
chart.setView({rows: rows});
chart.draw();
currentPage == 0 ? prevButton.setAttribute('disabled', 'disabled') :
prevButton.removeAttribute('disabled');
currentPage == numRows/pageSize-1 ? nextButton.setAttribute('disabled',
'disabled') : nextButton.removeAttribute('disabled');
}
prevButton.onclick = function() { paginate(-1) };
nextButton.onclick = function() { paginate(1) };
paginate(1);
}
</script>
<style>
.gviz-ui {font-size:10pt; vertical-align:middle;}
.gviz-ui .goog-inline-block input[id*="input"] {text-transform:uppercase
!important;}
</style>
</head>
<body>
<div id="dashboard_div">
<div id="control_div"></div>
<div id="chart_div"></div>
<button id="prevButton">Prev</button>
<button id="nextButton">Next</button>
</div>
</body>
<script>
/*$(document).ready(function() {*/
// Set input max length
jQuery('#7-input').attr('maxLength', 4).keypress(drawChart);
// Add function call on input keypress
/*$('#7-input').keypress(function(){
drawChart();
});*/
/*}); */
</script>
</html>
This screen cap is the error i see using Chrome:
<Loading Image...
The chart should automatically redraw and show 3 valid rows, but doesn't
until I click (unseen) "Next" button, then the "Prev" button and the chart
looks right.
<Loading Image...
What am I missing? I don't thin I can BIND the StringFilter control to the
pagination function. I though about having a "keypress" event call the
drawChart() function but it doesn't respond to my jQuery calls.
Thanks for any help you can provide.
--
You received this message because you are subscribed to the Google Groups "Google Visualization API" group.
To unsubscribe from this group and stop receiving emails from it, send an email to google-visualization-api+***@googlegroups.com.
To post to this group, send email to google-visualization-***@googlegroups.com.
Visit this group at https://groups.google.com/group/google-visualization-api.
To view this discussion on the web visit https://groups.google.com/d/msgid/google-visualization-api/3330276b-d7ee-4a57-8cd9-a565115fe48a%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
You received this message because you are subscribed to the Google Groups "Google Visualization API" group.
To unsubscribe from this group and stop receiving emails from it, send an email to google-visualization-api+***@googlegroups.com.
To post to this group, send email to google-visualization-***@googlegroups.com.
Visit this group at https://groups.google.com/group/google-visualization-api.
To view this discussion on the web visit https://groups.google.com/d/msgid/google-visualization-api/3330276b-d7ee-4a57-8cd9-a565115fe48a%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.