View Javadoc

1   /*
2    * @(#) HistogramDomainAxis.java Sep 28, 2003
3    * 
4    * Copyright (c) 2003 Delft University of Technology Jaffalaan 5, 2628 BX Delft,
5    * the Netherlands All rights reserved.
6    * 
7    * This software is proprietary information of Delft University of Technology
8    * The code is published under the General Public License
9    */
10  
11  package nl.tudelft.simulation.jstats.charts.histogram;
12  
13  import java.awt.Color;
14  import java.awt.Graphics2D;
15  import java.awt.geom.Rectangle2D;
16  import java.text.DecimalFormatSymbols;
17  import java.text.NumberFormat;
18  
19  import org.jfree.chart.axis.AxisSpace;
20  import org.jfree.chart.axis.AxisState;
21  import org.jfree.chart.axis.NumberAxis;
22  import org.jfree.chart.plot.Plot;
23  import org.jfree.chart.plot.PlotRenderingInfo;
24  import org.jfree.chart.plot.XYPlot;
25  import org.jfree.ui.RectangleEdge;
26  
27  /***
28   * The histogram domainAxis defines the x-Axis of a histogram.
29   * <p>
30   * (c) copyright 2002-2004 <a href="http://www.simulation.tudelft.nl">Delft
31   * University of Technology </a>, the Netherlands. <br>
32   * See for project information <a href="http://www.simulation.tudelft.nl">
33   * www.simulation.tudelft.nl </a> <br>
34   * License of use: <a href="http://www.gnu.org/copyleft/gpl.html">General Public
35   * License (GPL) </a>, no warranty <br>
36   * 
37   * @author <a href="http://www.tbm.tudelft.nl/webstaf/alexandv/index.htm">
38   *         Alexander Verbraeck </a> <br>
39   *         <a href="http://www.tbm.tudelft.nl/webstaf/peterja/index.htm"> Peter
40   *         Jacobs </a>
41   * @version 1.10 2004-03-22
42   * @since 1.2
43   */
44  public class HistogramDomainAxis extends NumberAxis
45  {
46  	/*** labels refers to the labels to be printed */
47  	protected String[] labels = null;
48  
49  	/*** maxLabelHeight refers to the maximum label heigth */
50  	protected double maxLabelHeight = -1;
51  
52  	/***
53  	 * constructs a new HistogramDomainAxis
54  	 * 
55  	 * @param parent the plot to which this axis belongs
56  	 * @param label the label of the axis
57  	 * @param domain the domain
58  	 * @param numberOfBins the numberOfBins
59  	 */
60  	public HistogramDomainAxis(final XYPlot parent, final String label,
61  			final double[] domain, final int numberOfBins)
62  	{
63  		super(label);
64  		this.setAutoRange(false);
65  		double binWidth = (domain[1] - domain[0]) / numberOfBins * 1.0;
66  		this.setLowerBound(domain[0] - binWidth);
67  		this.setUpperBound(domain[1] + binWidth);
68  		this.setVerticalTickLabels(true);
69  		//Let's copy the font etc from the y-axis
70  		this.setLabelFont(parent.getRangeAxis().getLabelFont());
71  		this.setTickLabelFont(parent.getRangeAxis().getTickLabelFont());
72  		this.labels = this.createLabels(domain, numberOfBins);
73  	}
74  
75  	/***
76  	 * @see org.jfree.chart.axis.ValueAxis#valueToJava2D(double,
77  	 *      java.awt.geom.Rectangle2D, org.jfree.ui.RectangleEdge)
78  	 */
79  	public double valueToJava2D(final double value, final Rectangle2D dataArea,
80  			final RectangleEdge edge)
81  	{
82  		double ratio = (value - this.getLowerBound())
83  				/ (this.getUpperBound() - this.getLowerBound());
84  		return dataArea.getX() + ratio * (dataArea.getWidth());
85  	}
86  
87  	/***
88  	 * @see org.jfree.chart.axis.ValueAxis#java2DToValue(double,
89  	 *      java.awt.geom.Rectangle2D, org.jfree.ui.RectangleEdge)
90  	 */
91  	public double java2DToValue(final double value, final Rectangle2D dataArea,
92  			final RectangleEdge edge)
93  	{
94  		double ratio = (value - dataArea.getX()) / dataArea.getWidth();
95  		return this.getLowerBound() + ratio
96  				* (this.getUpperBound() - this.getLowerBound());
97  	}
98  
99  	/***
100 	 * @see org.jfree.chart.axis.Axis #reserveSpace(Graphics2D, Plot,
101 	 *      Rectangle2D, RectangleEdge, AxisSpace)
102 	 */
103 	public AxisSpace reserveSpace(final Graphics2D g2, final Plot dataPlot,
104 			final Rectangle2D dataArea, final RectangleEdge edge,
105 			final AxisSpace axisSpace)
106 	{
107 		if (this.maxLabelHeight == -1)
108 		{
109 			g2.setFont(this.getTickLabelFont());
110 			//If we have not yet measured the heigth of the labels
111 			for (int i = 0; i < this.labels.length; i++)
112 			{
113 				//we draw 90degrees rotated, so heigth = width
114 				double height = g2.getFont().getStringBounds(this.labels[i],
115 						g2.getFontRenderContext()).getWidth();
116 				if (height > this.maxLabelHeight)
117 				{
118 					this.maxLabelHeight = height + 3;
119 				}
120 			}
121 		}
122 		AxisSpace result = new AxisSpace();
123 		result.add(this.maxLabelHeight, RectangleEdge.BOTTOM);
124 		return result;
125 	}
126 
127 	/***
128 	 * creates the labels for the axis
129 	 * 
130 	 * @param domain the domain of the histogram
131 	 * @param numberOfBins the number of bins
132 	 * @return the result
133 	 */
134 	private String[] createLabels(final double[] domain, final int numberOfBins)
135 	{
136 		String[] result = new String[numberOfBins + 2];
137 		NumberFormat formatter = NumberFormat.getInstance();
138 		formatter.setMaximumFractionDigits(2);
139 		double binWidth = (domain[1] - domain[0]) / numberOfBins * 1.0;
140 		double start = domain[0];
141 		for (int i = 1; i < numberOfBins + 1; i++)
142 		{
143 			result[i] = formatter.format(start);
144 			start = start + binWidth;
145 		}
146 		//Let's write infinity and -infinity
147 		DecimalFormatSymbols symbols = new DecimalFormatSymbols();
148 		result[0] = "-" + symbols.getInfinity();
149 		result[numberOfBins + 1] = symbols.getInfinity();
150 		return result;
151 	}
152 
153 	/***
154 	 * @see org.jfree.chart.axis.Axis#draw(java.awt.Graphics2D, double,
155 	 *      java.awt.geom.Rectangle2D, java.awt.geom.Rectangle2D,
156 	 *      org.jfree.ui.RectangleEdge, org.jfree.chart.plot.PlotRenderingInfo)
157 	 */
158 	public AxisState draw(final Graphics2D g2, final double cursor,
159 			final Rectangle2D plotArea, final Rectangle2D dataArea,
160 			final RectangleEdge edge, final PlotRenderingInfo arg5)
161 	{
162 		g2.setColor(Color.BLACK);
163 		g2.setFont(this.getTickLabelFont());
164 		double labelWidth = g2.getFont().getStringBounds(this.labels[0],
165 				g2.getFontRenderContext()).getHeight();
166 		double width = dataArea.getWidth() / (this.labels.length) * 1.0;
167 		double x = dataArea.getX() + 0.5 * width;
168 		double y = dataArea.getY() + dataArea.getHeight();
169 		g2.translate(x, y);
170 		g2.rotate(-Math.PI / 2.0);
171 		double offset = 0.0;
172 		for (int i = 0; i < this.labels.length; i++)
173 		{
174 			double labelHeight = g2.getFont().getStringBounds(this.labels[i],
175 					g2.getFontRenderContext()).getWidth() + 3;
176 			g2.drawString(this.labels[i], Math.round(-labelHeight), Math
177 					.round(offset + 0.33 * labelWidth));
178 			offset = offset + width;
179 		}
180 		g2.rotate(Math.PI / 2.0);
181 		g2.translate(-x, -y);
182 		return new AxisState();
183 	}
184 }