📄 logarithmicaxis.java
字号:
/* ===========================================================
* JFreeChart : a free chart library for the Java(tm) platform
* ===========================================================
*
* (C) Copyright 2000-2005, 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 published 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.]
*
* --------------------
* LogarithmicAxis.java
* --------------------
* (C) Copyright 2000-2005, by Object Refinery Limited and Contributors.
*
* Original Author: Michael Duffy / Eric Thomas;
* Contributor(s): David Gilbert (for Object Refinery Limited);
* David M. O'Donnell;
* Scott Sams;
*
* $Id: LogarithmicAxis.java,v 1.11.2.1 2005/10/25 20:37:34 mungady Exp $
*
* Changes
* -------
* 14-Mar-2002 : Version 1 contributed by Michael Duffy (DG);
* 19-Apr-2002 : drawVerticalString() is now drawRotatedString() in
* RefineryUtilities (DG);
* 23-Apr-2002 : Added a range property (DG);
* 15-May-2002 : Modified to be able to deal with negative and zero values (via
* new 'adjustedLog10()' method); occurrences of "Math.log(10)"
* changed to "LOG10_VALUE"; changed 'intValue()' to
* 'longValue()' in 'refreshTicks()' to fix label-text value
* out-of-range problem; removed 'draw()' method; added
* 'autoRangeMinimumSize' check; added 'log10TickLabelsFlag'
* parameter flag and implementation (ET);
* 25-Jun-2002 : Removed redundant import (DG);
* 25-Jul-2002 : Changed order of parameters in ValueAxis constructor (DG);
* 16-Jul-2002 : Implemented support for plotting positive values arbitrarily
* close to zero (added 'allowNegativesFlag' flag) (ET).
* 05-Sep-2002 : Updated constructor reflecting changes in the Axis class (DG);
* 02-Oct-2002 : Fixed errors reported by Checkstyle (DG);
* 08-Nov-2002 : Moved to new package com.jrefinery.chart.axis (DG);
* 22-Nov-2002 : Bug fixes from David M. O'Donnell (DG);
* 14-Jan-2003 : Changed autoRangeMinimumSize from Number --> double (DG);
* 20-Jan-2003 : Removed unnecessary constructors (DG);
* 26-Mar-2003 : Implemented Serializable (DG);
* 08-May-2003 : Fixed plotting of datasets with lower==upper bounds when
* 'minAutoRange' is very small; added 'strictValuesFlag'
* and default functionality of throwing a runtime exception
* if 'allowNegativesFlag' is false and any values are less
* than or equal to zero; added 'expTickLabelsFlag' and
* changed to use "1e#"-style tick labels by default
* ("10^n"-style tick labels still supported via 'set'
* method); improved generation of tick labels when range of
* values is small; changed to use 'NumberFormat.getInstance()'
* to create 'numberFormatterObj' (ET);
* 14-May-2003 : Merged HorizontalLogarithmicAxis and
* VerticalLogarithmicAxis (DG);
* 29-Oct-2003 : Added workaround for font alignment in PDF output (DG);
* 07-Nov-2003 : Modified to use new NumberTick class (DG);
* 08-Apr-2004 : Use numberFormatOverride if set - see patch 930139 (DG);
* 11-Jan-2005 : Removed deprecated code in preparation for 1.0.0 release (DG);
* 21-Apr-2005 : Added support for upper and lower margins; added
* get/setAutoRangeNextLogFlag() methods and changed
* default to 'autoRangeNextLogFlag'==false (ET);
* 22-Apr-2005 : Removed refreshTicks() and fixed names and parameters for
* refreshHorizontalTicks() & refreshVerticalTicks();
* changed javadoc on setExpTickLabelsFlag() to specify
* proper default (ET);
* 22-Apr-2005 : Renamed refreshHorizontalTicks --> refreshTicksHorizontal
* (and likewise the vertical version) for consistency with
* other axis classes (DG);
*
*/
package org.jfree.chart.axis;
import java.awt.Graphics2D;
import java.awt.geom.Rectangle2D;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.List;
import org.jfree.chart.plot.Plot;
import org.jfree.chart.plot.ValueAxisPlot;
import org.jfree.data.Range;
import org.jfree.ui.RectangleEdge;
import org.jfree.ui.TextAnchor;
/**
* A numerical axis that uses a logarithmic scale.
*
* @author Michael Duffy
*/
public class LogarithmicAxis extends NumberAxis {
/** For serialization. */
private static final long serialVersionUID = 2502918599004103054L;
/** Useful constant for log(10). */
public static final double LOG10_VALUE = Math.log(10.0);
/** Smallest arbitrarily-close-to-zero value allowed. */
public static final double SMALL_LOG_VALUE = 1e-100;
/** Flag set true to allow negative values in data. */
protected boolean allowNegativesFlag = false;
/** Flag set true make axis throw exception if any values are
* <= 0 and 'allowNegativesFlag' is false. */
protected boolean strictValuesFlag = true;
/** Number formatter for generating numeric strings. */
protected final NumberFormat numberFormatterObj
= NumberFormat.getInstance();
/** Flag set true for "1e#"-style tick labels. */
protected boolean expTickLabelsFlag = false;
/** Flag set true for "10^n"-style tick labels. */
protected boolean log10TickLabelsFlag = false;
/** True to make 'autoAdjustRange()' select "10^n" values. */
protected boolean autoRangeNextLogFlag = false;
/** Helper flag for log axis processing. */
protected boolean smallLogFlag = false;
/**
* Creates a new axis.
*
* @param label the axis label.
*/
public LogarithmicAxis(String label) {
super(label);
setupNumberFmtObj(); //setup number formatter obj
}
/**
* Sets the 'allowNegativesFlag' flag; true to allow negative values
* in data, false to be able to plot positive values arbitrarily close to
* zero.
*
* @param flgVal the new value of the flag.
*/
public void setAllowNegativesFlag(boolean flgVal) {
this.allowNegativesFlag = flgVal;
}
/**
* Returns the 'allowNegativesFlag' flag; true to allow negative values
* in data, false to be able to plot positive values arbitrarily close
* to zero.
*
* @return The flag.
*/
public boolean getAllowNegativesFlag() {
return this.allowNegativesFlag;
}
/**
* Sets the 'strictValuesFlag' flag; if true and 'allowNegativesFlag'
* is false then this axis will throw a runtime exception if any of its
* values are less than or equal to zero; if false then the axis will
* adjust for values less than or equal to zero as needed.
*
* @param flgVal true for strict enforcement.
*/
public void setStrictValuesFlag(boolean flgVal) {
this.strictValuesFlag = flgVal;
}
/**
* Returns the 'strictValuesFlag' flag; if true and 'allowNegativesFlag'
* is false then this axis will throw a runtime exception if any of its
* values are less than or equal to zero; if false then the axis will
* adjust for values less than or equal to zero as needed.
*
* @return <code>true</code> if strict enforcement is enabled.
*/
public boolean getStrictValuesFlag() {
return this.strictValuesFlag;
}
/**
* Sets the 'expTickLabelsFlag' flag. If the 'log10TickLabelsFlag'
* is false then this will set whether or not "1e#"-style tick labels
* are used. The default is to use regular numeric tick labels.
*
* @param flgVal true for "1e#"-style tick labels, false for
* log10 or regular numeric tick labels.
*/
public void setExpTickLabelsFlag(boolean flgVal) {
this.expTickLabelsFlag = flgVal;
setupNumberFmtObj(); //setup number formatter obj
}
/**
* Returns the 'expTickLabelsFlag' flag.
*
* @return <code>true</code> for "1e#"-style tick labels,
* <code>false</code> for log10 or regular numeric tick labels.
*/
public boolean getExpTickLabelsFlag() {
return this.expTickLabelsFlag;
}
/**
* Sets the 'log10TickLabelsFlag' flag. The default value is false.
*
* @param flag true for "10^n"-style tick labels, false for "1e#"-style
* or regular numeric tick labels.
*/
public void setLog10TickLabelsFlag(boolean flag) {
this.log10TickLabelsFlag = flag;
}
/**
* Returns the 'log10TickLabelsFlag' flag.
*
* @return <code>true</code> for "10^n"-style tick labels,
* <code>false</code> for "1e#"-style or regular numeric tick
* labels.
*/
public boolean getLog10TickLabelsFlag() {
return this.log10TickLabelsFlag;
}
/**
* Sets the 'autoRangeNextLogFlag' flag. This determines whether or
* not the 'autoAdjustRange()' method will select the next "10^n"
* values when determining the upper and lower bounds. The default
* value is false.
*
* @param flag <code>true</code> to make the 'autoAdjustRange()'
* method select the next "10^n" values, <code>false</code> to not.
*/
public void setAutoRangeNextLogFlag(boolean flag) {
this.autoRangeNextLogFlag = flag;
}
/**
* Returns the 'autoRangeNextLogFlag' flag.
*
* @return <code>true</code> if the 'autoAdjustRange()' method will
* select the next "10^n" values, <code>false</code> if not.
*/
public boolean getAutoRangeNextLogFlag() {
return this.autoRangeNextLogFlag;
}
/**
* Overridden version that calls original and then sets up flag for
* log axis processing.
*
* @param range the new range.
*/
public void setRange(Range range) {
super.setRange(range); // call parent method
setupSmallLogFlag(); // setup flag based on bounds values
}
/**
* Sets up flag for log axis processing. Set true if negative values
* not allowed and the lower bound is between 0 and 10.
*/
protected void setupSmallLogFlag() {
// set flag true if negative values not allowed and the
// lower bound is between 0 and 10:
double lowerVal = getRange().getLowerBound();
this.smallLogFlag
= (!this.allowNegativesFlag && lowerVal < 10.0 && lowerVal > 0.0);
}
/**
* Sets up the number formatter object according to the
* 'expTickLabelsFlag' flag.
*/
protected void setupNumberFmtObj() {
if (this.numberFormatterObj instanceof DecimalFormat) {
//setup for "1e#"-style tick labels or regular
// numeric tick labels, depending on flag:
((DecimalFormat) this.numberFormatterObj).applyPattern(
this.expTickLabelsFlag ? "0E0" : "0.###"
);
}
}
/**
* Returns the log10 value, depending on if values between 0 and
* 1 are being plotted. If negative values are not allowed and
* the lower bound is between 0 and 10 then a normal log is
* returned; otherwise the returned value is adjusted if the
* given value is less than 10.
*
* @param val the value.
*
* @return log<sub>10</sub>(val).
*/
protected double switchedLog10(double val) {
return this.smallLogFlag ? Math.log(val)
/ LOG10_VALUE : adjustedLog10(val);
}
/**
* Returns an adjusted log10 value for graphing purposes. The first
* adjustment is that negative values are changed to positive during
* the calculations, and then the answer is negated at the end. The
* second is that, for values less than 10, an increasingly large
* (0 to 1) scaling factor is added such that at 0 the value is
* adjusted to 1, resulting in a returned result of 0.
*
* @param val value for which log10 should be calculated.
*
* @return An adjusted log<sub>10</sub>(val).
*/
public double adjustedLog10(double val) {
boolean negFlag = (val < 0.0);
if (negFlag) {
val = -val; // if negative then set flag and make positive
}
if (val < 10.0) { // if < 10 then
val += (10.0 - val) / 10; //increase so 0 translates to 0
}
//return value; negate if original value was negative:
return negFlag ? -(Math.log(val) / LOG10_VALUE)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -