В старом 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.