public DataSet groupByLabel(DataProperty groupByProperty, int[] columns, String[] functionCodes, int sortIndex, int sortOrder) {
// Create the result data set instance.
DefaultDataSet _result = new DefaultDataSet(provider);
_result.setPropertySize(columns.length);
DataProperty _pivotProp = groupByProperty.cloneProperty();
// Get the pivot column
int pivotColumn = -1;
for (int j=0; j<columns.length; j++) {
DataProperty dataProp = getPropertyByColumn(columns[j]);
if (pivotColumn == -1 && groupByProperty.equals(dataProp)) {
pivotColumn = j;
break;
}
}
// Get the indexed labels
int groupByColumn = getPropertyColumn(groupByProperty);
List<DistinctValue> _distinctValues = index.getDistinctValues(groupByColumn);
List<DistinctValue> _sortedValues = new ArrayList(_distinctValues);
if (sortOrder != 0) {
if (sortIndex < 0 || sortIndex == pivotColumn) index.sortByValue(_sortedValues, sortOrder);
else index.sortByScalar(_sortedValues, functionCodes[sortIndex], columns[sortIndex], sortOrder);
}
// Build the label interval set from the sorted list of distinct values.
LabelDomain _pivotDomain = (LabelDomain) _pivotProp.getDomain();
List<Interval> intervals = _pivotDomain.getIntervals(_sortedValues);
// Populate the dataset with the calculations.
for (int j=0; j<columns.length; j++) {
DataProperty dataProp = getPropertyByColumn(columns[j]);
if (j == pivotColumn) {
_result.addProperty(_pivotProp, j);
// The row values for the pivot column are the own interval instances.
for (Interval interval : intervals) {
_result.addRowValue(j, interval);
}
} else {
DataProperty _prop = dataProp.cloneProperty();
_result.addProperty(_prop, j);
// The values for other columns is a scalar function applied on the interval's values.
ScalarFunctionManager scalarFunctionManager = DataProviderServices.lookup().getScalarFunctionManager();
ScalarFunction function = scalarFunctionManager.getScalarFunctionByCode(functionCodes[j]);
for (Interval interval : intervals) {
Double scalar = calculateScalar(interval, dataProp, function);
_result.addRowValue(j, scalar);
}
// After calculations, ensure the new property domain is numeric.
_prop.setDomain(new NumericDomain());
}
}
return _result;
}