2013-04-07 8 views
7

Sto utilizzando PHP per impostare un intervallo di date per la creazione di un grafico a linee di Google. Per ogni data nell'intervallo viene impostata una variabile ($ running_balance) per creare i punti sul grafico a linee usando i dati in un database. Mi piacerebbe essere in grado di impostare la variabile $ end, che essenzialmente determina l'intervallo di date, in modo dinamico, ma non sono sicuro di come fare in modo che il grafico venga ridisegnato in base a questo nuovo intervallo. Sono consapevole che potrei creare una nuova funzione che includa lo drawChart(); per ridisegnare il grafico e utilizzerei tre pulsanti per impostare l'intervallo di date su 1 anno, 3 mesi o 1 mese, ma non sono sicuro di come mettere tutto questo insieme. Ecco il codice che ho attualmente:Come si imposta una variabile dell'intervallo di date in modo dinamico e si ridisegna un grafico di Google?

$begin = new DateTime(date('Y-m-d', strtotime('+1 days'))); 
$end = new DateTime(date('Y-m-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> 
+0

È necessario creare (almeno) due funzioni separate. La funzione # 1 recupererà i dati.La funzione # 2 chiamerà la funzione di recupero dei dati e disegnerà il grafico. Quando fai clic su un pulsante/cambia un menu a discesa, dovrebbe chiamare una funzione di gestione che otterrà i dati appropriati e la invierà alla funzione di disegno del grafico. Fondamentalmente, prendi la prima metà del tuo codice (prima di 'drawChart()') e consegnalo a una funzione che accetta il parametro $ end. Hai già provato qualcosa del genere? – jmac

risposta

7

OK, se ti sto comprensione correttamente, hai problemi a concepire e progettare quali parti di queste azioni sono lato server (PHP) e quali parti sono lato client (Javascript) e quindi la strategia di comunicazione client-server. Questo è un speedbump comune. Ci sono diversi modi per affrontarlo.

Prima (e meno preferito) è possibile creare un modulo e ricaricare l'intera pagina con il nuovo intervallo di date:

// we're looking for '+1 year', '+3 months' or '+1 month'. if someone really 
// wants to send another value here, it's 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('Y-m-d', strtotime('+1 days'))); 
$end = new DateTime(date('Y-m-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> 

... la ragione che è il meno preferito è perché provoca un intero aggiornamento di la pagina.

Se si desidera evitare un aggiornamento di una pagina intera, si sta praticamente facendo la stessa cosa, ma farlo con ajax. La messa a punto è quasi identico, solo un paio minore cambiamenti:

// 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> 

Modifica per chiarezza:

  1. Non dimenticare di utilizzare il seguente blocco di codice dalla prima (aggiornamento della pagina) esempio, altrimenti non si sta usando il modulo a tutti:

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

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

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

  2. Ajax funziona solo se i dati solo si sta inviando indietro è il JSON codificato blocco, il che significa che i dati dell'edificio grafico ha bisogno di essere al top dello script prima di qualsiasi L'output HTML viene avviato, incluso il modello di pagina. Se non è possibile inserire il codice di creazione del grafico nella parte superiore dello script, sarà necessario aggiungerlo a un intero script separato che tutto ciò che fa è calcolare i dati per il grafico e quindi è possibile farlo restituire il dati Ajax senza tutti gli altri HTML sulla pagina. Se non riesci a fare nessuna di queste cose, devi solo disattivare il bit Ajax e aggiornare la pagina intera.


Edit 2: ho aggiunto l'attributo data-ajaxaction all'elemento <form>, questo è un attributo definito dall'utente che feci per fornire un'azione diversa solo per ajax. Ho anche modificato la chiamata $.ajax() per utilizzare questo attributo anziché l'attributo action.

+0

Grazie. Sì, mi capisci correttamente, e sì, preferisco il metodo AJAX. Ho installato jQuery. Ho incluso il tuo codice sulla pagina, ma quando clicco sul pulsante 'Redraw Chart', sono reindirizzato all'URL 'http://www.finance.nickputman.com/?ajax=0&range=%2B1+year&action= Redraw + Chart' che mi mostra la mia home page, piuttosto che la pagina corrente che ha il seguente url: 'http: //www.finance.nickputman.com/? Page_id = 174'. Qualche idea per cui questo sta accadendo? – Nick

+0

OK, per prima cosa, nel tag modifica modulo 'action =" "' A 'action =" ? "'. Questo ti manterrà su 'page_id = 174', e correggendo * dovrebbe * far funzionare il modulo, solo con un aggiornamento della pagina. In secondo luogo, sembra che non stia eseguendo nessuno degli eventi onsubmit di jQuery. Cerca gli errori nella console javascript che impediscono l'esecuzione del javascript (se utilizzi Chrome, premi F12 e tocca la scheda "Console"). Prima di 'preventDefault()', metti 'alert ('debug');', controlla se gira. – Jason

+0

Grazie. L'errore jQuery è ''Semantic Issue - Expected token') '' su questa riga: 'url: $ (this) .attr (' action '),'. C'è ancora un problema con la stringa URL per l'azione modulo. Con la tua modifica suggerita, sono ancora reindirizzato alla home page. Se ometto ' '' '' 'dall'URL, quindi l'URL è corretto a parte l'inclusione del punto di domanda, ad esempio' http://www.finance.nickputman.com/page_id=174?ajax=0&range=%2B3+ mesi & action = Ridisegna + Chart'. – Nick

Problemi correlati