2.3. Connecting Data
There are two ways how you can pass data to a chart: through the DataProvider interface or using the simplified data binding API, which allows adding the data directly using the addData() method and convenient MapDataItem constructors for those charts that are not bound to a data container. Example of Working with Charts illustrates all approaches to providing chart data.
- DataProvider:
-
The
DataProviderinterface has two standard implementations:ListDataProviderclass andContainerDataProviderclass.-
ListDataProvidercontains a list ofDataIteminstances from which the data for the chart will be taken. There are several standard implementations ofDataIteminterface:-
EntityDataItemtakes an instance of any entity from which the data for the chart will be taken:@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; } -
MapDataItemis a set of key-value pairs from which the data for the chart will be taken:@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); } -
SimpleDataItemtakes an instance of anypublicclass from which the data for the chart will be taken:@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; } }
-
-
ContainerDataProvideris used to assign a CollectionContainer to aChartcomponent.Suppose we have a data container with a loader which will load the
TransportCountinstances. Below is the fragment of the screen XML descriptor:<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>The screen controller defines the
onInit()method that sets the data provider for thestackedAreachart. Data provider is based on thetransportCountsDcdata container.@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"); } }This approach requires an entity that will represent chart data. It may be convenient when such an entity already exists in the application data model and also when chart data should be displayed as a table.
An instance of
DataProvideris passed to thesetDataProvider()method of chart configuration. This approach to providing chart data is the most universal, but it requires creating instances ofDataProviderorDataItemin a screen controller.Entity properties or the values contained in an instance of
DataProviderwhich are used for display purposes are defined in the chart attributes. The set of chart attributes may differ for different chart types. For example, for thechart:pieChartcomponent, you should define thevalueFieldandtitleFieldattributes. The following types are allowed for attribute values:Integer,Long,Double,String,Boolean,Date.Dynamic addition of data to an existing chart is supported for the data provider mechanisms.
-
- chart:data element:
-
This option is useful for quick prototyping of charts. The
chart:dataelement and its nesteditemelements enable you to set key-value pairs of data directly in the XML descriptor of the chart, for example:<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>