diff -r 7e08730da258 -r 4a1864c3e867 java/sql-dk/src/info/globalcode/sql/dk/formatting/BarChartFormatter.java --- a/java/sql-dk/src/info/globalcode/sql/dk/formatting/BarChartFormatter.java Mon Mar 04 17:06:42 2019 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,104 +0,0 @@ -/** - * SQL-DK - * Copyright © 2015 František Kučera (frantovo.cz) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package info.globalcode.sql.dk.formatting; - -import info.globalcode.sql.dk.Functions; -import info.globalcode.sql.dk.configuration.PropertyDeclaration; -import info.globalcode.sql.dk.logging.LoggerProducer; -import java.math.BigDecimal; -import java.math.MathContext; -import java.math.RoundingMode; -import java.util.List; -import java.util.logging.Level; -import java.util.logging.Logger; - -/** - * TODO: min/max values – range for case that no value is 100 % - * - * TODO: multiple barcharts in same table (last column is still default) + multiple resultsets - * - * TODO: negative values - bar starting from the middle, not always from the left - * - * @author Ing. František Kučera (frantovo.cz) - */ -@PropertyDeclaration(name = BarChartFormatter.PROPERTY_PRECISION, type = Integer.class, defaultValue = BarChartFormatter.PROPERTY_PRECISION_DEFAULT, description = "number of characters representing 100 % in the bar chart") -public class BarChartFormatter extends TabularPrefetchingFormatter { - - public static final String NAME = "barchart"; // bash-completion:formatter - public static final String PROPERTY_PRECISION = "precision"; - protected static final String PROPERTY_PRECISION_DEFAULT = "100"; - private static final MathContext mathContext = MathContext.DECIMAL128; - public static final Logger log = LoggerProducer.getLogger(); - private final BigDecimal chartPrecision; - private final char chartFull; - private final char chartEmpty; - - public BarChartFormatter(FormatterContext formatterContext) { - super(formatterContext); - chartPrecision = BigDecimal.valueOf(formatterContext.getProperties().getInteger(PROPERTY_PRECISION, Integer.parseInt(PROPERTY_PRECISION_DEFAULT))); - chartFull = isAsciiNostalgia() ? '#' : '█'; - chartEmpty = isAsciiNostalgia() ? '~' : '░'; - // TODO: consider using partial blocks for more precision: https://en.wikipedia.org/wiki/Block_Elements - } - - @Override - protected void postprocessPrefetchedResultSet(ColumnsHeader currentHeader, List currentResultSet) { - super.postprocessPrefetchedResultSet(currentHeader, currentResultSet); - - updateColumnWidth(currentHeader.getColumnCount(), chartPrecision.intValue()); - - BigDecimal maximum = BigDecimal.ZERO; - BigDecimal minimum = BigDecimal.ZERO; - int lastIndex = currentHeader.getColumnCount() - 1; - - Object valueObject = null; - try { - for (Object[] row : currentResultSet) { - valueObject = row[lastIndex]; - if (valueObject != null) { - BigDecimal value = new BigDecimal(valueObject.toString()); - maximum = maximum.max(value); - minimum = minimum.min(value); - } - } - - BigDecimal range = maximum.subtract(minimum); - - for (Object[] row : currentResultSet) { - valueObject = row[lastIndex]; - if (valueObject == null) { - row[lastIndex] = ""; - } else { - BigDecimal value = new BigDecimal(valueObject.toString()); - BigDecimal valueFromMinimum = value.subtract(minimum); - - BigDecimal points = chartPrecision.divide(range, mathContext).multiply(valueFromMinimum, mathContext); - int pointsRounded = points.setScale(0, RoundingMode.HALF_UP).intValue(); - row[lastIndex] = Functions.repeat(chartFull, pointsRounded) + Functions.repeat(chartEmpty, chartPrecision.intValue() - pointsRounded); - } - } - - } catch (NumberFormatException e) { - // https://en.wiktionary.org/wiki/parsable - log.log(Level.SEVERE, "Last column must be number or an object with toString() value parsable to a number. But was „{0}“", valueObject); - // FIXME: throw FormatterException - throw e; - } - } - -}