public DataSet groupBy(DataProperty groupByProperty, List<DataProperty> groupByProps, List<String> functionCodes) {
// Create the dataset instance.
DefaultDataSet groupByDataSet = new DefaultDataSet(null);
groupByDataSet.setPropertySize(groupByProps.size());
DataProperty pivotProp = null;
for (int i = 0; i < groupByProps.size(); i++) {
DataProperty grProp = groupByProps.get(i).cloneProperty();
groupByDataSet.addProperty(grProp, i);
if (pivotProp == null && grProp.equals(groupByProperty)) pivotProp = grProp;
}
// Populate the dataset with the calculations.
// For each group by interval add a row to the data set.
Predicate nonNullElements = new Predicate() { public boolean evaluate(Object o) { return o != null; }};
Interval[] groupByIntervals = groupByProperty.getDomain().getIntervals();
for (int i=0; i<groupByIntervals.length; i++) {
Interval groupByInterval = groupByIntervals[i];
// For each data set property calculate its grouped interval value.
for (int j=0; j<groupByProps.size(); j++) {
// The row value for the group by column is the own interval instance.
DataProperty grProp = groupByDataSet.getProperties()[j];
String grFunctionCode = functionCodes.get(j);
if (grProp == pivotProp) {
groupByDataSet.addRowValue(j, groupByInterval);
}
// The value for the other columns is a scalar function applied over the column values belonging to the interval.
else {
DataProperty dataSetProp = getPropertyById(grProp.getPropertyId());
Collection dataSetValues = groupByInterval.getValues(dataSetProp);
if (!CollectionUtils.exists(dataSetValues, nonNullElements)) {
// If all the interval elements to group are null then set 0.
groupByDataSet.addRowValue(j, new Double(0));
} else {
ScalarFunctionManager scalarFunctionManager = DataProviderServices.lookup().getScalarFunctionManager();
ScalarFunction grFunction = scalarFunctionManager.getScalarFunctionByCode(grFunctionCode);
double value = grFunction.scalar(dataSetValues);
groupByDataSet.addRowValue(j, new Double(value));
}
}
}
}
// After ending the group by calculations and populate the data set, set the domains.
DataProperty[] groupByProperties = groupByDataSet.getProperties();
for (int i = 0; i < groupByProperties.length; i++) {
DataProperty byProperty = groupByProperties[i];
if (byProperty.equals(groupByProperty)) byProperty.setDomain(new LabelDomain());
else byProperty.setDomain(new NumericDomain());
}
return groupByDataSet;
}