2011-12-09 54 views
3

在旧谷歌图表API是可以使用PHP来渲染图表的谷歌图,还出现了包装做到这一点: http://code.google.com/p/gchartphp/负载从一个异步Ajax响应

但随着新图表API http://code.google.com/apis/chart/ 它产生更多的发烧友图表,但只在浏览器中加载JavaScript。

我试图实现的效果是通过AJAX向服务器提交多选表单,让PHP更新数据库服务器端,然后返回更新的图表。

在旧的API方式我可以做到这一点。但以新的方式,我将JavaScript返回给浏览器并将其附加到文档以呈现图表。它不会因为这个而执行。我相信我可以eval()这个JavaScript,但这是不好的形式是不是因为有人可以做一些令人讨厌的东西,但他们不能 - eval()服务器端响应?

我该如何克服这个问题?有没有一个PHP包装来帮助这个?还是有另一个为什么我忽略了?

非常感谢

回答

6

我解决这个问题的方式最后很明显。我只需要跳出我的想法,从不同的角度来看待它。

我正在尝试使用PHP处理数据库信息并在服务器端创建Google Chart(在这种情况下为饼图)的所有工作。然后将其作为AJAX响应返回。

实际上,我所需要做的就是返回创建饼图所需的数据(以及一些额外的元数据,如目标元素ID)。我做了这个JSON。然后通过选择Google Charts文档,我能够找到如何使用客户端JavaScript来触发API来加载返回的JSON数据。然后让谷歌代码呈现图表客户端 - 所以我基本上将所有呈现责任转移到客户端浏览器。这是新旧图表API不同的地方。

Firebug花费了大量的反复试验和大量的帮助。一个大的跳闸点,这是值得一提的是,你需要加载所有的谷歌JSAPI收到JSON响应之前 - 以便初始页面呈现 - 一件事你必须做的:

google.load("visualization", "1", {packages:["corechart"]}); 

是确保它在页面渲染时加载。如果您在页面完成渲染后调用此页面,则页面将重新加载。

希望这可以帮助别人。

+3

我正在撕裂我的耳朵,试图弄清楚这一点,但读到你的评论,它突然变得有意义。在示例代码中,在“google.load ...”语句之后,总有一条语句,如google.setOnLoadCallback(drawVisualization);但是当然你不需要使用回调函数,你可以在你准备好绘制它时自己调用drawVisualization()方法。 – Ascendant

+0

你不知道这个答案的结构和帮助有多好!很容易被忽视,因为你没有将问题标记为答案(即使你提供了自己的答案,也请做),但是非常有帮助! – SW4

+0

我的坏!只是标记了它。 – andyg1

0

我已经在过去使用所返回的在任何格式所需的相关数据请求的一部分隐藏字段处理的情况是这样的。没有返回javascript。在ajax的成功回调中,您将获取并处理来自该输入的数据。

编辑:

基本上,如果你直接通过AJAX HTML得到更新页面和你不想改变如何,其功能,把作为Ajax响应一个隐藏输入的一部分

<input type="hidden" name="yourhiddeninputname" id="yourhiddeninputname" 
    value="whatever|data|you|want,blah,blah,blah" /> 

然后,一旦HTML注入到你的页面,你会做一些像

var yourdata = document.getElementById('yourhiddeninputname').value; 
// do stuff with your data here. 

这是最好的选择吗?我不确定。这真的取决于你如何交付你的Ajax。我让我的原始评论来自ASP.NET背景,在那里,你经常指望某些类实例为你生成html,并且你从生成的实际html(和其他东西)中抽象出来。当然还有其他方法可以处理这个问题,特别是如果您完全控制AJAX响应的呈现和处理方式。

+0

我不认为我完全理解这个答案。请你详细说明一下... – andyg1

+0

我修改了我的答案,以解释更多我的意思。 – JayC

3

由于andyg1上升,我能够做出像这样的工作(使用PrototypeJS而不是jQuery的,但这个想法是一样的)。由于这一点并不明显,我将展示所有步骤。

Ajax端点刚刚返回json,看起来像这样(一个.NET MVC模板)。请注意,我发现我已经引述一切这Google's documentation并不表明是必要的:

<% 
Response.Headers.Add("Content-type", "text/json"); 
Response.AddHeader("Content-type", "application/json"); 
%> 
{ 
    "cols": [ 
    {"id": "col_1", "label": "Date", "type": "string"}, 
    {"id": "col_2", "label": "Score", "type": "number"} 
    ], 
    "rows": [ 
    <% 
    int index = 0; 
    foreach(KeyValuePair<string, double> item in Model.Performance) { %> 
     {"c":[{"v":"<%= item.Key %>"}, {"v":<%= item.Value %>}]}<%= (index == Model.Performance.Count - 1) ? "" : "," %> 
     <% index++; %> 
     <% 
    } 
    %> 
    ] 
} 

然后母版页包含在此:

<script type="text/javascript" src="https://www.google.com/jsapi"></script> 
<script type="text/javascript" src="/js/myJavascriptFile.js" /> 

然后在myJavascriptFile.js(注意的最后一行初始化方法是google.setOnLoadCallback这在我的课没有drawChart)调用的方法:

google.load('visualization', '1', {'packages':['corechart']}); 
var colors = {'blue': '#369', 'red': '#c22', 'green': '#283', 'yellow': '#c91'}; 

var MyClass = Class.create({ 

    initialize: function() { 
    ... 
    google.setOnLoadCallback(this.getTeamCharts); 
    }, 

    getTeamCharts: function() { 
    $$(".chart-wrapper").each(function (div) { 
     var chartData = div.getData(); 
     var parameters = { 
     ... 
     }; 

     new Ajax.Request('/endpoints/TeamChart.aspx', { 
     method: 'get', 
     parameters: parameters, 
     onSuccess: function(transport) { 
      var jsonData = transport.responseJSON; 
      var data = new google.visualization.DataTable(jsonData); 
      var chartColor = colors[parameters.TeamColor]; 
      var chartDivId = 'chart_div_' + parameters.TeamIdAsString; 

      // Set chart options 
      var options = { 
       'chartArea': {'left':'15%','top':'15%','width':'80%','height':'70%'}, 
       'legend': {'position': 'none'}, 
       'lineWidth': 3, 
       'width': 262, 
       'height': 180, 
       'colors': [chartColor] 
      }; 

      // Instantiate and draw our chart, passing in some options. 
      var chart = new google.visualization.LineChart(document.getElementById(chartDivId)); 
      chart.draw(data, options); 
     } 
     }); 
    }); 
    } 

}); 

document.observe("dom:loaded", function() { 
    var thing = new MyClass(); 
}); 

我敢肯定,这可以进一步改进,但它的工程!