Breaks

The break step allows creation of title/total rows and preform multiple computations. It can be used to shrink rows and output only a summary of the input data, or simply add title/total rows in-between.



Input data

This data table will be the employees input:

ID FIRSTNAME LASTNAME SEX BIRTHDATE DEPARTMENT SALARY FEES LEVEL PARENT ACTIVE
01 Peter Bosshard M 05.02.1958 DIR 5800.00 340.05 1 true
02 Maria Skinov F 25.06.1964 DIR 5700.00 480.15 2 01 true
03 Casey Cole M 28.08.1955 DIR 5700.00 210.50 2 01 true
04 Roger Binner M 13.01.1959 DIR 5700.00 230.55 2 01 true
05 Olive Saltin F 31.03.1961 DIR 5700.00 727.12 2 01 false
06 Bill Amacker M 27.10.1968 HEA 5300.00 0.00 3 02 true
07 Aby Thornson F 26.11.1967 HEA 5300.00 140.00 3 02 true
08 Anne Pevler F 14.09.1967 HEA 5300.00 150.00 3 03 true
09 Annita Smith F 17.12.1967 HEA 5300.00 60.00 3 04 true
10 Robert Smith M 13.12.1970 DEV 5000.00 0.00 4 06 true
11 Maggie Frill F 29.02.1972 DEV 5000.00 0.00 4 06 true
12 Daniel Metzler M 01.01.1973 DEV 4900.00 0.00 4 07 true
13 Frank Witz M 05.01.1973 DEV 4900.00 10.00 4 07 true
14 Franky Bilen M 12.12.1972 DEV 4900.00 0.00 4 07 true
15 Ed Krack M 08.04.1969 DEV 5100.00 0.00 4 07 true
16 Sean Huskynd M 04.09.1971 DEV 4900.00 0.00 4 07 false
17 Alice Muller F 09.10.1976 STG 4500.00 0.00 4 07 true

Basic break

This section presents the basics features of a break step.

Title/Total

Basically, one want to be able to generate a special title row (special row before a bunch of rows) and a total row (special row after a bunch of rows). This works a s simple projection step tagged with title and total.

One can put anything in a title/total row but the type of the column must be the same ! Hence you cannot put a String in column that should contain a BigDecimal.

<blueiron output="final">
  <input id="employees">
    <column id="ID" type="String" />
    <column id="FIRSTNAME" type="String" />
    <column id="LASTNAME" type="String" />
    <column id="SEX" type="String" />
    <column id="BIRTHDATE" type="Date" />
    <column id="DEPARTMENT" type="String" />
    <column id="SALARY" type="BigDecimal" />
    <column id="FEES" type="BigDecimal" />
    <column id="LEVEL" type="Integer" />
    <column id="PARENT" type="String" />
    <column id="ACTIVE" type="Boolean" />
  </input>

  <step id="final" source="employees">
    <break>
      <title>
        <value id="FIRSTNAME">All Employees</value>
        <value id="LASTNAME">Title</value>
      </title>
      <total>
        <value id="FIRSTNAME">All Employees</value>
        <value id="LASTNAME">Total</value>
      </total>
    </break>
  </step>
</blueiron>

In the descriptor above, there is no special condition, hence only one title and total row will be created at the top and bottom of the list:

ID FIRSTNAME LASTNAME SEX BIRTHDATE DEPARTMENT SALARY FEES LEVEL PARENT ACTIVE
All Employees Title
01 Peter Bosshard M 05.02.1958 DIR 5800.00 340.05 1 true
02 Maria Skinov F 25.06.1964 DIR 5700.00 480.15 2 01 true
03 Casey Cole M 28.08.1955 DIR 5700.00 210.50 2 01 true
04 Roger Binner M 13.01.1959 DIR 5700.00 230.55 2 01 true
05 Olive Saltin F 31.03.1961 DIR 5700.00 727.12 2 01 false
06 Bill Amacker M 27.10.1968 HEA 5300.00 0.00 3 02 true
07 Aby Thornson F 26.11.1967 HEA 5300.00 140.00 3 02 true
08 Anne Pevler F 14.09.1967 HEA 5300.00 150.00 3 03 true
09 Annita Smith F 17.12.1967 HEA 5300.00 60.00 3 04 true
10 Robert Smith M 13.12.1970 DEV 5000.00 0.00 4 06 true
11 Maggie Frill F 29.02.1972 DEV 5000.00 0.00 4 06 true
12 Daniel Metzler M 01.01.1973 DEV 4900.00 0.00 4 07 true
13 Frank Witz M 05.01.1973 DEV 4900.00 10.00 4 07 true
14 Franky Bilen M 12.12.1972 DEV 4900.00 0.00 4 07 true
15 Ed Krack M 08.04.1969 DEV 5100.00 0.00 4 07 true
16 Sean Huskynd M 04.09.1971 DEV 4900.00 0.00 4 07 false
17 Alice Muller F 09.10.1976 STG 4500.00 0.00 4 07 true
All Employees Total

Note that you could have only total or title rows (see further).

Computations

Generally, then intent of having breaks is to present computed results, for instance the sum of salaries and fees.

The tag computations allows to defines operations that must be computed. The latter can then be referenced in the title/total rows in column tags using the source attribute.

<blueiron output="final">
  <input id="employees">...</input>

  <step id="final" source="employees">
    <break>
      <total>
        <value id="LASTNAME">Total</value>
        <column id="SALARY" source="SUM_SALARIES" />
        <column id="FEES" source="SUM_FEES" />
      </total>
      <computations>
        <expr id="SUM_SALARIES">previousValue + SALARY</expr>
        <expr id="SUM_FEES">previousValue + FEES</expr>
      </computations>
    </break>
  </step>
</blueiron>

As one can see, there is a special variable called previousValue. Since each computation processor is invoked for each row, this variable will hold the value of the previous call. The scope of this variable is limited to each processor. Hence the previousValue of SUM_SALARIES is totally independant of the one in SUM_FEES.

ID FIRSTNAME LASTNAME SEX BIRTHDATE DEPARTMENT SALARY FEES LEVEL PARENT ACTIVE
01 Peter Bosshard M 05.02.1958 DIR 5800.00 340.05 1 true
02 Maria Skinov F 25.06.1964 DIR 5700.00 480.15 2 01 true
03 Casey Cole M 28.08.1955 DIR 5700.00 210.50 2 01 true
04 Roger Binner M 13.01.1959 DIR 5700.00 230.55 2 01 true
05 Olive Saltin F 31.03.1961 DIR 5700.00 727.12 2 01 false
06 Bill Amacker M 27.10.1968 HEA 5300.00 0.00 3 02 true
07 Aby Thornson F 26.11.1967 HEA 5300.00 140.00 3 02 true
08 Anne Pevler F 14.09.1967 HEA 5300.00 150.00 3 03 true
09 Annita Smith F 17.12.1967 HEA 5300.00 60.00 3 04 true
10 Robert Smith M 13.12.1970 DEV 5000.00 0.00 4 06 true
11 Maggie Frill F 29.02.1972 DEV 5000.00 0.00 4 06 true
12 Daniel Metzler M 01.01.1973 DEV 4900.00 0.00 4 07 true
13 Frank Witz M 05.01.1973 DEV 4900.00 10.00 4 07 true
14 Franky Bilen M 12.12.1972 DEV 4900.00 0.00 4 07 true
15 Ed Krack M 08.04.1969 DEV 5100.00 0.00 4 07 true
16 Sean Huskynd M 04.09.1971 DEV 4900.00 0.00 4 07 false
17 Alice Muller F 09.10.1976 STG 4500.00 0.00 4 07 true
Total 89000.00 2348.37

The id of the computations must be unique in the computations tag. It could have the same name as a column without any problem. Computations can then be referenced in the title/total rows. This time we use a direct reference to the computation. This allows to insert multiple computations result in the same column.

In the example above, the results of the sums are simply copied in the SALARY and FEES columns, but it is possible to use them in other columns:

<blueiron output="final">
  <input id="employees">...</input>

  <step id="final" source="employees">
    <break>
      <title>
        <value id="FIRSTNAME">Employees (${SUM_SALARIES} / ${SUM_FEES})</value>
      </title>
      <computations>
        <expr id="SUM_SALARIES">previousValue + SALARY</expr>
        <expr id="SUM_FEES">previousValue + FEES</expr>
      </computations>
    </break>
  </step>
</blueiron>
ID FIRSTNAME LASTNAME SEX BIRTHDATE DEPARTMENT SALARY FEES LEVEL PARENT ACTIVE
Employees (89,000.00 / 2,348.37)
01 Peter Bosshard M 05.02.1958 DIR 5800.00 340.05 1 true
02 Maria Skinov F 25.06.1964 DIR 5700.00 480.15 2 01 true
03 Casey Cole M 28.08.1955 DIR 5700.00 210.50 2 01 true
04 Roger Binner M 13.01.1959 DIR 5700.00 230.55 2 01 true
05 Olive Saltin F 31.03.1961 DIR 5700.00 727.12 2 01 false
06 Bill Amacker M 27.10.1968 HEA 5300.00 0.00 3 02 true
07 Aby Thornson F 26.11.1967 HEA 5300.00 140.00 3 02 true
08 Anne Pevler F 14.09.1967 HEA 5300.00 150.00 3 03 true
09 Annita Smith F 17.12.1967 HEA 5300.00 60.00 3 04 true
10 Robert Smith M 13.12.1970 DEV 5000.00 0.00 4 06 true
11 Maggie Frill F 29.02.1972 DEV 5000.00 0.00 4 06 true
12 Daniel Metzler M 01.01.1973 DEV 4900.00 0.00 4 07 true
13 Frank Witz M 05.01.1973 DEV 4900.00 10.00 4 07 true
14 Franky Bilen M 12.12.1972 DEV 4900.00 0.00 4 07 true
15 Ed Krack M 08.04.1969 DEV 5100.00 0.00 4 07 true
16 Sean Huskynd M 04.09.1971 DEV 4900.00 0.00 4 07 false
17 Alice Muller F 09.10.1976 STG 4500.00 0.00 4 07 true

Conditions

When one want to have multiple breaks, it is necessary to define a condition. Depending on how you want your breaks, consider sorting your data. This is because BlueIron processes the rows one by one and do not look ahead for further rows that should be included in the current break when the current row implies a new break. Hence, having a break condition of unsorted rows will probably output unwanted results.

Basically, the condition tells whether the row is in the current break or if a new one must be generated. A condition can be either a Boolean or an object that will be handled as a code: while the row has the same object, it is considered to be in the same break. The most simple implementation of a condition is to use a column:

<blueiron output="final">
  <input id="employees">...</input>

  <step id="final" source="employees">
    <break>
      <condition type="column" id="DEPARTMENT" />
      <total>
        <column id="DEPARTMENT" />
        <column id="SALARY" source="SUM_SALARIES" />
        <column id="FEES" source="SUM_FEES" />
      </total>
      <computations>
        <expr id="SUM_SALARIES">previousValue + SALARY</expr>
        <expr id="SUM_FEES">previousValue + FEES</expr>
      </computations>
    </break>
  </step>
</blueiron>
ID FIRSTNAME LASTNAME SEX BIRTHDATE DEPARTMENT SALARY FEES LEVEL PARENT ACTIVE
01 Peter Bosshard M 05.02.1958 DIR 5800.00 340.05 1 true
02 Maria Skinov F 25.06.1964 DIR 5700.00 480.15 2 01 true
03 Casey Cole M 28.08.1955 DIR 5700.00 210.50 2 01 true
04 Roger Binner M 13.01.1959 DIR 5700.00 230.55 2 01 true
05 Olive Saltin F 31.03.1961 DIR 5700.00 727.12 2 01 false
DIR 28600.00 1988.37
06 Bill Amacker M 27.10.1968 HEA 5300.00 0.00 3 02 true
07 Aby Thornson F 26.11.1967 HEA 5300.00 140.00 3 02 true
08 Anne Pevler F 14.09.1967 HEA 5300.00 150.00 3 03 true
09 Annita Smith F 17.12.1967 HEA 5300.00 60.00 3 04 true
HEA 21200.00 350.00
10 Robert Smith M 13.12.1970 DEV 5000.00 0.00 4 06 true
11 Maggie Frill F 29.02.1972 DEV 5000.00 0.00 4 06 true
12 Daniel Metzler M 01.01.1973 DEV 4900.00 0.00 4 07 true
13 Frank Witz M 05.01.1973 DEV 4900.00 10.00 4 07 true
14 Franky Bilen M 12.12.1972 DEV 4900.00 0.00 4 07 true
15 Ed Krack M 08.04.1969 DEV 5100.00 0.00 4 07 true
16 Sean Huskynd M 04.09.1971 DEV 4900.00 0.00 4 07 false
DEV 34700.00 10.00
17 Alice Muller F 09.10.1976 STG 4500.00 0.00 4 07 true
STG 4500.00 0.00

Hiding data

In some cases, only the summary of computations must be outputted. This can be done by simply adding the data attribute on the break tag.

<blueiron output="final">
  <input id="employees">...</input>

  <step id="final" source="employees">
    <break data="false">  <!--                      <======= do not output input data rows -->
      <condition type="column" id="DEPARTMENT" />
      <total>
        <column id="DEPARTMENT" />
        <column id="SALARY" source="SUM_SALARIES" />
        <column id="FEES" source="SUM_FEES" />
      </total>
      <computations>
        <expr id="SUM_SALARIES">previousValue + SALARY</expr>
        <expr id="SUM_FEES">previousValue + FEES</expr>
      </computations>
    </break>
  </step>
</blueiron>
ID FIRSTNAME LASTNAME SEX BIRTHDATE DEPARTMENT SALARY FEES LEVEL PARENT ACTIVE
DIR 28600.00 1988.37
HEA 21200.00 350.00
DEV 34700.00 10.00
STG 4500.00 0.00

Inner breaks

Breaks can beand define new conditions.

This can be simply done by adding a sub break tag and specify the condition. In the example below, there will be a total line per department (done by the sub-break) and a general total line (main break).

<blueiron output="final">
  <input id="employees">...</input>

  <step id="final" source="employees">
    <break>
      <total>
        <value id="DEPARTMENT">All</value>
        <column id="SALARY" source="SUM_SALARIES" />
        <column id="FEES" source="SUM_FEES" />
      </total>
      <computations>
        <expr id="SUM_SALARIES">previousValue + SALARY</expr>
        <expr id="SUM_FEES">previousValue + FEES</expr>
      </computations>
      <break>
        <condition type="column" id="DEPARTMENT" />
        <total>
          <column id="DEPARTMENT" />
          <column id="SALARY" source="SUM_SALARIES" />
          <column id="FEES" source="SUM_FEES" />
        </total>
        <computations>
          <expr id="SUM_SALARIES">previousValue + SALARY</expr>
          <expr id="SUM_FEES">previousValue + FEES</expr>
        </computations>
      </break>
    </break>
  </step>
</blueiron>
ID FIRSTNAME LASTNAME SEX BIRTHDATE DEPARTMENT SALARY FEES LEVEL PARENT ACTIVE
01 Peter Bosshard M 05.02.1958 DIR 5800.00 340.05 1 true
02 Maria Skinov F 25.06.1964 DIR 5700.00 480.15 2 01 true
03 Casey Cole M 28.08.1955 DIR 5700.00 210.50 2 01 true
04 Roger Binner M 13.01.1959 DIR 5700.00 230.55 2 01 true
05 Olive Saltin F 31.03.1961 DIR 5700.00 727.12 2 01 false
DIR 28600.00 1988.37
06 Bill Amacker M 27.10.1968 HEA 5300.00 0.00 3 02 true
07 Aby Thornson F 26.11.1967 HEA 5300.00 140.00 3 02 true
08 Anne Pevler F 14.09.1967 HEA 5300.00 150.00 3 03 true
09 Annita Smith F 17.12.1967 HEA 5300.00 60.00 3 04 true
HEA 21200.00 350.00
10 Robert Smith M 13.12.1970 DEV 5000.00 0.00 4 06 true
11 Maggie Frill F 29.02.1972 DEV 5000.00 0.00 4 06 true
12 Daniel Metzler M 01.01.1973 DEV 4900.00 0.00 4 07 true
13 Frank Witz M 05.01.1973 DEV 4900.00 10.00 4 07 true
14 Franky Bilen M 12.12.1972 DEV 4900.00 0.00 4 07 true
15 Ed Krack M 08.04.1969 DEV 5100.00 0.00 4 07 true
16 Sean Huskynd M 04.09.1971 DEV 4900.00 0.00 4 07 false
DEV 34700.00 10.00
17 Alice Muller F 09.10.1976 STG 4500.00 0.00 4 07 true
STG 4500.00 0.00
All 89000.00 2348.37

Computations inheritance

One can see that the descriptor above is somewhat verbose: all the computations must be redefined in the sub-break inbe avoided by using the inheritsComputations attribute.

Hence, the following descriptor will provide exactly the same output as the one above:

<blueiron output="final">
  <input id="employees">...</input>

  <step id="final" source="employees">
    <break>
      <total>
        <value id="DEPARTMENT">All</value>
        <column id="SALARY" source="SUM_SALARIES" />
        <column id="FEES" source="SUM_FEES" />
      </total>
      <computations>
        <expr id="SUM_SALARIES">previousValue + SALARY</expr>
        <expr id="SUM_FEES">previousValue + FEES</expr>
      </computations>
      <break inheritsComputations="true">
        <condition type="column" id="DEPARTMENT" />
        <total>
          <column id="DEPARTMENT" />
          <column id="SALARY" source="SUM_SALARIES" />
          <column id="FEES" source="SUM_FEES" />
        </total>
      </break>
    </break>
  </step>
</blueiron>

Actually, this attribute will cause the computations of the main break to be copied into the sub-break. This means, there will be two instances of each computation, one for the main break and one for the sub-break and all of them will be in their own scope.

Advanced computations

Sometimes, just applying an expression on each row is not enough: for instance if one wants to compute an average, it is needed to apply an expression after the last line.

BlueIron supports two special processors that are extensions of and <script>: and .

On each of them, it is possible to define the following types:

  • filter : the expression/script will be applied only to rows that match the filter.
  • pre : an expression/script ran before the first row.
  • each : an expression/script ran on each row (corresponds to <expr> and <script>).
  • post : an expression/script ran after the last row.

For instance, the configuration below will compute the average of salaries per men and women:

<blueiron output="final">
  <input id="employees">...</input>

  <step id="final" source="employees">
    <break>
      <total>
        <value id="DEPARTMENT">All (${AVG_WOMEN} / ${AVG_MEN})</value>
        <column id="SALARY" source="SUM_SALARIES" />
        <column id="FEES" source="SUM_FEES" />
      </total>
      <computations>
        <expr id="SUM_SALARIES">previousValue + SALARY</expr>
        <expr id="SUM_FEES">previousValue + FEES</expr>
        <expression id="AVG_MEN">
          <filter>SEX == "M"</filter>
          <each>previousValue + SALARY</each>
          <post>previousValue / nbMatchingRows</post>
        </expression>
        <expression id="AVG_WOMEN">
          <filter>SEX == "F"</filter>
          <each>previousValue + SALARY</each>
          <post>previousValue / nbMatchingRows</post>
        </expression>
      </computations>
      <break inheritsComputations="true">
        <condition type="column" id="DEPARTMENT" />
        <total>
          <value id="DEPARTMENT">${DEPARTMENT} (${AVG_WOMEN} / ${AVG_MEN})</value>
          <column id="SALARY" source="SUM_SALARIES" />
          <column id="FEES" source="SUM_FEES" />
        </total>
      </break>
    </break>
  </step>
</blueiron>
ID FIRSTNAME LASTNAME SEX BIRTHDATE DEPARTMENT SALARY FEES LEVEL PARENT ACTIVE
01 Peter Bosshard M 05.02.1958 DIR 5800.00 340.05 1 true
02 Maria Skinov F 25.06.1964 DIR 5700.00 480.15 2 01 true
03 Casey Cole M 28.08.1955 DIR 5700.00 210.50 2 01 true
04 Roger Binner M 13.01.1959 DIR 5700.00 230.55 2 01 true
05 Olive Saltin F 31.03.1961 DIR 5700.00 727.12 2 01 false
DIR (5,700.00 / 5,733.33) 28600.00 1988.37
06 Bill Amacker M 27.10.1968 HEA 5300.00 0.00 3 02 true
07 Aby Thornson F 26.11.1967 HEA 5300.00 140.00 3 02 true
08 Anne Pevler F 14.09.1967 HEA 5300.00 150.00 3 03 true
09 Annita Smith F 17.12.1967 HEA 5300.00 60.00 3 04 true
HEA (5,300.00 / 5,300.00) 21200.00 350.00
10 Robert Smith M 13.12.1970 DEV 5000.00 0.00 4 06 true
11 Maggie Frill F 29.02.1972 DEV 5000.00 0.00 4 06 true
12 Daniel Metzler M 01.01.1973 DEV 4900.00 0.00 4 07 true
13 Frank Witz M 05.01.1973 DEV 4900.00 10.00 4 07 true
14 Franky Bilen M 12.12.1972 DEV 4900.00 0.00 4 07 true
15 Ed Krack M 08.04.1969 DEV 5100.00 0.00 4 07 true
16 Sean Huskynd M 04.09.1971 DEV 4900.00 0.00 4 07 false
DEV (5,000.00 / 4,950.00) 34700.00 10.00
17 Alice Muller F 09.10.1976 STG 4500.00 0.00 4 07 true
STG (4,500.00 / 0.00) 4500.00 0.00
All (5,257.14 / 5,220.00) 89000.00 2348.37

Combine computations

In a computations, it is possible to reference another computation in the same scope. This can be done by using the computations prefix:

<break>
  <total>
    <value id="DEPARTMENT">All (${AVG_WOMEN} + ${AVG_MEN} = ${TOTAL_AVG})</value>
    <column id="SALARY" source="SUM_SALARIES" />
    <column id="FEES" source="SUM_FEES" />
  </total>
  <computations>
    <expr id="SUM_SALARIES">previousValue + SALARY</expr>
    <expr id="SUM_FEES">previousValue + FEES</expr>
    <expression id="AVG_MEN">
      <filter>SEX == "M"</filter>
      <each>previousValue + SALARY</each>
      <post>previousValue / nbMatchingRows</post>
    </expression>
    <expression id="AVG_WOMEN">
      <filter>SEX == "F"</filter>
      <each>previousValue + SALARY</each>
      <post>previousValue / nbMatchingRows</post>
    </expression>
    <expression id="TOTAL_AVG"> <!--                Combines two other computations -->
      <post>computations.AVG_WOMEN + computations.AVG_MEN</post>
    </expression>
  </computations>
</break>

Reset

When a new break is generated, all the computations of the break (and sub-breaks) are reset: all the computed data are thrown away and a fresh context is created. In most of the cases, this is what is wanted because computations are meant to operate on their data set independantly.

However it might be possible in some cases that this behaviour is not desired, for instance when a continued sum must be computed to see the progression row-by-row. To disable the automatic reset, just set the resetComputations to ‘never’.