KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > krysalis > jcharts > axisChart > customRenderers > axisValue > renderers > ValueLabelRenderer


1 /***********************************************************************************************
2  * File Info: $Id: ValueLabelRenderer.java,v 1.3 2004/05/31 16:23:03 nathaniel_auvil Exp $
3  * Copyright (C) 2002
4  * Author: Nathaniel G. Auvil, John Thomsen
5  * Contributor(s):
6  *
7  * Copyright 2002 (C) Nathaniel G. Auvil. All Rights Reserved.
8  *
9  * Redistribution and use of this software and associated documentation ("Software"), with or
10  * without modification, are permitted provided that the following conditions are met:
11  *
12  * 1. Redistributions of source code must retain copyright statements and notices.
13  * Redistributions must also contain a copy of this document.
14  *
15  * 2. Redistributions in binary form must reproduce the above copyright notice, this list of
16  * conditions and the following disclaimer in the documentation and/or other materials
17  * provided with the distribution.
18  *
19  * 3. The name "jCharts" or "Nathaniel G. Auvil" must not be used to endorse or promote
20  * products derived from this Software without prior written permission of Nathaniel G.
21  * Auvil. For written permission, please contact nathaniel_auvil@users.sourceforge.net
22  *
23  * 4. Products derived from this Software may not be called "jCharts" nor may "jCharts" appear
24  * in their names without prior written permission of Nathaniel G. Auvil. jCharts is a
25  * registered trademark of Nathaniel G. Auvil.
26  *
27  * 5. Due credit should be given to the jCharts Project (http://jcharts.sourceforge.net/).
28  *
29  * THIS SOFTWARE IS PROVIDED BY Nathaniel G. Auvil AND CONTRIBUTORS ``AS IS'' AND ANY
30  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
31  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
32  * jCharts OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
33  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
34  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
35  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,STRICT LIABILITY, OR TORT
36  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
37  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
38  ************************************************************************************************/

39
40
41 package org.krysalis.jcharts.axisChart.customRenderers.axisValue.renderers;
42
43
44 import org.krysalis.jcharts.axisChart.AxisChart;
45 import org.krysalis.jcharts.axisChart.customRenderers.axisValue.AxisValueRenderEvent;
46 import org.krysalis.jcharts.axisChart.customRenderers.axisValue.PostAxisValueRenderListener;
47 import org.krysalis.jcharts.chartData.interfaces.IAxisChartDataSet;
48 import org.krysalis.jcharts.chartText.NumericTagGroup;
49 import org.krysalis.jcharts.chartText.TextTag;
50 import org.krysalis.jcharts.properties.util.ChartFont;
51
52 import java.awt.*;
53 import java.text.NumberFormat JavaDoc;
54
55
56 public class ValueLabelRenderer implements PostAxisValueRenderListener
57 {
58
59     private NumberFormat JavaDoc numberFormat;
60
61     private ChartFont valueChartFont = ChartFont.DEFAULT_AXIS_VALUE;
62
63     //---holds the derived Font if needed so don't have to recalculate it each time.
64
private Font derivedFont;
65
66     //---vertical labels are only used when plotting on vertical charts; not used for horizontal bar plots.
67
private boolean isLabelVertical = false;
68
69     private ValueLabelPosition valueLabelPosition = ValueLabelPosition.ON_TOP;
70
71     private int pixelValuePadding = 4;
72
73
74     /**********************************************************************************
75      *
76      * @param isCurrency
77      * @param showGrouping
78      * @param roundingPowerOfTen
79      * @deprecated use the other Constructor
80      **********************************************************************************/

81     public ValueLabelRenderer( boolean isCurrency, boolean showGrouping, int roundingPowerOfTen )
82     {
83         this.numberFormat = NumericTagGroup.getNumberFormatInstance( isCurrency, false, showGrouping, roundingPowerOfTen );
84     }
85
86
87     /**********************************************************************************
88      *
89      * @param isCurrency
90      * @param isPercent
91      * @param showGrouping
92      * @param roundingPowerOfTen
93      **********************************************************************************/

94     public ValueLabelRenderer( boolean isCurrency, boolean isPercent, boolean showGrouping, int roundingPowerOfTen )
95     {
96         this.numberFormat = NumericTagGroup.getNumberFormatInstance( isCurrency, isPercent, showGrouping, roundingPowerOfTen );
97     }
98
99
100     /************************************************************************************
101      * Sets where you would like to position the label
102      *
103      * @param valueLabelPosition
104      ***********************************************************************************/

105     public void setValueLabelPosition( ValueLabelPosition valueLabelPosition )
106     {
107         this.valueLabelPosition = valueLabelPosition;
108     }
109
110
111     /************************************************************************************
112      *
113      * @param valueChartFont
114      ***********************************************************************************/

115     public void setValueChartFont( ChartFont valueChartFont )
116     {
117         this.valueChartFont = valueChartFont;
118     }
119
120
121     /***********************************************************************************
122      *
123      * @param useVerticalLabels
124      **********************************************************************************/

125     public void useVerticalLabels( boolean useVerticalLabels )
126     {
127         this.isLabelVertical = useVerticalLabels;
128
129         //---set this here so can reuse same font
130
if( this.isLabelVertical )
131         {
132             this.derivedFont = this.valueChartFont.deriveFont();
133         }
134     }
135
136
137     /***********************************************************************************
138      * The pixel padding between the label and the data point.
139      *
140      * @param pixelValuePadding
141      **********************************************************************************/

142     public void setPixelValuePadding( int pixelValuePadding )
143     {
144         this.pixelValuePadding = pixelValuePadding;
145     }
146
147
148     /***********************************************************************************
149      *
150      * @param axisValueRenderEvent
151      ***********************************************************************************/

152     public void postRender( AxisValueRenderEvent axisValueRenderEvent )
153     {
154         AxisChart axisChart = (AxisChart) axisValueRenderEvent.getSource();
155         TextTag valueTag;
156         float x;
157         float y;
158
159
160         if( axisValueRenderEvent.getiAxisPlotDataSet() instanceof IAxisChartDataSet )
161         {
162             IAxisChartDataSet iAxisChartDataSet = (IAxisChartDataSet) axisValueRenderEvent.getiAxisPlotDataSet();
163             double value = iAxisChartDataSet.getValue( axisValueRenderEvent.getDataSetIndex(), axisValueRenderEvent.getValueIndex() );
164
165             valueTag = new TextTag( this.numberFormat.format( value ),
166                                             this.valueChartFont.getFont(),
167                                             this.derivedFont,
168                                             axisValueRenderEvent.getFontRenderContext() );
169
170             if( axisChart.getAxisProperties().isPlotHorizontal() )
171             {
172                 x = this.calculateXHorizontalPlot( axisValueRenderEvent, valueTag, (value < 0) );
173                 y = this.calculateYHorizontalPlot( axisValueRenderEvent, valueTag );
174             }
175             else
176             {
177                 x = this.calculateXVerticalPlot( axisValueRenderEvent, valueTag );
178                 y = this.calculateYVerticalPlot( axisValueRenderEvent, valueTag, (value < 0) );
179             }
180         }
181         else
182         {
183 //todo scatter and hi/low
184
valueTag = null;
185             x = 100;
186             y = 100;
187
188             throw new RuntimeException JavaDoc( "Axis Values not yet implemented for this type of chart." );
189         }
190
191
192 /*
193         Line2D.Float line= new Line2D.Float( x, y, x, y -20 );
194         axisValueRenderEvent.getGraphics2D().draw( line );
195 */

196
197         valueTag.setXPosition( x );
198         valueTag.setYPosition( y );
199         valueTag.render( axisValueRenderEvent.getGraphics2D(), this.valueChartFont.getPaint() );
200     }
201
202
203     /*************************************************************************************************
204      * Calculates the label x so that the label is centered on the scale item.
205      *
206      * @param axisValueRenderEvent
207      * @param formattedTextTag
208      * @return float
209      ************************************************************************************************/

210     private float calculateXVerticalPlot( AxisValueRenderEvent axisValueRenderEvent, TextTag formattedTextTag )
211     {
212         float x = axisValueRenderEvent.getValueX();
213
214         if( this.isLabelVertical )
215         {
216             x += formattedTextTag.getFontDescent();
217         }
218         else
219         {
220             x -= (formattedTextTag.getWidth() / 2);
221         }
222
223         return x;
224     }
225
226
227     /*************************************************************************************************
228      *
229      * @param axisValueRenderEvent
230      * @param formattedTextTag
231      * @return float
232      ************************************************************************************************/

233     private float calculateYHorizontalPlot( AxisValueRenderEvent axisValueRenderEvent,
234                                                          TextTag formattedTextTag )
235     {
236         float y = axisValueRenderEvent.getValueY();
237
238         if( this.isLabelVertical )
239         {
240             y += (formattedTextTag.getWidth() / 2);
241         }
242         else
243         {
244             y += formattedTextTag.getFontDescent();
245         }
246
247         return y;
248     }
249
250
251     /*************************************************************************************************
252      *
253      * @param axisValueRenderEvent
254      * @param formattedTextTag
255      * @param isNegative
256      ************************************************************************************************/

257     private float calculateXHorizontalPlot( AxisValueRenderEvent axisValueRenderEvent,
258                                                          TextTag formattedTextTag,
259                                                          boolean isNegative )
260     {
261         float x = axisValueRenderEvent.getValueX();
262
263         if( this.valueLabelPosition.equals( ValueLabelPosition.ON_TOP ) )
264         {
265             //---if the value is negative, 'top' is to the left
266
if( isNegative )
267             {
268                 x -= (this.isLabelVertical) ? 0 : formattedTextTag.getWidth();
269                 x -= this.pixelValuePadding;
270             }
271             else
272             {
273                 x += (this.isLabelVertical) ? formattedTextTag.getFontAscent() : 0;
274                 x += this.pixelValuePadding;
275             }
276         }
277         else if( this.valueLabelPosition.equals( ValueLabelPosition.AT_TOP ) )
278         {
279             if( isNegative )
280             {
281                 x += (this.isLabelVertical) ? formattedTextTag.getFontAscent() : 0;
282                 x += this.pixelValuePadding;
283             }
284             else
285             {
286                 x -= (this.isLabelVertical) ? formattedTextTag.getFontDescent() : formattedTextTag.getWidth();
287                 x -= this.pixelValuePadding;
288             }
289         }
290         else if( this.valueLabelPosition.equals( ValueLabelPosition.ABOVE_ZERO_LINE ) )
291         {
292             x = axisValueRenderEvent.getZeroLineCoordinate();
293
294             if( isNegative )
295             {
296                 x += (this.isLabelVertical) ? formattedTextTag.getFontAscent() : 0;
297                 x += this.pixelValuePadding;
298             }
299             else
300             {
301                 x -= (this.isLabelVertical) ? formattedTextTag.getFontDescent() : formattedTextTag.getWidth();
302                 x -= this.pixelValuePadding;
303             }
304         }
305
306
307         else if( this.valueLabelPosition.equals( ValueLabelPosition.AXIS_TOP ) )
308         {
309             x = axisValueRenderEvent.getTotalItemAxisArea().x + axisValueRenderEvent.getTotalItemAxisArea().width;
310
311             x -= (this.isLabelVertical) ? 0 : formattedTextTag.getWidth();
312             x -= this.pixelValuePadding;
313         }
314         else if( this.valueLabelPosition.equals( ValueLabelPosition.AXIS_BOTTOM ) )
315         {
316             x = axisValueRenderEvent.getTotalItemAxisArea().x;
317             x += (this.isLabelVertical) ? formattedTextTag.getFontAscent() : 0;
318             x += this.pixelValuePadding;
319         }
320
321
322         //VALIDATION - force labels into plot area, in case there is a user defined scale.
323
//todo could we skip this validation for non-user defined scales?
324
//---if label goes off the right edge, force it to stay in the plot area.
325
if( (x + formattedTextTag.getWidth())
326             > (axisValueRenderEvent.getTotalItemAxisArea().x + axisValueRenderEvent.getTotalItemAxisArea().width) )
327         {
328             x = axisValueRenderEvent.getTotalItemAxisArea().x + axisValueRenderEvent.getTotalItemAxisArea().width;
329             x -= formattedTextTag.getWidth();
330             x -= this.pixelValuePadding;
331         }
332         //---if label goes off left edge, force to the right
333
else if( x < axisValueRenderEvent.getTotalItemAxisArea().x )
334         {
335             x = axisValueRenderEvent.getTotalItemAxisArea().x;
336             x += this.pixelValuePadding;
337         }
338
339         return x;
340     }
341
342
343     /*************************************************************************************************
344      *
345      * @param axisValueRenderEvent
346      * @param formattedTextTag
347      * @param isNegative
348      ************************************************************************************************/

349     private float calculateYVerticalPlot( AxisValueRenderEvent axisValueRenderEvent,
350                                                       TextTag formattedTextTag,
351                                                       boolean isNegative )
352     {
353         float y = axisValueRenderEvent.getValueY();
354
355         if( this.valueLabelPosition.equals( ValueLabelPosition.ON_TOP ) )
356         {
357             //---if the value is negative, 'top' is to the bottom
358
if( isNegative )
359             {
360                 y += (this.isLabelVertical) ? formattedTextTag.getWidth() : formattedTextTag.getHeight();
361                 y += this.pixelValuePadding;
362             }
363             else
364             {
365                 y -= this.pixelValuePadding;
366             }
367         }
368         else if( this.valueLabelPosition.equals( ValueLabelPosition.AT_TOP ) )
369         {
370             //---if the value is negative, 'top' is to the bottom
371
if( isNegative )
372             {
373                 y -= this.pixelValuePadding;
374             }
375             else
376             {
377                 y += (this.isLabelVertical) ? formattedTextTag.getWidth() : formattedTextTag.getHeight();
378                 y += this.pixelValuePadding;
379             }
380         }
381         else if( this.valueLabelPosition.equals( ValueLabelPosition.ABOVE_ZERO_LINE ) )
382         {
383             y = axisValueRenderEvent.getZeroLineCoordinate();
384
385             //---if the value is negative, 'top' is to the bottom
386
if( isNegative )
387             {
388                 y -= this.pixelValuePadding;
389             }
390             else
391             {
392                 y += (this.isLabelVertical) ? formattedTextTag.getWidth() : formattedTextTag.getHeight();
393                 y += this.pixelValuePadding;
394             }
395         }
396
397         else if( this.valueLabelPosition.equals( ValueLabelPosition.AXIS_TOP ) )
398         {
399             y = axisValueRenderEvent.getTotalItemAxisArea().y;
400             y += (this.isLabelVertical) ? formattedTextTag.getWidth() : formattedTextTag.getHeight();
401             y += this.pixelValuePadding;
402         }
403         else if( this.valueLabelPosition.equals( ValueLabelPosition.AXIS_BOTTOM ) )
404         {
405             y = axisValueRenderEvent.getTotalItemAxisArea().y + axisValueRenderEvent.getTotalItemAxisArea().height;
406             y -= this.pixelValuePadding;
407         }
408
409
410
411         //VALIDATION - force labels into plot area, in case there is a user defined scale.
412
if( isLabelVertical )
413         {
414             //---if label goes off the bottom edge, force it to stay in the plot area.
415
if( ( y - formattedTextTag.getWidth() ) < axisValueRenderEvent.getTotalItemAxisArea().y )
416             {
417                 y = axisValueRenderEvent.getTotalItemAxisArea().y;
418                 y += formattedTextTag.getWidth();
419                 y += this.pixelValuePadding;
420             }
421             //---if label goes off bottom edge, force to the up
422
else if( y > axisValueRenderEvent.getTotalItemAxisArea().y + axisValueRenderEvent.getTotalItemAxisArea().height )
423             {
424                 y = axisValueRenderEvent.getTotalItemAxisArea().y + axisValueRenderEvent.getTotalItemAxisArea().height;
425                 y -= this.pixelValuePadding;
426             }
427         }
428         else
429         {
430             //---if label goes off the top edge, force it to stay in the plot area.
431
if( ( y - formattedTextTag.getHeight() ) < axisValueRenderEvent.getTotalItemAxisArea().y )
432             {
433                 y = axisValueRenderEvent.getTotalItemAxisArea().y;
434                 y += formattedTextTag.getHeight();
435                 y += this.pixelValuePadding;
436             }
437             //---if label goes off bottom edge, force to the up
438
else if( y > axisValueRenderEvent.getTotalItemAxisArea().y + axisValueRenderEvent.getTotalItemAxisArea().height )
439             {
440                 y = axisValueRenderEvent.getTotalItemAxisArea().y + axisValueRenderEvent.getTotalItemAxisArea().height;
441                 y -= this.pixelValuePadding;
442             }
443         }
444
445         return y;
446     }
447 }
448
Popular Tags