使用jquery ajax进行Google Visualization Gauge动态更新 – 来自json feed

我有一个来自客户端的REQ,希望在LAMP服务器上看到sysInfo数据的图形表示。 对于我们这些喜欢视觉效果的人来说, 这里有现场演示 。

我在谷歌图表上找到了仪表,在他们的演示中,图表正在移动。 这就是我向客户展示的内容,这就是他们想要的。 只是在经过深思熟虑之后,我很快就意识到他们只是用随机数更新它。 所以我试图自己做。 我搜索了互联网,我甚至在这里发布了我的问题,但没有人回复。

所以,这就是我做的……

最初,我试图让我的谷歌可视化仪表图表通过ajax更新。 我的json feed返回了:

[ {"key":"label1","value":"50.25"}, {"key":"label2","value":"99.43"}, {"key":"label3","value":"4.47"}, {"key":"label4","value":"7.06"} ] 

我得到它最初渲染静态图像,但它似乎永远不会更新。 我花了一段时间,然后我发现我的价值观引用了他们。 问题是#1:API正在寻找数字数据。这是我第一次使用json服务。 我不确定我是否需要以某种方式添加状态:“ok”或者如果我需要做一个eval(),就像许多其他post告诉我的那样。 好吧,我也不需要……

我的脚本如下:

    // 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: , redTo:100, yellowFrom:, yellowTo:, greenFrom:0, greenTo:, minorTicks: 5}; // initialize ajax update of chart every 15 seconds setInterval("getStats ('./getJson.sysinfo.php?dash')", 15000); }); 

然后我渲染了一个静态图:

 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, ); data.setValue(1, 0, 'label2'); data.setValue(1, 1, ); data.setValue(2, 0, 'label3'); data.setValue(2, 1, ); data.setValue(3, 0, 'label4'); data.setValue(3, 1, ); chart.draw(data, options); } 

所有这一切似乎工作得很好,直到doc.ready中的那个讨厌的setInterval()方法踢了我的草率代码 – 15秒后。 ajax源是一个用json_encode()包装的php数组。 当脚本更新时,我的整个图表都消失了 – 有点糟糕! 我看到json通过萤火虫进来了。 它只是没有用。 看一看:

 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); } }); } 

然后我的refreshChart()就是一切都崩溃了:

  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); }  

我想也许我需要创建另一个DataTable对象,或者如果在函数外声明它,也许我可以使用setInterval(data.setValue(i,1,serverData i ),1500)直接更新元素。 无论哪种方式,第一步是访问json数据。 我知道我一定是在做一些愚蠢的事情……在我的post的底部(在这个页面上,在我重新编辑它之前),我补充道:“任何帮助甚至是在正确方向上的推动都会大大增加赞赏……“我每天都回来一个星期并重新重新编辑。 我以为我只是不清楚或者这是一个愚蠢的问题。 “我看到愚蠢的问题得到了解答”,我想,“也许我真的非常愚蠢?” 尽管如此,我仍然需要一个答案。 虽然我不是最好的程序员 – 我是一个相当不错的Google员工。 我读了所有我能看到的东西。 没运气。 nada,non,zylch,niet,nothing ……

好吧,它让我疯了,所以这就是我想出来的:

  1. 正如我之前提到的,我在数字值附近引用了引号。 这就是让我的图表炸弹的原因……而且由于jQuery没有给你任何错误,我有点盲目的事实是我把字符数据填充到我的新数组中,直到我调用.draw()方法和我的漂亮图片消失了。
  2. 我没想到的另一个问题是我正在使用的jQuery版本。 它很老,并没有内置json解析。 所以,我将不得不评估服务器数据,解析数据流并从那里构建数据结构。
  3. #1和#2都导致数据行更新失败,我的字段WERE全部返回未定义。
  4. 我还有一些超出范围的变量声明 – 即添加了.Guage的类和不可思议的.DataTable() – 它来自于骑行。
  5. data.setValue(i,1,serverData [i] .value)应该在AJAX()调用的成功回调中循环 – 这完全消除了我的refreshChart()方法。
  6. 我遇到的最后一个问题是弄清楚如何访问json数据并将其填充到我现有的数组中。 这比我想象的要复杂一些。 一个更有经验的程序员可能会更好地知道……但是,我很顽固。 你可以看到我试图将chartData.push()放到现有数组中。 几个晚上我都在调用arrayName [] []的每个组合。 事实certificate,我可以重新使用谷歌的.setValue()方法。 正如您将在下面看到的,使用success()回调方法,我能够将第一个元素填充到量表中,然后将其余元素放入需要去的其他位置,使用:
 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); } ... 

我从头开始重写整个事情。 在接下来的几天里,我可能会再次重写它,好几次。 最终,这将演变成完整的drupal和wordpress插件以及一篇how-to文章。 我将在我的博客LogicWizards.NET上发布它b / c jQuery文档含糊不清,谷歌网站上的示例演示也不是很直接。

为了使故事更长,这就是我想出的:

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

您将看到大量的繁重工作是通过updateJSON()函数完成的。 现在它的效果非常好。 我想如果我遇到这么多问题,那么其他人可能会从我原来的post中快速编辑中受益 – 随着我的回答,我回答了自己的问题。 我认为为StackedOverflow写出问题的过程帮助我区分问题和症状,并找到答案。 即使没有其他人有答案。

如果有人想看现场演示,请访问http://LogicWizards.NET如果您需要这个表示层的东西,请随意从“查看源”中窃取它。 应用程序的内容都在后端……现在,我花了一周的时间将所有部分组合在一起。 请原谅我漫无目的。 当我有更多时间时,我会编辑这个。 我刚从这个网站和社区的其他人那里拿了这么多代码,这些年来,我觉得回馈一点点好……如果你使用它,只记得投票这篇文章。

我希望它可以帮助需要它的人。

快乐黑客,

Joe Negron~纽约市

根据项目问题跟踪器 ,升级到1.1应该解决问题。

代替

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

使用

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