org.pentaho.plugin.jfreereport.reportcharts.ScalingLogarithmicAxis.java Source code

Java tutorial

Introduction

Here is the source code for org.pentaho.plugin.jfreereport.reportcharts.ScalingLogarithmicAxis.java

Source

/*!
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License, version 2.1 as published by the Free Software
* Foundation.
*
* You should have received a copy of the GNU Lesser General Public License along with this
* program; if not, you can obtain a copy at http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html
* or from the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* 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 Lesser General Public License for more details.
*
* Copyright (c) 2002-2017 Hitachi Vantara..  All rights reserved.
*/

package org.pentaho.plugin.jfreereport.reportcharts;

import org.jfree.chart.axis.LogarithmicAxis;
import org.jfree.chart.axis.NumberTick;
import org.jfree.chart.plot.ValueAxisPlot;
import org.jfree.data.Range;
import org.jfree.ui.RectangleEdge;
import org.jfree.ui.TextAnchor;

import java.awt.*;
import java.awt.geom.Rectangle2D;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.List;

public class ScalingLogarithmicAxis extends LogarithmicAxis {

    private static final long serialVersionUID = 1L;
    private int ticksVertical = -1;

    public ScalingLogarithmicAxis(final String label) {
        super(label);
    }

    public void autoAdjustRange() {
        super.autoAdjustRange();
        if (getPlot() instanceof ValueAxisPlot) {
            final Range range = this.getRange();
            setRange(new Range(range.getLowerBound() * 10.0, range.getUpperBound() * 10.0), false, false);
            setupSmallLogFlag();
        }
    }

    protected List refreshTicksVertical(final Graphics2D g2, final Rectangle2D dataArea, final RectangleEdge edge) {

        final ArrayList ticks = new ArrayList();

        // get lower bound value:
        double lowerBoundVal = getRange().getLowerBound();
        // if small log values and lower bound value too small
        // then set to a small value (don't allow <= 0):
        if (this.smallLogFlag && lowerBoundVal < SMALL_LOG_VALUE) {
            lowerBoundVal = SMALL_LOG_VALUE;
        }
        // get upper bound value
        final double upperBoundVal = getRange().getUpperBound();

        // get log10 version of lower bound and round to integer:
        int iBegCount = (int) Math.rint(switchedLog10(lowerBoundVal));
        // get log10 version of upper bound and round to integer:
        final int iEndCount = (int) Math.rint(switchedLog10(upperBoundVal));

        if (iBegCount == iEndCount && iBegCount > 0 && Math.pow(10, iBegCount) > lowerBoundVal) {
            // only 1 power of 10 value, it's > 0 and its resulting
            // tick value will be larger than lower bound of data
            --iBegCount; // decrement to generate more ticks
        }

        double tickVal;
        String tickLabel;
        boolean zeroTickFlag = false;
        final int[] intervals = { 10, 10, 10, 10, 10, 5, 5, 5, 3, 3 };

        for (int i = iBegCount; i <= iEndCount; i++) {
            // for each tick with a label to be displayed
            int jEndCount = getTicksVertical();
            if (jEndCount == -1) {
                jEndCount = Math.abs(iEndCount - iBegCount) < 10 ? intervals[iEndCount - iBegCount] : 1;
            }

            if (i == iEndCount) {
                jEndCount = 1;
            }

            for (int j = 0; j < jEndCount; j++) {
                // for each tick to be displayed
                if (this.smallLogFlag) {
                    // small log values in use
                    tickVal = Math.pow(10, i) + (Math.pow(10, i) * j);
                    if (j == 0) {
                        // first tick of group; create label text
                        if (this.log10TickLabelsFlag) {
                            // if flag then
                            tickLabel = "10^" + i; // create "log10"-type label
                        } else { // not "log10"-type label
                            if (this.expTickLabelsFlag) {
                                // if flag then
                                tickLabel = "1e" + i; // create "1e#"-type label
                            } else { // not "1e#"-type label
                                if (i >= 0) { // if positive exponent then
                                    // make integer
                                    final NumberFormat format = getNumberFormatOverride();
                                    if (format != null) {
                                        tickLabel = format.format(tickVal);
                                    } else {
                                        tickLabel = LogCategoryItemLabelGenerator.formatValue(new Double(tickVal));
                                        /*tickLabel = Long.toString((long) Math.rint(tickVal));*/
                                    }
                                } else {
                                    // negative exponent; create fractional value
                                    // set exact number of fractional digits to
                                    // be shown:
                                    this.numberFormatterObj.setMaximumFractionDigits(-i);
                                    // create tick label:
                                    tickLabel = this.numberFormatterObj.format(tickVal);
                                }
                            }
                        }
                    } else { // not first tick to be displayed
                        tickLabel = ""; // no tick label
                    }
                } else { // not small log values in use; allow for values <= 0
                    if (zeroTickFlag) { // if did zero tick last iter then
                        --j;
                    } // decrement to do 1.0 tick now
                    tickVal = (i >= 0) ? Math.pow(10, i) + (Math.pow(10, i) * j)
                            : j == 0 ? -Math.pow(10, -i) : -(Math.pow(10, -i) - (Math.pow(10, -i - 1) * (9 - j)));
                    if (j == 0) { // first tick of group
                        if (!zeroTickFlag) { // did not do zero tick last
                            // iteration
                            if (i > iBegCount && i < iEndCount && Math.abs(tickVal - 1.0) < 0.0001) {
                                // not first or last tick on graph and value
                                // is 1.0
                                tickVal = 0.0; // change value to 0.0
                                zeroTickFlag = true; // indicate zero tick
                                tickLabel = "0"; // create label for tick
                            } else {
                                // first or last tick on graph or value is 1.0
                                // create label for tick:
                                if (this.log10TickLabelsFlag) {
                                    // create "log10"-type label
                                    tickLabel = (((i < 0) ? "-" : "") + "10^" + Math.abs(i));
                                } else {
                                    if (this.expTickLabelsFlag) {
                                        // create "1e#"-type label
                                        tickLabel = (((i < 0) ? "-" : "") + "1e" + Math.abs(i));
                                    } else {
                                        final NumberFormat format = getNumberFormatOverride();
                                        if (format != null) {
                                            tickLabel = format.format(tickVal);
                                        } else {
                                            tickLabel = LogCategoryItemLabelGenerator.formatValue(new Double(
                                                    tickVal));/*
                                                              tickLabel =  Long.toString((long) Math.rint(tickVal));*/
                                        }
                                    }
                                }
                            }
                        } else { // did zero tick last iteration
                            tickLabel = ""; // no label
                            zeroTickFlag = false; // clear flag
                        }
                    } else { // not first tick of group
                        tickLabel = ""; // no label
                        zeroTickFlag = false; // make sure flag cleared
                    }
                }

                if (tickVal > upperBoundVal) {
                    return ticks; // if past highest data value then exit method
                }

                if (tickVal >= lowerBoundVal - SMALL_LOG_VALUE) {
                    // tick value not below lowest data value
                    final TextAnchor anchor;
                    final TextAnchor rotationAnchor;
                    double angle = 0.0;
                    if (isVerticalTickLabels()) {
                        if (edge == RectangleEdge.LEFT) {
                            anchor = TextAnchor.BOTTOM_CENTER;
                            rotationAnchor = TextAnchor.BOTTOM_CENTER;
                            angle = -Math.PI / 2.0;
                        } else {
                            anchor = TextAnchor.BOTTOM_CENTER;
                            rotationAnchor = TextAnchor.BOTTOM_CENTER;
                            angle = Math.PI / 2.0;
                        }
                    } else {
                        if (edge == RectangleEdge.LEFT) {
                            anchor = TextAnchor.CENTER_RIGHT;
                            rotationAnchor = TextAnchor.CENTER_RIGHT;
                        } else {
                            anchor = TextAnchor.CENTER_LEFT;
                            rotationAnchor = TextAnchor.CENTER_LEFT;
                        }
                    }

                    ticks.add(new NumberTick(new Double(tickVal), tickLabel, anchor, rotationAnchor, angle));
                }
            }
        }
        return ticks;
    }

    public void setTicksVertical(final int ticksVertical) {
        this.ticksVertical = ticksVertical;
    }

    public int getTicksVertical() {
        return ticksVertical;
    }

}