/** Executes some calculations to support a dynamic axis labeling for a linear scale. */ private void prepareLinAxis() { // range as driving force for following calculations, no matter if INT // or DBL ... whatsoever double range = Math.abs(max - min); if (range == 0) return; // small ranges between min and max value if (range < 1) { final double dec = 1.0d / range; double pow = (int) (Math.floor(Math.log10(dec) + .5d) + 1) * 2; final double fac = (int) Math.pow(10, pow); final double tmin = min * fac; final double tmax = max * fac; range = Math.abs(tmax - tmin); pow = range < 10 ? 0 : (int) Math.floor(Math.log10(range) + .5d) - 1; calculatedCaptionStep = (int) Math.pow(10, pow); calculatedCaptionStep /= fac; return; } final int pow = range < 10 ? 0 : (int) Math.floor(Math.log10(range) + .5d) - 1; calculatedCaptionStep = (int) Math.pow(10, pow); }
/** * Calculates axis caption depending on view width / height. * * @param space space of view axis available for captions */ void calcCaption(final int space) { if (type == Kind.DBL || type == Kind.INT) { final double range = Math.abs(max - min); if (range == 0) { nrCaptions = 1; return; } // labeling for logarithmic scale if (log) { startvalue = min; nrCaptions = 3; return; } // labeling for linear scale final boolean dbl = type == Kind.DBL; actlCaptionStep = calculatedCaptionStep; nrCaptions = (int) (range / actlCaptionStep) + 1; while (2 * nrCaptions * PlotView.CAPTIONWHITESPACE * 3 < space && (dbl || actlCaptionStep % 2 == 0)) { actlCaptionStep /= 2; nrCaptions = (int) (range / actlCaptionStep); } while (nrCaptions * PlotView.CAPTIONWHITESPACE * 3 > space) { actlCaptionStep *= 2; nrCaptions = (int) (range / actlCaptionStep); } // calculate first value to be drawn startvalue = min + actlCaptionStep - min % actlCaptionStep; if (startvalue - min < actlCaptionStep / 4) startvalue += actlCaptionStep; // type == TEXT / CAT } else { nrCaptions = space / (PlotView.CAPTIONWHITESPACE * 3); if (nrCaptions > nrCats) nrCaptions = nrCats; actlCaptionStep = 1.0d / (nrCaptions - 1); } }
/** * Calculates base e logarithm for the given value. * * @param d value * @return base e logarithm for d */ private double ln(final double d) { return d == 0 ? 0 : Math.log1p(Math.abs(d)); }
/** * Formats the specified number and returns a string representation. * * @param item item * @param pics pictures * @param ii input info * @return picture variables * @throws QueryException query exception */ private byte[] format(final ANum item, final Picture[] pics, final InputInfo ii) throws QueryException { // Rule 1: return results for NaN final double d = item.dbl(ii); if (Double.isNaN(d)) return nan; // Rule 2: check if value if negative (smaller than zero or -0) final boolean neg = d < 0 || d == 0 && Double.doubleToLongBits(d) == Long.MIN_VALUE; final Picture pic = pics[neg && pics.length == 2 ? 1 : 0]; final IntList res = new IntList(), intgr = new IntList(), fract = new IntList(); int exp = 0; // Rule 3: percent/permille ANum num = item; if (pic.pc) num = (ANum) Calc.MULT.ev(num, Int.get(100), ii); if (pic.pm) num = (ANum) Calc.MULT.ev(num, Int.get(1000), ii); if (Double.isInfinite(num.dbl(ii))) { // Rule 4: infinity intgr.add(new TokenParser(inf).toArray()); } else { // Rule 5: exponent if (pic.minExp != 0 && d != 0) { BigDecimal dec = num.dec(ii).abs().stripTrailingZeros(); int scl = 0; if (dec.compareTo(BigDecimal.ONE) >= 0) { scl = dec.setScale(0, RoundingMode.HALF_DOWN).precision(); } else { while (dec.compareTo(BigDecimal.ONE) < 0) { dec = dec.multiply(BigDecimal.TEN); scl--; } scl++; } exp = scl - pic.min[0]; if (exp != 0) { final BigDecimal n = BigDecimal.TEN.pow(Math.abs(exp)); num = (ANum) Calc.MULT.ev(num, Dec.get(exp > 0 ? BigDecimal.ONE.divide(n) : n), ii); } } num = num.round(pic.maxFrac, true).abs(); // convert positive number to string final String s = (num instanceof Dbl || num instanceof Flt ? Dec.get(BigDecimal.valueOf(num.dbl(ii))) : num) .toString(); // integer/fractional separator final int sep = s.indexOf('.'); // create integer part final int sl = s.length(); final int il = sep == -1 ? sl : sep; for (int i = il; i < pic.min[0]; ++i) intgr.add(zero); // fractional number: skip leading 0 if (!s.startsWith("0.") || pic.min[0] > 0) { for (int i = 0; i < il; i++) intgr.add(zero + s.charAt(i) - '0'); } // squeeze in grouping separators if (pic.group[0].length == 1 && pic.group[0][0] > 0) { // regular pattern with repeating separators for (int p = intgr.size() - (neg ? 2 : 1); p > 0; --p) { if (p % pic.group[0][0] == 0) intgr.insert(intgr.size() - p, grouping); } } else { // irregular pattern, or no separators at all final int gl = pic.group[0].length; for (int g = 0; g < gl; ++g) { final int pos = intgr.size() - pic.group[0][g]; if (pos > 0) intgr.insert(pos, grouping); } } // create fractional part final int fl = sep == -1 ? 0 : sl - il - 1; if (fl != 0) for (int i = sep + 1; i < sl; i++) fract.add(zero + s.charAt(i) - '0'); for (int i = fl; i < pic.min[1]; ++i) fract.add(zero); // squeeze in grouping separators in a reverse manner final int ul = fract.size(); for (int p = pic.group[1].length - 1; p >= 0; p--) { final int pos = pic.group[1][p]; if (pos < ul) fract.insert(pos, grouping); } } // add minus sign if (neg && pics.length != 2) res.add(minus); // add prefix and integer part res.add(pic.prefSuf[0].toArray()).add(intgr.finish()); // add fractional part if (!fract.isEmpty()) res.add(decimal).add(fract.finish()); // add exponent if (pic.minExp != 0) { res.add(exponent); if (exp < 0) res.add(minus); final String s = Integer.toString(Math.abs(exp)); final int sl = s.length(); for (int i = sl; i < pic.minExp; i++) res.add(zero); for (int i = 0; i < sl; i++) res.add(zero + s.charAt(i) - '0'); } // add suffix res.add(pic.prefSuf[1].toArray()); return new TokenBuilder(res.finish()).finish(); }