Binding Data in BIRT
The data set or data sets you create return the data you want to use in a report. Before you can use or display data set data in a report, you must first create the necessary data bindings. As the first tutorial demonstrated, to display the data in a report, you simply drag data set fields from Data Explorer to a table in the layout editor.
You might also remember in that same tutorial that when you dragged a data set field to the layout editor, BIRT Report Designer first displayed a dialog called Select Data Binding. This dialog, shown in Figure 8-1, shows the data binding that BIRT Report Designer creates each time you insert a data set field. This data binding, called a column binding, defines an expression that specifies what data to display. The column binding also defines a name that report elements use to access data.
Figure 8-1 Select Data Binding showing a column binding
Understanding column bindings
For each piece of data to display in a report, there must be a column binding. For this discussion, note that data refers to dynamic data, and not static text that you type for a label. Dynamic data is data from a data set, or data that is calculated from a function or a formula. The data is dynamic, because the values are not fixed at design time.
The default column binding, which BIRT Report Designer creates for a data set field, uses the data set field name as the name of the column binding. You can change the name of the column binding, and you might want to do so if the data set field name is not descriptive. In Figure 8-1, the expression defined for the column binding is dataSetRow["CUSTOMERNAME"]. This expression indicates that the column binding accesses data from the data set field, CUSTOMERNAME. In the layout editor, the column-binding name appears within square brackets ([ ]) in the report, as shown in Figure 8-2.
Figure 8-2 Data element displaying the column-binding name
Column bindings form an intermediate layer between data set data and report elements—such as chart, data, dynamic text, and image elements—that display data. Figure 8-3 illustrates this concept. Report elements can access data only through column bindings.
Figure 8-3 Report elements access data set data through column bindings
Figure 8-4 shows this column binding defined in Select Data Binding.
Figure 8-4 User-defined column binding
One of the benefits of using column bindings is that you control the names used in the report. Instead of displaying data set field names, which are often not descriptive enough, or formulas, which can be long, you can specify short and descriptive names. If you share report designs with other report developers, descriptive names make that design much easier to understand. Modifying and maintaining a report design that has user-friendly names is easier. When deciding what names to use, consider that, in the layout editor, elements display up to 20 characters.
Dynamic updates of calculated data
Another advantage of column bindings becomes apparent when you work with calculated data. When a report needs to display a series of related calculated data, column bindings enable you to create and update calculations easily. For example, assume a report contains the following four data elements:
- The first data element uses column binding, Total_National_Sales, which defines the following expression to calculate the sum of all order amounts:
The second data element uses column binding, Total_State_Sales, which defines the following expression to calculate the sum of order amounts in each state:
This expression is the same as the previous expression, but both return different results, because they perform the aggregate calculation over different sets of rows.
The third data element uses column binding, Percent_State_Sales, which uses the previous column bindings to calculate a state's total sales as a percentage of the overall sales. The expression is:
row["Total_State_Sales"]/row["Total_National_Sales"] * 100
Without column bindings, the calculation would have to be more complicated:
Total.sum(row["Order_Amount"], null, "state")/ Total.sum(row["Order_Amount"], null, "overall") * 100
The fourth data element uses column binding, National_Profit, which contains this expression:
row["Total_National_Sales"] - row["Total_Costs"]
Without column bindings, this calculation would also be more complicated:
Total.sum(row["Order_Amount"], null, "overall") - Total.sum(row["Item_Cost"])
You have already seen how column bindings make expressions shorter and more readable. Now, consider the case where you need to update one calculation that is used by other calculations. Suppose you need to change how the total national sales is calculated, from
Total.sum(row["Order_Amount"]) - Total.sum(row["Order_Amount"]) * 0.08
Because the third and fourth data elements use the total national sales calculation in their calculations, without column bindings, you would have to manually edit those calculations as well. Without column bindings, you would have to revise the expression for the fourth element as follows:
(Total.sum(row["Order_Amount"])- Total.sum(row["Order_Amount"]) * 0.08)- Total.sum(row["Item_Cost"])
By using column bindings, any change to the first calculation automatically applies to the third and fourth calculations. Instead of modifying three expressions, you modify only one. Your work is faster and less error-prone.