Загрузите диаграмму Google из асинхронного ответа AJAX

В старом API Google Chart API можно было использовать PHP для рендеринга диаграммы, для этого была даже обертка: http://code.google.com/p/gchartphp/

Но с новым API диаграмм http://code.google.com/apis/chart/, который создает гораздо более привлекательный график, но загружается только с помощью javascript в браузере.

Эффект, который я пытаюсь достичь, представляет собой форму множественного выбора для сервера через AJAX, обновляет PHP серверы БД, а затем возвращает обновленную диаграмму.

По старому API-интерфейсу я мог бы это сделать. Но по-новому я бы возвращал javascript в браузер и добавлял его в документ, чтобы отобразить диаграмму. Из-за этого этого не произойдет. Я считаю, что я мог бы eval () этот javascript, но это плохая форма, не так ли, потому что кто-то мог сделать что-то неприятное с этим, не могли бы они – eval () ответить на сервер?

Как я могу это преодолеть? Есть ли оболочка PHP, чтобы помочь этому? Или есть еще одна причина, которую я упустил?

Большое спасибо

То, как я решил эту проблему, было довольно очевидно в конце. Мне просто нужно было выйти за пределы моих мыслей и подходить к нему под другим углом.

Я пытался выполнить всю работу с обработкой информации о базе данных и создать диаграмму Google (круговую диаграмму в этом случае) на стороне сервера, используя PHP. Затем верните это как ответ AJAX.

Фактически все, что мне нужно было сделать, это вернуть данные, необходимые для создания круговой диаграммы (наряду с некоторыми дополнительными метаданными, такими как идентификатор целевого элемента). Я сделал это как JSON. Затем, просмотрев документацию Google Charts, я смог узнать, как запустить API с помощью javascript на стороне клиента, чтобы загрузить возвращаемые данные JSON. Затем пусть код Google отобразит клиентскую часть диаграммы – поэтому я в основном перенес все ответственность за визуализацию в клиентский браузер. Здесь различаются старые и новые API диаграмм.

Это потребовало много проб и ошибок и много помощи от Firebug. Стоит особо отметить, что вам нужно загрузить весь JSAPI Google, прежде чем вы получите ответ JSON – так, как и первая страница, и одна вещь, которую вы должны сделать:

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

убедитесь, что он загружается, когда страница выполняет рендеринг. Если вы вызовете это после того, как страница полностью отобразится, страница перезагрузится.

Надеюсь, это поможет кому-то.

Благодаря andyg1 и Ascendant я смог заставить его работать так (используя PrototypeJS, а не jQuery, но идея такая же). Поскольку это не совсем очевидно, я собираюсь показать все шаги.

Конечная точка Ajax просто возвращает json и выглядит так (шаблон .NET MVC). Обратите внимание, что я обнаружил, что мне нужно процитировать все, что не предлагает документация Google :

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

Я уверен, что это может быть улучшено, но оно работает!

В прошлом я рассматривал подобные ситуации, используя скрытое поле, которое возвращается как часть запроса с соответствующими данными в любом формате. 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. 

Это лучший вариант? Я не уверен. Это действительно зависит от того, как вы передаете свой аякс. Я сделал свои оригинальные комментарии, исходя из фона ASP.NET, где часто вы рассчитываете на определенные экземпляры класса для генерации html для вас, и вы отвлекаетесь от фактического html (и других вещей), которые генерируются. Есть, конечно, другие способы справиться с этим, особенно если у вас есть полный контроль над тем, как обрабатывается и обрабатывается ответ AJAX.