KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > krysalis > jcharts > Legend


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
36 package org.krysalis.jcharts;
37
38
39 import java.awt.Graphics2D JavaDoc;
40 import java.awt.Paint JavaDoc;
41 import java.awt.Shape JavaDoc;
42 import java.awt.geom.AffineTransform JavaDoc;
43 import java.awt.geom.Line2D JavaDoc;
44 import java.awt.geom.Rectangle2D JavaDoc;
45 import java.io.Serializable JavaDoc;
46 import java.util.ArrayList JavaDoc;
47 import java.util.Iterator JavaDoc;
48
49 import org.krysalis.jcharts.Chart;
50 import org.krysalis.jcharts.chartData.interfaces.IAxisDataSeries;
51 import org.krysalis.jcharts.chartData.interfaces.IAxisPlotDataSet;
52 import org.krysalis.jcharts.chartData.interfaces.IData;
53 import org.krysalis.jcharts.chartData.interfaces.IPieChartDataSet;
54 import org.krysalis.jcharts.chartData.processors.TextProcessor;
55 import org.krysalis.jcharts.properties.LegendAreaProperties;
56 import org.krysalis.jcharts.properties.LegendProperties;
57 import org.krysalis.jcharts.properties.LineChartProperties;
58 import org.krysalis.jcharts.properties.PointChartProperties;
59 import org.krysalis.jcharts.test.HTMLGenerator;
60 import org.krysalis.jcharts.test.HTMLTestable;
61 import org.krysalis.jcharts.types.ChartType;
62
63
64 /*************************************************************************************
65  *
66  * @author Nathaniel Auvil, Sandor Dornbush, Sundar Balasubramanian
67  * @version $Id: Legend.java,v 1.10 2004/05/31 16:26:13 nathaniel_auvil Exp $
68  ************************************************************************************/

69 final public class Legend implements HTMLTestable, Serializable JavaDoc
70 {
71     private Chart chart;
72     private LegendProperties legendProperties;
73
74     private float iconSide;
75
76
77     //---derived values
78
private float widestLabelAndColumnPadding;
79     private int numColumns;
80     private int numRows;
81
82
83     private TextProcessor textProcessor;
84
85     private float x;
86     private float y;
87     private float width = 0;
88     private float height = 0;
89
90
91     //---used to extract the legendLabels and paints from the data set and make them easy to loop through
92
private ArrayList JavaDoc labels;
93     private ArrayList JavaDoc paints;
94     private ArrayList JavaDoc shapes = new ArrayList JavaDoc();
95     private ArrayList JavaDoc fillPointsFlags = new ArrayList JavaDoc();
96     private ArrayList JavaDoc pointOutlinePaints = new ArrayList JavaDoc();
97     private ChartType chartType;
98     private PointChartProperties pointChartProperties;
99     private LineChartProperties lineChartProperties;
100
101
102     /*********************************************************************************************
103      *
104      * @param chart
105      * @deprecated
106      **********************************************************************************************/

107     public Legend( Chart chart )
108     {
109         this.chart = chart;
110     }
111
112
113     /*********************************************************************************************
114      *
115      * @param chart
116      * @param legendProperties
117      **********************************************************************************************/

118     public Legend( Chart chart, LegendProperties legendProperties )
119     {
120         this.chart = chart;
121         this.legendProperties = legendProperties;
122     }
123
124
125     public void setX( float x )
126     {
127         this.x = x;
128     }
129
130
131     public void setY( float y )
132     {
133         this.y = y;
134     }
135
136
137     /*****************************************************************************************
138      *
139      * @param iAxisDataSeries
140      * @param chartTitleHeight
141      ****************************************************************************************/

142     public void computeLegendXY( IAxisDataSeries iAxisDataSeries, float chartTitleHeight )
143     {
144         //---PROCESS the size needed for drawing the legend.
145
this.calculateDrawingValues( iAxisDataSeries );
146
147         if( (this.getLegendProperties().getPlacement() == LegendAreaProperties.RIGHT)
148             || (this.getLegendProperties().getPlacement() == LegendAreaProperties.LEFT) )
149         {
150             if( this.getHeight() > this.chart.getImageHeight() - this.chart.getChartProperties().getEdgePadding() * 2 )
151             {
152                 this.setY( this.chart.getChartProperties().getEdgePadding() );
153             }
154             else
155             {
156                 this.setY( (this.chart.getImageHeight() / 2) - (this.getHeight() / 2) );
157             }
158
159             if( this.getLegendProperties().getPlacement() == LegendAreaProperties.RIGHT )
160             {
161                 this.setX( this.chart.getImageWidth() - this.getWidth() - this.chart.getChartProperties().getEdgePadding() );
162             }
163             else //---else, LegendAreaProperties.LEFT
164
{
165                 this.setX( this.chart.getChartProperties().getEdgePadding() );
166             }
167         }
168         else //---LegendAreaProperties.BOTTOM, OR LegendAreaProperties.TOP
169
{
170             if( this.getWidth() + this.chart.getChartProperties().getEdgePadding() * 2 > this.chart.getImageWidth() )
171             {
172                 this.setX( this.chart.getChartProperties().getEdgePadding() );
173             }
174             else
175             {
176                 this.setX( (this.chart.getImageWidth() / 2) - (this.getWidth() / 2) );
177             }
178
179             if( this.getLegendProperties().getPlacement() == LegendAreaProperties.BOTTOM )
180             {
181                 this.setY( this.chart.getImageHeight() - this.getHeight() - this.chart.getChartProperties().getEdgePadding() );
182             }
183             else //---else, LegendAreaProperties.TOP
184
{
185                 this.setY( this.chart.getChartProperties().getEdgePadding() + chartTitleHeight );
186             }
187         }
188     }
189
190
191     /**********************************************************************************************
192      * Central method for processing data; try to minimize looping.
193      * 1) calculate the maximum height of labels
194      * 2) find the maximum label width
195      *
196      * @param iAxisDataSeries
197      **********************************************************************************************/

198     private void processData( IAxisDataSeries iAxisDataSeries )
199     {
200         this.textProcessor = new TextProcessor();
201
202         Iterator JavaDoc iterator = iAxisDataSeries.getIAxisPlotDataSetIterator();
203
204         //LOOP
205
while( iterator.hasNext() )
206         {
207             this.processLegendLabels( (IAxisPlotDataSet) iterator.next() );
208         }
209     }
210
211
212     /**********************************************************************************************
213      * Central method for processing data; try to minimize looping.
214      * 1) calculate the maximum height of labels
215      * 2) find the maximum label width
216      *
217      * @param iPieChartDataSet
218      **********************************************************************************************/

219     private void processData( IPieChartDataSet iPieChartDataSet )
220     {
221         this.textProcessor = new TextProcessor();
222         this.processLegendLabels( iPieChartDataSet );
223     }
224
225
226     /**********************************************************************************************
227      * Method for processing data for AxisPlot datasets; try to minimize
228      * looping.
229      * 1) calculate the maximum height of labels
230      * 2) find the maximum label width
231      *
232      * @param iAxisPlotDataSet
233      * *********************************************************************************************/

234     private void processLegendLabels( IAxisPlotDataSet iAxisPlotDataSet )
235     {
236         for( int i = 0; i < iAxisPlotDataSet.getNumberOfLegendLabels(); i++ )
237         {
238             //---StockChartDataSets could have NULLs depending on the data
239
if( iAxisPlotDataSet.getLegendLabel( i ) != null )
240             {
241                 this.textProcessor.addLabel( iAxisPlotDataSet.getLegendLabel( i ), this.legendProperties.getChartFont().getFont(), this.chart.getGraphics2D().getFontRenderContext() );
242
243                 //---pair labels with paints to get around ugly piechart vs axischart data structure mess
244
this.labels.add( iAxisPlotDataSet.getLegendLabel( i ) );
245                 this.paints.add( iAxisPlotDataSet.getPaint( i ) );
246
247                 if( iAxisPlotDataSet.getChartType().equals( ChartType.POINT ) )
248                 {
249                     this.chartType = ChartType.POINT;
250                     this.pointChartProperties = (PointChartProperties) iAxisPlotDataSet.getChartTypeProperties();
251                     this.shapes.add( pointChartProperties.getShape( i ) );
252                     this.fillPointsFlags.add( new Boolean JavaDoc( pointChartProperties.getFillPointsFlag( i ) ) );
253                     this.pointOutlinePaints.add( pointChartProperties.getPointOutlinePaints( i ) );
254                 }
255                 if( iAxisPlotDataSet.getChartType().equals( ChartType.LINE ) )
256                 {
257                     this.chartType = ChartType.LINE;
258                     this.lineChartProperties = (LineChartProperties) iAxisPlotDataSet.getChartTypeProperties();
259                     if( lineChartProperties.getShapes() != null )
260                     {
261                         this.shapes.add( lineChartProperties.getShapes()[i] );
262                     }
263                 }
264             }
265         }
266     }
267
268
269     /**********************************************************************************************
270      * Method for processing data for PieCharts; try to minimize looping.
271      * 1) calculate the maximum height of labels
272      * 2) find the maximum label width
273      * @param iPieChartDataSet
274      * ********************************************************************************************/

275     private void processLegendLabels( IPieChartDataSet iPieChartDataSet )
276     {
277         for( int i = 0; i < iPieChartDataSet.getNumberOfLegendLabels(); i++ )
278         {
279             //---StockChartDataSets could have NULLs depending on the data
280
if( iPieChartDataSet.getLegendLabel( i ) != null )
281             {
282                 this.textProcessor.addLabel( iPieChartDataSet.getLegendLabel( i ), this.legendProperties.getChartFont().getFont(), this.chart.getGraphics2D().getFontRenderContext() );
283
284                 //---pair labels with paints to get around ugly piechart vs axischart data structure mess
285
this.labels.add( iPieChartDataSet.getLegendLabel( i ) );
286                 this.paints.add( iPieChartDataSet.getPaint( i ) );
287             }
288         }
289     }
290
291
292     /************************************************************************************************
293      *
294      *************************************************************************************************/

295     public LegendProperties getLegendProperties()
296     {
297         return this.legendProperties;
298     }
299
300
301     /************************************************************************************************
302      * Calculates the width and height needed to display the Legend. Use the getWidth() and
303      * getHeight() methods to extract this information.
304      *
305      * @param iData can pass either the IPieChartDataSet or the IChartDataSeries to this.
306      ************************************************************************************************/

307     public void calculateDrawingValues( IData iData )
308     {
309         int numberOfLabels;
310         this.labels = new ArrayList JavaDoc();
311         this.paints = new ArrayList JavaDoc();
312
313
314         if( iData instanceof IAxisDataSeries )
315         {
316             IAxisDataSeries iAxisDataSeries = (IAxisDataSeries) iData;
317             this.processData( iAxisDataSeries );
318             numberOfLabels = iAxisDataSeries.getTotalNumberOfDataSets();
319         }
320         else
321         {
322             IPieChartDataSet iPieChartDataSet = (IPieChartDataSet) iData;
323             this.processData( iPieChartDataSet );
324             numberOfLabels = iPieChartDataSet.getNumberOfLegendLabels();
325         }
326
327
328         //---make the icon proportional to the Font being used.
329
this.iconSide = (float) .50 * this.textProcessor.getTallestLabel();
330         //---for POINT and LINE charts, set iconSide to max width of legend shapes
331
if( (chartType == ChartType.POINT) || (chartType == ChartType.LINE) )
332         {
333             //for( int i = 0; i < numberOfLabels; i++ )
334
for( int i = 0; i < this.shapes.size(); i++ )
335             {
336                 //---get the bounds of the shape
337
try
338                                 {
339                                     Double JavaDoc shapeWidthDouble = new Double JavaDoc( ( ( (Shape JavaDoc) this.shapes.get( i ) ).getBounds2D().getWidth() ) );
340                                     float shapeWidth = shapeWidthDouble.floatValue();
341                                     this.iconSide = Math.max(this.iconSide, shapeWidth);
342                                 }
343                                 catch (NullPointerException JavaDoc npe)
344                                 {
345                                     // Looks like in 0.74 it was quite acceptable to make shape = null
346
// we should probably catch all these and render a "null" shape to the legend
347
System.err.println("Warning: legend shape is null");
348                                     npe.printStackTrace();
349                                 }
350             }
351         }
352
353         this.determineWidthAndHeight( numberOfLabels );
354     }
355
356
357     /********************************************************************************************
358      *
359      ********************************************************************************************/

360     public float getWidth()
361     {
362         return this.width;
363     }
364
365
366     /********************************************************************************************
367      *
368      ********************************************************************************************/

369     public int getHeight()
370     {
371 //why not return a float here?
372
return ((int) Math.ceil( this.height ));
373     }
374
375
376     /**********************************************************************************************
377      * Determines the dimensions needed for the Legend and creates the image for it.
378      *
379      **********************************************************************************************/

380     private void determineWidthAndHeight( int numberOfLabels )
381     {
382         //---start with the padding no matter how many columns or specified width
383
width = this.legendProperties.getEdgePadding() * 2;
384         height = width;
385
386
387         //---if don't care how many columns or the number of labels is less than num columns specified, all in one row.
388
if( this.legendProperties.getNumColumns() == LegendAreaProperties.COLUMNS_AS_MANY_AS_NEEDED
389             || this.legendProperties.getNumColumns() >= numberOfLabels )
390         {
391             this.numColumns = numberOfLabels;
392             width += this.textProcessor.getTotalLabelWidths();
393
394             this.numRows = 1;
395         }
396         //---else, more than one row
397
else
398         {
399             //---one less addition to do when looping.
400
this.widestLabelAndColumnPadding = this.textProcessor.getWidestLabel() + this.legendProperties.getColumnPadding();
401
402             if( legendProperties.getNumColumns() == LegendAreaProperties.COLUMNS_FIT_TO_IMAGE )
403             {
404                 // calculate that the columns match exactly
405
float actualWidth = legendProperties.getSize().width;
406
407                 float widestLabelColumnAndIcon =
408                     widestLabelAndColumnPadding +
409                     iconSide +
410                     legendProperties.getIconPadding() +
411                     legendProperties.getColumnPadding();
412
413                 numColumns = (int) (actualWidth / widestLabelColumnAndIcon);
414                 numColumns = Math.min( numColumns, numberOfLabels );
415             }
416             else
417             {
418                 numColumns = this.legendProperties.getNumColumns();
419             }
420
421             width += this.textProcessor.getWidestLabel() * this.numColumns;
422
423             this.numRows = (int) Math.ceil( (double) numberOfLabels / (double) this.numColumns );
424         }
425
426
427         //---account for icons
428
width += (this.iconSide + this.legendProperties.getIconPadding()) * this.numColumns;
429
430         //---account for space between each column
431
width += this.legendProperties.getColumnPadding() * (this.numColumns - 1);
432
433         //---account for lineStrokes for LINE charts
434
if( chartType == ChartType.LINE)
435         {
436             width += this.legendProperties.getIconLineStrokeLength() * 2 * this.numColumns;
437         }
438
439         //---account for each row
440
height += (this.textProcessor.getTallestLabel() * this.numRows);
441
442         //---account for each row padding
443
height += (this.legendProperties.getRowPadding() * (this.numRows - 1));
444     }
445
446
447     /**********************************************************************************************
448      * Renders the legend.
449      *
450      **********************************************************************************************/

451     public void render()
452     {
453         Graphics2D JavaDoc g2d = this.chart.getGraphics2D();
454
455         //---get the bounds of the image
456
Rectangle2D.Float JavaDoc rectangle = new Rectangle2D.Float JavaDoc( this.x, this.y, width - 1, this.height - 1 );
457
458         //---fill the background of the Legend with the specified Paint
459
if( this.legendProperties.getBackgroundPaint() != null )
460         {
461             g2d.setPaint( this.legendProperties.getBackgroundPaint() );
462             g2d.fill( rectangle );
463         }
464
465         //---draw Legend border
466
if( this.legendProperties.getBorderStroke() != null )
467         {
468             this.legendProperties.getBorderStroke().draw( g2d, rectangle );
469         }
470
471         //---dont think we want this so text will be clean but leave commented out.
472
//g2d.setRenderingHint( RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF );
473

474         //---set the font and text color.
475
g2d.setFont( this.legendProperties.getChartFont().getFont() );
476
477         //---icon coordinates
478
rectangle.y += this.legendProperties.getEdgePadding() + (this.textProcessor.getTallestLabel() / 2) - (this.iconSide / 2);
479         rectangle.width = this.iconSide;
480         rectangle.height = this.iconSide;
481
482
483         float posX = this.x + this.legendProperties.getEdgePadding();
484         float fontY = rectangle.y + rectangle.height;
485
486
487         //---pre calculate utility values
488
float yIncrement = this.textProcessor.getTallestLabel() + this.legendProperties.getRowPadding();
489         float iconAndPaddingWidth = this.iconSide + this.legendProperties.getIconPadding();
490
491         int labelIndex = 0;
492
493         //LOOP
494
for( int j = 0; j < this.numRows; j++ )
495         {
496             //LOOP
497
for( int i = 0; i < this.numColumns; i++ )
498             {
499                 rectangle.x = posX;
500
501                 //---display icon
502
g2d.setPaint( (Paint JavaDoc) this.paints.get( labelIndex ) );
503
504                 // only Point and Line Charts will have shapes drawn
505

506                 if( this.shapes.size() > 0 && this.shapes.size() > labelIndex )
507                 {
508                     //Shape shape = (Shape)this.shapes.get( labelIndex);
509

510                     //---get the original transform so can reset it
511
AffineTransform JavaDoc affineTransform = g2d.getTransform();
512
513                     //---translate the Shape into position
514
g2d.translate( rectangle.x, rectangle.y );
515
516                     if( this.fillPointsFlags.size() > 0 )
517                     {
518                         if( ((Boolean JavaDoc) this.fillPointsFlags.get( labelIndex )).booleanValue() )
519                         {
520                             g2d.fill( (Shape JavaDoc) this.shapes.get( labelIndex ) );
521
522                             //---if we are filling the points, see if we should outline the Shape
523
//---applicable only to POINt charts
524
if( this.pointOutlinePaints.get( labelIndex ) != null )
525                             {
526                                 g2d.setPaint( (Paint JavaDoc) this.pointOutlinePaints.get( labelIndex ) );
527                                 g2d.draw( (Shape JavaDoc) this.shapes.get( labelIndex ) );
528                             }
529                         }
530                     }
531                     else
532                     {
533                         // for Point Charts, only draw shape
534
if( chartType == ChartType.POINT)
535                         {
536                             g2d.draw( (Shape JavaDoc) this.shapes.get( labelIndex ) );
537                         } else
538                         // chartType == ChartType.LINE
539
// for Line Charts, fill the shape
540
{
541                             //---get the bounds of the shape
542
Rectangle2D JavaDoc shapeBounds = ( (Shape JavaDoc) this.shapes.get( labelIndex ) ).getBounds2D();
543                             double XOffset = shapeBounds.getWidth() / 2;
544                             double YOffset = shapeBounds.getHeight() / 2;
545
546                             g2d.setStroke(this.lineChartProperties.getLineStrokes()[ labelIndex]);
547
548                             Line2D.Double JavaDoc line = new Line2D.Double JavaDoc(0, YOffset, this.legendProperties.getIconLineStrokeLength(), YOffset);
549                             g2d.draw( line );
550                             // move posX to account for the lineStroke before the shape. for example, ---o
551
posX += this.legendProperties.getIconLineStrokeLength();
552                             //---translate the Shape to adjust for the IconLineStrokeLength
553
g2d.translate( this.legendProperties.getIconLineStrokeLength() - XOffset , 0 );
554
555
556                             line.x1 = XOffset;
557                             g2d.draw( line );
558
559
560                             g2d.fill( (Shape JavaDoc) this.shapes.get( labelIndex ) );
561
562                             //---border around icon
563
if( this.legendProperties.getIconBorderStroke() != null && this.pointOutlinePaints.size() != 0 )
564                             {
565                                 if( this.pointOutlinePaints != null ) {
566                                     g2d.setStroke( this.legendProperties.getIconBorderStroke() );
567                                     g2d.setPaint( (Paint JavaDoc) this.pointOutlinePaints.get( labelIndex ) );
568                                     g2d.draw( (Shape JavaDoc) this.shapes.get( labelIndex ) );
569                                 }
570                             }
571
572
573                             // move posX to account for the lineStroke after the shape. for example, o---
574
posX += this.legendProperties.getIconLineStrokeLength();
575                         }
576                     }
577                     //---reset original transform
578
g2d.setTransform( affineTransform );
579                 }
580                 // for other charts, just draw a rectangle
581
else
582                 {
583                     g2d.fill( rectangle );
584
585                     //---border around icon
586
if( this.legendProperties.getIconBorderStroke() != null )
587                     {
588                         g2d.setStroke( this.legendProperties.getIconBorderStroke() );
589                         g2d.setPaint( this.legendProperties.getIconBorderPaint() );
590                         g2d.draw( rectangle );
591                     }
592                 }
593
594
595                 //---draw the label
596
g2d.setPaint( this.legendProperties.getChartFont().getPaint() );
597                 posX += iconAndPaddingWidth;
598                 g2d.drawString( (String JavaDoc) this.labels.get( labelIndex ), posX, fontY );
599
600
601                 if( this.legendProperties.getNumColumns() == LegendAreaProperties.COLUMNS_AS_MANY_AS_NEEDED
602                     || this.legendProperties.getNumColumns() >= this.labels.size() )
603                 {
604                     //---each column is as wide as it needs to be
605
posX += this.textProcessor.getTextTag( labelIndex ).getWidth() + this.legendProperties.getColumnPadding();
606                 }
607                 else
608                 {
609                     //---all columns have the same width
610
posX += this.widestLabelAndColumnPadding;
611                 }
612
613                 labelIndex++;
614
615                 //---if no more labels, we are done.
616
if( labelIndex == this.labels.size() ) break;
617             }
618
619             posX = this.x + this.legendProperties.getEdgePadding();
620             fontY += yIncrement;
621             rectangle.y += yIncrement;
622         }
623     }
624
625
626     /*********************************************************************************************
627      * Enables the testing routines to display the contents of this Object.
628      *
629      * @param htmlGenerator
630      **********************************************************************************************/

631     public void toHTML( HTMLGenerator htmlGenerator )
632     {
633         htmlGenerator.legendTableStart();
634
635         htmlGenerator.addTableRow( "Width", Float.toString( this.width ) );
636         htmlGenerator.addTableRow( "Height", Float.toString( this.height ) );
637         htmlGenerator.addTableRow( "Icon Side", Float.toString( this.iconSide ) );
638
639         htmlGenerator.innerTableRowStart();
640         this.legendProperties.toHTML( htmlGenerator );
641         htmlGenerator.innerTableRowEnd();
642
643         htmlGenerator.legendTableEnd();
644     }
645
646 }
647
Popular Tags