use of org.jooq.FormattingProvider in project jOOQ by jOOQ.
the class AbstractResult method format.
// -------------------------------------------------------------------------
// XXX: Formattable API
// -------------------------------------------------------------------------
@Override
public final void format(Writer writer, TXTFormat format) {
try {
final FormattingProvider fp = Tools.configuration(this).formattingProvider();
// Numeric columns have greater max width because values are aligned
final int NUM_COL_MAX_WIDTH = format.maxColWidth() == Integer.MAX_VALUE ? Integer.MAX_VALUE : 2 * format.maxColWidth();
// The max number of records that will be considered for formatting purposes
final int MAX_RECORDS = min(50, format.maxRows());
final Deque<R> buffer = new ArrayDeque<>();
final Iterator<R> it = iterator();
// Buffer some rows for formatting purposes
for (int i = 0; i < MAX_RECORDS && it.hasNext(); i++) buffer.offer(it.next());
// Get max decimal places for numeric type columns
int size = fields.size();
final int[] decimalPlaces = new int[size];
final int[] widths = new int[size];
for (int index = 0; index < size; index++) {
if (Number.class.isAssignableFrom(fields.field(index).getType())) {
List<Integer> decimalPlacesList = new ArrayList<>(1 + buffer.size());
// Initialize
decimalPlacesList.add(0);
// Collect all decimal places for the column values
for (R record : buffer) decimalPlacesList.add(decimalPlaces(format0(record.get(index), record.changed(index), true)));
// Find max
decimalPlaces[index] = Collections.max(decimalPlacesList);
}
}
// Get max column widths
int colMaxWidth;
for (int index = 0; index < size; index++) {
// Is number column?
boolean isNumCol = Number.class.isAssignableFrom(fields.field(index).getType());
colMaxWidth = isNumCol ? NUM_COL_MAX_WIDTH : format.maxColWidth();
// Collect all widths for the column
List<Integer> widthList = new ArrayList<>(1 + buffer.size());
// Add column name width first
widthList.add(min(colMaxWidth, max(format.minColWidth(), fp.width(fields.field(index).getName()))));
// Add column values width
for (R record : buffer) {
String value = format0(record.get(index), record.changed(index), true);
// Align number values before width is calculated
if (isNumCol)
value = alignNumberValue(decimalPlaces[index], value);
widthList.add(min(colMaxWidth, fp.width(value)));
}
// Find max
widths[index] = Collections.max(widthList);
}
// Write top line
if (format.horizontalTableBorder())
formatHorizontalLine(writer, format, widths);
// Write headers
if (format.verticalTableBorder())
writer.append('|');
for (int index = 0; index < size; index++) {
if (index > 0)
if (format.verticalCellBorder())
writer.append('|');
else
writer.append(' ');
String padded;
String name = fields.field(index).getName();
int width = fp.width(name);
if (Number.class.isAssignableFrom(fields.field(index).getType()))
padded = leftPad(name, width, widths[index]);
else
padded = rightPad(name, width, widths[index]);
if (widths[index] < 4)
writer.append(padded);
else
writer.append(abbreviate(padded, widths[index]));
}
if (format.verticalTableBorder())
writer.append('|');
writer.append('\n');
// Write separator
if (format.horizontalHeaderBorder())
formatHorizontalLine(writer, format, widths);
// Write records
int i;
recordLoop: for (i = 0; i < format.maxRows(); i++) {
R record = buffer.pollFirst();
if (record == null)
if (it.hasNext())
record = it.next();
else
break recordLoop;
// Write separator
if (i > 0 && format.horizontalCellBorder())
formatHorizontalLine(writer, format, widths);
if (format.verticalTableBorder())
writer.append('|');
for (int index = 0; index < size; index++) {
if (index > 0)
if (format.verticalCellBorder())
writer.append('|');
else
writer.append(' ');
String value = StringUtils.replace(StringUtils.replace(StringUtils.replace(format0(record.get(index), record.changed(index), true), "\n", "{lf}"), "\r", "{cr}"), "\t", "{tab}");
String padded;
if (Number.class.isAssignableFrom(fields.field(index).getType()))
padded = leftPad(alignNumberValue(decimalPlaces[index], value), widths[index]);
else
padded = rightPad(value, fp.width(value), widths[index]);
if (widths[index] < 4)
writer.append(padded);
else
writer.append(abbreviate(padded, widths[index]));
}
if (format.verticalTableBorder())
writer.append('|');
writer.append('\n');
}
// Write bottom line
if (format.horizontalTableBorder() && i > 0)
formatHorizontalLine(writer, format, widths);
// Write truncation message, if applicable
if (it.hasNext()) {
if (format.verticalTableBorder())
writer.append('|');
writer.append("...record(s) truncated...\n");
}
writer.flush();
} catch (java.io.IOException e) {
throw new IOException("Exception while writing TEXT", e);
}
}
use of org.jooq.FormattingProvider 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