2010-12-11 36 views
3

J'avais un REQ d'un client qui voulait voir une représentation graphique des données sysInfo sur un serveur LAMP. Pour ceux d'entre nous qui préfèrent un visuel, il y a live demo here. J'ai trouvé les jauges sur Google Maps et dans leur démo le graphique bougeait. C'est ce que j'ai montré au client, c'est ce qu'ils voulaient. C'est juste qu'après avoir farfouillé sous le capot, je me suis vite rendu compte qu'ils étaient juste en train de le mettre à jour avec des nombres aléatoires. alors j'ai essayé de le faire moi-même. J'ai parcouru internet et j'ai même posté mes problèmes ici mais personne n'a répondu.Google Visualization Gauge mise à jour dynamique avec jquery ajax - from json feed

Alors, voici ce que je faisais ...

Dans un premier temps, je tentais d'obtenir ma carte de jauge de visualisation de Google pour mettre à jour via ajax. mon flux json retourné:

Je l'ai eu pour rendre initialement une image statique, mais il n'a jamais semblé mettre à jour. Il m'a fallu un moment, puis j'ai compris que mes valeurs avaient des citations autour d'eux. C'était le problème n ° 1: l'API cherchait des données numériques. C'était ma première fois avec un service json. Je n'étais pas sûr si j'avais besoin d'ajouter en quelque sorte le statut: "ok" ou si j'avais besoin de faire un eval() comme tant d'autres messages me l'ont dit. Eh bien, je ne l'ai pas besoin non plus ...

Mon script était comme suit:

<script type='text/javascript' src='http://www.google.com/jsapi'></script> 
    <script type='text/javascript'> 
    // load the visualization api & skin 
    google.load('visualization', '1', {packages:['gauge']}); 
    // draw the initial chart from snapshot data for quick rendering 
    google.setOnLoadCallback(drawChart); 
    // set global vars once DOM finishes 
    $(document).ready(function() { 
     chart = new google.visualization.Gauge(document.getElementById('chart_div')); 
     options = {width: 400, height: 120, 
      redFrom: <?=$CODE_RED?>, redTo:100, 
      yellowFrom:<?=$CODE_YEL?>, yellowTo:<?=$CODE_RED?>, 
      greenFrom:<?=$CODE_GRN?>0, greenTo:<?=$CODE_YEL?>, 
      minorTicks: 5}; 
     // initialize ajax update of chart every 15 seconds 
     setInterval("getStats ('./getJson.sysinfo.php?dash')", 15000); 
    }); 

je un graphique statique rendu avec:

function drawChart() { 
    var data = new google.visualization.DataTable(); 
    data.addColumn('string', 'Label'); 
    data.addColumn('number', 'Value'); 
    data.addRows(8); 
    data.setValue(0, 0, 'label1'); 
    data.setValue(0, 1, <?=number_format($X1,2) ?>); 
    data.setValue(1, 0, 'label2'); 
    data.setValue(1, 1, <?=number_format($X2,2)?>); 
    data.setValue(2, 0, 'label3'); 
    data.setValue(2, 1, <?=number_format($X3,2)?>); 
    data.setValue(3, 0, 'label4'); 
    data.setValue(3, 1, <?=number_format($X4,3)?>); 
    chart.draw(data, options); 
} 

tout cela semblait bien fonctionner jusqu'à ce que la méthode setInterval() dans doc.ready kicked dans mon code bâclé - 15 secondes plus tard. La source ajax est un tableau PHP enveloppé avec json_encode(). Lorsque le script a été mis à jour, tout mon graphique a disparu, ce qui a été un peu nul! J'ai vu le json arriver via firebug. Ça ne fonctionnait pas. Jetez un oeil:

function getStats (source) { 
    $.ajax({ 
    url: source, 
    type: 'POST', 
    dataType: 'json', 
    success: function(data) { refreshChart(data); }, 
    error: function (request, status, error) { 
      alert("REQUEST:\t"+request 
       +"\nSTATUS:\t"+status 
       +"\nERROR:\t"+error); 
    } 
    }); 
} 

puis mon refreshChart() est l'endroit où tout est tombé juste en dehors:

function refreshChart(serverData) { 
     var chartData = []; 
     for(var i = 0; i < serverData.length; i++) { 
    //  chartData.push([serverData[i][0], $.serverData[i][1]['value']]); 
    //  chartData.push([serverData[i][0], $.serverData[i][1].val()]); 
      chartData.push([serverData[i][0], serverData[i][1].value]); 
     } 
// note2self[347] = "I tried the above a million different ways and firebug coming back 
//+ with: "missing ] after element list" on the function declaration line..." 
     var data = new google.visualization.DataTable(); 
     data.addColumn('string', 'Label'); 
     data.addColumn('number', 'Value'); 
     data.addRows(chartData); 
     chart.draw(data, options); 
    } 

    </script> 

Je pensais peut-être que je devais créer un autre objet DataTable, ou si elle est déclarée en dehors de la fonction , peut-être que je peux utiliser setInterval (data.setValue (i, 1, serverData i), 1500) pour mettre à jour l'élément directement. Dans un cas comme dans l'autre, la première étape consistait à accéder aux données json. Je savais que je devais faire quelque chose de stupide ... Au bas de mon message (sur cette page, avant de le re-éditer), j'ai ajouté: "toute aide ou même un coup de pouce dans la bonne direction serait grandement apprécié ... "Je suis revenu chaque jour pendant une semaine et re-ré-édité. Je pensais que je n'étais juste pas clair ou que c'était une question stupide. "J'ai vu des réponses stupides à des questions", pensais-je, "peut-être que la mienne était vraiment ... vraiment stupide?" Néanmoins, j'avais toujours besoin d'une réponse. Bien que je ne sois pas le meilleur programmeur - je suis un très bon googleur. J'ai lu tout ce que je pouvais voir. Pas de chance. nada, non, zylch, niet, rien ...

Eh bien, il me rend dingue, voici donc ce que j'ai compris:

  1. Comme je l'ai mentionné précédemment, j'avais des guillemets autour de mes valeurs numériques. C'est ce qui a fait exploser ma carte ... et puisque jQuery ne vous donne aucune erreur, j'étais un peu aveugle au fait que je bourrais des données de caractères dans mon nouveau tableau jusqu'à ce que j'appelle la méthode .draw() et ma jolie image disparu.
  2. Un autre problème que je ne pensais pas vérifier était la version de jQuery que j'utilisais. Il était vieux & n'a pas json parsing intégré en elle. Donc, j'aurais eu à évaluer les données du serveur, analyser le flux de données & construire la structure de données à partir de là.
  3. Les deux # 1 & # 2 ont provoqué l'échec des mises à jour des lignes de données et tous mes champs retournaient indéfinis.
  4. J'ai également eu certaines déclarations de variables hors de portée - à savoir la classe qui a ajouté le .Guage et accessoirement le .DataTable() - qui est venu pour le tour. Data.setValue (i, 1, serverData [i] .value) aurait dû être bouclé dans le rappel de succès de l'appel AJAX() - et cela a complètement éliminé ma méthode refreshChart().
  5. Le dernier problème que j'avais était de comprendre comment accéder aux données json & bourrer dans mon tableau existant. C'était un peu plus compliqué que je ne le pensais. un programmeur plus expérimenté aurait probablement su mieux ... mais, j'étais têtu. Vous pouvez voir où j'essayais de faire un chartData.push() dans le tableau existant. J'appelais possible chaque combinaison de arrayName [] [] pour plusieurs nuits. Il s'est avéré que je pouvais juste réutiliser la méthode .setValue() de google. Comme vous le verrez ci-dessous, en utilisant le succès() méthode de rappel, j'ai pu en boucle une fois Farcir les 1ères éléments dans la jauge et le reste dans les autres endroits dont il a besoin pour aller, en utilisant:
for (var i = 0; i < data.length; i++) { 
     if (i<4) { 
      dashData.setValue(i, 0, jsonData[i].k); 
      dashData.setValue(i, 1, jsonData[i].v); 
      } ... 

J'ai réécrit le tout à partir de zéro. Dans les prochains jours, je vais probablement le réécrire à plusieurs reprises. Finalement, cela évoluera en drupal & plugins wordpress et un article de how-to. Je l'afficherai sur mon blog LogicWizards.NET b/c la documentation de jQuery est vague et la démo d'exemple sur le site de google n'est pas très simple non plus.

Pour faire une histoire encore plus longtemps, voici ce que je suis venu avec:

<!-- /** Client-Side Scripts **/ --> 
<script type='text/javascript' src='http://www.google.com/jsapi'></script> 
<script type='text/javascript'> 
// load the visualization api & skin 
google.load('visualization', '1', {packages:['gauge']}); 
// draw the initial chart from snapshot data for quick rendering 
google.setOnLoadCallback(drawChart); //as soon as the API is loaded 
// set global vars once DOM finishes 
$(document).ready(function() { 
    dash = new google.visualization.Gauge(document.getElementById('chart_div')); 
    dashData = new google.visualization.DataTable(); 
    options = { width: 400, height: 120, 
     redFrom:75, redTo:100, 
     yellowFrom:50, yellowTo:75, 
     greenFrom:00, greenTo:50, 
     minorTicks: 5}; 
}); 

function drawChart() { 
// method to define initial chart 
    dashData.addColumn('string', 'Label'); 
    dashData.addColumn('number', 'Value'); 
    dashData.addRows(8); 
    dashData.setValue(0, 0, 'CPU'); 
    dashData.setValue(0, 1, 54.40); 
    dashData.setValue(1, 0, 'RAM'); 
    dashData.setValue(1, 1, 99.54); 
    dashData.setValue(2, 0, 'SWAP'); 
    dashData.setValue(2, 1, 4.25); 
    dashData.setValue(3, 0, 'NET'); 
    dashData.setValue(3, 1, 0.402); 
    dash.draw(dashData, options); 
} 

function updateJSON (source) { 
// method to update all subsequent charts 
var jsonData = null; //there's really no reason for this anymore (see below) 
$.ajax({ url:source, type:'POST', dataType:'json', 
    success: function(data) { jsonData=data; 
    for (var i = 0; i < data.length; i++) { 
     if (i<4) { 
      dashData.setValue(i, 0, jsonData[i].k); 
      dashData.setValue(i, 1, jsonData[i].v); 
      if (i<3) { dash.draw(dashData, options); } 
     } 
      $("#"+jsonData[i].k).text(jsonData[i].v); 
     } 
    }, 
    error: function (request, status, error) { 
      alert("REQUEST:\t"+request 
       +"\nSTATUS:\t"+status 
       +"\nERROR:\t"+error);  } 
    }); //end-ajax 
    return jsonData; //obsolete: updates are now done through the success callback 
} 

function isSet (variable) { // mimic the php function 
    return (typeof variable !== "undefined" && variable.length) ? 1 : 0; 
} 

function setDelay(delay){ 
// method to change timer's sleep interval 
    clearInterval(timer); //kill the last timer 
    timer=setInterval(json,delay*1000); //delay is miliseconds 
    } 
</script> 

Vous verrez que la majeure partie de la soulever des charges lourdes se fait via la fonction updateJSON(). et maintenant ça marche plutôt bien. Je me suis dit que si j'avais autant de problèmes, quelqu'un d'autre pourrait bénéficier d'une modification rapide de mon message original - en répondant à mes propres questions au fur et à mesure. Je pense que le processus d'écriture de mes questions sur StackedOverflow m'a aidé à faire la différence entre les problèmes et les symptômes, et aussi à trouver les réponses. Même si personne d'autre n'avait de réponse.

Si quelqu'un souhaite voir une démonstration en direct, rendez-vous au http://LogicWizards.NET Si vous avez besoin de cette couche de présentation, n'hésitez pas à la dérober à la 'source de la vue'. Les tripes de l'application sont toutes sur le dos ... Maintenant, il m'a fallu la meilleure partie de la semaine pour mettre tous les morceaux ensemble. Pardonnez-moi de m'être promené. Je vais modifier cela quand j'ai plus de temps. Je viens de prendre tellement de code de CE site et le reste de la communauté, au fil des ans, je me sens bien de donner un peu de retour ... n'oubliez pas de voter cet article, si vous l'utilisez.

J'espère que cela aide quelqu'un qui en a besoin.

Happy Hacking,

Joe Negron ~ NYC

+0

ce qui est très similaire à http://stackoverflow.com/questions/3411854/ajax-google-visualization-api-gauge-with-jquery mais sur les stéroïdes ... – WWWIZARDS

+0

Avez-vous déjà eu une réponse pour cela? – adardesign

Répondre

1

Selon le projet issues tracker, mise à niveau 1.1 devrait résoudre le problème.

au lieu de

google.load('visualization', '1') 

utilisation

google.load('visualization', '1.1') 
+0

Une autre pensée: après avoir reçu vos données, assurez-vous que la valeur que vous avez reçue est un nombre. Si ce n'est pas le cas, parsisez avec parseFloat –