📄 valueaxis.java
字号:
/* ===========================================================
* JFreeChart : a free chart library for the Java(tm) platform
* ===========================================================
*
* (C) Copyright 2000-2007, by Object Refinery Limited and Contributors.
*
* Project Info: http://www.jfree.org/jfreechart/index.html
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as publihed by
* the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This library 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.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
* USA.
*
* [Java is a trademark or registered trademark of Sun Microsystems, Inc.
* in the United States and other countries.]
*
* --------------
* ValueAxis.java
* --------------
* (C) Copyright 2000-2007, by Object Refinery Limited and Contributors.
*
* Original Author: David Gilbert (for Object Refinery Limited);
* Contributor(s): Jonathan Nash;
* Nicolas Brodu (for Astrium and EADS Corporate Research
* Center);
*
* Changes
* -------
* 18-Sep-2001 : Added standard header and fixed DOS encoding problem (DG);
* 23-Nov-2001 : Overhauled standard tick unit code (DG);
* 04-Dec-2001 : Changed constructors to protected, and tidied up default
* values (DG);
* 12-Dec-2001 : Fixed vertical gridlines bug (DG);
* 16-Jan-2002 : Added an optional crosshair, based on the implementation by
* Jonathan Nash (DG);
* 23-Jan-2002 : Moved the minimum and maximum values to here from NumberAxis,
* and changed the type from Number to double (DG);
* 25-Feb-2002 : Added default value for autoRange. Changed autoAdjustRange
* from public to protected. Updated import statements (DG);
* 23-Apr-2002 : Added setRange() method (DG);
* 29-Apr-2002 : Added range adjustment methods (DG);
* 13-Jun-2002 : Modified setCrosshairValue() to notify listeners only when the
* crosshairs are visible, to avoid unnecessary repaints, as
* suggested by Kees Kuip (DG);
* 25-Jul-2002 : Moved lower and upper margin attributes from the NumberAxis
* class (DG);
* 05-Sep-2002 : Updated constructor for changes in Axis class (DG);
* 01-Oct-2002 : Fixed errors reported by Checkstyle (DG);
* 04-Oct-2002 : Moved standardTickUnits from NumberAxis --> ValueAxis (DG);
* 08-Nov-2002 : Moved to new package com.jrefinery.chart.axis (DG);
* 19-Nov-2002 : Removed grid settings (now controlled by the plot) (DG);
* 27-Nov-2002 : Moved the 'inverted' attributed from NumberAxis to
* ValueAxis (DG);
* 03-Jan-2003 : Small fix to ensure auto-range minimum is observed
* immediately (DG);
* 14-Jan-2003 : Changed autoRangeMinimumSize from Number --> double (DG);
* 20-Jan-2003 : Replaced monolithic constructor (DG);
* 26-Mar-2003 : Implemented Serializable (DG);
* 09-May-2003 : Added AxisLocation parameter to translation methods (DG);
* 13-Aug-2003 : Implemented Cloneable (DG);
* 01-Sep-2003 : Fixed bug 793167 (setMaximumAxisValue exception) (DG);
* 02-Sep-2003 : Fixed bug 795366 (zooming on inverted axes) (DG);
* 08-Sep-2003 : Completed Serialization support (NB);
* 08-Sep-2003 : Renamed get/setMinimumValue --> get/setLowerBound,
* and get/setMaximumValue --> get/setUpperBound (DG);
* 27-Oct-2003 : Changed DEFAULT_AUTO_RANGE_MINIMUM_SIZE value - see bug ID
* 829606 (DG);
* 07-Nov-2003 : Changes to tick mechanism (DG);
* 06-Jan-2004 : Moved axis line attributes to Axis class (DG);
* 21-Jan-2004 : Removed redundant axisLineVisible attribute. Renamed
* translateJava2DToValue --> java2DToValue, and
* translateValueToJava2D --> valueToJava2D (DG);
* 23-Jan-2004 : Fixed setAxisLinePaint() and setAxisLineStroke() which had no
* effect (andreas.gawecki@coremedia.com);
* 07-Apr-2004 : Changed text bounds calculation (DG);
* 26-Apr-2004 : Added getter/setter methods for arrow shapes (DG);
* 18-May-2004 : Added methods to set axis range *including* current
* margins (DG);
* 02-Jun-2004 : Fixed bug in setRangeWithMargins() method (DG);
* 30-Sep-2004 : Moved drawRotatedString() from RefineryUtilities
* --> TextUtilities (DG);
* 11-Jan-2005 : Removed deprecated methods in preparation for 1.0.0
* release (DG);
* 21-Apr-2005 : Replaced Insets with RectangleInsets (DG);
* ------------- JFREECHART 1.0.x ---------------------------------------------
* 10-Oct-2006 : Source reformatting (DG);
* 22-Mar-2007 : Added new defaultAutoRange attribute (DG);
* 02-Aug-2007 : Check for major tick when drawing label (DG);
*
*/
package org.jfree.chart.axis;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics2D;
import java.awt.Polygon;
import java.awt.Shape;
import java.awt.font.LineMetrics;
import java.awt.geom.AffineTransform;
import java.awt.geom.Line2D;
import java.awt.geom.Rectangle2D;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.Iterator;
import java.util.List;
import org.jfree.chart.event.AxisChangeEvent;
import org.jfree.chart.plot.Plot;
import org.jfree.data.Range;
import org.jfree.io.SerialUtilities;
import org.jfree.text.TextUtilities;
import org.jfree.ui.RectangleEdge;
import org.jfree.ui.RectangleInsets;
import org.jfree.util.ObjectUtilities;
import org.jfree.util.PublicCloneable;
/**
* The base class for axes that display value data, where values are measured
* using the <code>double</code> primitive. The two key subclasses are
* {@link DateAxis} and {@link NumberAxis}.
*/
public abstract class ValueAxis extends Axis
implements Cloneable, PublicCloneable,
Serializable {
/** For serialization. */
private static final long serialVersionUID = 3698345477322391456L;
/** The default axis range. */
public static final Range DEFAULT_RANGE = new Range(0.0, 1.0);
/** The default auto-range value. */
public static final boolean DEFAULT_AUTO_RANGE = true;
/** The default inverted flag setting. */
public static final boolean DEFAULT_INVERTED = false;
/** The default minimum auto range. */
public static final double DEFAULT_AUTO_RANGE_MINIMUM_SIZE = 0.00000001;
/** The default value for the lower margin (0.05 = 5%). */
public static final double DEFAULT_LOWER_MARGIN = 0.05;
/** The default value for the upper margin (0.05 = 5%). */
public static final double DEFAULT_UPPER_MARGIN = 0.05;
/**
* The default lower bound for the axis.
*
* @deprecated From 1.0.5 onwards, the axis defines a defaultRange
* attribute (see {@link #getDefaultAutoRange()}).
*/
public static final double DEFAULT_LOWER_BOUND = 0.0;
/**
* The default upper bound for the axis.
*
* @deprecated From 1.0.5 onwards, the axis defines a defaultRange
* attribute (see {@link #getDefaultAutoRange()}).
*/
public static final double DEFAULT_UPPER_BOUND = 1.0;
/** The default auto-tick-unit-selection value. */
public static final boolean DEFAULT_AUTO_TICK_UNIT_SELECTION = true;
/** The maximum tick count. */
public static final int MAXIMUM_TICK_COUNT = 500;
/**
* A flag that controls whether an arrow is drawn at the positive end of
* the axis line.
*/
private boolean positiveArrowVisible;
/**
* A flag that controls whether an arrow is drawn at the negative end of
* the axis line.
*/
private boolean negativeArrowVisible;
/** The shape used for an up arrow. */
private transient Shape upArrow;
/** The shape used for a down arrow. */
private transient Shape downArrow;
/** The shape used for a left arrow. */
private transient Shape leftArrow;
/** The shape used for a right arrow. */
private transient Shape rightArrow;
/** A flag that affects the orientation of the values on the axis. */
private boolean inverted;
/** The axis range. */
private Range range;
/**
* Flag that indicates whether the axis automatically scales to fit the
* chart data.
*/
private boolean autoRange;
/** The minimum size for the 'auto' axis range (excluding margins). */
private double autoRangeMinimumSize;
/**
* The default range is used when the dataset is empty and the axis needs
* to determine the auto range.
*
* @since 1.0.5
*/
private Range defaultAutoRange;
/**
* The upper margin percentage. This indicates the amount by which the
* maximum axis value exceeds the maximum data value (as a percentage of
* the range on the axis) when the axis range is determined automatically.
*/
private double upperMargin;
/**
* The lower margin. This is a percentage that indicates the amount by
* which the minimum axis value is "less than" the minimum data value when
* the axis range is determined automatically.
*/
private double lowerMargin;
/**
* If this value is positive, the amount is subtracted from the maximum
* data value to determine the lower axis range. This can be used to
* provide a fixed "window" on dynamic data.
*/
private double fixedAutoRange;
/**
* Flag that indicates whether or not the tick unit is selected
* automatically.
*/
private boolean autoTickUnitSelection;
/** The standard tick units for the axis. */
private TickUnitSource standardTickUnits;
/** An index into an array of standard tick values. */
private int autoTickIndex;
/** A flag indicating whether or not tick labels are rotated to vertical. */
private boolean verticalTickLabels;
/**
* Constructs a value axis.
*
* @param label the axis label (<code>null</code> permitted).
* @param standardTickUnits the source for standard tick units
* (<code>null</code> permitted).
*/
protected ValueAxis(String label, TickUnitSource standardTickUnits) {
super(label);
this.positiveArrowVisible = false;
this.negativeArrowVisible = false;
this.range = DEFAULT_RANGE;
this.autoRange = DEFAULT_AUTO_RANGE;
this.defaultAutoRange = DEFAULT_RANGE;
this.inverted = DEFAULT_INVERTED;
this.autoRangeMinimumSize = DEFAULT_AUTO_RANGE_MINIMUM_SIZE;
this.lowerMargin = DEFAULT_LOWER_MARGIN;
this.upperMargin = DEFAULT_UPPER_MARGIN;
this.fixedAutoRange = 0.0;
this.autoTickUnitSelection = DEFAULT_AUTO_TICK_UNIT_SELECTION;
this.standardTickUnits = standardTickUnits;
Polygon p1 = new Polygon();
p1.addPoint(0, 0);
p1.addPoint(-2, 2);
p1.addPoint(2, 2);
this.upArrow = p1;
Polygon p2 = new Polygon();
p2.addPoint(0, 0);
p2.addPoint(-2, -2);
p2.addPoint(2, -2);
this.downArrow = p2;
Polygon p3 = new Polygon();
p3.addPoint(0, 0);
p3.addPoint(-2, -2);
p3.addPoint(-2, 2);
this.rightArrow = p3;
Polygon p4 = new Polygon();
p4.addPoint(0, 0);
p4.addPoint(2, -2);
p4.addPoint(2, 2);
this.leftArrow = p4;
this.verticalTickLabels = false;
}
/**
* Returns <code>true</code> if the tick labels should be rotated (to
* vertical), and <code>false</code> otherwise.
*
* @return <code>true</code> or <code>false</code>.
*
* @see #setVerticalTickLabels(boolean)
*/
public boolean isVerticalTickLabels() {
return this.verticalTickLabels;
}
/**
* Sets the flag that controls whether the tick labels are displayed
* vertically (that is, rotated 90 degrees from horizontal). If the flag
* is changed, an {@link AxisChangeEvent} is sent to all registered
* listeners.
*
* @param flag the flag.
*
* @see #isVerticalTickLabels()
*/
public void setVerticalTickLabels(boolean flag) {
if (this.verticalTickLabels != flag) {
this.verticalTickLabels = flag;
notifyListeners(new AxisChangeEvent(this));
}
}
/**
* Returns a flag that controls whether or not the axis line has an arrow
* drawn that points in the positive direction for the axis.
*
* @return A boolean.
*
* @see #setPositiveArrowVisible(boolean)
*/
public boolean isPositiveArrowVisible() {
return this.positiveArrowVisible;
}
/**
* Sets a flag that controls whether or not the axis lines has an arrow
* drawn that points in the positive direction for the axis, and sends an
* {@link AxisChangeEvent} to all registered listeners.
*
* @param visible the flag.
*
* @see #isPositiveArrowVisible()
*/
public void setPositiveArrowVisible(boolean visible) {
this.positiveArrowVisible = visible;
notifyListeners(new AxisChangeEvent(this));
}
/**
* Returns a flag that controls whether or not the axis line has an arrow
* drawn that points in the negative direction for the axis.
*
* @return A boolean.
*
* @see #setNegativeArrowVisible(boolean)
*/
public boolean isNegativeArrowVisible() {
return this.negativeArrowVisible;
}
/**
* Sets a flag that controls whether or not the axis lines has an arrow
* drawn that points in the negative direction for the axis, and sends an
* {@link AxisChangeEvent} to all registered listeners.
*
* @param visible the flag.
*
* @see #setNegativeArrowVisible(boolean)
*/
public void setNegativeArrowVisible(boolean visible) {
this.negativeArrowVisible = visible;
notifyListeners(new AxisChangeEvent(this));
}
/**
* Returns a shape that can be displayed as an arrow pointing upwards at
* the end of an axis line.
*
* @return A shape (never <code>null</code>).
*
* @see #setUpArrow(Shape)
*/
public Shape getUpArrow() {
return this.upArrow;
}
/**
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -