Auto Refresh Highcharts

Ciao a tutti,

Da poco mi sono affacciato al mondo di questo bellissimo framework e sono qui per chiedere un aiuto!!

In pratica ho un grafico creato con il widget highcharts e vorrei che ogni tot minuti si aggiornasse in automatico.

controll:


public function ActionUpdateAjax() {


	$query = Yii::app()->db->createCommand()

                ->select('campo1,campo2')

                ->from('TabellaMia')

                ->queryAll();




				$i = 0;

				foreach ($query as $key => $value)

					{

					$colore = "red";

					$c[]=array('name' => $query[$i]['Nome'],'y' => (double)$query[$i]['email'], 'color' => 'red' );

					$i++;

					}




		IF ($c == "") {

			$colore = "#66FF00";

			$c[]=array('name' => 'Servizio','y' => 30, 'color' => $colore );

		}

		

		$c["ciao"] = $c;

		$this->renderPartial('new2',$c, false, true);

new2:


$this->Widget('ext.highcharts.HighchartsWidget', array(

        'options'=>array( 

				#'chart'=> array('renderTo'=>'container'),

			

                'title' => array('text' => 'ALLARMI'),

         

                'credits' => array('enabled' => false),

                'exporting' => array('enabled' => false),

		'plotOptions' => array(

        'pie' => array(

			 'renderTo'=>'container',

            'allowPointSelect' => true,

            'cursor' => 'pointer',

            'dataLabels' => array(

            'enabled' => true,

            'color' => 'Black',

            'connectorColor' => 'green',

            'formatter' => "js:function(){return '<b>'+ this.point.name + ' </b>' + this.y + ' </b>' ;}",

            ),

        )

        ),

             'series' => array(array(

						'animation' => false,

						'name' => '%',

                        'type' => 'pie',

                        'data' => $ciao,

                   /* array(

                        'name' => array($c),

                        'y' => array($<img src='http://www.yiiframework.com/forum/public/style_emoticons/default/cool.gif' class='bbc_emoticon' alt='B)' />,

                        'color' => array($colore),

                    ),*/

					

        

                        

                ))

        )

));

view:


$url=$this->createUrl('web/UpdateAjax');




Yii::app()->clientScript->registerScript("refresh","

function updateData()

{

    $.ajax({

        'url':'".$url."',

        'success':function(data){

            $('#data').html(data);

            }        

        });

}


updateData();


var auto_refresh = setInterval(function(){

            updateData()

}, 10000);

");




?>


<div id="data" method="post" class="block-content"> 


</div>

Al primo refresh compare il grafico, ma al secondo giro scompare…!!

dove sbaglio??

grazie mille…

cosa intendi per il primo refresh?

mi spiego: se carichi la pagina, e dopo n secondi (primo refresh) appare il grafico, ma poi non appare più

oppure

se carichi, e dopo n secondi (primo refresh), NON appare il grafico nuovo, cioè lo vedi solo la prima volta

hai controllato l’error log vero?

Ciao a tutti

stavo per postare una domanda anch’io su highcharts ma temo che il problema sia lo stesso qui riportato, per cui mi accodo

io uso highcharts insieme ad ajax, praticamente uso una combobox per determinare la data di inizio di un certo grafico;

quando carico la pagina va tutto bene, nel senso che il grafico viene fuori correttamente

il problema arriva quando uso la combobox, che di fatto fa una chiamata ajax e ricarica il grafico:

non esce fuori nulla

credo che sia lo stesso tuo problema messo in un altro modo

analizzando la cosa ho scoperto che nel ricaricarsi highcharts rende un codice di errore 16, che vuol dire:

Highcharts already defined in the page

in effetti dentro la parte che ajax carica, generata automaticamente dal widget, trovo il tag script che include il js di highcharts (<script src="ecc.ecc…)

che presumo essere la causa del problema, in quanto lo stesso codice deve essere stato messo anche quando highcharts si pubblica come estensione

stando così le cose, ancora non ho trovato soluzione a questa situazione

qualcuno ha una soluzione?

se il mio problema non ha niente a che fare col tuo mi scuso e creo un nuovo topic :rolleyes:

allora, in generale per yii vale questa regola:

  • il js deve essere definito solo nella vista principale, questa ‘creata’ tramite $this->render, per intenderci

  • il js deve essere fatto in modo, in genere tramite eventi live jQuery, da poter funzionare anche su contenuti non ancora caricati, caso tipico in cui via ajax si carica qualcosa

A questo punto vi chiedo come/dove avete creato il grafico.

Se state cercando di caricare via ajax il risultato dell’esecuzione di un javascript dovete mettere a true l’opzione del renderPartial che permette l’esecuzione del javascript, però ciò non toglie che la libreria highcharts deve essere inclusa una sola volta e solo nella vista principale. un po’ come jquery, non potete reincluderla ‘n’ volte [cioè, con jQuey funzionerebbe anche, ma cercate di capirmi… ]

Grazie a tutti per le risposte.

Intedo: se carichi la pagina, e dopo n secondi (primo refresh) appare il grafico, ma poi non appare più

Il grafico è creato nella pagina new2.php richiamata dal renderpartial dal controller.

riesci a postarmi un esempio?

Grazie

mi spiace, ma non uso da nessuna parte i grafici fatti via js, perchè quasi sempre poi gli utenti mi chiedono “e se lo voglio salvare?”… o … “me lo puoi includere nel file excel con i dati” … e non ho di certo voglio di toccare le cose lato server per accontentare delle capre :)

Chiusa parentesi.

Per dare il via alla lunga e noiosa spiegazione, mi servirebbe sapere un dettaglio: tu usi highcahrts nudo e crudo come libreria js? o stai usando una estensione di yii ? perchè cambia moltissimo

Lo uso come estensione di Yii :rolleyes:

ah, ecco, sarà dura, vediamo come risolvere…

Dimmi se ho capito bene

controller

  • action che fa il render principale

  • via ajax viene chiamata una seconda action fa il renderPartial

  • dentro a questa view c’è il codice php di highcharts.

Prova questo, per capire cosa combina dietro le quinte l’estensione. Installa WebDeveloper, una estensione di firefox, se puoi. Lo scopo è, DOPO il secondo refresh (cioè a quel punto hai già l’errore js), cliccare sulla pagina col destro, scegliere view source -> view GENERATED source.

A quel punto dovresti verificare che dentro al sorgente html ‘generato’ in seguito ai refresh via ajax ci sono più tag script che includono la libreria di highcharts.

1° Scrivi all’autore e segnalagli il problema

2° Hai mai usato una libreria js a manina dentro yii? Perchè se si, beh, è la strada migliore…

3° A proposito: non sono un guru, non ho tutte le risposte, non vorrei deluderti ma in questo caso faccio fatica ad aiutarti. Ad ogni modo, verifica se il problema è la inclusione multipla della libreria

Ho fatto come mi hai detto, l’unica differenza prima e dopo il refresh e la seguente:

Prima:


  <div class="block-content">

        <form class="form" id="data" name="table_form" method="post" action="" style="height:280px;">




<div data-highcharts-chart="0" id="yw0"><div style="position: relative; overflow: hidden; width: 910px; height: 400px; text-align: left; line-height: normal; z-index: 0; left: 0.5px; top: 0px;" id="highcharts-0" class="highcharts-container"><svg height="400" width="910" xmlns="http://www.w3.org/2000/svg" style="font-family:&quot;Lucida Grande&quot;, &quot;Lucida Sans Unicode&quot;, Verdana, Arial, Helvetica, sans-serif;font-size:12px;" version="1.1"><desc>Created with Highcharts 3.0.10</desc><defs><clipPath id="highcharts-1"><rect height="334" width="890" y="0" x="0"></rect></clipPath></defs><rect class=" highcharts-background" fill="#FFFFFF" ry="5" rx="5" height="400" width="910" y="0" x="0"></rect><g zIndex="3" class="highcharts-series-group"><g style="cursor:pointer;" transform="translate(10,51) scale(1 1)" zIndex="0.1" visibility="visible" class="highcharts-series highcharts-tracker"><path visibility="inherit" stroke-width="1" stroke="green" d="M 450 322 C 445 322 445 314 445 303 L 445 292" fill="none"></path><path visibility="inherit" transform="translate(0,0)" stroke-linejoin="round" stroke-width="1" stroke="#FFFFFF" d="M 444.971282078279 10.000002924535579 A 141 141 0 1 1 444.8041538287319 10.000136013267024 L 445 151 A 0 0 0 1 0 445 151 Z" fill="red"></path></g><g transform="translate(10,51) scale(1 1)" zIndex="0.1" visibility="visible" class="highcharts-markers"></g></g><text style="color:#274b6d;font-size:16px;fill:#274b6d;width:846px;" zIndex="4" class="highcharts-title" text-anchor="middle" y="25" x="455"><tspan x="455">ALLARMI</tspan></text><g style="cursor:pointer;" transform="translate(10,51) scale(1 1)" zIndex="6" visibility="visible" class="highcharts-data-labels highcharts-tracker"><g visibility="inherit" transform="translate(455,312)" style="cursor:pointer;" zIndex="1"><text style="font-size:11px;color:Black;fill:Black;" zIndex="1" y="15" x="3"><tspan x="3" style="font-weight:bold">IHB-AL               </tspan><tspan dx="0">25 </tspan></text></g></g><g zIndex="7" class="highcharts-legend"><rect visibility="hidden" fill="none" stroke-width="1" stroke="#909090" ry="5" rx="5" height="7" width="7" y="0.5" x="0.5"></rect><g zIndex="1"><g></g></g></g><g transform="translate(0,-9999)" style="cursor:default;padding:0;white-space:nowrap;" zIndex="8" class="highcharts-tooltip"><rect transform="translate(1, 1)" stroke-width="5" stroke-opacity="0.049999999999999996" stroke="black" isShadow="true" ry="3" rx="3" fill-opacity="0.85" fill="none" height="16" width="16" y="0.5" x="0.5"></rect><rect transform="translate(1, 1)" stroke-width="3" stroke-opacity="0.09999999999999999" stroke="black" isShadow="true" ry="3" rx="3" fill-opacity="0.85" fill="none" height="16" width="16" y="0.5" x="0.5"></rect><rect transform="translate(1, 1)" stroke-width="1" stroke-opacity="0.15" stroke="black" isShadow="true" ry="3" rx="3" fill-opacity="0.85" fill="none" height="16" width="16" y="0.5" x="0.5"></rect><rect ry="3" rx="3" fill-opacity="0.85" fill="rgb(255,255,255)" height="16" width="16" y="0.5" x="0.5"></rect><text style="font-size:12px;color:#333333;fill:#333333;" zIndex="1" y="21" x="8"></text></g></svg></div></div>

</form>

    </div>

dopo:


 <div class="block-content">

        <form class="form" id="data" name="table_form" method="post" action="" style="height:280px;">




<div id="yw0"></div>

</form>

No ma posso provare…!!

Non ti preoccupare… non ho queste pretese…!! :rolleyes:

sei stato gentilissimo già a rispondere…

come vedi, dopo il refresh NON c’è la parte creata dinamicamente dal js. segno appunto che qualcosa è andato storto.

in questi casi, un cui bisogna eseguire più volte lo stesso javascript ma su codice html caricato via aja, beh, CREDO e dico CREDO, che l’unica strada sia

  • caricare la libreria js nella view principale tramite registerScript

  • l’action che fa il renderPartial deve contenere NON l’uso di highcharts come estensione, ma proprio il javascript che genera il grafico … cioè qualcosa tipo




$('<selettore>').highcharts({

 ... configurazione del grafico

});



Avendo cura che il renderPartial abbia a true il parametro di esecuzione degli script.

Così la libreria viene caricata una sola volta e via ajax ogni volta il grafico è libero di essere ricreato.

Da qui in poi sono nella nebbia anche io, ma quando ho bisogno io seguo proprio questa strada.

Cioè una cosa del genere ?

View:


Yii :: app () -> ClientScript -> registerscript .........

controller:


$this->renderPartial('new3',$c, true,true)

esempio new3.php:


Yii::app()->clientScript->registerScript("view-script","

$(function () { 

    $('#data').highcharts({

        chart: {

            type: 'bar'

        },

        title: {

            text: 'Fruit Consumption'

        },

        xAxis: {

            categories: ['Apples', 'Bananas', 'Oranges']

        },

        yAxis: {

            title: {

                text: 'Fruit eaten'

            }

        },

        series: [{

            name: 'Jane',

            data: [1, 0, 4]

        }, {

            name: 'John',

            data: [5, 7, 3]

        }]

    });

});");



Non vorrei creare confusione ma con Highcharts ti conviene aggiornare i dati direttamente via Javascript.

Al posto di fare di nuovo il render fai un’action che restituisce, in JSON, i dati che vuoi stampare nel grafico poi, scrivi uno script js per impostare il nuovo set di dati per Highcharts.

Non devi far altro che individuare l’oggetti Highcharts istanziato da HighchartsWidget e usare questa funzione dper impostare il nuovo set di dati.

In pratica le cose da fare sono:

Stampare il grafico di partenza tramite il widget.

Nel tuo JS avrai un evento che ogni N secondi fa una chiamata $.getJson alla tua action che ritorna i nuovi dati (ovviamente in JSON :)), se la chiamata JSON ha successo imposti il nuovo set di dati alla tua serie con la funzione setData().

Ecco anche un esempio.

+10 a Nicola

Grazie Mille per la dritta…

ho impostato la mia action così:


 public function ActionUpdateAjax() {

   


       $catexp = Yii::app()->db3->createCommand()

                ->select('NomeServizio,Perc')

                ->from('Vw_AnomalieServizi')

                ->order('Perc DESC')

                ->queryAll();




				$i = 0;

				foreach ($catexp as $key => $value)

					{

					$colore = "red";

					$c[]=array('name' => $catexp[$i]['NomeServizio'],'y' => (double)$catexp[$i]['Perc'], 'color' => 'red' );

					$i++;

					}




		IF ($c == "") {

			$colore = "#66FF00";

			$c[]=array('name' => 'Servizio','y' => 100, 'color' => $colore );

		}

		

		

		




            echo CJSON::encode($c);

eseguendo l’action mi ritorna il mio array:

([{"name":"IHB-AL ","y":25,"color":"red"}])

lato view la getjson come va impostata, purtroppo non sono assolutamente pratico… :blink:

avevo provato una cosa del genere ma senza successo:


$(document).ready(function() {

    var options = {

        chart: {

            renderTo: 'container',

            type: 'spline'

        },

        series: [{}]

    };

  

    var url =  "VwAnomalieServizi/UpdateAjax";

    $.getJSON(url,  function(data) {

	alert(data);

        options.series[0].data = data;

        var chart = new Highcharts.Chart(options);

	});

	 

});

grazie

Non ho mai usato Highcharts quindi vado ad occhio avendo dato una letta alle API e non so come funziona l’extension Yii.

Comunque tu dovresti avere prima una istanza di Highcharts con i dati di partenza,facendola a mano dovresti fare una cosa tipo:




$('#container').highcharts({

        ...

        series: [{

            data: [29.9, 71.5, 106.4, 129.2, 144.0, 176.0, 135.6, 148.5, 216.4, 194.1, 95.6, 54.4]

        }]

    });



poi la parte che si occupa del refresh che va ad aggiornare l’oggetto esistente




$.getJSON(url, function(data) {

        var chart = $('#container').highcharts();

        chart.series[0].setData(data);

        });



A quanto vedo “data” deve contenere solo i valori che vuoi visualizzare, quindi un array di numeri es. [1,23,45,67], l’equivalente, in php, di array(1,23,45,67).

edit: data può contenere Queste cose qua :)

Se utilizzi l’ext di Yii devi capire qual’è il container del grafico, a occhio direi che è quello specificato nelle options -> chart -> renderTo




$this->Widget('ext.highcharts.HighchartsWidget', array(

                    'options' => array(

                        'chart' => array(

                            'renderTo' => 'myContainer',

                            ....                           

                        ),

                       ...

                       ));

echo '<div id="myContainer"></div>';



quindi nel tuo script per il refresh andrai a mettere




$.getJSON(url, function(data) {

        var chart = $('#myContainer').highcharts();

        chart.series[0].setData(data);

        });



il tutto è a spanne quindi verifica tutto controllando quello che fa l’extension e il tipo di dato che ti ritrovi dalla chiamata Json.

Ok grazie, provo e ti faccio sapere…!!

Funziona… !!

Sei un grande…

Ancora grazie…!!

bella!