How to adjust the dynamics of a date range dynamically and redraw a Google chart?

I use PHP to set the date range to create a Google ruler chart. For each date in the range, a variable ($ running_balance) is set to create points on the line chart using the data in the database. I would like to be able to set the $ end variable, which essentially determines the date range, dynamically, but I'm not sure how to do this so that the chart is redrawn in accordance with this new range. I know that I could create a new function that includes drawChart(); to redraw the chart, and I would use three buttons to set the date range to 1 year, 3 months or 1 month, but I'm not sure how to put it all together. Here is the code I have:

 $begin = new DateTime(date('Ym-d', strtotime('+1 days'))); $end = new DateTime(date('Ym-d', strtotime('+365 days'))); $interval = DateInterval::createFromDateString('1 day'); $period = new DatePeriod($begin, $interval, $end); foreach ( $period as $dt ) { $date_display = $dt->format("D j M"); ..... code to generate $running_balance ..... $temp = array(); $temp[] = array('v' => (string) $date_display); $temp[] = array('v' => (string) $running_balance); $temp[] = array('v' => (string) $running_balance); $rows[] = array('c' => $temp); } $table['rows'] = $rows; $jsonTable = json_encode($table); <script type="text/javascript"> // Load the Visualization API and the piechart package. google.load('visualization', '1', {'packages':['corechart']}); // Set a callback to run when the Google Visualization API is loaded. google.setOnLoadCallback(drawChart); var table = <?php echo $jsonTable; ?>; function drawChart() { var data = new google.visualization.DataTable(table); // Create our data table out of JSON data loaded from server. // var data = new google.visualization.DataTable(<?=$jsonTable?>); var formatter = new google.visualization.NumberFormat({fractionDigits:2,prefix:'\u00A3'}); formatter.format(data, 1); var options = { pointSize: 5, legend: 'none', hAxis: { showTextEvery:31 }, series: {0:{color:'2E838F',lineWidth:2}}, chartArea: {left:50,width:"95%",height:"80%"}, backgroundColor: '#F7FBFC', height: 400 }; // Instantiate and draw our chart, passing in some options. //do not forget to check ur div ID var chart = new google.visualization.LineChart(document.getElementById('chart_div')); chart.draw(data, options); } </script> 
+7
source share
1 answer

Well, if I understand you correctly, you have problems understanding and concretizing which parts of these actions are server-side (PHP) and which parts are client-side (Javascript), and then the client-server communication strategy. This is the overall speed. There are several ways to handle this.

First (and less preferably) you can create a form and reload the entire page with a new date range:

 // we're looking for '+1 year', '+3 months' or '+1 month'. if someone really // wants to send another value here, it not likely to be a security risk // but know your own application and note that you might want to validate $range = isset($_GET['range'])&&$_GET['range']?$_GET['range']:'+1 year'; $begin = new DateTime(date('Ym-d', strtotime('+1 days'))); $end = new DateTime(date('Ym-d', strtotime($range))); // ... the rest of your code to build the chart. ?> <form action="<?= $_SERVER['PHP_SELF']; ?>" method="get"> <select name="range" size="1"> <option value="+1 year">1 year</option> <option value="+3 months">3 months</option> <option value="+1 month">1 month</option> </select> <input type="submit" name="action" value="Redraw Chart"> </form> 

... the reason why it is less preferable is that it causes a full page refresh.

If you want to avoid refreshing the entire page, you are doing pretty much the same thing, but you are doing it with ajax. The setup is almost identical, with only a few minor changes:

 // between building the data table and the javascript to build the chart... $jsonTable = json_encode($table); if (isset($_GET['ajax']) && $_GET['ajax']) { echo json_encode(array('table' => $table)); exit; } // remainder of your code, then our new form from above ?> <form id="redraw_chart_form" action="<?= $_SERVER['PHP_SELF']; ?>" data-ajaxaction="forecast.php" method="get"> <? foreach ($_GET as $key => $val) { ?> <input type="hidden" name="<?= $key; ?>" value="<?= $val; ?>"> <? } ?> <input type="hidden" name="ajax" id="redraw_chart_form_ajax" value="0"> <select name="range" size="1"> <option value="+1 year">1 year</option> <option value="+3 months">3 months</option> <option value="+1 month">1 month</option> </select> <input type="submit" name="action" value="Redraw Chart"> </form> <script> // I'm assuming you've got jQuery installed, if not there are // endless tutorials on running your own ajax query $('#redraw_chart_form').submit(function(event) { event.preventDefault(); // this stops the form from processing normally $('#redraw_chart_form_ajax').val(1); $.ajax({ url: $(this).attr('data-ajaxaction'), type: $(this).attr('method'), data: $(this).serialize(), complete: function() { $('#redraw_chart_form_ajax').val(0); }, success: function(data) { // referring to the global table... table = data.table; drawChart(); }, error: function() { // left as an exercise for the reader, if ajax // fails, attempt to submit the form normally // with a full page refresh. } }); return false; // if, for whatever reason, the preventDefault from above didn't prevent form processing, this will }); </script> 

Edit for clarity:

  • Remember to use the following code block from the first example (page refresh), otherwise you are not using the form at all:

    $range = isset($_GET['range'])&&$_GET['range']?$_GET['range']:'+1 year';

    $begin = new DateTime(date('Ym-d', strtotime('+1 days')));

    $end = new DateTime(date('Ym-d', strtotime($range)));

  • Ajax will only work if the data you send back is a json-encoded block, which means that your charting data must be at the top of the script before any HTML output is run, including your page template. If you can’t put the charting code at the top of the script, then you will need to add it to a whole separate script, which all it does is calculate the data for the chart, and then you can let it return ajax data without all the rest of the HTML on the page . If you cannot do any of these things, you just need to disable the Ajax bit and refresh the whole page.


Edit 2: I added the data-ajaxaction to the <form> element, this is a user-defined attribute that I created to provide another action only for ajax. I also changed the call to $.ajax() to use this attribute, not the action attribute.

+7
source

All Articles