На этой странице описывается, как можно реализовать службу, поддерживающую протокол источника данных инструментов диаграмм, чтобы предоставлять данные для диаграмм с помощью класса Query .
Содержание
Аудитория
Эта страница предназначена в первую очередь для разработчиков, которые будут создавать свои собственные источники данных без помощи библиотеки источников данных инструментов для работы с диаграммами . Если вы используете эту или любую другую вспомогательную библиотеку, сначала прочитайте документацию вашей библиотеки.
Эта страница также предназначена для читателей, заинтересованных в понимании проводного протокола, используемого для связи между клиентской визуализацией и источником данных.
Если вы создаете или используете визуализацию, вам не нужно читать эту страницу.
Чтобы прочитать этот документ, вы должны понимать базовый синтаксис запросов JSON и HTTP. Вы также должны понимать, как работают диаграммы с точки зрения пользователя.
Обзор
Вы можете внедрить протокол источника данных инструментов диаграмм, чтобы стать поставщиком источника данных для ваших собственных диаграмм или других диаграмм. Источник данных инструментов для работы с диаграммами предоставляет URL-адрес, называемый URL -адресом источника данных, на который диаграмма может отправлять HTTP-запросы GET. В ответ источник данных возвращает правильно отформатированные данные, которые диаграмма может использовать для отображения графики на странице. Этот протокол запроса-ответа известен как проводной протокол Google Visualization API .
Данные, обслуживаемые источником данных, могут быть извлечены из различных ресурсов, таких как файл или база данных. Единственное ограничение состоит в том, что вы можете отформатировать данные как двумерную таблицу с типизированными столбцами.
В качестве источника данных инструментов для работы с диаграммами вы должны анализировать запрос в определенном формате и возвращать ответ в определенном формате. Вы можете сделать это одним из двух основных способов:
- Используйте одну из следующих вспомогательных библиотек для обработки запроса и ответа и создайте DataTable для возврата. Если вы используете одну из этих библиотек, вам нужно написать только код, необходимый для того, чтобы сделать ваши данные доступными для библиотеки в виде таблицы.
- Библиотека источников данных Java — обрабатывает запрос и ответ, создает таблицу ответов на основе предоставленных вами данных и реализует язык запросов Google Chart Tools SQL.
- Библиотека источников данных Python — создает таблицу ответов, генерирует синтаксис ответа. Не выполняет синтаксический анализ запроса или реализацию языка запросов Google Chart Tools SQL .
ИЛИ ЖЕ
- Напишите свой собственный источник данных с нуля , обработав запрос, создав DataTable и отправив ответ.
Как это работает:
- Источник данных предоставляет URL-адрес, называемый URL -адресом источника данных, на который диаграммы отправляют HTTP-запрос GET.
- Клиент отправляет HTTP-запрос GET с параметрами, описывающими формат возвращаемых данных, необязательную строку запроса и необязательные настраиваемые параметры.
- Источник данных получает и анализирует запрос, как описано в разделе Формат запроса .
- Источник данных подготавливает данные в запрошенном формате; обычно это таблица JSON. Форматы ответов описаны в разделе Формат ответа . Источник данных может дополнительно поддерживать язык запросов API визуализации, который определяет фильтрацию, сортировку и другие операции с данными.
- Источник данных создает ответ HTTP, который включает сериализованные данные и другие параметры ответа, и отправляет его обратно клиенту, как описано в разделе Формат ответа.
Примечание. Все параметры и значения строковых констант, перечисленные в этом документе для запросов и ответов (например, responseHandler
и «ok»), написаны строчными буквами и чувствительны к регистру.
Минимальные требования
Вот минимальные требования для использования в качестве источника данных инструментов для работы с диаграммами:
- Источник данных должен принимать запросы HTTP GET и должен быть доступен вашим клиентам.
- Протокол может изменяться и поддерживает схему версий (текущая версия — 0.6), поэтому ваш источник данных должен поддерживать запросы с использованием предыдущих версий, а также текущей версии. Вы должны стараться поддерживать новые версии, как только они будут выпущены, чтобы избежать поломки клиентов, которые быстро обновляются до новейшей версии.
- Не сбой, если неизвестные свойства отправляются как часть запроса. Это связано с тем, что новые версии могут вводить новые свойства, о которых вы не знаете.
- Анализируйте только ожидаемые свойства. Хотя в новых версиях могут появиться новые свойства, не принимайте и не используйте всю строку запроса вслепую. Чтобы защитить себя от вредоносных атак, тщательно анализируйте и используйте только те свойства, которые вы ожидаете.
- Внимательно документируйте требования к источнику данных, если вы не пишете клиентские диаграммы самостоятельно. Это включает в себя документирование следующей информации:
- Любые специальные параметры, которые вы принимаете,
- Независимо от того, можете ли вы анализировать язык запросов Google Visualization API и
- Какие данные вы возвращаете, и структуру этих данных (что представляют строки и столбцы, а также любую маркировку).
- Примите все стандартные меры безопасности для сайта, принимающего запросы от неизвестных клиентов . Вы можете разумно поддерживать MD5, хеширование и другие механизмы безопасности в своих параметрах для проверки подлинности запросов или защиты от злонамеренных атак и ожидать, что клиенты будут знать о ваших требованиях и реагировать на них. Тем не менее, обязательно хорошо задокументируйте все свои требования, если вы не программируете диаграммы самостоятельно. См. Вопросы безопасности ниже.
- Все строки запросов и ответов должны быть в кодировке UTF-8.
- Наиболее важным форматом ответа является JSON. Обязательно сначала реализуйте JSON, так как этот формат используется в большинстве диаграмм. Позже добавьте другие типы ответов.
- Вы не обязаны поддерживать язык запросов Visualization API , но это делает ваш источник данных более полезным для клиентов.
- Вы не обязаны поддерживать запросы от любых типов диаграмм, и вы можете поддерживать пользовательские параметры для пользовательских диаграмм. Но вы должны возвращать ответы в стандартном формате, описанном ниже.
Вопросы безопасности
При проектировании источника данных вам необходимо учитывать, насколько безопасными должны быть ваши данные. Вы можете использовать различные схемы безопасности для своего сайта, от простого доступа по паролю до безопасной аутентификации с помощью файлов cookie.
Атаки XSSI (включение межсайтовых сценариев) представляют собой риск для диаграмм. Пользователь может перейти на страницу, содержащую вредоносный сценарий, который затем начинает пытаться делать запросы к URL-адресам источников данных, используя учетные данные текущего пользователя. Если пользователь не вышел с сайта, сценарий будет аутентифицирован как текущий пользователь и получит разрешения на этом сайте. Используя тег <script src>, вредоносный скрипт может включать источник данных, аналогичный JSONP.
В качестве дополнительного уровня безопасности вы можете рассмотреть возможность ограничения запросов теми, которые исходят из того же домена, что и ваш источник данных. Это значительно ограничит видимость вашего источника данных, но если у вас есть очень конфиденциальные данные, к которым нельзя получить доступ из-за пределов вашего домена, вы должны это учитывать. Источник данных, который разрешает запросы только из одного и того же домена, называется источником данных с ограничениями , в отличие от источника данных без ограничений , который принимает запросы из любого домена. Вот некоторые подробности о том, как реализовать ограниченный источник данных:
Чтобы убедиться, что запрос действительно исходит из вашего домена , а не из внешнего домена (или браузера внутри домена, который подвергается атаке XSRF ):
- Проверьте наличие заголовка «X-DataSource-Auth» в запросе. Этот заголовок определяется API визуализации Google; вам не нужно проверять содержимое этого заголовка, только убедитесь, что он есть. Если вы используете библиотеку источников данных Google Chart Tools , вы можете поручить эту работу библиотеке.
- Используйте аутентификацию cookie для аутентификации клиента. Не существует известного способа внедрить пользовательские заголовки в междоменный запрос, сохраняя при этом файлы cookie аутентификации.
- Сделайте JavaScript маловероятным при включении с тегом <script src>. Для этого добавьте к ответу JSON префикс )]}', за которым следует новая строка. В вашем клиенте удалите префикс из ответа. Для XmlHttpRequest это возможно только в том случае, если запрос исходит из того же домена.
Формат запроса
Клиент отправляет HTTP-запрос GET с несколькими параметрами, включая настраиваемые элементы, необязательную строку запроса, подпись и другие элементы. Вы несете ответственность только за анализ параметров, описанных в этом разделе, и должны быть осторожны, чтобы не обрабатывать другие параметры, чтобы избежать злонамеренных атак.
Обязательно установите значения по умолчанию для дополнительных параметров (как стандартных, так и пользовательских) и задокументируйте все значения по умолчанию в документации вашего сайта.
Вот несколько примеров запросов (вы можете увидеть больше примеров запросов и ответов в конце этого документа в разделе Примеры ):
Примечание . Следующие строки запроса, а также строки, показанные в разделе « Примеры », должны быть экранированы URL-адресом перед отправкой.
Basic request, no parameters: http://www.example.com/mydatasource Request with the tqx parameter that contains two properties: http://www.example.com/mydatasource?tqx=reqId:0;sig:4641982796834063168 Request with a query string: http://www.example.com/mydatasource?tq=limit 1
Вот список всех стандартных параметров в строке запроса. Обратите внимание, что как имена параметров (такие как «версия»), так и константные строковые значения (такие как «ok», «warning» и «not_modified») чувствительны к регистру. В таблице также указано, требуется ли отправка параметра и, если он отправлен, требуется ли его обработка.
Параметр | Требуется в запросе? | Источник данных должен обрабатываться? | Описание |
---|---|---|---|
ТК | Нет | Нет | Запрос, написанный на языке запросов Google Visualization API и указывающий, как фильтровать, сортировать или иным образом обрабатывать возвращаемые данные. Строку не нужно заключать в кавычки. Пример: |
tqx | Нет | Да | Набор пар ключ/значение, разделенных двоеточием, для стандартных или настраиваемых параметров. Пары разделяются точкой с запятой. Вот список стандартных параметров, определенных протоколом визуализации:
Пример: |
tqrt | Нет | Нет | Зарезервировано: игнорируйте этот параметр. Метод, который использовался для отправки запроса. |
Формат ответа
Формат ответа зависит от параметра out
запроса, который определяет тип ожидаемого ответа. См. следующие разделы, чтобы узнать, как отвечать на запросы каждого типа:
- JSON — возвращает ответ JSON, включающий данные в объекте JavaScript, который можно передать непосредственно в конструктор
DataTable
для его заполнения. Это, безусловно, самый распространенный тип запроса и наиболее важный для правильной реализации. - CSV — возвращает плоский список значений, разделенных запятыми, для обработки браузером.
- TSV — возвращает список значений, разделенных табуляцией, для обработки браузером.
- HTML — возвращает HTML-таблицу для отображения в браузере.
Вы можете использовать библиотеку источников данных визуализации Google (java) или библиотеку Python для визуализации, чтобы сгенерировать эти форматы вывода.
Формат ответа JSON
Формат ответа по умолчанию — JSON , если запрос включает заголовок «X-DataSource-Auth», и JSONP в противном случае. Обратите внимание, что клиент диаграммы Google фактически поддерживает модифицированную версию JSON и JSONP; если вы используете вспомогательные библиотеки Java или Python , они предоставят вам правильный код; если вы анализируете ответы вручную, см. раздел « Модификации JSON » ниже.
Если вы применяете запросы к тому же домену, вам следует проверить наличие заголовка «X-DataSource-Auth» в запросе и использовать файлы cookie авторизации.
Это единственный формат ответа, указанный методом Google Visualization API google.visualization.Query.send()
. Вы можете увидеть несколько примеров запросов и ответов JSON в конце этой страницы в разделе Примеры . Вы можете использовать вспомогательные библиотеки Java или Python для создания этой строки ответа.
Этот формат ответа представляет собой объект JSON в кодировке UTF-8 (объект, заключенный в фигурные скобки { }, где каждое свойство отделено запятой), который включает свойства в таблице ниже (данные присваиваются свойству table
). Этот объект JSON должен быть заключен в значение параметра responseHandler
из запроса. Итак, если значением responseHandler
запроса было «myHandler», вы должны вернуть строку, подобную этой (для краткости показано только одно свойство):
"myHandler({status:ok, ...})"
Если запрос не включает значение responseHandler
, значением по умолчанию является "google.visualization.Query.setResponse", поэтому вы должны вернуть строку, подобную этой (для краткости показано только одно свойство):
"google.visualization.Query.setResponse({status:ok, ...})"
Вот доступные члены объекта ответа:
Имущество | Необходимый? | Описание |
---|---|---|
версия | Нет | Строковый номер, указывающий номер версии проводного протокола визуализации Google. Если не указано, клиент предполагает последнюю версию. Пример: |
reqId | Да* | Номер строки, указывающий идентификатор этого запроса для этого клиента. Если это было в запросе, вернуть то же значение. См. описание reqId в разделе запроса для получения более подробной информации.* Если этот параметр не был указан в запросе, в ответе его можно не задавать. |
статус | Да | Строка, описывающая успех или неудачу этой операции. Должно быть одно и только одно из следующих значений:
Пример: |
предупреждения | Только если status=warning | Массив из одного или нескольких объектов, каждый из которых описывает некритическую проблему. Требуется, если
Пример: |
ошибки | Требуется, если status=error | Массив из одного или нескольких объектов, каждый из которых описывает ошибку. Требуется, если Массив состоит из следующих строковых элементов (возвращает только одно значение для каждого члена):
Пример: |
знак | Нет | Хэшированное значение объекта таблицы. Полезно для оптимизации передачи данных между клиентом и источником данных. Вы можете выбрать любой алгоритм хеширования. Если вы поддерживаете это свойство, вы должны вернуть значение, переданное клиентом, если данные не возвращаются, или вернуть новый хэш, если возвращаются новые данные. Пример: |
стол | Нет | Объект {cols:[{id:'Col1',label:'',type:'number'}], rows:[{c:[{v:1.0,f:'1'}]}, {c:[{v:2.0,f:'2'}]}, {c:[{v:3.0,f:'3'}]}, {c:[{v:1.0,f:'1'}]} ] } Свойство Пример: см. примеры ниже. |
Вспомогательные библиотеки Google и все запросы, отправленные в Google, возвращают строгий JSON/JSONP. Если вы не анализируете возвращаемый код самостоятельно, это не должно иметь для вас значения. Если да, вы можете использовать JSON.parse() для преобразования строки JSON в объект JavaScript. Одно из отличий в том, как JSON обрабатывается API, заключается в том, что, хотя JSON не поддерживает значения даты JavaScript (например, «новая дата (2008,1,28,0,31,26)», API поддерживает действительный JSON представление дат в виде строки в следующем формате: Date(year, month, day[,hour, minute, second[, millisecond]])
где все после дня является необязательным, а месяцы отсчитываются от нуля .
Оптимизация ответов JSON
Если клиент делает два запроса, и данные не изменились между запросами, имеет смысл не отправлять данные повторно; это приведет к потере пропускной способности. Чтобы сделать запросы более эффективными, протокол поддерживает кэширование данных на клиенте и отправку сигнала в ответ, если данные не изменились с момента последнего запроса. Вот как это работает:
- Клиент отправляет запрос к источнику данных.
- Источник данных создает
DataTable
, а также хэш объектаDataTable
и возвращает оба в своем ответе (хэш возвращается в параметреtqx.
sig
). Клиент Google Visualization API кэширует значениеDataTable
иsig
. - Клиент отправляет еще один запрос данных, включая кэшированное значение
tqx.sig
. - Источник данных может ответить одним из двух способов:
- Если данные изменились по сравнению с предыдущим запросом, источник данных отправляет обратно новую
DataTable
данных и хэш нового значенияsig
. - Если данные не изменились по сравнению с предыдущим запросом, источник данных возвращает
status=error
,reason=not_modified
,sig= old_sig_value
.
- Если данные изменились по сравнению с предыдущим запросом, источник данных отправляет обратно новую
- В любом случае страница, на которой размещена диаграмма, получает успешный ответ и может получить
DataTable
, вызвавQueryResponse.getDataTable()
. Если данные совпадают, это будет просто кешированная версия таблицы.
Обратите внимание, что это работает только для запросов JSON от диаграмм, созданных с помощью Google Visualization API.
Формат ответа CSV
Если в запросе указано out:csv
, ответ не включает метаданные, а просто представляет данные в формате CSV. Таблица CSV обычно представляет собой список, разделенный запятыми, где каждая строка данных представляет собой список значений, разделенных запятыми, заканчивающийся символом новой строки UNIX (\n). Значения ячеек должны иметь одинаковый тип для каждого столбца. Первая строка — это метки столбцов. Вот пример таблицы с тремя строками и тремя столбцами:
A, B, C 1.0, "yes", true 2.0, "no", false 3.0, "maybe", true
Формат CSV не определяется этим протоколом; источник данных отвечает за определение своего формата CSV. Однако общий формат представляет собой набор значений, разделенных запятыми (без промежуточных пробелов) и символом новой строки (\n) в конце каждой строки. Когда браузер получает ответ в виде строки CSV, он может спросить пользователя, какое приложение следует использовать для открытия строки, или может просто отобразить ее на экране. Библиотеки с открытым исходным кодом Java и Python предоставляют метод для преобразования DataTable в строку CSV.
Если запрос включает элемент outFileName
параметра tqx
, следует попытаться включить указанное имя файла в заголовки ответа.
Объект google.visualization.Query
не поддерживает запрос ответа в формате CSV. Если клиент хочет запросить CSV, вы можете встроить гаджет панели инструментов визуализации на свою страницу, или он может использовать собственный код для создания запроса, или вы можете предоставить ссылку, которая явно задает свойство out:csv
для tqx
, как показано на следующий URL-адрес запроса:
Запрос
http://www.example.com/mydatasource?tqx=reqId:1;out:csv
Ответ
Label 1,Label2\n1,a\n2,b\n3,c\n4,d
Формат ответа TSV
Если в запросе указано out:tsv-excel
, ответ не включает метаданные, а просто представляет данные, разделенные табуляцией, в кодировке utf-16 . Если запрос включает элемент outFileName
параметра tqx
, следует попытаться включить указанное имя файла в заголовки ответа.
HTML-формат ответа
Если в запросе указано out:html
, ответом должна быть HTML-страница, определяющая HTML-таблицу с данными. Это полезно для отладки вашего кода, потому что браузер может напрямую отображать ваш результат в удобочитаемом формате. Вы не можете отправить запрос на HTML-ответ, используя объект google.visualization.Query
. Вы должны сделать запрос на получение HTML-ответа, используя собственный код или введя URL-адрес, аналогичный этому, в браузере:
Запрос
http://www.example.com/mydatasource?tqx=reqId:1;out:html
Ответ
<html><body><table border='1' cellpadding='2' cellspacing='0'><tr style='font-weight: bold; background-color: #aaa;'><td>label 1</td><td>label 2</td></tr><tr bgcolor='#f0f0f0'><td align='right'>1</td><td>a</td></tr><tr bgcolor='#ffffff'><td align='right'>2</td><td>b</td></tr><tr bgcolor='#f0f0f0'><td align='right'>3</td><td>c</td></tr><tr bgcolor='#ffffff'><td align='right'>4</td><td>d</td></tr></table></body></html>
Примеры
Вот несколько примеров запросов и ответов. Обратите внимание, что запросы не были экранированы URL; обычно это делается браузером или объектом google.visualization.Query
.
Простой запрос : возвращает основную информацию в виде таблицы из трех столбцов и четырех строк.
Request: http://www.example.com/mydatasource Response google.visualization.Query.setResponse({version:'0.6',reqId:'0',status:'ok',sig:'5982206968295329967',table:{cols:[{id:'Col1',label:'',type:'number'},{id:'Col2',label:'',type:'number'},{id:'Col3',label:'',type:'number'}],rows:[{c:[{v:1.0,f:'1'},{v:2.0,f:'2'},{v:3.0,f:'3'}]},{c:[{v:2.0,f:'2'},{v:3.0,f:'3'},{v:4.0,f:'4'}]},{c:[{v:3.0,f:'3'},{v:4.0,f:'4'},{v:5.0,f:'5'}]},{c:[{v:1.0,f:'1'},{v:2.0,f:'2'},{v:3.0,f:'3'}]}]}});
Простой запрос с обработчиком ответа: возвращает таблицу из трех столбцов и трех строк с разными типами данных.
Request: http://www.example.com/mydatasource?tqx=responseHandler:myHandlerFunction Response myHandlerFunction({version:'0.6',reqId:'0',status:'ok',sig:'4641982796834063168',table:{cols:[{id:'A',label:'NEW A',type:'string'},{id:'B',label:'B-label',type:'number'},{id:'C',label:'C-label',type:'datetime'}],rows:[{c:[{v:'a'},{v:1.0,f:'1'},{v:new Date(2008,1,28,0,31,26),f:'2/28/08 12:31 AM'}]},{c:[{v:'b'},{v:2.0,f:'2'},{v:new Date(2008,2,30,0,31,26),f:'3/30/08 12:31 AM'}]},{c:[{v:'c'},{v:3.0,f:'3'},{v:new Date(2008,3,30,0,31,26),f:'4/30/08 12:31 AM'}]}]}});
Запрос с простой строкой запроса: запрос одного столбца возвращает один столбец с четырьмя строками.
Request: http://www.example.com/mydatasource?tq=select Col1 Response: google.visualization.Query.setResponse({version:'0.6',reqId:'0',status:'ok',sig:'6099996038638149313',table:{cols:[{id:'Col1',label:'',type:'number'}],rows:[{c:[{v:1.0,f:'1'}]},{c:[{v:2.0,f:'2'}]},{c:[{v:3.0,f:'3'}]},{c:[{v:1.0,f:'1'}]}]}});
Ошибка не измененных данных: пример ошибки not_modified
.
Request: http://www.example.com/mydatasource?tqx=reqId:0;sig:4641982796834063168 Response: google.visualization.Query.setResponse({version:'0.6',reqId:'0',status:'error',errors:[{reason:'not_modified',message:'Data not modified'}]});
Предупреждение об усечении данных: пример предупреждения data_truncated
. Обратите внимание, что запрос по-прежнему возвращает данные.
Request: http://www.example.com/mydatasource?tq=limit 1 Response: google.visualization.Query.setResponse({version:'0.6',reqId:'0',status:'warning',warnings:[{reason:'data_truncated',message:'Retrieved data was truncated'}],sig:'1928724788649668508',table:{cols:[{id:'A',label:'NEW A',type:'string'},{id:'B',label:'B-label',type:'number'},{id:'C',label:'C-label',type:'datetime'}],rows:[{c:[{v:'a'},{v:1.0,f:'1'},{v:new Date(2008,1,28,0,31,26),f:'2/28/08 12:31 AM'}]}]}});
Ошибка отказа в доступе: пример ошибки access_denied
.
Request: http://www.example.com/mydatasource Response: google.visualization.Query.setResponse({version:'0.6',reqId:'0',status:'error',errors:[{reason:'access_denied',message:'Access denied',detailed_message:'Access Denied'}]});
Недопустимая строка запроса: пример запроса с недопустимой строкой запроса. Обратите внимание, что подробное сообщение является общим сообщением, а не фактическим сообщением об ошибке.
Request: http://www.example.com/mydatasource?tq=select A Response: google.visualization.Query.setResponse({version:'0.6',reqId:'0',status:'error',errors:[{reason:'invalid_query',message:'Invalid query',detailed_message:'Bad query string.'}]});
Инструменты разработки
- Библиотека источников данных Java (от Google) — обрабатывает запрос и ответ, создает таблицу ответов на основе предоставленных вами данных и реализует язык запросов Google Chart Tools SQL.
- Библиотека источников данных Python (от Google) — создает таблицу ответов, генерирует синтаксис ответа. Не выполняет синтаксический анализ запроса или реализацию языка запросов Google Chart Tools SQL .
- MC-Google_Visualization (сторонняя) — это серверная библиотека PHP, которую вы можете использовать для реализации источника данных Chart Tools для механизмов баз данных MySQL, SQLite и PostgreSQL с использованием PDO.
- bortosky-google-visualization (Сторонние) — это вспомогательная библиотека для создания таблицы данных Google Visualization API для пользователей .NET.
- GV Streamer (сторонний) — GV Streamer — это инструмент на стороне сервера, который может преобразовывать данные из разных источников в действительные ответы на запросы к диаграммам Google. GV Streamer поддерживает несколько языков (например, PHP, Java, .NET) и несколько исходных источников данных (например, MySql).
- TracGViz (Сторонний) — TracGViz — это бесплатный инструмент с открытым исходным кодом, который предоставляет компоненты, позволяющие Trac использовать гаджеты диаграмм, а также реализует данные, управляемые Trac, в качестве источника данных Google Chart Tools.
- vis-table (Сторонние) — библиотека, реализующая источник данных Google Chart Tools на PHP. Он состоит из трех основных частей. Сама реализация datatable, анализатор языка запросов и средства форматирования.
- Реализация источника данных Google в Oracle PL/SQL (сторонний) — пакет Oracle PL/SQL, который позволяет Oracle серверировать источники данных непосредственно из базы данных. Таким образом, вы можете использовать любой запрос Oracle в качестве источника данных Google Chart Tools (пакет вернет файл JSON с данными). Он имеет почти полную поддержку языка запросов Google.