Cmobilecom AF 5.19 Developer Guide

18 Report and Charting

Charting

EntityChartProperty is used for building cartesian or pie chart model, and thus a chart will be shown as an entity property of an EntityBackingBean or EntityListBackingBean.

Example 1: create a cartesian chart


	EntityChartProperty<T> chartProperty = new EntityChartProperty<T>(backingBean, propertyName, null);
	// bar or line chart
	RenderStyle renderStyle = new RenderStyle(RenderStyle.BAR_CHART);
	chartProperty.setRenderStyle(renderStyle);

	CartesianChart cartesianChart = new CartesianChart();
	cartesianChart.setTitle(new ParameterizedMessage("Year-on-year Car Sales", true));
	cartesianChart.setStacked(true);

	ChartSeries chartSeriesA = new ChartSeries(
			I18NName.valueOf("Car Model A", true),
			Arrays.asList(200, 300, 500));

	ChartSeries chartSeriesB = new ChartSeries(
			I18NName.valueOf("Car Model B", true),
			Arrays.asList(300, 500, 800));

	cartesianChart.addSeries(chartSeriesA);
	cartesianChart.addSeries(chartSeriesB);
	cartesianChart.setLabels(I18NName.asList(true, "2020", "2021", "2022"));

	chartProperty.setCartesianChart(cartesianChart);

	// partial behavior to enable drill down
	chartProperty.getPartialBehaviorSupport(true).addPartialBehavior(
			new PartialBehavior(PartialBehavior.EVENT_ITEM_SELECT));
		
	backingBean.getEntityPropertyList(true).add(chartProperty);
Example 2: create a pie chart

	EntityChartProperty<T> chartProperty = new EntityChartProperty<T>(backingBean, propertyName, null);
	RenderStyle renderStyle = new RenderStyle(RenderStyle.PIE_CHART);
	chartProperty.setRenderStyle(renderStyle);

	PieChart pieChart = new PieChart();
	pieChart.setTitle(new ParameterizedMessage("Year-on-year Car Sales", true));

	ChartSeries chartSeries = new ChartSeries(
			I18NName.valueOf("Car Sales", true),
			Arrays.asList(500, 800, 1300));
	pieChart.addSeries(chartSeries);
	pieChart.setLabels(I18NName.asList(true, "2020", "2021", "2022"));

	chartProperty.setPieChart(pieChart);

	// partial behavior to enable drill down
	chartProperty.getPartialBehaviorSupport(true).addPartialBehavior(
			new PartialBehavior(PartialBehavior.EVENT_ITEM_SELECT));
		
	backingBean.getEntityPropertyList(true).add(chartProperty);
To support more chart types, see Extensions.

Reporting

Reporting involves building a database query that generates data for charting and/or tabular listing. Report type can be year-on-year or period_on_period.

For charting, the X-axis is date periods, and Y-axis is reporting values. Multiple series of values can be shown in one chart, and they can be stacked in bar or line chart. For tabular listing, the table headers are date periods, and table rows are series of values. Clicking items in chart or tabular listing will pop up dialog for drill down.

ReportQueryForm and ReportQueryFormBean are the base classes for reporting. A ReportQueryForm allows users to input or select report data, date periods and report display options. Display options include display format, chart type, whether to stack, legend position and chart dimensions. For the example HR module, ExpenseReportQueryForm extends ReportQueryForm to add employee and ExpenseClaimItem code as query restrictions.


public class ExpenseReportQueryForm extends ReportQueryForm {
	
	private Employee employee;
	private String code;

	public Employee getEmployee() {
		return employee;
	}

	public void setEmployee(Employee employee) {
		this.employee = employee;
	}

	public String getCode() {
		return code;
	}

	public void setCode(String code) {
		this.code = code;
	}
	
}

ExpenseReportQueryFormBean extends ReportQueryFormBean, adding employee, code and groupBy properties. Group by employee or code. The reportDataList and groupBy of ReportQueryForm are integers, and they need to have names for display.


public class ExpenseReportQueryFormBean extends ReportQueryFormBean<ExpenseReportQueryForm> {
	
	@UIDefines({
		@UIDefine(name=UI_QUERY_PROPERTIES, value={
			@Property(name="groupBy", view={ViewType.ALL},  
				renderStyle=@RenderStyleDef(style=RenderStyle.SELECT_ONE_MENU)),
		  				        
			@Property(name="employee", view={ViewType.ALL}),
			@Property(name="code", view={ViewType.ALL})
		})
	})
	public boolean hasPropertyAnnotations() {
		return true; 
	}
  
	@Override
	public List<SelectItem> getPropertySelectItems(EntityProperty<ExpenseReportQueryForm> property) throws SystemException {
		// return selectItems for reportDataList and groupBy
	}
  
	@Override
	protected I18NName getReportDataName(Integer reportData) throws SystemException {
		// reportData name
	}
	
	@Override
	protected NumberDescriptor getReportDataNumberDescriptor(Integer reportData) throws SystemException {
		// reportData number type
	}
	
	@Override
	protected I18NName getGroupByName(Integer groupBy) throws SystemException {
		// groupBy choice name
	}
	
	@Override
	protected void buildCriteriaQuery(CriteriaBuilder criteriaBuilder, CriteriaQuery<Object[]> criteriaQuery,
		T reportQueryForm, List<Integer> reportDataList, DatePeriod datePeriod, int periodIndex) {
		// build query criteria for the report data list
	}
		
	@Override
	protected List<I18NName> getGroupByValueDisplayNames(T queryForm,
			List<Comparable> groupByValues,
			Map<Comparable, PersistenceEntity> groupByValueEntityMap) throws SystemException {
  		// display names of group by values, employee names or codes
	}

	@Override
	protected Predicate getRestriction(CriteriaBuilder criteriaBuilder, CriteriaQuery<Object[]> criteriaQuery, 
  		int reportData, int groupBy, Object groupByValue) {
  		// get restriction for the reportData and groupBy value
  	}
	
	@Override
	protected DatePeriodInfo getDefaultDatePeriodInfo() throws SystemException {
		// default date period for ReportQueryForm
	}
	
	@Override
	public HelpPathInfo getHelpPathInfo(PersistenceDataBackingBean<ExpenseReportQueryForm> backingBean) {
		// help URL path
	}
}
See the example HR module on how to implement these methods.

Building query criteria is the main task of reporting. If groupBy is not null, add the groupBy to the query criteria. If groupBy is selected, only one reportData is allowed. For the example HR module, if there are 10 employees and expense report is grouping by employee, then there will be 10 series of values, one for each employee. If there are too many series of values, tabular list is a better options for report display, which can be exported as Excel.

ViewConfig Parameters

ReportQueryFormBean viewConfig supports the following parameters:

Drill Down

The default drill down is showing the list of entities that are used to compute the report data. To show different content, override the following method in its ReportQueryFormBean subclass.

	@Override
	public PageNavigation handleItemSelect(ReportBean reportBean, 
			int seriesIndex, int itemIndex) throws SystemException {
	}
Entity Batch PrintResource BundleFrames / No Frames