albertosanchez
(Jose Alberto Sanchez Nieto)
August 24, 2017, 11:18am
#1
Hello, I try to generate a table dynamically using a datasource type ValueGroupDatasourceImpl with KeyValueEntity, I also need to add to this table several columns dynamically that will contain the result of a calculation made on different fields of the created table. To finish I would also like to add aggregations type “sum” to several fields of this table. What would be the best method to perform these operations? For the moment the creation of the table dynamically using a datasource of type KeyValueEntitiy has worked me correctly, which I can not create is to create fields dynamically (using addGeneratedColumn) with calculations made on the fields created in the table, I also have not got the aggretation type to work on the created fields.
Any examples or ideas?, I show the code so far.
public void init(Map<String, Object> params) {
super.init(params);
Map<Jerarquia, List<Analisis>> mapaDatos = generarTablaService.generar();
ValueGroupDatasourceImpl ds = DsBuilder.create().buildValuesGroupDatasource();
for (Map.Entry<Jerarquia, List<Analisis>> dato : mapaDatos.entrySet()) {
KeyValueEntity entidad = new KeyValueEntity();
//obtengo descripcion de jerarquia
ds.addProperty("jerarquia", com.albertosancheznieto.tabladinamica.entity.Jerarquia.class);
ds.addProperty("nivel 1", String.class);
ds.addProperty("nivel 2", String.class);
ds.addProperty("nivel 3", String.class);
ds.addProperty("nivel 4", String.class);
entidad.setValue("jerarquia", dato.getKey());
entidad.setValue("nivel 1", dato.getKey().getNivel1());
entidad.setValue("nivel 2", dato.getKey().getNivel2());
entidad.setValue("nivel 3", dato.getKey().getNivel3());
entidad.setValue("nivel 4", dato.getKey().getNivel4());
for (Analisis a : dato.getValue()) {
ds.addProperty(a.getConcepto().getDescripcion(), BigDecimal.class);
entidad.setValue(a.getConcepto().getDescripcion(), a.getImporte());
}
ds.addItem(entidad);
}
Table laTabla = componentsFactory.createComponent(GroupTable.class);
laTabla.setDatasource(ds);
laTabla.setWidth("100%");
laTabla.setHeight("100%");
//laTabla.setAggregatable(true);
//laTabla.addAggregationProperty("compras", AggregationInfo.Type.SUM);
laTabla.addGeneratedColumn("resultado", entity -> {
return new Table.PlainTextCell(entity.getInstanceName());
});
vbox.add(laTabla);
Thanks and regards.
artamonov
(Yuriy Artamonov)
August 30, 2017, 4:04pm
#2
Hi,
It is possible, but it is no so easy. You have to create columns programmatically and set up aggregation for them.
Example:
public class DemoScreen extends AbstractWindow {
@Inject
private ComponentsFactory componentsFactory;
@Inject
private Metadata metadata;
@Inject
private UuidSource uuidSource;
@Override
public void init(Map<String, Object> params) {
super.init(params);
ValueGroupDatasourceImpl ds = DsBuilder.create()
.setId("groupDs")
.setRefreshMode(RefreshMode.NEVER)
.buildValuesGroupDatasource();
ds.setIdName("id");
// register properties
ds.addProperty("name", String.class);
ds.addProperty("count", Integer.class);
ds.addProperty("value", Integer.class);
// set random data
ds.addItem(item("Sam Dough", 10, 10));
ds.addItem(item("Bill Dodson", 12, 30));
// create table
GroupTable table = componentsFactory.createComponent(GroupTable.class);
table.setWidth("100%");
table.setHeight("100%");
// enable aggregation
table.setAggregatable(true);
// create columns programmatically before we set datasource
MetaClass metaClass = ds.getMetaClass();
MetaPropertyPath nameMpp = metaClass.getPropertyPath("name");
Table.Column nameColumn = new Table.Column(nameMpp, "Name");
nameColumn.setType(nameMpp.getRangeJavaClass());
table.addColumn(nameColumn);
MetaPropertyPath countMpp = metaClass.getPropertyPath("count");
Table.Column countColumn = new Table.Column(countMpp, "Count");
countColumn.setType(countMpp.getRangeJavaClass());
AggregationInfo countAggInfo = new AggregationInfo();
countAggInfo.setPropertyPath(ds.getMetaClass().getPropertyPath("count"));
countAggInfo.setType(Type.SUM);
countColumn.setAggregation(countAggInfo);
table.addColumn(countColumn);
MetaPropertyPath valueMpp = metaClass.getPropertyPath("value");
Table.Column valueColumn = new Table.Column(valueMpp, "value");
valueColumn.setType(valueMpp.getRangeJavaClass());
AggregationInfo valueAggInfo = new AggregationInfo();
valueAggInfo.setPropertyPath(ds.getMetaClass().getPropertyPath("count"));
valueAggInfo.setType(Type.COUNT);
valueColumn.setAggregation(valueAggInfo);
table.addColumn(valueColumn);
// finally, set datasource
table.setDatasource(ds);
add(table);
}
public KeyValueEntity item(String name, int count, int value) {
KeyValueEntity entity = metadata.create(KeyValueEntity.class);
entity.setValue("id", uuidSource.createUuid());
entity.setValue("name", name);
entity.setValue("count", count);
entity.setValue("value", value);
return entity;
}
}
See also sources on github: GitHub - cuba-labs/keyvalue-table-aggregation
Hope it will help you, we will try to simplify Table API in the near future.
Alex
(Alex)
July 21, 2018, 10:16am
#3
…we will try to simplify Table API in the near future.
Is there any simpler way now?
neutrino36
(neutrino neutrino)
September 13, 2019, 12:55pm
#4
Hello,
add is part of AbstractFrame.
Can you advise how to use this method in Cuba 7?
Here we have …extend Screen (not extend AbstractWindow).
krivopustov
(Konstantin Krivopustov)
November 6, 2020, 1:44pm
#5