Php 从异步AJAX响应加载Google图表

Php 从异步AJAX响应加载Google图表,php,ajax,google-visualization,Php,Ajax,Google Visualization,在旧的Google图表API中,可以使用PHP来呈现图表,甚至有一个包装器来实现: 但是使用新的chartapi 这会生成更为奇特的图表,但只在浏览器中加载javascript 我试图实现的效果是通过AJAX向服务器提交一个多选表单,让PHP更新DB服务器端,然后返回更新后的图表 以旧的API方式,我可以做到这一点。但是,以新的方式,我会将javascript返回到浏览器,并将其附加到文档中,以便呈现图表。因为这个,它不会执行。我相信我可以评估()这个javascript,但这是一个糟糕的形式

在旧的Google图表API中,可以使用PHP来呈现图表,甚至有一个包装器来实现:

但是使用新的chartapi 这会生成更为奇特的图表,但只在浏览器中加载javascript

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

以旧的API方式,我可以做到这一点。但是,以新的方式,我会将javascript返回到浏览器,并将其附加到文档中,以便呈现图表。因为这个,它不会执行。我相信我可以评估()这个javascript,但这是一个糟糕的形式,不是吗,因为有人可以用它做一些讨厌的事情,他们不能评估()服务器端响应吗

我怎样才能克服这个问题?是否有PHP包装器可以帮助实现这一点?还是我忽略了另一个原因


非常感谢

我过去曾使用一个隐藏字段处理过类似的情况,该字段作为请求的一部分返回,包含您想要的任何格式的相关数据。没有返回javascript。在ajax的成功回调中,您将获取并处理来自该输入的数据

编辑:

基本上,如果您直接通过ajaxhtml更新页面,并且不想更改页面的功能,那么在ajax响应中添加一个隐藏的输入

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

这是最好的选择吗?我不确定。这实际上取决于您如何处理ajax。我最初的评论来自ASP.NET的背景,在那里,通常情况下,您依赖于某些类实例来生成html,并且您是从实际生成的html(和其他内容)中抽象出来的。当然还有其他方法可以处理这个问题,特别是如果您完全可以控制AJAX响应的呈现和处理方式

我解决这个问题的方法最终非常明显。我只需要跳出我的思维,从不同的角度来看待它

我试图用PHP处理数据库信息和在服务器端创建Google图表(本例中为饼图)的所有后续工作。然后将其作为AJAX响应返回

实际上,我所需要做的就是返回创建饼图所需的数据(以及一些额外的元数据,如目标元素id)。我是作为JSON做的。然后,通过浏览GoogleCharts文档,我找到了如何使用客户端javascript触发API来加载返回的JSON数据。然后让Google代码呈现图表客户端-因此我基本上把所有的呈现责任都转移到了客户端浏览器上。这就是新旧图表API的不同之处

这需要大量的尝试和错误,以及Firebug的大量帮助。值得一提的一个重要问题是,在收到JSON响应之前,您需要加载所有Google JSAPI——正如初始页面所呈现的那样——还有一件事您必须做:

google.load("visualization", "1", {packages:["corechart"]});
确保它在页面呈现时加载。如果在页面完全呈现后调用此函数,则页面将重新加载

希望这对某人有所帮助。

多亏了andyg1和Ascendant,我才能够让它像这样工作(使用PrototypeJS而不是jQuery,但想法是一样的)。由于这一点并不明显,我将展示所有步骤

Ajax端点只返回json,如下所示(一个.NETMVC模板)。请注意,我发现我必须引用所有不必要的内容:

<% 
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++; %>
      <% 
    } 
    %>
  ]
}

我相信它可以进一步改进,但它是有效的

我已经修改了我的答案来解释更多我的意思。我正努力想弄明白这一点,但是读了你的评论,它突然变得有意义了。在示例代码中,在“google.load…”语句之后,总是有一个类似于google.setOnLoadCallback(drawVisualization)的语句;但当然,您不需要使用回调函数,只要您真正准备好绘制它,就可以自己调用drawVisualization()。您不知道这个答案的结构有多好,有多有用!很容易被忽略,因为你没有将问题标记为已回答(请这样做,即使你提供了自己的答案),但是非常有用!谢谢@Ascendant,是你的评论解决了我的问题,最好将其作为答案发布
<% 
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" />
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();
});