28 июл. 2008 г.

Flash графики в Apex на полную мощность



Речь пойдет о построении графиков и диаграмм в Oracle Apex 3.1. Дело в том, что Apex для построения флэш графиков использует стороннюю компоненту AnyChart. Но для стандартных графиков используется AnyChart версии 3, в то время как intaractive reports строят графики с помощью AnyChart версии 4. Так вот эта самая четвертая версия выгодно отличается своим внешним видом от своей предшественницы.
Для сравнения галлерея AnyChart 3 и галлерея AnyChart 4 (или уже 5?). Замечу еще, что для AnyChart 4 требуется Flash Player версии 9 и выше, в то время как для AnyChart 3 достаточно Flash Player 8.
Итак, что мы имеем: Apex 3.1 с двумя встроенными компонентами для построения графиков и диаграмм. И к этому всему достаточно бедный интерфейс для их создания в самом апексе, да и то для устаревшей версии.

Будем исправлять ситуацию.
Для начала создадим Application Process типа OnDemand с именем GETDATA следующего содержания:

begin
htp.p('<anychart>
<settings>
<animation enabled="True"/>
</settings>
<charts>
<chart plot_type="CategorizedVertical">
<data_plot_settings default_series_type="Bar" enable_3d_mode="true" z_padding="0.2" z_aspect="0.8">
<bar_series point_padding="0" group_padding="0.2">
<tooltip_settings enabled="True"/>
</bar_series>
</data_plot_settings>
<chart_settings>
<title enabled="true">
<text>Multi-Series: Columns Clustered by Z-Axis</text>
</title>
<axes>
<y_axis>
<scale mode="Overlay"/>
<labels>
<format>{%Value}{numDecimals:0}</format>
</labels>
</y_axis>
</axes>
</chart_settings>
<data>
<series name="Series 1">
<point name="P1" y="22"/>
<point name="P2" y="34"/>
<point name="P3" y="16"/>
<point name="P4" y="32"/>
<point name="P5" y="68"/>
</series>

<series name="Series 2">
<point name="P1" y="23"/>
<point name="P2" y="45"/>
<point name="P3" y="46"/>
<point name="P4" y="86"/>
<point name="P5" y="45"/>
</series>

<series name="Series 3">
<point name="P1" y="25"/>
<point name="P2" y="56"/>
<point name="P3" y="67"/>
<point name="P4" y="32"/>
<point name="P5" y="27"/>
</series>

<series name="Series 4">
<point name="P1" y="33"/>
<point name="P2" y="29"/>
<point name="P3" y="56"/>
<point name="P4" y="49"/>
<point name="P5" y="77"/>
</series>
</data>
</chart>
</charts>
</anychart>
');
end;


Этот процесс всего лишь возвращает данные в виде xml, сформатированном для компоненты AnyChart. Формат xml можно подсмотреть в документации. Я для простоты взял готовый xml оттуда же. А в принципе, как раз на этом шаге можно моделировать график, исходя из своей фантазии и возможностей AnyChart, пользуясь исключительно знакомым pl/sql.

Дальше на странице, где будем "рисовать" график в поле HTML Header добавим:

<script type="text/javascript" src="/i/flashchart/js/AnyChart.js"></script>


И последнее. Создадим на странице HTML Region, в источнике которого пропишем:

<div id="chart1">
<script type="text/javascript" language="javascript">
var chart = new AnyChart('/i/flashchart/swf/AnyChart.swf');
var get = new htmldb_Get(null,$x('pFlowId').value,'APPLICATION_PROCESS=GETDATA',1);
gRet = get.get(null);
get = null;
chart.setData(gRet);
chart.write(chart1);
</script>
</div>


Вуаля! Посмотреть результат проделанного можно здесь - должно быть примерно то же самое что и на картинке в самом начале поста.

PS
Буду очень рад любым комментариям и поправкам к статье.

5 комментариев:

Анонимный комментирует...

А Вы знаете, что это нарушает лицензию?
про законные методы - тут: http://www.anychart.com/products/anychart/docs/upgrade-charts-in-apex.php

Alp комментирует...

Я что-то не понял как это нарушает лицензию. Типа нельзя напрямую пользовать AnyChart?

Анонимный комментирует...

Просто в текущей версии Apex новые версию чартов можно использовать только в Interactive reports.

Хотя на самом деле у Вас очень интересное техническое решение, и мы (компания AnyChart) даже готовы поддерживать подобные инициативные проекты на Apex. Если Вам интересно сотрудничество с нами - дайте знать (контакты на сайте http://www.anychart.com/support/)

Andrey комментирует...

Здравствуйте, уважаемый! Мне понравилось ваше решение. Повторив его получил превосходный результат. Последовав Вашему способу не заморачиваться с созданием собственного XML скопировал его из имеющихся в наличиии у AnyChart. Великолепно! Спасибо за такие примеры!
А теперь вопрос. Я генирирую динамический XML с помощью функции на стороне сервера. Функция возвращает тип XML. Если я преобразовываю этот тип в строку символов, то график строится, а ежели нет, то ошибка. Если сгенерированный XML достаточно большой, то в лучшем случае получаю только размеченный в осях график без данных. Что я не так делаю? Подскажите.

Alp комментирует...

Видимо проблема в том, что htp.p принимает varchar2, соответсвенно натыкаетесь на ограничение по размеру. Вам нужно обойти его, разбив ваш xml на части. Еще можете глянуть в сторону пакета OWA_TEXT, возможно найдете для себя что-нибудь полезное.