В следующем примере мы рассмотрим диаграмму, которая получает данные из источника данных и обновляет их автоматически. Когда в источник добавляются новые данные, диаграмма не обновляется полностью: новые точки добавляются в график на лету каждые 2 секунды. Этот принцип удобно использовать при создании динамически обновляемых виджетов.
Пример основан на тестовом приложении Sales, к которому мы добавим диаграмму для отображения динамики новых заказов, то есть создания новых экземпляров сущности Order
.
-
Скачайте приложение Sales и добавьте к нему компонент charts, следуя инструкции из раздела [chart_project_setup].
-
Создайте в Studio новый пустой экран. Назовите его orders-history, так как в нём будет отображаться история создания новых заказов.
-
Добавьте к экрану компонент
serialChart
. Чтобы реализовать инкрементальное обновление данных, необходимо создать источник данных с типомcollectionDatasource
и привязать к нему диаграмму. В этом примере мы не будем загружать данные из базы, вместо этого мы будем создавать тестовые данные на лету, поэтому запрос в источнике данных создавать не нужно.Для оси категорий укажите атрибут
date
, для оси значений - атрибутamount
.link:../../../../source/chart/chart_incremental-update.xml[role=include]
-
Для обновления данных на лету используйте
timer
- специальный UI-компонент, который будет отправлять HTTP-запросы на сторону сервера.Отройте вкладку Properties дизайнера экрана и нажмите на кнопку Timers, чтобы добавить таймер на экран. Заполните поле id. Допустим, мы хотим, чтобы данные обновлялись каждые 2 секунды, в этом случае в поле delay укажем значение 2000 миллисекунд.
В поле onTimer укажем имя метода Java -
updateChart
. Этот метод будет вызываться каждый раз при срабатывании события таймера. Сгенерируйте метод в контроллере экрана, нажав на кнопку >>, после чего сохраните его, нажав Apply. -
Откройте контроллер экрана в IDE. Для разработки логики работы таймера нам понадобится инжектировать следующие зависимости:
timeSource
,metadata
и экземпляр источника данных. Мы будем генерировать новый экземпляр сущностиOrder
с произвольным значениемamount
при каждом событии срабатывания таймера. Новый экземпляр добавляется к источнику данных с помощью методаincludeItem()
.Инициализируйте диаграмму в методе
init()
, создав таким же образом исходный экземпляр сущностиOrder
.link:../../../../source/chart/chart_incremental-update.java[role=include]
На этом этапе диаграмма полностью функциональна, но размер источника данных после запуска таймера будет стремительно расти, поэтому реализуем ограничение количества отображаемых заказов.
-
Создайте экземпляр класса
Queue
для очереди заказов. При каждом срабатывании таймера созданный заказ будет добавлен наверх очередиitemsQueue
. Когда размер очереди превышает 10 заказов, самый старый заказ удаляется.private Queue<Order> itemsQueue = new LinkedList<>();
link:../../../../source/chart/chart_incremental-update_2.java[role=include]
- Результат
-
Данные поступают в браузер инкрементально. Если открыть консоль разработчика в Chrome, на вкладке Network будет видно, что каждые 2 секунды страница отправляет HTTP-запрос на backend и в ответе получает очень маленький JSON, содержащий только операции
add
иremove
со значениями поляamount
. Это позволяет избежать повторной пересылки всех данных диаграммы.