KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > krysalis > jcharts > axisChart > BarChart


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

34
35 package org.krysalis.jcharts.axisChart;
36
37
38 import java.awt.Graphics2D JavaDoc;
39 import java.awt.geom.Rectangle2D JavaDoc;
40
41 import org.krysalis.jcharts.axisChart.customRenderers.axisValue.AxisValueRenderEvent;
42 import org.krysalis.jcharts.chartData.interfaces.IAxisChartDataSet;
43 import org.krysalis.jcharts.chartText.TextTagGroup;
44 import org.krysalis.jcharts.imageMap.RectMapArea;
45 import org.krysalis.jcharts.properties.BarChartProperties;
46
47
48 /*****************************************************************************************
49  * @author Nathaniel Auvil
50  * @version $Id: BarChart.java,v 1.3 2004/05/27 02:15:19 nathaniel_auvil Exp $
51  ****************************************************************************************/

52 abstract class BarChart
53 {
54
55     /***************************************************************************************
56      * Draws the chart uses Rectangle2D......keep having rounding problems.
57      *
58      * @param axisChart
59      * @param iAxisChartDataSet
60      **************************************************************************************/

61     static void render( AxisChart axisChart, IAxisChartDataSet iAxisChartDataSet )
62     {
63         Graphics2D JavaDoc g2d = axisChart.getGraphics2D();
64         BarChartProperties barChartProperties = (BarChartProperties) iAxisChartDataSet.getChartTypeProperties();
65         float barWidth;
66
67         //---y axis position on screen to start drawing.
68
float startingX;
69         float startingY;
70         float width;
71         float height;
72
73         if( axisChart.getAxisProperties().isPlotHorizontal() )
74         {
75             barWidth = axisChart.getYAxis().getScalePixelWidth() * barChartProperties.getPercentage();
76             startingX = axisChart.getXAxis().getZeroLineCoordinate();
77             startingY = axisChart.getYAxis().getLastTickY() - (barWidth / 2);
78             width = 0;
79             height = barWidth;
80             Rectangle2D.Float JavaDoc rectangle = new Rectangle2D.Float JavaDoc( startingX, startingY, width, height );
81
82             BarChart.horizontalPlot( axisChart,
83                                                 iAxisChartDataSet,
84                                                 barChartProperties,
85                                                 g2d,
86                                                 rectangle,
87                                                 startingX );
88         }
89         else
90         {
91             barWidth = axisChart.getXAxis().getScalePixelWidth() * barChartProperties.getPercentage();
92             startingX = axisChart.getXAxis().getTickStart() - (barWidth / 2);
93             startingY = axisChart.getYAxis().getZeroLineCoordinate();
94             width = barWidth;
95             height = 0;
96             Rectangle2D.Float JavaDoc rectangle = new Rectangle2D.Float JavaDoc( startingX, startingY, width, height );
97
98             BarChart.verticalPlot( axisChart,
99                                             iAxisChartDataSet,
100                                             barChartProperties,
101                                             g2d,
102                                             rectangle,
103                                             startingY );
104         }
105     }
106
107
108     /***************************************************************************************
109      * @param axisChart
110      * @param iAxisChartDataSet
111      * @param barChartProperties
112      * @param g2d
113      * @param rectangle
114      * @param startingX
115      **************************************************************************************/

116     private static void horizontalPlot( AxisChart axisChart,
117                                                     IAxisChartDataSet iAxisChartDataSet,
118                                                     BarChartProperties barChartProperties,
119                                                     Graphics2D JavaDoc g2d,
120                                                     Rectangle2D.Float JavaDoc rectangle,
121                                                     float startingX )
122     {
123         int imageMapLabelIndex = axisChart.getYAxis().getNumberOfScaleItems() - 1;
124
125         //---setup the total area rectangle
126
Rectangle2D.Float JavaDoc totalItemArea = new Rectangle2D.Float JavaDoc();
127         totalItemArea.y = axisChart.getYAxis().getOrigin() - axisChart.getYAxis().getPixelLength() + 1;
128         totalItemArea.height = axisChart.getYAxis().getScalePixelWidth() - 1;
129         totalItemArea.x = axisChart.getXAxis().getOrigin() + 1;
130         totalItemArea.width = axisChart.getXAxis().getPixelLength() - 1;
131
132         //---reuse the same Object for pre and post render events.
133
AxisValueRenderEvent axisValueRenderEvent = new AxisValueRenderEvent( axisChart,
134                                                                                                     iAxisChartDataSet,
135                                                                                                     g2d,
136                                                                                                     totalItemArea,
137                                                                                                     axisChart.getXAxis().getZeroLineCoordinate() );
138
139         //---there is only ever one data set for a regular bar chart
140
axisValueRenderEvent.setDataSetIndex( 0 );
141
142         //LOOP
143
for( int i = 0; i < iAxisChartDataSet.getNumberOfDataItems(); i++ )
144         {
145             //---reset the paint as it might have changed for the outline drawing
146
g2d.setPaint( iAxisChartDataSet.getPaint( 0 ) );
147
148             //---set values for the preRender event
149
axisValueRenderEvent.setValueX( axisChart.getXAxis().getZeroLineCoordinate() );
150             axisValueRenderEvent.setValueY( (float) rectangle.getCenterY() );
151             axisValueRenderEvent.setValueIndex( i );
152
153             //---we want to do this regardless if we render an item
154
barChartProperties.firePreRender( axisValueRenderEvent );
155
156             //---if value == 0 do not plot anything.
157
if( iAxisChartDataSet.getValue( 0, i ) != 0.0d )
158             {
159                 if( iAxisChartDataSet.getValue( 0, i ) < 0 )
160                 {
161                     rectangle.x = axisChart.getXAxis().computeAxisCoordinate( axisChart.getXAxis().getOrigin(),
162                                                                                                     iAxisChartDataSet.getValue( 0, i ),
163                                                                                                     axisChart.getXAxis().getScaleCalculator().getMinValue() );
164                     rectangle.width = startingX - rectangle.x;
165
166                     //---set values for the postRender event
167
axisValueRenderEvent.setValueX( rectangle.x );
168                 }
169                 else
170                 {
171                     rectangle.x = startingX;
172                     rectangle.width = BarChart.computeScaleHeightOfValue( iAxisChartDataSet.getValue( 0, i ),
173                                                                                             axisChart.getXAxis().getOneUnitPixelSize() );
174
175                     //---set values for the postRender event
176
axisValueRenderEvent.setValueX( rectangle.x + rectangle.width );
177                 }
178
179                 //---with a user defined scale, we could have non-zero data points with a height of zero.
180
if( rectangle.width != 0 )
181                 {
182                     g2d.fill( rectangle );
183
184                     if( barChartProperties.getShowOutlinesFlag() )
185                     {
186                         barChartProperties.getBarOutlineStroke().draw( g2d, rectangle );
187                     }
188
189                     //---if we are generating an ImageMap, store the image coordinates
190
if( axisChart.getGenerateImageMapFlag() )
191                     {
192                         RectMapArea rectMapArea= createImageMapArea( axisChart.getYAxis().getAxisLabelsGroup(),
193                                                                                     imageMapLabelIndex,
194                                                                                     rectangle,
195                                                                                     iAxisChartDataSet.getValue( 0, i ),
196                                                                                     iAxisChartDataSet.getLegendLabel( 0 ) );
197                         axisChart.getImageMap().addImageMapArea( rectMapArea );
198                         
199                         imageMapLabelIndex--;
200                     }
201                 }
202             }
203             else
204             {
205                 //---else, value is zero.
206

207                 //---if we are generating an ImageMap, store the image coordinates
208
if( axisChart.getGenerateImageMapFlag() )
209                 {
210                     //---check if zero scale line is visible
211
//---make sure zero is even visible on the scale.
212
//---If zero is not visible on scale nothing will be clickable for that item
213
if( axisChart.getXAxis().getScaleCalculator().getMaxValue() >= 0
214                             && axisChart.getXAxis().getScaleCalculator().getMinValue() <= 0 )
215                     {
216                         rectangle.x = startingX;
217                         rectangle.width = 1;
218                             
219                         RectMapArea rectMapArea = createImageMapArea( axisChart.getYAxis().getAxisLabelsGroup(),
220                                                                                         imageMapLabelIndex,
221                                                                                         rectangle,
222                                                                                         iAxisChartDataSet.getValue( 0, i ),
223                                                                                         iAxisChartDataSet.getLegendLabel( 0 ) );
224
225                         axisChart.getImageMap().addImageMapArea( rectMapArea );
226                     }
227                     
228                     imageMapLabelIndex--;
229                 }
230             }
231
232             //---notify everyone we just rendered
233
barChartProperties.firePostRender( axisValueRenderEvent );
234             totalItemArea.y += axisChart.getYAxis().getScalePixelWidth();
235
236             rectangle.y += axisChart.getYAxis().getScalePixelWidth();
237         }
238     }
239
240
241     /***************************************************************************************
242      * @param axisChart
243      * @param iAxisChartDataSet
244      * @param barChartProperties
245      * @param g2d
246      * @param rectangle
247      * @param startingY
248      **************************************************************************************/

249     private static void verticalPlot( AxisChart axisChart,
250                                                     IAxisChartDataSet iAxisChartDataSet,
251                                                     BarChartProperties barChartProperties,
252                                                     Graphics2D JavaDoc g2d,
253                                                     Rectangle2D.Float JavaDoc rectangle,
254                                                     float startingY )
255     {
256         //---setup the total area rectangle
257
Rectangle2D.Float JavaDoc totalItemArea = new Rectangle2D.Float JavaDoc();
258         totalItemArea.x = axisChart.getXAxis().getOrigin() + 1;
259         totalItemArea.y = axisChart.getYAxis().getOrigin() - axisChart.getYAxis().getPixelLength() + 1;
260         totalItemArea.width = axisChart.getXAxis().getScalePixelWidth() - 1;
261         totalItemArea.height = axisChart.getYAxis().getPixelLength() - 1;
262
263         //---reuse the same Object for pre and post render events.
264
AxisValueRenderEvent axisValueRenderEvent = new AxisValueRenderEvent( axisChart,
265                                                                                                     iAxisChartDataSet,
266                                                                                                     g2d,
267                                                                                                     totalItemArea,
268                                                                                                     axisChart.getYAxis().getZeroLineCoordinate() );
269
270         //---there is only ever one data set for a regular bar chart
271
axisValueRenderEvent.setDataSetIndex( 0 );
272
273         //LOOP
274
for( int i = 0; i < iAxisChartDataSet.getNumberOfDataItems(); i++ )
275         {
276             //---reset the paint as it might have changed for the outline drawing
277
g2d.setPaint( iAxisChartDataSet.getPaint( 0 ) );
278
279             //---set values for the preRender event
280
axisValueRenderEvent.setValueX( (float) rectangle.getCenterX() );
281             axisValueRenderEvent.setValueY( axisChart.getYAxis().getZeroLineCoordinate() );
282             axisValueRenderEvent.setValueIndex( i );
283
284             //---we want to do this regardless if we render an item
285
barChartProperties.firePreRender( axisValueRenderEvent );
286
287             //---if value == 0 do not plot anything.
288
if( iAxisChartDataSet.getValue( 0, i ) != 0.0d )
289             {
290                 if( iAxisChartDataSet.getValue( 0, i ) < 0 )
291                 {
292                     rectangle.y = startingY;
293                     rectangle.height = BarChart.computeScaleHeightOfValue( iAxisChartDataSet.getValue( 0, i ), axisChart.getYAxis().getOneUnitPixelSize() );
294
295                     axisValueRenderEvent.setValueY( rectangle.y + rectangle.height );
296                 }
297                 else
298                 {
299                     rectangle.y = axisChart.getYAxis().computeAxisCoordinate( axisChart.getYAxis().getOrigin(),
300                                                                                                  iAxisChartDataSet.getValue( 0, i ),
301                                                                                                  axisChart.getYAxis().getScaleCalculator().getMinValue() );
302                     rectangle.height = startingY - rectangle.y;
303
304                     axisValueRenderEvent.setValueY( rectangle.y );
305                 }
306
307                 
308                 //---with a user defined scale, we could have non-zero data points with a height of zero.
309
if( rectangle.height != 0 )
310                 {
311                     g2d.fill( rectangle );
312
313                     if( barChartProperties.getShowOutlinesFlag() )
314                     {
315                         barChartProperties.getBarOutlineStroke().draw( g2d, rectangle );
316                         g2d.setPaint( iAxisChartDataSet.getPaint( 0 ) );
317                     }
318                 }
319
320                 //---even if the bar is not visible, we still need to generate an ImageMapArea
321
if( axisChart.getGenerateImageMapFlag() )
322                 {
323                     RectMapArea rectMapArea = createImageMapArea( axisChart.getXAxis().getAxisLabelsGroup(),
324                                                                                     i,
325                                                                                     rectangle,
326                                                                                     iAxisChartDataSet.getValue( 0, i ),
327                                                                                     iAxisChartDataSet.getLegendLabel( 0 ) );
328
329                     axisChart.getImageMap().addImageMapArea( rectMapArea );
330                 }
331             }
332             else
333             {
334                 //---if we are generating an ImageMap, store the image coordinates
335
if( axisChart.getGenerateImageMapFlag() )
336                 {
337                     //---make sure zero is even visible on the scale.
338
//---If zero is not visible on scale nothing will be clickable for that item
339
if( axisChart.getYAxis().getScaleCalculator().getMaxValue() >= 0
340                             && axisChart.getYAxis().getScaleCalculator().getMinValue() <= 0 )
341                     {
342                         rectangle.y = startingY;
343                         rectangle.height = 1;
344                             
345                         RectMapArea rectMapArea = createImageMapArea( axisChart.getXAxis().getAxisLabelsGroup(),
346                                                                                         i,
347                                                                                         rectangle,
348                                                                                         iAxisChartDataSet.getValue( 0, i ),
349                                                                                         iAxisChartDataSet.getLegendLabel( 0 ) );
350
351                         axisChart.getImageMap().addImageMapArea( rectMapArea );
352                     }
353                 }
354             }
355
356             //---notify everyone we just rendered
357
barChartProperties.firePostRender( axisValueRenderEvent );
358             totalItemArea.x += axisChart.getXAxis().getScalePixelWidth();
359
360             rectangle.x += axisChart.getXAxis().getScalePixelWidth();
361         }
362     }
363
364
365     /***************************************************************************************
366      * Takes a value and determines the number of pixels it should fill on the screen. If
367      * there is a user defined scale and the passed value is greater than the MAX or less
368      * than the MIN, the height will be forced to the MAX or MIN respectively.
369      *
370      * @param value
371      * @param oneUnitPixelSize
372      * @return float the screen pixel coordinate
373      **************************************************************************************/

374     static float computeScaleHeightOfValue( double value, double oneUnitPixelSize )
375     {
376         return (float) Math.abs( (value) * oneUnitPixelSize );
377     }
378
379
380     /***************************************************************************************
381      * @param axisLabelsGroup
382      * @param labelIndex
383      * @param rectangle
384      * @param value
385      * @param legendLabel
386      * @return RectMapArea
387      **************************************************************************************/

388     private static RectMapArea createImageMapArea( TextTagGroup axisLabelsGroup,
389                                                                    int labelIndex,
390                                                                     Rectangle2D.Float JavaDoc rectangle,
391                                                                     double value,
392                                                                     String JavaDoc legendLabel )
393     {
394         String JavaDoc label;
395         if( axisLabelsGroup != null )
396         {
397             label = axisLabelsGroup.getTextTag( labelIndex ).getText();
398         }
399         else
400         {
401             label = "";
402         }
403
404         return new RectMapArea( rectangle, value, label, legendLabel );
405     }
406 }
Popular Tags