Frames | No Frames |
1: /* =========================================================== 2: * JFreeChart : a free chart library for the Java(tm) platform 3: * =========================================================== 4: * 5: * (C) Copyright 2000-2007, by Object Refinery Limited and Contributors. 6: * 7: * Project Info: http://www.jfree.org/jfreechart/index.html 8: * 9: * This library is free software; you can redistribute it and/or modify it 10: * under the terms of the GNU Lesser General Public License as published by 11: * the Free Software Foundation; either version 2.1 of the License, or 12: * (at your option) any later version. 13: * 14: * This library is distributed in the hope that it will be useful, but 15: * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 16: * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 17: * License for more details. 18: * 19: * You should have received a copy of the GNU Lesser General Public 20: * License along with this library; if not, write to the Free Software 21: * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 22: * USA. 23: * 24: * [Java is a trademark or registered trademark of Sun Microsystems, Inc. 25: * in the United States and other countries.] 26: * 27: * ---------------------------------- 28: * AbstractPieItemLabelGenerator.java 29: * ---------------------------------- 30: * (C) Copyright 2004-2007, by Object Refinery Limited. 31: * 32: * Original Author: David Gilbert (for Object Refinery Limited); 33: * Contributor(s): -; 34: * 35: * Changes 36: * ------- 37: * 09-Nov-2004 : Version 1, draws out code from StandardPieItemLabelGenerator 38: * and StandardPieToolTipGenerator (DG); 39: * ------------- JFREECHART 1.0.x --------------------------------------------- 40: * 03-May-2006 : Fixed bug 1480978, a problem in the clone() method (DG); 41: * 42: */ 43: 44: package org.jfree.chart.labels; 45: 46: import java.io.Serializable; 47: import java.text.MessageFormat; 48: import java.text.NumberFormat; 49: 50: import org.jfree.data.general.DatasetUtilities; 51: import org.jfree.data.general.PieDataset; 52: 53: /** 54: * A base class used for generating pie chart item labels. 55: */ 56: public class AbstractPieItemLabelGenerator implements Serializable { 57: 58: /** For serialization. */ 59: private static final long serialVersionUID = 7347703325267846275L; 60: 61: /** The label format string. */ 62: private String labelFormat; 63: 64: /** A number formatter for the value. */ 65: private NumberFormat numberFormat; 66: 67: /** A number formatter for the percentage. */ 68: private NumberFormat percentFormat; 69: 70: /** 71: * Creates an item label generator using the specified number formatters. 72: * 73: * @param labelFormat the label format string (<code>null</code> not 74: * permitted). 75: * @param numberFormat the format object for the values (<code>null</code> 76: * not permitted). 77: * @param percentFormat the format object for the percentages 78: * (<code>null</code> not permitted). 79: */ 80: protected AbstractPieItemLabelGenerator(String labelFormat, 81: NumberFormat numberFormat, 82: NumberFormat percentFormat) { 83: 84: if (labelFormat == null) { 85: throw new IllegalArgumentException("Null 'labelFormat' argument."); 86: } 87: if (numberFormat == null) { 88: throw new IllegalArgumentException("Null 'numberFormat' argument."); 89: } 90: if (percentFormat == null) { 91: throw new IllegalArgumentException( 92: "Null 'percentFormat' argument."); 93: } 94: this.labelFormat = labelFormat; 95: this.numberFormat = numberFormat; 96: this.percentFormat = percentFormat; 97: 98: } 99: 100: /** 101: * Returns the label format string. 102: * 103: * @return The label format string (never <code>null</code>). 104: */ 105: public String getLabelFormat() { 106: return this.labelFormat; 107: } 108: 109: /** 110: * Returns the number formatter. 111: * 112: * @return The formatter (never <code>null</code>). 113: */ 114: public NumberFormat getNumberFormat() { 115: return this.numberFormat; 116: } 117: 118: /** 119: * Returns the percent formatter. 120: * 121: * @return The formatter (never <code>null</code>). 122: */ 123: public NumberFormat getPercentFormat() { 124: return this.percentFormat; 125: } 126: 127: /** 128: * Creates the array of items that can be passed to the 129: * {@link MessageFormat} class for creating labels. The returned array 130: * contains four values: 131: * <ul> 132: * <li>result[0] = the section key converted to a <code>String</code>;</li> 133: * <li>result[1] = the formatted data value;</li> 134: * <li>result[2] = the formatted percentage (of the total);</li> 135: * <li>result[3] = the formatted total value.</li> 136: * </ul> 137: * 138: * @param dataset the dataset (<code>null</code> not permitted). 139: * @param key the key (<code>null</code> not permitted). 140: * 141: * @return The items (never <code>null</code>). 142: */ 143: protected Object[] createItemArray(PieDataset dataset, Comparable key) { 144: Object[] result = new Object[4]; 145: double total = DatasetUtilities.calculatePieDatasetTotal(dataset); 146: result[0] = key.toString(); 147: Number value = dataset.getValue(key); 148: if (value != null) { 149: result[1] = this.numberFormat.format(value); 150: } 151: else { 152: result[1] = "null"; 153: } 154: double percent = 0.0; 155: if (value != null) { 156: double v = value.doubleValue(); 157: if (v > 0.0) { 158: percent = v / total; 159: } 160: } 161: result[2] = this.percentFormat.format(percent); 162: result[3] = this.numberFormat.format(total); 163: return result; 164: } 165: 166: /** 167: * Generates a label for a pie section. 168: * 169: * @param dataset the dataset (<code>null</code> not permitted). 170: * @param key the section key (<code>null</code> not permitted). 171: * 172: * @return The label (possibly <code>null</code>). 173: */ 174: protected String generateSectionLabel(PieDataset dataset, Comparable key) { 175: String result = null; 176: if (dataset != null) { 177: Object[] items = createItemArray(dataset, key); 178: result = MessageFormat.format(this.labelFormat, items); 179: } 180: return result; 181: } 182: 183: /** 184: * Tests the generator for equality with an arbitrary object. 185: * 186: * @param obj the object to test against (<code>null</code> permitted). 187: * 188: * @return A boolean. 189: */ 190: public boolean equals(Object obj) { 191: if (obj == this) { 192: return true; 193: } 194: if (!(obj instanceof AbstractPieItemLabelGenerator)) { 195: return false; 196: } 197: 198: AbstractPieItemLabelGenerator that 199: = (AbstractPieItemLabelGenerator) obj; 200: if (!this.labelFormat.equals(that.labelFormat)) { 201: return false; 202: } 203: if (!this.numberFormat.equals(that.numberFormat)) { 204: return false; 205: } 206: if (!this.percentFormat.equals(that.percentFormat)) { 207: return false; 208: } 209: return true; 210: 211: } 212: 213: /** 214: * Returns an independent copy of the generator. 215: * 216: * @return A clone. 217: * 218: * @throws CloneNotSupportedException should not happen. 219: */ 220: public Object clone() throws CloneNotSupportedException { 221: AbstractPieItemLabelGenerator clone 222: = (AbstractPieItemLabelGenerator) super.clone(); 223: if (this.numberFormat != null) { 224: clone.numberFormat = (NumberFormat) this.numberFormat.clone(); 225: } 226: if (this.percentFormat != null) { 227: clone.percentFormat = (NumberFormat) this.percentFormat.clone(); 228: } 229: return clone; 230: } 231: 232: }