use of org.jooq.Cursor in project jOOQ by jOOQ.
the class AbstractResult method formatChart.
@SuppressWarnings("unchecked")
@Override
public final void formatChart(Writer writer, ChartFormat format) {
Result<R> result;
if (this instanceof Result)
result = (Result<R>) this;
else if (this instanceof Cursor)
result = ((Cursor<R>) this).fetch();
else
throw new IllegalStateException();
try {
if (result.isEmpty()) {
writer.append("No data available");
return;
}
DSLContext ctx = configuration.dsl();
FormattingProvider fp = configuration.formattingProvider();
Field<?> category = fields.field(format.category());
TreeMap<Object, Result<R>> groups = new TreeMap<>(result.intoGroups(format.category()));
if (!format.categoryAsText()) {
if (Date.class.isAssignableFrom(category.getType())) {
Date categoryMin = (Date) groups.firstKey();
Date categoryMax = (Date) groups.lastKey();
for (Date i = categoryMin; i.before(categoryMax); i = new Date(i.getYear(), i.getMonth(), i.getDate() + 1)) if (!groups.containsKey(i))
groups.put(i, (Result<R>) ctx.newResult(fields.fields.fields));
}
}
List<?> categories = new ArrayList<>(groups.keySet());
int categoryPadding = 1;
int categoryWidth = 0;
for (Object o : categories) categoryWidth = Math.max(categoryWidth, fp.width("" + o));
double axisMin = Double.POSITIVE_INFINITY;
double axisMax = Double.NEGATIVE_INFINITY;
for (Result<R> values : groups.values()) {
double sum = 0;
for (int i = 0; i < format.values().length; i++) {
if (format.display() == Display.DEFAULT)
sum = 0;
for (Record r : values) sum = sum + r.get(format.values()[i], double.class);
if (sum < axisMin)
axisMin = sum;
if (sum > axisMax)
axisMax = sum;
}
}
int verticalLegendWidth = format.showVerticalLegend() ? (format.display() == Display.HUNDRED_PERCENT_STACKED) ? fp.width(format.percentFormat().format(100.0)) : Math.max(format.numericFormat().format(axisMin).length(), format.numericFormat().format(axisMax).length()) : 0;
int horizontalLegendHeight = format.showHorizontalLegend() ? 1 : 0;
int verticalBorderWidth = format.showVerticalLegend() ? 1 : 0;
int horizontalBorderHeight = format.showHorizontalLegend() ? 1 : 0;
int chartHeight = format.height() - horizontalLegendHeight - horizontalBorderHeight;
int chartWidth = format.width() - verticalLegendWidth - verticalBorderWidth;
double barWidth = (double) chartWidth / groups.size();
double axisStep = (axisMax - axisMin) / (chartHeight - 1);
for (int y = chartHeight - 1; y >= 0; y--) {
double axisLegend = axisMax - (axisStep * (chartHeight - 1 - y));
double axisLegendPercent = (axisLegend - axisMin) / (axisMax - axisMin);
if (format.showVerticalLegend()) {
String axisLegendString = (format.display() == Display.HUNDRED_PERCENT_STACKED) ? format.percentFormat().format(axisLegendPercent * 100.0) : format.numericFormat().format(axisLegend);
for (int x = fp.width(axisLegendString); x < verticalLegendWidth; x++) writer.write(' ');
writer.write(axisLegendString);
for (int x = 0; x < verticalBorderWidth; x++) writer.write('|');
}
for (int x = 0; x < chartWidth; x++) {
int index = (int) (x / barWidth);
Result<R> group = groups.get(categories.get(index));
double[] values = new double[format.values().length];
for (Record record : group) for (int i = 0; i < values.length; i++) values[i] = values[i] + record.get(format.values()[i], double.class);
if (format.display() == Display.STACKED || format.display() == Display.HUNDRED_PERCENT_STACKED)
for (int i = 1; i < values.length; i++) values[i] = values[i] + values[i - 1];
if (format.display() == Display.HUNDRED_PERCENT_STACKED)
for (int i = 0; i < values.length; i++) values[i] = values[i] / values[values.length - 1];
int shadeIndex = -1;
for (int i = values.length - 1; i >= 0; i--) if ((format.display() == Display.HUNDRED_PERCENT_STACKED ? axisLegendPercent : axisLegend) > values[i])
break;
else
shadeIndex = i;
if (shadeIndex == -1)
writer.write(' ');
else
writer.write(format.shades()[shadeIndex % format.shades().length]);
}
writer.write(format.newline());
}
if (format.showHorizontalLegend()) {
for (int y = 0; y < horizontalBorderHeight; y++) {
if (format.showVerticalLegend()) {
for (int x = 0; x < verticalLegendWidth; x++) writer.write('-');
for (int x = 0; x < verticalBorderWidth; x++) writer.write('+');
}
for (int x = 0; x < chartWidth; x++) writer.write('-');
writer.write(format.newline());
}
for (int y = 0; y < horizontalLegendHeight; y++) {
if (format.showVerticalLegend()) {
for (int x = 0; x < verticalLegendWidth; x++) writer.write(' ');
for (int x = 0; x < verticalBorderWidth; x++) writer.write('|');
}
double rounding = 0.0;
for (double x = 0.0; x < chartWidth; ) {
String label = "" + categories.get((int) (x / barWidth));
int width = fp.width(label);
double padding = Math.max(categoryPadding, (barWidth - width) / 2);
rounding = (rounding + padding - Math.floor(padding)) % 1;
x = x + (padding + rounding);
for (int i = 0; i < (int) (padding + rounding); i++) writer.write(' ');
x = x + width;
if (x >= chartWidth)
break;
writer.write(label);
rounding = (rounding + padding - Math.floor(padding)) % 1;
x = x + (padding + rounding);
for (int i = 0; i < (int) (padding + rounding); i++) writer.write(' ');
}
writer.write(format.newline());
}
}
} catch (java.io.IOException e) {
throw new IOException("Exception while writing Chart", e);
}
}
Aggregations