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);
	
	chartProperty.setChartTitle("Year-on-year Car Sales ");
	chartProperty.setCssStyle("width:300px;height:200px");
	chartProperty.setLegendPosition("ne");
	chartProperty.setStacked(true);
	
	int[][] salesVolumes = new int[][]{
		new int[]{200, 300, 500},  // series: Model A
		new int[]{300, 500, 800}   // series: Model B
		};
		
	String[] models = new String[]{"Model A", "Model B"};
	String[] periods = new String[]{"2012", "2013", "2014"};
		
	chartProperty.createCartesianChartModel(salesVolumes, 
		models, periods, 0, null, 0, null);
		
	// ajax 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);
	
	chartProperty.setChartTitle("Year-on-year Car Sales ");
	chartProperty.setCssStyle("width:300px;height:300px");
	chartProperty.setLegendPosition("ne");
	chartProperty.setShowDataLabels(true);
	
	int[] salesVolumes = new int[]{500, 800, 1300};
	String[] periods = new String[]{"2012", "2013", "2014"};
		
	chartProperty.createPieChartModel(salesVolumes, 
		periods, 0, null);

	// ajax 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.

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 popup 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 ExampleHR example, 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 needs 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 String getReportDataDisplayName(Integer reportData) throws SystemException {
		// reportData display name
	}
	
	@Override
	protected NumberDescriptor getReportDataNumberDescriptor(Integer reportData) throws SystemException {
		// reportData number type
	}
	
	@Override
	protected String getGroupByDisplayName(Integer groupBy) throws SystemException {
		// groupBy display 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<String> getGroupByValueDisplayNames(ExpenseReportQueryForm form, 
  		List<Comparable<Object>> groupByValues) 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
	}
}

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 ExampleHR example, 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 listing is a better options for report display.

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 the its ReportQueryFormBean subclass.

	public PageNavigation handleItemSelect(ReportBean reportBean, 
			int seriesIndex, int itemIndex) throws SystemException

Export

All entity list can be exported as Excel. Report tabular list is a MapEntity list and thus can be exported as Excel.