2.3. Связь с данными
Реализовано два варианта передачи данных в диаграмму: через интерфейс DataProvider
и с использованием упрощённого API, позволяющего привязывать данные напрямую при помощи метода addData()
и удобных конструкторов класса MapDataItem
. Последний способ подходит для диаграмм, для которых не определен контейнер данных. В главе Пример работы с диаграммами проиллюстрированы все способы получения данных.
- DataProvider:
-
Интерфейс
DataProvider
имеет две стандартные реализации: классListDataProvider
и классContainerDataProvider
.-
ListDataProvider
содержит список экземпляровDataItem
, из которых будут браться данные для диаграммы. Существует несколько стандартных реализаций интерфейсаDataItem
:-
EntityDataItem
принимает экземпляр сущности, из которой будут браться данные для диаграммы:@Inject private PieChart chart; @Inject private Metadata metadata; @Subscribe protected void onInit(InitEvent event) { ListDataProvider dataProvider = new ListDataProvider(); dataProvider.addItem(new EntityDataItem(valueDescription(75, "Sky"))); dataProvider.addItem(new EntityDataItem(valueDescription(7, "Shady side of pyramid"))); dataProvider.addItem(new EntityDataItem(valueDescription(18, "Sunny side of pyramid"))); chart.setDataProvider(dataProvider); } private ValueDescription valueDescription(Integer value, String description) { ValueDescription entity = metadata.create(ValueDescription.class); entity.setValue(value); entity.setDescription(description); return entity; }
-
MapDataItem
содержит набор пар ключ-значение, из которого будут браться данные для диаграммы:@Inject private PieChart chart; @Subscribe protected void onInit(InitEvent event) { ListDataProvider dataProvider = new ListDataProvider(); dataProvider.addItem(new MapDataItem( ImmutableMap.of("value", 75, "description", "Sky"))); dataProvider.addItem(new MapDataItem( ImmutableMap.of("value", 7, "description", "Shady side of pyramid"))); dataProvider.addItem(new MapDataItem( ImmutableMap.of("value", 18, "description", "Sunny side of pyramid"))); chart.setDataProvider(dataProvider); }
-
SimpleDataItem
принимает экземпляр любогоpublic
класса, из которого будут браться данные для диаграммы:
@Inject private PieChart chart; @Subscribe protected void onInit(InitEvent event) { ListDataProvider dataProvider = new ListDataProvider(); dataProvider.addItem(new SimpleDataItem(new ValueDescription(75, "Sky"))); dataProvider.addItem(new SimpleDataItem(new ValueDescription(7, "Shady side of pyramid"))); dataProvider.addItem(new SimpleDataItem(new ValueDescription(18, "Sunny side of pyramid"))); chart.setDataProvider(dataProvider); } public class ValueDescription { private Integer value; private String description; public ValueDescription(Integer value, String description) { this.value = value; this.description = description; } public Integer getValue() { return value; } public String getDescription() { return description; } }
-
-
ContainerDataProvider
используется для связи CollectionContainer с компонентом диаграммы.Предположим, имеется контейнер данных с загрузчиком, который получает список экземпляров сущности
TransportCount
. Ниже приведен фрагмент XML-дескриптора экрана:<data> <collection id="transportCountsDc" class="com.company.sampler.entity.TransportCount" view="_local"> <loader id="transportCountsDl"> <query><![CDATA[select e from sampler_TransportCount e order by e.year]]></query> </loader> </collection> </data> <layout> <chart:serialChart id="stackedArea" marginLeft="0" marginTop="10" plotAreaBorderAlpha="0" height="100%" width="100%"> <!--...--> </chart:serialChart> </layout>
В контроллере экрана определяется метод
onInit()
, который задает провайдер данных для диаграммыstackedArea
. Провайдер данных создан на основе контейнера данныхtransportCountsDc
.@UiController("sampler_StackedareaChartSample") @UiDescriptor("stackedarea-chart-sample.xml") @LoadDataBeforeShow public class StackedareaChartSample extends Screen { @Inject private CollectionContainer<TransportCount> transportCountsDc; @Inject private SerialChart stackedArea; @Subscribe private void onInit(InitEvent event) { stackedArea.setDataProvider(new ContainerDataProvider(transportCountsDc)); stackedArea.setCategoryField("year"); } }
Данный вариант требует наличия сущности, представляющей данные диаграммы. Он удобен, когда такая сущность уже есть в модели данных приложения, а также когда данные диаграммы нужно отобразить и в виде таблицы.
Экземпляр
DataProvider
передается методуsetDataProvider()
конфигурации диаграммы. Данный способ предоставления данных для диаграммы наиболее универсален, однако требует создания экземпляровDataProvider
илиDataItem
в коде контроллера экрана.Используемые для отображения свойства сущности или значения, содержащиеся в экземпляре
DataProvider
, задаются в атрибутах диаграммы, причем атрибуты различаются для разных типов диаграмм. Например для компонентаchart:pieChart
необходимо задать атрибутыvalueField
иtitleField
.В качестве значений могут выступать типыInteger
,Long
,Double
,String
,Boolean
,Date
.С помощью механизма
DataProvider
поддерживается динамическое добавление данных в существующий график. -
- Элемент chart:data:
-
Этот способ удобен для быстрого прототипирования диаграмм. Элемент
chart:data
и вложенные в него элементыitem
позволяют вручную указать фиксированные значения прямо в XML-дескрипторе диаграммы, например:<chart:pieChart id="pieChart" titleField="key" valueField="value"> <chart:data> <chart:item> <chart:property name="key" value="piece of apple pie"/> <chart:property name="value" value="70" type="int"/> </chart:item> <chart:item> <chart:property name="key" value="piece of blueberry pie"/> <chart:property name="value" value="20" type="int"/> </chart:item> <chart:item> <chart:property name="key" value="piece of cherry pie"/> <chart:property name="value" value="10" type="int"/> </chart:item> </chart:data> </chart:pieChart>