06 abr 2009

Agrupamento genérico

Em projetos desenvolvidos em Flex é comum clientes solicitarem agrupamento de dados que devem ser exibidos de forma hierarquica em um AdvancedDataGrid ou uma Tree. Como esta solicitação se tornou comum, desenvolvi um agrupador genérico em Java que transforma listas “flat” em listas agrupadas.


O AdvancedDataGrid do Flex possui métodos que realizam este tipo de agrupamento mas quando a quantidade de dados é grande o grid fica lento por ter que renderizar muitos dados.

Para melhor entendimento, suponha o caso aonde os dados gerados por um Select qualquer é o seguinte:

Filial Categoria Nome Algum valor
SP Coolaborador Bruno $ 250.22
SP Coolaborador José $ 582.00
SP Cliente Cliente redspark $ 587.66
RJ Coolaborador João $ 542.35
RJ Coolaborador Maria $ 122.66

Com base nestes dados, podemos gerar alguns tipos de agrupamento como por Filial e Categoria ou, em outra ordem, Categoria e depois Filial. As principais funcionalidades do agrupador são somar os dados agrupados e criar outros cálculos simples em cima de valores existentes.

Filial + Categoria (Tabela 1.1) Categoria + Filial (Tabela 1.2)
Item Valor
+ SP $ 1419.88
    + Colaborador $ 832.22
           Bruno $ 250.22
           José $ 582.00
    + Cliente $ 587.66
           Cliente redspark $ 587.66
+ RJ $ 665.01
    + Colaborador $ 665.01
           João $ 542.35
           Maria $ 122.66
Item Valor
+ Colaborador $ 1497.23
    + SP $ 832.22
           Bruno $ 250.22
           José $ 582.00
    + RJ $ 665.01
           João $ 542.35
           Maria $ 122.66
+ Cliente $ 587.66
    + SP $ 587.66
           Cliente redspark $ 587.66

Utilizando a API

Para tornar possível a utilização desta API, o DTO que mantém os dados do select deve implementar a interface Groupable como o exemplo a seguir:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class ExemploDTO implements Groupable<exemploDTO> {

    private String label;
    private List<exemploDTO> children;

    private String filial;
    private String categoria;
    private String nome;
    private Double valor;

    @Override
    public Object clone() throws CloneNotSupportedException {
        return super.clone();
    }

    //getters n' setters
}

Em seguida, devemos criar uma nova instância da classe GenericGrouper. Neste exemplo vamos criar um agrupamento por Filial e Categoria respectivamente, gerando os dados mostrados na tabela 1.1. Vou mostrar no exemplo como utilizar:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public List<exemploDTO> getListaAgrupada() {

    Grouper<exemploDTO> grouper = new GenericGrouper<exemploDTO>();

    //adiciona propriedades que devem ser agrupadas respectivamente
    grouper.addGroupingProperty( "filial" );
    grouper.addGroupingProperty( "categoria" );

    //adiciona propriedades que devem ser somadas
    grouper.addSumProperty( "valor" );

    //define qual propriedade deve ser exibida no último nível do agrupamento (label)
    grouper.setLastLevelProperty( "nome" );

    //define qual a coleção de dados que deve ser agrupado
    grouper.setCollection( dados );

    List<exemploDTO> result = grouper.group();
    return result;

}

Adicionando cálculos

Para adicionar um cálculo devemos definir quais as duas propriedades em questão e em qual propriedade o resultado será atribuido. Obviamente também precisamos definir qual tipo de operação deve ser realizada, como segue no exemplo:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public List<exemploDTO> getListaAgrupada() {

    ...
    GrouperMath calculoExemplo = new GrouperMath();

    //define as propriedades que devem ser utilizadas
    calculoExemplo.setArg1( "valorTotal" );
    calculoExemplo.setArg2( "valorParcial" );

    //define a propriedade em que o resultado será atribuido
    calculoExemplo.setProjection( "resultado" );

    //define o tipo de cáculo (SUM, SUBTRACT, DIVIDE ou MULTIPLY)
    calculoExemplo.setOperation( GrouperOperations.SUBTRACT );

    //adiciona o cálculo ao agrupador
    grouper.addMath(calculoExemplo);
    ...

}

Estou disponibilizando o JAR para download. Em breve envio os sources com mais informações.

grouper-1.0.0.jar.zip

Comments

Leave a Comment