001/* =========================================================== 002 * JFreeChart : a free chart library for the Java(tm) platform 003 * =========================================================== 004 * 005 * (C) Copyright 2000-present, by David Gilbert and Contributors. 006 * 007 * Project Info: http://www.jfree.org/jfreechart/index.html 008 * 009 * This library is free software; you can redistribute it and/or modify it 010 * under the terms of the GNU Lesser General Public License as published by 011 * the Free Software Foundation; either version 2.1 of the License, or 012 * (at your option) any later version. 013 * 014 * This library is distributed in the hope that it will be useful, but 015 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 016 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 017 * License for more details. 018 * 019 * You should have received a copy of the GNU Lesser General Public 020 * License along with this library; if not, write to the Free Software 021 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 022 * USA. 023 * 024 * [Oracle and Java are registered trademarks of Oracle and/or its affiliates. 025 * Other names may be trademarks of their respective owners.] 026 * 027 * -------------- 028 * LogFormat.java 029 * -------------- 030 * (C) Copyright 2007-present, by David Gilbert and Contributors. 031 * 032 * Original Author: David Gilbert; 033 * Contributor(s): -; 034 * 035 */ 036 037package org.jfree.chart.util; 038 039import java.text.DecimalFormat; 040import java.text.FieldPosition; 041import java.text.NumberFormat; 042import java.text.ParsePosition; 043 044/** 045 * A number formatter for logarithmic values. This formatter does not support 046 * parsing. 047 */ 048public class LogFormat extends NumberFormat { 049 050 /** The log base value. */ 051 private double base; 052 053 /** The natural logarithm of the base value. */ 054 private double baseLog; 055 056 /** The label for the log base (for example, "e"). */ 057 private String baseLabel; 058 059 /** 060 * The label for the power symbol. 061 */ 062 private String powerLabel; 063 064 /** A flag that controls whether or not the base is shown. */ 065 private boolean showBase; 066 067 /** The number formatter for the exponent. */ 068 private NumberFormat formatter = new DecimalFormat("0.0#"); 069 070 /** 071 * Creates a new instance using base 10. 072 */ 073 public LogFormat() { 074 this(10.0, "10", true); 075 } 076 077 /** 078 * Creates a new instance. 079 * 080 * @param base the base. 081 * @param baseLabel the base label ({@code null} not permitted). 082 * @param showBase a flag that controls whether or not the base value is 083 * shown. 084 */ 085 public LogFormat(double base, String baseLabel, boolean showBase) { 086 this(base, baseLabel, "^", showBase); 087 } 088 089 /** 090 * Creates a new instance. 091 * 092 * @param base the base. 093 * @param baseLabel the base label ({@code null} not permitted). 094 * @param powerLabel the power label ({@code null} not permitted). 095 * @param showBase a flag that controls whether or not the base value is 096 * shown. 097 */ 098 public LogFormat(double base, String baseLabel, String powerLabel, 099 boolean showBase) { 100 Args.nullNotPermitted(baseLabel, "baseLabel"); 101 Args.nullNotPermitted(powerLabel, "powerLabel"); 102 this.base = base; 103 this.baseLog = Math.log(this.base); 104 this.baseLabel = baseLabel; 105 this.showBase = showBase; 106 this.powerLabel = powerLabel; 107 } 108 109 /** 110 * Returns the number format used for the exponent. 111 * 112 * @return The number format (never {@code null}). 113 */ 114 public NumberFormat getExponentFormat() { 115 return (NumberFormat) this.formatter.clone(); 116 } 117 118 /** 119 * Sets the number format used for the exponent. 120 * 121 * @param format the formatter ({@code null} not permitted). 122 */ 123 public void setExponentFormat(NumberFormat format) { 124 Args.nullNotPermitted(format, "format"); 125 this.formatter = format; 126 } 127 128 /** 129 * Calculates the log of a given value. 130 * 131 * @param value the value. 132 * 133 * @return The log of the value. 134 */ 135 private double calculateLog(double value) { 136 return Math.log(value) / this.baseLog; 137 } 138 139 /** 140 * Returns a formatted representation of the specified number. 141 * 142 * @param number the number. 143 * @param toAppendTo the string buffer to append to. 144 * @param pos the position. 145 * 146 * @return A string buffer containing the formatted value. 147 */ 148 @Override 149 public StringBuffer format(double number, StringBuffer toAppendTo, 150 FieldPosition pos) { 151 StringBuffer result = new StringBuffer(); 152 if (this.showBase) { 153 result.append(this.baseLabel); 154 result.append(this.powerLabel); 155 } 156 result.append(this.formatter.format(calculateLog(number))); 157 return result; 158 } 159 160 /** 161 * Formats the specified number as a hexadecimal string. The decimal 162 * fraction is ignored. 163 * 164 * @param number the number to format. 165 * @param toAppendTo the buffer to append to (ignored here). 166 * @param pos the field position (ignored here). 167 * 168 * @return The string buffer. 169 */ 170 @Override 171 public StringBuffer format(long number, StringBuffer toAppendTo, 172 FieldPosition pos) { 173 StringBuffer result = new StringBuffer(); 174 if (this.showBase) { 175 result.append(this.baseLabel); 176 result.append(this.powerLabel); 177 } 178 result.append(this.formatter.format(calculateLog(number))); 179 return result; 180 } 181 182 /** 183 * Parsing is not implemented, so this method always returns 184 * {@code null}. 185 * 186 * @param source ignored. 187 * @param parsePosition ignored. 188 * 189 * @return Always {@code null}. 190 */ 191 @Override 192 public Number parse (String source, ParsePosition parsePosition) { 193 return null; // don't bother with parsing 194 } 195 196 /** 197 * Tests this formatter for equality with an arbitrary object. 198 * 199 * @param obj the object ({@code null} permitted). 200 * 201 * @return A boolean. 202 */ 203 @Override 204 public boolean equals(Object obj) { 205 if (obj == this) { 206 return true; 207 } 208 if (!(obj instanceof LogFormat)) { 209 return false; 210 } 211 LogFormat that = (LogFormat) obj; 212 if (this.base != that.base) { 213 return false; 214 } 215 if (!this.baseLabel.equals(that.baseLabel)) { 216 return false; 217 } 218 if (this.baseLog != that.baseLog) { 219 return false; 220 } 221 if (this.showBase != that.showBase) { 222 return false; 223 } 224 if (!this.formatter.equals(that.formatter)) { 225 return false; 226 } 227 return super.equals(obj); 228 } 229 230 /** 231 * Returns a clone of this instance. 232 * 233 * @return A clone. 234 */ 235 @Override 236 public Object clone() { 237 LogFormat clone = (LogFormat) super.clone(); 238 clone.formatter = (NumberFormat) this.formatter.clone(); 239 return clone; 240 } 241 242}