2011-12-09 53 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(); 
}); 

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