Search in sources :

Example 1 with Cursor

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);
    }
}
Also used : FormattingProvider(org.jooq.FormattingProvider) ArrayList(java.util.ArrayList) DSLContext(org.jooq.DSLContext) IOException(org.jooq.exception.IOException) Cursor(org.jooq.Cursor) TreeMap(java.util.TreeMap) Date(java.sql.Date) Result(org.jooq.Result) TableRecord(org.jooq.TableRecord) Record(org.jooq.Record)

Aggregations

Date (java.sql.Date)1 ArrayList (java.util.ArrayList)1 TreeMap (java.util.TreeMap)1 Cursor (org.jooq.Cursor)1 DSLContext (org.jooq.DSLContext)1 FormattingProvider (org.jooq.FormattingProvider)1 Record (org.jooq.Record)1 Result (org.jooq.Result)1 TableRecord (org.jooq.TableRecord)1 IOException (org.jooq.exception.IOException)1