KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > krysalis > jcharts > nonAxisChart > PieChart3D


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.nonAxisChart;
36
37
38 import org.krysalis.jcharts.Chart;
39 import org.krysalis.jcharts.chartData.interfaces.IPieChartDataSet;
40 import org.krysalis.jcharts.chartData.processors.PieChartDataProcessor;
41 import org.krysalis.jcharts.imageMap.CircleMapArea;
42 import org.krysalis.jcharts.imageMap.ImageMap;
43 import org.krysalis.jcharts.imageMap.PolyMapArea;
44 import org.krysalis.jcharts.properties.ChartProperties;
45 import org.krysalis.jcharts.properties.LegendAreaProperties;
46 import org.krysalis.jcharts.properties.LegendProperties;
47 import org.krysalis.jcharts.properties.PieChart3DProperties;
48 import org.krysalis.jcharts.test.HTMLChartTestable;
49 import org.krysalis.jcharts.test.HTMLGenerator;
50 import org.krysalis.jcharts.types.PieLabelType;
51
52 import java.awt.*;
53 import java.awt.font.FontRenderContext JavaDoc;
54 import java.awt.geom.Arc2D JavaDoc;
55 import java.awt.geom.Line2D JavaDoc;
56
57
58 /*************************************************************************************
59  * PieChart3D was originally in jCharts 0.2.0 but mysteriously left until 1.0.0
60  *
61  * @author Nathaniel Auvil
62  * @version $Id: PieChart3D.java,v 1.9 2003/09/03 02:39:09 nathaniel_auvil Exp $
63  * @since 1.0.0
64  ************************************************************************************/

65 public class PieChart3D extends Chart implements HTMLChartTestable
66 {
67     private float pieX;
68     private float pieY;
69
70     private float pie3dWidth;
71     private float pie3dHeight;
72     private static final float RATIO = 0.5f;
73
74     private float diameter = 0;
75
76
77     private IPieChartDataSet iPieChartDataSet;
78     private PieChartDataProcessor pieChartDataProcessor;
79
80     private PieLabels pieLabels;
81
82
83     /************************************************************************************************
84      * Constructor
85      *
86      * @param iPieChartDataSet
87      * @param legendProperties
88      * @param chartProperties general chart properties
89      * @param pixelWidth
90      * @param pixelHeight
91      ************************************************************************************************/

92     public PieChart3D( IPieChartDataSet iPieChartDataSet,
93                              LegendProperties legendProperties,
94                              ChartProperties chartProperties,
95                              int pixelWidth,
96                              int pixelHeight )
97     {
98         super( legendProperties, chartProperties, pixelWidth, pixelHeight );
99         this.iPieChartDataSet = iPieChartDataSet;
100     }
101
102
103     /************************************************************************************************
104      * Draws the chart
105      *
106      ************************************************************************************************/

107     protected void renderChart()
108     {
109         PieChart3DProperties properties = (PieChart3DProperties) this.iPieChartDataSet.getChartTypeProperties();
110         FontRenderContext JavaDoc fontRenderContext = super.getGraphics2D().getFontRenderContext();
111
112         this.pieChartDataProcessor = new PieChartDataProcessor( this.iPieChartDataSet );
113         this.pieChartDataProcessor.processData();
114
115
116         //---cache calcs used more than once
117
float edgePaddingTimesTwo = super.getChartProperties().getEdgePadding() * 2;
118         float halfImageWidth = super.getImageWidth() / 2;
119         float halfImageHeight = super.getImageHeight() / 2;
120
121
122         //---render the TITLE. If no title, this will return zero.
123
float chartTitleHeightPlusPadding = super.renderChartTitle( this.iPieChartDataSet.getChartTitle(), fontRenderContext );
124
125
126         //---figure out what size is needed to hold all the components of the pie chart, then size the pie accordingly
127
float widthAvailable = super.getImageWidth() - edgePaddingTimesTwo;
128
129         float heightAvailable = super.getImageHeight() - edgePaddingTimesTwo;
130         heightAvailable -= chartTitleHeightPlusPadding;
131         heightAvailable -= properties.getDepth();
132
133
134         //---take labels sizing into consideration if needed.
135
if( !properties.getPieLabelType().equals( PieLabelType.NO_LABELS ) )
136         {
137             this.pieLabels = new PieLabels( properties, this.iPieChartDataSet, fontRenderContext );
138
139             //---if there is only one item in pie, label will be below plot so width is not a concern
140
if( iPieChartDataSet.getNumberOfDataItems() != 1 )
141             {
142                 widthAvailable -= this.pieLabels.getWidestLabelTimesTwo();
143                 widthAvailable -= ( properties.getTickLength() * 2 );
144             }
145
146             heightAvailable -= this.pieLabels.getTallestLabelTimesTwo();
147             heightAvailable -= ( properties.getTickLength() * 2 );
148         }
149
150
151         //---if there is a legend...
152
if( this.getLegend() != null )
153         {
154             float legendX = 0f;
155             float legendY = 0f;
156
157             //---calculate all the legend rendering coordinates and positions.
158
this.getLegend().calculateDrawingValues( iPieChartDataSet );
159
160
161             //---adjust width and height based on the Legend size.
162
if( ( this.getLegend().getLegendProperties().getPlacement() == LegendAreaProperties.RIGHT )
163                 || ( this.getLegend().getLegendProperties().getPlacement() == LegendAreaProperties.LEFT ) )
164             {
165                 widthAvailable -= this.getLegend().getWidth();
166                 widthAvailable -= this.getLegend().getLegendProperties().getChartPadding();
167
168                 //---diameter of pie will be at least one pixel, even if the legend takes up the whole image.
169
//---this will keep the renderer from blowing up.
170
this.diameter = Math.max( widthAvailable, 1.0f );
171
172                 //---make sure we do not make the pie diameter taller than the image
173
this.diameter = Math.min( this.diameter, heightAvailable );
174
175                 this.pie3dWidth = this.diameter;
176                 this.pie3dHeight = this.pie3dWidth * RATIO;
177
178
179 /*
180 this.pie3dWidth= 200;
181 this.pie3dHeight= 200;
182 */

183
184
185                 //---calculate the entire width of everything to be drawn so can center everything
186
float plotWidth = this.diameter;
187                 plotWidth += this.getLegend().getWidth();
188                 plotWidth += this.getLegend().getLegendProperties().getChartPadding();
189                 if( this.pieLabels != null )
190                 {
191                     plotWidth += ( this.pieLabels.getWidestLabel() * 2 );
192                     plotWidth += ( properties.getTickLength() * 2 );
193                 }
194
195                 if( this.getLegend().getLegendProperties().getPlacement() == LegendAreaProperties.RIGHT )
196                 {
197                     //---pie's diameter may not fill image width as may be image height constrained.
198
this.pieX = halfImageWidth - ( plotWidth / 2 );
199
200                     if( this.pieLabels != null )
201                     {
202                         this.pieX += this.pieLabels.getWidestLabel();
203                         this.pieX += properties.getTickLength();
204                         legendX += this.pieLabels.getWidestLabel();
205                         legendX += properties.getTickLength();
206                     }
207
208                     //---position legend based on the pie position
209
legendX += this.pieX + this.diameter;
210                     legendX += this.getLegend().getLegendProperties().getChartPadding();
211                 }
212                 else
213                 {
214                     legendX = halfImageWidth - ( plotWidth / 2 );
215
216                     if( this.pieLabels != null )
217                     {
218                         this.pieX = legendX;
219                         this.pieX += this.getLegend().getWidth();
220                         this.pieX += this.getLegend().getLegendProperties().getChartPadding();
221                         this.pieX += this.pieLabels.getWidestLabel();
222                         this.pieX += properties.getTickLength();
223                     }
224                 }
225
226                 //---center the legend vertically
227
legendY = halfImageHeight - ( this.getLegend().getHeight() / 2 );
228
229                 //---center the pie vertically
230
this.pieY = halfImageHeight - ( ( this.pie3dHeight + properties.getDepth() ) / 2 );
231             }
232             //---else the legend is either under or on top of the pie
233
else
234             {
235                 heightAvailable -= this.getLegend().getHeight();
236                 heightAvailable -= this.getLegend().getLegendProperties().getChartPadding();
237
238                 //---diameter of pie will be at least one pixel, even if the legend takes up the whole image.
239
//---this will keep the renderer from blowing up.
240
this.diameter = Math.max( heightAvailable, 1.0f );
241
242                 //---make sure we do not make the pie diameter wider than the image
243
this.diameter = Math.min( this.diameter, widthAvailable );
244
245                 this.pie3dWidth = this.diameter;
246                 this.pie3dHeight = this.pie3dWidth * RATIO;
247
248
249                 if( this.getLegend().getLegendProperties().getPlacement() == LegendAreaProperties.BOTTOM )
250                 {
251                     this.pieY = super.getChartProperties().getEdgePadding();
252                     this.pieY += chartTitleHeightPlusPadding;
253
254                     if( this.pieLabels != null )
255                     {
256                         //---adds label height from top of pie
257
this.pieY += this.pieLabels.getTallestLabel();
258                         this.pieY += properties.getTickLength();
259
260                         //---add label hight from bottom of pie
261
legendY += this.pieLabels.getTallestLabel();
262                         legendY += properties.getTickLength();
263                     }
264
265                     legendY += this.pieY;
266                     legendY += this.pie3dHeight;
267                     legendY += this.getLegend().getLegendProperties().getChartPadding();
268                     legendY += properties.getDepth();
269                 }
270                 else
271                 {
272                     legendY = super.getChartProperties().getEdgePadding();
273                     legendY += chartTitleHeightPlusPadding;
274
275                     this.pieY = legendY;
276                     this.pieY += this.getLegend().getHeight();
277                     this.pieY += this.getLegend().getLegendProperties().getChartPadding();
278
279                     if( this.pieLabels != null )
280                     {
281                         //---adds label height from top of pie
282
this.pieY += this.pieLabels.getTallestLabel();
283                         this.pieY += properties.getTickLength();
284                     }
285                 }
286
287                 //---center the legend horizontally
288
legendX = halfImageWidth - ( this.getLegend().getWidth() / 2 );
289
290                 //---center the pie horizontally
291
this.pieX = halfImageWidth - ( this.diameter / 2 );
292             }
293
294             super.getLegend().setX( legendX );
295             super.getLegend().setY( legendY );
296             super.getLegend().render();
297
298         }
299         //---else, the Legend is NULL
300
else
301         {
302             //---diameter of pie will be at least one pixel, even if the legend takes up the whole image.
303
//---this will keep the renderer from blowing up.
304
this.diameter = Math.max( widthAvailable, 1.0f );
305
306             //---make sure we do not make the pie diameter taller than the image
307
this.diameter = Math.min( this.diameter, heightAvailable );
308
309             this.pie3dWidth = this.diameter;
310             this.pie3dHeight = this.pie3dWidth * RATIO;
311
312
313             //---if there is no legend, fill the image with the pie
314
//this.diameter = Math.min( heightAvailable, widthAvailable );
315

316             float halfDiameter = ( this.diameter + properties.getDepth() ) / 2;
317
318             //---center the pie horizontally
319
this.pieX = halfImageWidth - halfDiameter;
320
321             //---center the pie vertically
322
//this.pieY = halfImageHeight - halfDiameter;
323

324             this.pieY = halfImageHeight - ( ( this.pie3dHeight + properties.getDepth() ) / 2 );
325         }
326
327
328         //---IMAGE MAP setup
329
//---if we are saving all the coordinates for an ImageMap, create the ImageMap Object as we
330
//--- know how many area elements there are.
331
if( super.getGenerateImageMapFlag() )
332         {
333             ImageMap imageMap = new ImageMap( iPieChartDataSet.getNumberOfDataItems() );
334             super.setImageMap( imageMap );
335         }
336
337
338         PieChart3D.render( this );
339     }
340
341
342     /************************************************************************************************
343      * Implement the method to render the Chart.
344      *
345      * @param pieChart3D
346      ************************************************************************************************/

347     static void render( PieChart3D pieChart3D )
348     {
349         Graphics2D g2d = pieChart3D.getGraphics2D();
350         PieChart3DProperties properties = (PieChart3DProperties) pieChart3D.iPieChartDataSet.getChartTypeProperties();
351
352
353         //---the following only for Image Map-----------------------------
354
//---IMAGE MAP
355
//---number of subdivisions to break each slice into to 'fill' slice
356
int subdivisions = 3;
357         float halfDiameter = 0;
358         float xPieMiddle = 0;
359         float yPieMiddle = 0;
360         float imageMapPoints[][] = null;
361         if( pieChart3D.getImageMap() != null )
362         {
363             halfDiameter = (float) ( pieChart3D.diameter / 2.0 );
364             xPieMiddle = halfDiameter + pieChart3D.pieX;
365             yPieMiddle = halfDiameter + pieChart3D.pieY;
366             imageMapPoints = new float[pieChart3D.iPieChartDataSet.getNumberOfDataItems() * ( subdivisions + 1 )][2];
367         }
368
369
370         //---get the starting degree
371
float currentDegrees = properties.getZeroDegreeOffset();
372
373         double percentageOfPie = 0;
374
375
376
377         //---if only one item in chart, just draw border around outside.
378
//---if do a draw of the arc, will get a line in the pie as arc has a start and end.
379
if( pieChart3D.iPieChartDataSet.getNumberOfDataItems() == 1 )
380         {
381             Arc2D.Double JavaDoc arc = new Arc2D.Double JavaDoc( pieChart3D.pieX,
382                                                              pieChart3D.pieY + properties.getDepth(),
383                                                              pieChart3D.diameter,
384                                                              pieChart3D.diameter,
385                                                              currentDegrees,
386                                                              360,
387                                                              Arc2D.OPEN );
388
389
390             //---fake 3d loop will slide pie up the image to give illusion of 3D.
391
for( int i = properties.getDepth(); i >= 0; i-- )
392             {
393                 g2d.setPaint( pieChart3D.iPieChartDataSet.getPaint( 0 ) );
394                 g2d.fill( arc );
395
396                 if( i == properties.getDepth() || i == 0 )
397                 {
398                     properties.getBorderChartStroke().draw( g2d, arc );
399                 }
400
401                 arc.y -= 1;
402             }
403
404
405             //---if only a single value use a circle map
406
//---IMAGE MAP
407
if( pieChart3D.getImageMap() != null )
408             {
409                 CircleMapArea circleMapArea = new CircleMapArea( xPieMiddle, yPieMiddle, pieChart3D.iPieChartDataSet.getValue( 0 ), null, pieChart3D.iPieChartDataSet.getLegendLabel( 0 ) );
410                 circleMapArea.setRadius( (int) pieChart3D.diameter );
411                 pieChart3D.getImageMap().addImageMapArea( circleMapArea );
412             }
413
414 // System.out.println( pieChart3D.pieLabels.getTextTag( 0 ).getText() );
415

416             float x = pieChart3D.pieX + ( pieChart3D.diameter / 2 ) - ( pieChart3D.pieLabels.getTextTag( 0 ).getWidth() / 2 );
417             float y = pieChart3D.pieY - properties.getTickLength();
418 // System.out.println( "x=" + x );
419
// System.out.println( "y=" + y );
420

421             properties.getValueLabelFont().setupGraphics2D( g2d );
422             g2d.drawString( pieChart3D.pieLabels.getTextTag( 0 ).getText(), x, y );
423         }
424         else
425         {
426             Arc2D.Double JavaDoc arc = new Arc2D.Double JavaDoc( pieChart3D.pieX,
427                                                              pieChart3D.pieY + properties.getDepth(),
428                                                              pieChart3D.pie3dWidth,
429                                                              pieChart3D.pie3dHeight,
430                                                              currentDegrees,
431                                                              360,
432                                                              Arc2D.PIE );
433
434
435             //---draw the center line in case people are using transparent paint
436
Line2D.Float JavaDoc line = new Line2D.Float JavaDoc();
437             line.x1 = pieChart3D.pieX + ( pieChart3D.pie3dWidth / 2 );
438             line.y1 = pieChart3D.pieY + ( pieChart3D.pie3dHeight / 2 );
439             line.x2 = line.x1;
440             line.y2 = line.y1 + properties.getDepth();
441             properties.getBorderChartStroke().draw( g2d, line );
442
443
444             //---fake 3d loop will slide pie up the image to give illusion of 3D.
445
for( int slider = properties.getDepth(); slider >= 0; slider-- )
446             {
447                 currentDegrees = properties.getZeroDegreeOffset();
448
449                 //---IMAGE MAP
450
int mapCounter = 0;
451
452                 for( int i = 0; i < pieChart3D.iPieChartDataSet.getNumberOfDataItems(); i++ )
453                 {
454                     percentageOfPie = pieChart3D.pieChartDataProcessor.getPercentageOfPie( i );
455
456                     arc.setAngleStart( currentDegrees );
457                     arc.setAngleExtent( percentageOfPie );
458
459                     //---set the color, and fill the pie piece.
460
g2d.setPaint( pieChart3D.iPieChartDataSet.getPaint( i ) );
461                     g2d.fill( arc );
462
463
464                     //---renders borders
465
drawFraming( slider, properties, g2d, arc, currentDegrees );
466
467
468                     //---if we are going to display labels
469
if( pieChart3D.pieLabels != null && slider == 0 )
470                     {
471                         //---get the angle the center of slice
472
double sliceCenterDegrees = ( currentDegrees ) + percentageOfPie / 2;
473
474                         if( sliceCenterDegrees > 360 )
475                         {
476                             sliceCenterDegrees -= 360;
477                         }
478
479
480
481 // double sliceCenterRadians = Math.toRadians( sliceCenterDegrees );
482

483
484 /*
485
486 >a2 := a * a;
487 >b2 := b * b;
488 >sin2 := Sqr (Sin(theta));
489 >cos2 := Sqr(Cos(theta));
490 >r = Sqrt( a2 * b2 / (a2 * sin2 + b2 * cos2) );
491 */

492 /*
493                         double a2 = pieChart3D.pie3dWidth * pieChart3D.pie3dWidth;
494                         double b2 = pieChart3D.pie3dHeight * pieChart3D.pie3dHeight;
495                         double sin2 = Math.pow( Math.sin( sliceCenterRadians ), 2 );
496                         double cos2 = Math.pow( Math.cos( sliceCenterRadians ), 2 );
497                         double radius = pieChart3D.pie3dWidth * pieChart3D.pie3dHeight / Math.sqrt( ( a2 * sin2 + b2 * cos2 ) );
498                         radius /= 2;
499
500
501                         //r= (ab) / ( sqrt( a^2 sin^2 theta + b^2 cos^2 theta ) )
502
503                         //---compute the cos and sin of the label angle.
504                         double cosOfLabel = Math.cos( sliceCenterRadians );
505                         double sinOfLabel = Math.sin( sliceCenterRadians );
506
507                         //halfDiameter = (float) ( pieChart3D.diameter / 2.0 );
508
509
510                         //---start point of the label border line.
511                         float borderXstart = (float) ( cosOfLabel * radius );
512                         float borderYstart = (float) -( sinOfLabel * radius );
513
514                         //---end point of the label border line.
515                         float borderXend = (float) ( cosOfLabel * ( radius + properties.getTickLength() ) );
516                         float borderYend = (float) -( sinOfLabel * ( radius + properties.getTickLength() ) );
517 */

518
519
520                         xPieMiddle = (float) arc.x + pieChart3D.pie3dWidth / 2;
521                         yPieMiddle = (float) arc.y + pieChart3D.pie3dHeight / 2;
522
523
524                         Arc2D.Double JavaDoc circle = new Arc2D.Double JavaDoc( pieChart3D.pieX,
525                                                                              pieChart3D.pieY,
526                                                                              pieChart3D.pie3dWidth,
527                                                                              pieChart3D.pie3dHeight,
528                                                                              currentDegrees,
529                                                                              percentageOfPie / 2,
530                                                                              Arc2D.PIE );
531                         Arc2D.Double JavaDoc circle2 = new Arc2D.Double JavaDoc( pieChart3D.pieX - properties.getTickLength(),
532                                                                               pieChart3D.pieY - properties.getTickLength(),
533                                                                               pieChart3D.pie3dWidth + properties.getTickLength() * 2,
534                                                                               pieChart3D.pie3dHeight + properties.getTickLength() * 2,
535                                                                               currentDegrees,
536                                                                               percentageOfPie / 2,
537                                                                               Arc2D.PIE );
538
539                         //---draw the line out from middle of slice
540
properties.getBorderChartStroke().draw( g2d, new Line2D.Float JavaDoc( circle.getEndPoint(), circle2.getEndPoint() ) );
541
542                         float borderXend = (float) circle2.getEndPoint().getX();
543                         float borderYend = (float) circle2.getEndPoint().getY();
544
545                         properties.getValueLabelFont().setupGraphics2D( g2d );
546
547
548                         float labelY = borderYend;
549                         if( sliceCenterDegrees > 60 && sliceCenterDegrees < 120 )
550                         {
551                             labelY -= pieChart3D.pieLabels.getTextTag( i ).getFontDescent();
552                         }
553                         else if( sliceCenterDegrees > 240 && sliceCenterDegrees < 300 )
554                         {
555                             labelY += pieChart3D.pieLabels.getTextTag( i ).getFontAscent();
556                         }
557
558
559                         if( sliceCenterDegrees > 180 && sliceCenterDegrees < 360 )
560                         {
561                             labelY+= properties.getDepth();
562                         }
563
564                         if( sliceCenterDegrees > 90 && sliceCenterDegrees < 270 )
565                         {
566                             g2d.drawString( pieChart3D.pieLabels.getTextTag( i ).getText(),
567                                                  borderXend - pieChart3D.pieLabels.getTextTag( i ).getWidth() - properties.getTickLength(),
568                                                  labelY );
569                         }
570                         else
571                         {
572                             g2d.drawString( pieChart3D.pieLabels.getTextTag( i ).getText(),
573                                                  borderXend + properties.getTickLength(),
574                                                  labelY );
575                         }
576                     }
577
578
579                     //---if we are generating an image map...
580
//---IMAGE MAP
581
if( pieChart3D.getImageMap() != null )
582                     {
583                         //---increment a separate amount to minimize rounding errors.
584
double workDegrees = currentDegrees;
585
586                         //---compute the cos and sin of the bodrder angle.
587
double cosOfBorder;
588                         double sinOfBorder;
589                         double splitDegree = percentageOfPie / subdivisions;
590
591                         for( int j = 0; j <= subdivisions; j++ )
592                         {
593                             cosOfBorder = Math.cos( Math.toRadians( workDegrees ) );
594                             sinOfBorder = Math.sin( Math.toRadians( workDegrees ) );
595
596                             //---end point of the slice border line.
597
imageMapPoints[mapCounter][0] = xPieMiddle + (float) ( cosOfBorder * halfDiameter );
598                             imageMapPoints[mapCounter][1] = yPieMiddle + (float) -( sinOfBorder * halfDiameter );
599
600                             //DEBUG to make sure calculating points correctly
601
//g2d.setPaint( Color.red );
602
//g2d.fillRect( (int) imageMapPoints[ mapCounter ][ 0 ], (int) imageMapPoints[ mapCounter ][ 1 ], 6, 6 );
603

604                             mapCounter++;
605                             workDegrees += splitDegree;
606                         }
607                     }
608
609                     currentDegrees += percentageOfPie;
610                 }
611
612
613                 //---if we are generating an image map...
614
//---IMAGE MAP
615
if( pieChart3D.getImageMap() != null )
616                 {
617                     //---each slice has 3 + subdivision slices...
618
//int counter= pieChart3D.iPieChartDataSet.getNumberOfDataItems() * ( 3 + subdivisions );
619
int counter = 0;
620
621                     //---for each data item
622
for( int i = 0; i < pieChart3D.iPieChartDataSet.getNumberOfDataItems(); i++ )
623                     {
624                         int coordinateCounter = 0;
625
626                         //---there are three points plus some number of subdivisions...
627
PolyMapArea polyMapArea = new PolyMapArea( 3 + subdivisions, pieChart3D.iPieChartDataSet.getValue( i ), null, pieChart3D.iPieChartDataSet.getLegendLabel( i ) );
628                         polyMapArea.addCoordinate( coordinateCounter++, xPieMiddle, yPieMiddle );
629
630                         //---include the first border point, plus the subdivisions
631
for( int h = 0; h <= subdivisions; h++ )
632                         {
633                             polyMapArea.addCoordinate( coordinateCounter++, imageMapPoints[counter][0], imageMapPoints[counter][1] );
634                             counter++;
635                         }
636
637                         //---if this is the last slice, add the first calculated map point
638
if( ( i + 1 ) == pieChart3D.iPieChartDataSet.getNumberOfDataItems() )
639                         {
640                             polyMapArea.addCoordinate( coordinateCounter, imageMapPoints[0][0], imageMapPoints[0][1] );
641                         }
642                         //---else add the next calculated point
643
else
644                         {
645                             polyMapArea.addCoordinate( coordinateCounter, imageMapPoints[counter][0], imageMapPoints[counter][1] );
646                         }
647
648                         pieChart3D.getImageMap().addImageMapArea( polyMapArea );
649                     }
650                 }
651
652                 //---slide the pie up one pixel
653
arc.y -= 1;
654             }
655
656 /*
657             //---draw the edges of the pie
658             line.x1= pieChart3D.pieX - 1;
659             line.x2= line.x1;
660             g2d.draw( line );
661             line.x1= pieChart3D.pieX + pieChart3D.pie3dWidth + 1;
662             line.x2= line.x1;
663             g2d.draw( line );
664 */

665
666         }
667     }
668
669
670     /****************************************************************************************
671      *
672      * @param slider
673      * @param properties
674      * @param g2d
675      * @param arc
676      * @param currentDegrees
677      ****************************************************************************************/

678     private static void drawFraming( int slider,
679                                                 PieChart3DProperties properties,
680                                                 Graphics2D g2d,
681                                                 Arc2D.Double JavaDoc arc,
682                                                 float currentDegrees )
683     {
684         //---draw the top borders of the pie, and draw the bottom in case there are transparent Paints
685
if( slider == properties.getDepth() || slider == 0 )
686         {
687             properties.getBorderChartStroke().draw( g2d, arc );
688
689             //---draw the vertical borders
690
//---in case there are translucent Paints, need to draw the backside borders before the chart.
691
if( slider == properties.getDepth() )
692             {
693                 if( currentDegrees > 0 && currentDegrees < 180 )
694                 {
695                     properties.getBorderChartStroke().draw( g2d, new Line2D.Double JavaDoc( arc.getStartPoint().getX(),
696                                                                                                          arc.getStartPoint().getY(),
697                                                                                                          arc.getStartPoint().getX(),
698                                                                                                          arc.getStartPoint().getY() - properties.getDepth() ) );
699                 }
700             }
701             else if( slider == 0 )
702             {
703                 if( currentDegrees == 0 || ( currentDegrees >= 180 && currentDegrees < 360 ) )
704                 {
705                     properties.getBorderChartStroke().draw( g2d, new Line2D.Double JavaDoc( arc.getStartPoint().getX(),
706                                                                                                          arc.getStartPoint().getY(),
707                                                                                                          arc.getStartPoint().getX(),
708                                                                                                          arc.getStartPoint().getY() + properties.getDepth() ) );
709                 }
710             }
711         }
712     }
713
714
715     /**********************************************************************************************
716      * Enables the testing routines to display the contents of this Object. Override Chart
717      * implementation as PieCharts use AreaProperties directly rather than a child.
718      *
719      * @param htmlGenerator
720      * @param imageFileName
721      **********************************************************************************************/

722     public void toHTML( HTMLGenerator htmlGenerator, String JavaDoc imageFileName )
723     {
724         if( this.getLegend() != null )
725         {
726             htmlGenerator.chartTableRowStart();
727             this.getLegend().toHTML( htmlGenerator );
728             htmlGenerator.chartTableRowEnd();
729         }
730
731         htmlGenerator.chartTableEnd();
732     }
733
734 }
735
Popular Tags