public Double asNumeric() { return (Data.asNumeric(low) + Data.asNumeric(high)) / 2.0; }
private double extent() { return Data.asNumeric(high) - Data.asNumeric(low); }
private Field[] make() { // Assemble arrays of fields Field[] dimensionFields = getFields(dimensions); Field[] percentBaseFields = percentBase.toArray(new Field[percentBase.size()]); Field[] measureFields = getFields(measures); // The comparators to let us know when rows differ FieldRowComparison dimComparison = new FieldRowComparison(dimensionFields, null, false); FieldRowComparison percentBaseComparison = new FieldRowComparison(percentBaseFields, null, false); // group[row] gives the index of the summary group for row 'row'; 'groupCount' is the number of // groups int[] group = new int[rowCount]; int groupCount = buildGroups(group, dimComparison); // These are just like the summary groups, but only for the percent bases // The percent groups nest within each base group: rows with the same group have the same // summary group also // we do not create these if they are not needed, for efficiency int[] percentGroup = percentNeeded ? new int[rowCount] : null; int percentGroupCount = percentNeeded ? buildGroups(percentGroup, percentBaseComparison) : 0; // Create the summary values for each group, and percentage sums SummaryValues[] summaries = new SummaryValues[groupCount]; for (int i = 0; i < summaries.length; i++) summaries[i] = new SummaryValues(measureFields, percentBaseFields, dimensionFields); double[][] percentSums = new double[percentGroupCount][measureFields.length]; // Perform the Aggregation for (int row = 0; row < rowCount; row++) { SummaryValues value = summaries[group[row]]; if (percentNeeded) { // If the group has not had percent sums set yet, then set it if (value.percentSums == null) value.percentSums = percentSums[percentGroup[row]]; // Then add the values to the percentage count for (int i = 0; i < measureFields.length; i++) { if (measures.get(i).isPercent()) { Double v = Data.asNumeric(measureFields[i].value(row)); if (v != null) value.percentSums[i] += v; } } } // Add the current row to that group, with the relevant 'sums' for percentages value.rows.add(row); } Object[][] dimData = new Object[dimensions.size()][groupCount]; Object[][] measureData = new Object[measures.size()][groupCount]; for (int g = 0; g < groupCount; g++) { SummaryValues values = summaries[g]; int originalRow = values.firstRow(); // Set the dimension values for (int i = 0; i < dimensions.size(); i++) dimData[i][g] = dimensionFields[i].value(originalRow); // Set the measure values for (int i = 0; i < measures.size(); i++) { MeasureField m = measures.get(i); measureData[i][g] = values.get(i, m); } } // Assemble fields Field[] fields = new Field[dimData.length + measureData.length]; for (int i = 0; i < dimData.length; i++) { DimensionField f = dimensions.get(i); fields[i] = Fields.makeColumnField(f.rename, f.label(), dimData[i]); Fields.copyBaseProperties(f.field, fields[i]); } for (int i = 0; i < measureData.length; i++) { MeasureField m = measures.get(i); Field result = Fields.makeColumnField(m.rename, m.label(), measureData[i]); setProperties(m.method, result, m.field); result.set("summary", m.method); result.set("calculated", true); if (m.field != null) result.set("originalLabel", m.field.label); fields[dimData.length + i] = result; } return fields; }