edu.jhuapl.graphs.jfreechart.utils.CustomLabelNumberAxis.java Source code

Java tutorial

Introduction

Here is the source code for edu.jhuapl.graphs.jfreechart.utils.CustomLabelNumberAxis.java

Source

/*
 * Copyright (c) 2013 The Johns Hopkins University/Applied Physics Laboratory
 *                             All rights reserved.
 *
 * This material may be used, modified, or reproduced by or for the U.S.
 * Government pursuant to the rights granted under the clauses at
 * DFARS 252.227-7013/7014 or FAR 52.227-14.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * NO WARRANTY.   THIS MATERIAL IS PROVIDED "AS IS."  JHU/APL DISCLAIMS ALL
 * WARRANTIES IN THE MATERIAL, WHETHER EXPRESS OR IMPLIED, INCLUDING (BUT NOT
 * LIMITED TO) ANY AND ALL IMPLIED WARRANTIES OF PERFORMANCE,
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT OF
 * INTELLECTUAL PROPERTY RIGHTS. ANY USER OF THE MATERIAL ASSUMES THE ENTIRE
 * RISK AND LIABILITY FOR USING THE MATERIAL.  IN NO EVENT SHALL JHU/APL BE
 * LIABLE TO ANY USER OF THE MATERIAL FOR ANY ACTUAL, INDIRECT,
 * CONSEQUENTIAL, SPECIAL OR OTHER DAMAGES ARISING FROM THE USE OF, OR
 * INABILITY TO USE, THE MATERIAL, INCLUDING, BUT NOT LIMITED TO, ANY DAMAGES
 * FOR LOST PROFITS.
 */

package edu.jhuapl.graphs.jfreechart.utils;

import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.axis.NumberTick;
import org.jfree.chart.axis.Tick;
import org.jfree.chart.axis.TickType;
import org.jfree.chart.axis.TickUnit;
import org.jfree.chart.axis.ValueAxis;
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;
import java.util.Map;

public class CustomLabelNumberAxis extends NumberAxis {

    private static final long serialVersionUID = 3184634416365314383L;
    private Map<Double, String> tickValueToLabelMapping = null;
    private Double lowestTickValue = null;
    private Integer tickCount = null;

    public CustomLabelNumberAxis(Map<Double, String> tickValueToLabelMapping) {
        this.tickValueToLabelMapping = tickValueToLabelMapping;
    }

    public CustomLabelNumberAxis(Map<Double, String> tickValueToLabelMapping, String label) {
        super(label);
        this.tickValueToLabelMapping = tickValueToLabelMapping;
    }

    public void setLowestTickValue(Double lowestTickValue) {
        this.lowestTickValue = lowestTickValue;
    }

    public void setTickCount(Integer tickCount) {
        this.tickCount = tickCount;
    }

    @Override
    protected List<Tick> refreshTicksHorizontal(Graphics2D g2, Rectangle2D dataArea, RectangleEdge edge) {
        List<Tick> result = new ArrayList<Tick>();
        Font tickLabelFont = getTickLabelFont();
        g2.setFont(tickLabelFont);

        if (isAutoTickUnitSelection()) {
            selectAutoTickUnit(g2, dataArea, edge);
        }

        TickUnit tu = getTickUnit();
        double size = tu.getSize();
        int count = this.tickCount != null ? this.tickCount : calculateVisibleTickCount();
        double lowestTickValue = this.lowestTickValue != null ? this.lowestTickValue
                : calculateLowestVisibleTickValue();

        if (count <= ValueAxis.MAXIMUM_TICK_COUNT) {
            int minorTickSpaces = getMinorTickCount();

            if (minorTickSpaces <= 0) {
                minorTickSpaces = tu.getMinorTickCount();
            }

            for (int minorTick = 1; minorTick < minorTickSpaces; minorTick++) {
                double minorTickValue = lowestTickValue - size * minorTick / minorTickSpaces;

                if (getRange().contains(minorTickValue)) {
                    result.add(new NumberTick(TickType.MINOR, minorTickValue, "", TextAnchor.TOP_CENTER,
                            TextAnchor.CENTER, 0.0));
                }
            }

            for (int i = 0; i < count; i++) {
                double currentTickValue = lowestTickValue + (i * size);
                String tickLabel = tickValueToLabelMapping.get(currentTickValue);

                if (tickLabel == null) {
                    NumberFormat formatter = getNumberFormatOverride();

                    if (formatter != null) {
                        tickLabel = formatter.format(currentTickValue);
                    } else {
                        tickLabel = getTickUnit().valueToString(currentTickValue);
                    }
                }

                TextAnchor anchor = null;
                TextAnchor rotationAnchor = null;
                double angle = 0.0;

                if (isVerticalTickLabels()) {
                    anchor = TextAnchor.CENTER_RIGHT;
                    rotationAnchor = TextAnchor.CENTER_RIGHT;

                    if (edge == RectangleEdge.TOP) {
                        angle = Math.PI / 2.0;
                    } else {
                        angle = -Math.PI / 2.0;
                    }
                } else {
                    if (edge == RectangleEdge.TOP) {
                        anchor = TextAnchor.BOTTOM_CENTER;
                        rotationAnchor = TextAnchor.BOTTOM_CENTER;
                    } else {
                        anchor = TextAnchor.TOP_CENTER;
                        rotationAnchor = TextAnchor.TOP_CENTER;
                    }
                }

                Tick tick = new NumberTick(new Double(currentTickValue), tickLabel, anchor, rotationAnchor, angle);
                result.add(tick);
                double nextTickValue = lowestTickValue + ((i + 1) * size);

                for (int minorTick = 1; minorTick < minorTickSpaces; minorTick++) {
                    double minorTickValue = currentTickValue
                            + (nextTickValue - currentTickValue) * minorTick / minorTickSpaces;

                    if (getRange().contains(minorTickValue)) {
                        result.add(new NumberTick(TickType.MINOR, minorTickValue, "", TextAnchor.TOP_CENTER,
                                TextAnchor.CENTER, 0.0));
                    }
                }
            }
        }

        return result;
    }

    @Override
    protected List<Tick> refreshTicksVertical(Graphics2D g2, Rectangle2D dataArea, RectangleEdge edge) {
        List<Tick> result = new ArrayList<Tick>();
        Font tickLabelFont = getTickLabelFont();
        g2.setFont(tickLabelFont);

        if (isAutoTickUnitSelection()) {
            selectAutoTickUnit(g2, dataArea, edge);
        }

        TickUnit tu = getTickUnit();
        double size = tu.getSize();
        int count = this.tickCount != null ? this.tickCount : calculateVisibleTickCount();
        double lowestTickValue = this.lowestTickValue != null ? this.lowestTickValue
                : calculateLowestVisibleTickValue();

        if (count <= ValueAxis.MAXIMUM_TICK_COUNT) {
            int minorTickSpaces = getMinorTickCount();

            if (minorTickSpaces <= 0) {
                minorTickSpaces = tu.getMinorTickCount();
            }

            for (int minorTick = 1; minorTick < minorTickSpaces; minorTick++) {
                double minorTickValue = lowestTickValue - size * minorTick / minorTickSpaces;

                if (getRange().contains(minorTickValue)) {
                    result.add(new NumberTick(TickType.MINOR, minorTickValue, "", TextAnchor.TOP_CENTER,
                            TextAnchor.CENTER, 0.0));
                }
            }

            for (int i = 0; i < count; i++) {
                double currentTickValue = lowestTickValue + (i * size);
                String tickLabel = tickValueToLabelMapping.get(currentTickValue);

                if (tickLabel == null) {
                    NumberFormat formatter = getNumberFormatOverride();

                    if (formatter != null) {
                        tickLabel = formatter.format(currentTickValue);
                    } else {
                        tickLabel = getTickUnit().valueToString(currentTickValue);
                    }
                }

                TextAnchor anchor = null;
                TextAnchor rotationAnchor = null;
                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;
                    }
                }

                Tick tick = new NumberTick(new Double(currentTickValue), tickLabel, anchor, rotationAnchor, angle);
                result.add(tick);
                double nextTickValue = lowestTickValue + ((i + 1) * size);

                for (int minorTick = 1; minorTick < minorTickSpaces; minorTick++) {
                    double minorTickValue = currentTickValue
                            + (nextTickValue - currentTickValue) * minorTick / minorTickSpaces;

                    if (getRange().contains(minorTickValue)) {
                        result.add(new NumberTick(TickType.MINOR, minorTickValue, "", TextAnchor.TOP_CENTER,
                                TextAnchor.CENTER, 0.0));
                    }
                }
            }
        }

        return result;
    }
}