KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > jcckit > plot > Legend


1 /*
2  * Copyright 2003-2004, Franz-Josef Elmer, All rights reserved
3  *
4  * This library is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU Lesser General Public License as published by
6  * the Free Software Foundation; either version 2.1 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU Lesser General Public License for more details
13  * (http://www.gnu.org/copyleft/lesser.html).
14  *
15  * You should have received a copy of the GNU Lesser General Public License
16  * along with this library; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18  */

19 package jcckit.plot;
20
21 import jcckit.graphic.BasicGraphicAttributes;
22 import jcckit.graphic.GraphicalElement;
23 import jcckit.graphic.GraphicalComposite;
24 import jcckit.graphic.GraphicAttributes;
25 import jcckit.graphic.GraphPoint;
26 import jcckit.graphic.Polygon;
27 import jcckit.graphic.Rectangle;
28 import jcckit.graphic.ShapeAttributes;
29 import jcckit.graphic.Text;
30 import jcckit.graphic.TextAttributes;
31 import jcckit.util.ConfigData;
32 import jcckit.util.ConfigParameters;
33 import jcckit.util.ConfigParametersBasedConfigData;
34 import jcckit.util.Factory;
35 import jcckit.util.PropertiesBasedConfigData;
36
37 import java.util.Properties JavaDoc;
38
39
40 /**
41  * Helper class for creating the legend of a {@link Plot}.
42  *
43  * @author Franz-Josef Elmer
44  */

45 public class Legend {
46   /** Configuration parameter key. */
47   public static final String JavaDoc UPPER_RIGHT_CORNER_KEY = "upperRightCorner",
48                              BOX_WIDTH_KEY = "boxWidth",
49                              BOX_HEIGHT_KEY = "boxHeight",
50                              BOX_ATTRIBUTES_KEY = "boxAttributes",
51                              TITLE_KEY = "title",
52                              TITLE_DISTANCE_KEY = "titleDistance",
53                              TITLE_ATTRIBUTES_KEY = "titleAttributes",
54                              LEFT_DISTANCE_KEY = "leftDistance",
55                              BOTTOM_DISTANCE_KEY = "bottomDistance",
56                              TOP_DISTANCE_KEY = "topDistance",
57                              LINE_LENGTH_KEY = "lineLength",
58                              SYMBOL_SIZE_KEY = "symbolSize",
59                              CURVE_TITLE_DISTANCE_KEY = "curveTitleDistance",
60                              CURVE_TITLE_ATTRIBUTES_KEY
61                                               = "curveTitleAttributes";
62
63   private final GraphicalComposite _box;
64   private final TextAttributes _curveTitleAttributes;
65   private final double _xSymbol;
66   private final double _xText;
67   private final double _yBase;
68   private final double _yLastRow;
69   private final double _length;
70   private final double _size;
71
72   /**
73    * Creates an instance from the specified configuration parameters.
74    * All numbers (lengths, fontsizes, linethicknesses, etc.) are in
75    * device-independent units.
76    * <table border=1 cellpadding=5>
77    * <tr><th>Key &amp; Default Value</th><th>Type</th><th>Mandatory</th>
78    * <th>Description</th></tr>
79    * <tr><td><tt>bottomDistance = 0.02</tt></td>
80    * <td><tt>double</tt></td><td>no</td>
81    * <td>Distance between the last row and the bottom of the legend box.
82    * </td></tr>
83    * <tr><td><tt>boxAttributes = </tt>default values of
84    * {@link ShapeAttributes} with a white fill color.</td>
85    * <td><tt>ConfigParameters</tt></td><td>no</td>
86    * <td>Attributes of the legend box.</td></tr>
87    * <tr><td><tt>boxHeight = 0.1</tt></td>
88    * <td><tt>double</tt></td><td>no</td>
89    * <td>Height of the legend box.</td></tr>
90    * <tr><td><tt>boxWidth = 0.2</tt></td>
91    * <td><tt>double</tt></td><td>no</td>
92    * <td>Width of the legend box.</td></tr>
93    * <tr><td><tt>curveTitleAttributes = </tt>default values of
94    * {@link BasicGraphicAttributes}</td>
95    * <td><tt>ConfigParameters</tt></td><td>no</td>
96    * <td>Text attributes of curve titles printed in the legend.</td></tr>
97    * <tr><td><tt>curveTitleDistance = 0.005</tt></td>
98    * <td><tt>double</tt></td><td>no</td>
99    * <td>Horizontal distance between the line part of the legend symbol
100    * and the curve title.</td></tr>
101    * <tr><td><tt>leftDistance = 0.01</tt></td>
102    * <td><tt>double</tt></td><td>no</td>
103    * <td>Horizontal distance between the line part of the legend symbol
104    * and the left border of the legend box.</td></tr>
105    * <tr><td><tt>lineLength = 0.035</tt></td>
106    * <td><tt>double</tt></td><td>no</td>
107    * <td>Length of the line part of the legend symbol.</td></tr>
108    * <tr><td><tt>symbolSize = 0.01</tt></td>
109    * <td><tt>double</tt></td><td>no</td>
110    * <td>Size of the symbol part of the legend symbol. Will be the
111    * <tt>size</tt> argument of {@link SymbolFactory#createLegendSymbol
112    * createLegendSymbol} in a {@link SymbolFactory}.</td></tr>
113    * <tr><td><tt>titleAttributes = </tt>default values of
114    * {@link BasicGraphicAttributes} with a text anchor CENTER
115    * TOP.</td>
116    * <td><tt>ConfigParameters</tt></td><td>no</td>
117    * <td>Text attributes of the title of the legend box.</td></tr>
118    * <tr><td><tt>title = Legend</tt></td>
119    * <td><tt>String</tt></td><td>no</td>
120    * <td>Title of the legend box.</td></tr>
121    * <tr><td><tt>titleDistance = 0.005</tt></td>
122    * <td><tt>double</tt></td><td>no</td>
123    * <td>Distance between the center of the upper line of the legend box
124    * and the anchor of the legend title.</td></tr>
125    * <tr><td><tt>topDistance = 0.04</tt></td>
126    * <td><tt>double</tt></td><td>no</td>
127    * <td>Distance between the first row and the top of the legend box.
128    * </td></tr>
129    * <tr><td><tt>upperRightCorner = 0.94,&nbsp;0.54</tt></td>
130    * <td><tt>doubleü[]</tt></td><td>no</td>
131    * <td>Position of the upper-right corner of the legend box.</td></tr>
132    * </table>
133    */

134   public Legend(ConfigParameters config) {
135     config = mergeWithDefaultConfig(config);
136     GraphPoint corner
137         = new GraphPoint(config.getDoubleArray(UPPER_RIGHT_CORNER_KEY,
138                                                new double[] {0.94, 0.54}));
139     double width = config.getDouble(BOX_WIDTH_KEY, 0.2);
140     double height = config.getDouble(BOX_HEIGHT_KEY, 0.1);
141     _curveTitleAttributes = (TextAttributes) Factory.create(
142         config.getNode(CURVE_TITLE_ATTRIBUTES_KEY));
143     _xSymbol = corner.getX() - width
144                + config.getDouble(LEFT_DISTANCE_KEY, 0.01);
145     _yBase = corner.getY() - config.getDouble(TOP_DISTANCE_KEY, 0.04);
146     _yLastRow = corner.getY() - height
147                 + config.getDouble(BOTTOM_DISTANCE_KEY, 0.02);
148     _length = config.getDouble(LINE_LENGTH_KEY, 0.035);
149     _size = config.getDouble(SYMBOL_SIZE_KEY, 0.01);
150     _xText = _xSymbol + _length
151              + config.getDouble(CURVE_TITLE_DISTANCE_KEY, 0.005);
152
153     _box = new GraphicalComposite(null);
154     double xCenter = corner.getX() - width / 2;
155     _box.addElement(new Rectangle(
156         new GraphPoint(xCenter, corner.getY() - height / 2), width, height,
157         (GraphicAttributes) Factory.create(
158                                 config.getNode(BOX_ATTRIBUTES_KEY))));
159     _box.addElement(new Text(
160         new GraphPoint(xCenter, corner.getY()
161                                 - config.getDouble(TITLE_DISTANCE_KEY, 0.005)),
162         config.get(TITLE_KEY, "Legend"),
163         (TextAttributes) Factory.create(
164                                 config.getNode(TITLE_ATTRIBUTES_KEY))));
165   }
166
167   private ConfigParameters mergeWithDefaultConfig(ConfigParameters config) {
168     Properties JavaDoc p = new Properties JavaDoc();
169     p.put(BOX_ATTRIBUTES_KEY + '/' + Factory.CLASS_NAME_KEY,
170           ShapeAttributes.class.getName());
171     p.put(BOX_ATTRIBUTES_KEY + '/'
172           + ShapeAttributes.FILL_COLOR_KEY, "0xffffff");
173     p.put(BOX_ATTRIBUTES_KEY + '/'
174           + ShapeAttributes.LINE_COLOR_KEY, "0");
175     p.put(TITLE_ATTRIBUTES_KEY + '/' + Factory.CLASS_NAME_KEY,
176           BasicGraphicAttributes.class.getName());
177     p.put(TITLE_ATTRIBUTES_KEY + '/'
178           + BasicGraphicAttributes.HORIZONTAL_ANCHOR_KEY, "center");
179     p.put(TITLE_ATTRIBUTES_KEY + '/'
180           + BasicGraphicAttributes.VERTICAL_ANCHOR_KEY, "top");
181     p.put(CURVE_TITLE_ATTRIBUTES_KEY + '/' + Factory.CLASS_NAME_KEY,
182           BasicGraphicAttributes.class.getName());
183     ConfigData cd = new PropertiesBasedConfigData(p);
184     cd = new ConfigParametersBasedConfigData(config, new ConfigParameters(cd));
185     return new ConfigParameters(cd);
186   }
187
188   /**
189    * Returns the legend box with title but without legend symbols and curve
190    * titles.
191    */

192   public GraphicalElement getBox() {
193     return _box;
194   }
195
196   /**
197    * Creates the symbol part of a legend symbol.
198    * @param curveIndex Index of the curve. Will be needed to calculate the
199    * y-coordinate of the symbol.
200    * @param numberOfCurves Number of curves. Will be needed to calculate the
201    * y-coordinate of the symbol.
202    * @param factory Factory for the symbol part of the legend symbol.
203    * Can be <tt>null</tt>.
204    * @param withLine <tt>true</tt> if the line part of the legend symbol
205    * should be created.
206    * @param lineAttributes Attributes of the line part.
207    */

208   public GraphicalElement createSymbol(int curveIndex, int numberOfCurves,
209                                        SymbolFactory factory,
210                                        boolean withLine,
211                                        GraphicAttributes lineAttributes) {
212     GraphicalComposite result = new GraphicalComposite(null);
213     double y = calculateBaseLine(curveIndex, numberOfCurves);
214     if (withLine) {
215       Polygon line = new Polygon(lineAttributes, false);
216       line.addPoint(new GraphPoint(_xSymbol, y));
217       line.addPoint(new GraphPoint(_xSymbol + _length, y));
218       result.addElement(line);
219     }
220     if (factory != null) {
221       result.addElement(factory.createLegendSymbol(
222                           new GraphPoint(_xSymbol + _length / 2, y), _size));
223     }
224     return result;
225   }
226
227   private double calculateBaseLine(int curveIndex, int numberOfCurves) {
228     if (numberOfCurves > 1) {
229       return _yBase + ((_yLastRow - _yBase) / (numberOfCurves - 1))
230                       * curveIndex;
231     } else {
232       return 0.5 * (_yBase + _yLastRow);
233     }
234   }
235
236   /**
237    * Creates the title part of a legend symbol.
238    * @param curveIndex Index of the curve. Will be needed to calculate the
239    * y-coordinate of the title.
240    * @param numberOfCurves Number of curves. Will be needed to calculate the
241    * y-coordinate of the symbol.
242    * @param title Title text.
243    */

244   public GraphicalElement createCurveTitle(int curveIndex, int numberOfCurves,
245                                            String JavaDoc title) {
246     return new Text(new GraphPoint(_xText, calculateBaseLine(curveIndex,
247                                                              numberOfCurves)),
248                     title, _curveTitleAttributes);
249   }
250 }
251
Popular Tags