KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > net > sourceforge > chart2d > GraphArea


1 /**
2  * Chart2D, a java library for drawing two dimensional charts.
3  * Copyright (C) 2001 Jason J. Simas
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  * Lesser General Public License for more details.
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  *
18  * The author of this library may be contacted at:
19  * E-mail: jjsimas@users.sourceforge.net
20  * Street Address: J J Simas, 887 Tico Road, Ojai, CA 93023-3555 USA
21  */

22
23
24 package net.sourceforge.chart2d;
25
26
27 import java.awt.*;
28 import java.awt.geom.*;
29 import java.util.*;
30
31
32 /**
33  * A container for many variables and components relating to a graph area.
34  * A graph area is the area that both the y axis and x axis touch, and in which
35  * bars, lines, or dots are plotted to represent the data set.
36  */

37 class GraphArea extends Area {
38
39
40   /**
41    * Indicates the continuous.
42    */

43   static float[] CONTINUOUS = {10.0f, 0.0f};
44   /**
45    * Indicates the dashed.
46    */

47   static float[] DASHED = {7.0f, 3.0f};
48   /**
49    * Indicates the dotted.
50    */

51   static float[] DOTTED = {3.0f, 3.0f};
52   /**
53    * Indicates positive.
54    */

55   static int POS = 1;
56   /**
57    * Indicates both positive and negative.
58    */

59   static int MIX = 0;
60   /**
61    * Indicates negative.
62    */

63   static int NEG = -1;
64
65
66   static final int COMPONENT = 0;
67   static final int GRAPH = 1;
68
69
70   private int type;
71   private boolean allowComponentAlignment;
72
73   private Rectangle[] xTicks;
74   private Rectangle[] yTicks;
75   private int ticksAlignment;
76   private int[][] graphValues;
77   private int[][] barLowValues;
78
79   private boolean linesThicknessAssociation;
80   private boolean verticalLinesExistence;
81   private Line2D.Double[] verticalLines;
82   private int verticalLinesThicknessModel;
83   private int verticalLinesThickness;
84   private Color verticalLinesColor;
85   private float[] verticalLinesStyle;
86   private BasicStroke verticalLinesStroke;
87
88   private boolean horizontalLinesExistence;
89   private Line2D.Double[] horizontalLines;
90   private int horizontalLinesThicknessModel;
91   private int horizontalLinesThickness;
92   private Color horizontalLinesColor;
93   private float[] horizontalLinesStyle;
94   private BasicStroke horizontalLinesStroke;
95
96   private boolean barsExistence;
97   private int barsThicknessModel;
98   private Color[] barColors;
99   private float barsExcessSpaceFeedbackRatio;
100   private float barsWithinCategoryOverlapRatio;
101
102   private boolean dotsExistence;
103   private int dotsThicknessModel;
104   private Color[] dotColors;
105   private float dotsExcessSpaceFeedbackRatio;
106   private float dotsWithinCategoryOverlapRatio;
107
108   private boolean linesExistence;
109   private int linesThicknessModel;
110   private Color[] lineColors;
111   private boolean linesFillInterior;
112   private int linesFillInteriorBaseValue;
113   private float linesExcessSpaceFeedbackRatio;
114   private float linesWithinCategoryOverlapRatio;
115
116   private boolean outlineComponents;
117   private Color outlineComponentsColor;
118
119   private boolean betweenComponentsGapExistence;
120   private int betweenComponentsGapThicknessModel;
121
122   private float barRoundingRatio;
123   private int roundSide;
124   private int lightSource;
125   private int lightType;
126   private Vector warningRegions;
127   private boolean clip;
128   private boolean componentsColoringByCat;
129   private Color[] componentsColorsByCat;
130
131   private int dataSign;
132
133   private AlphaComposite componentsAlphaComposite;
134
135   private boolean needsUpdate;
136
137
138   /**
139    * Creates a graph area with the default values of the Area class
140    * (except where overridden here), and its own default values.
141    */

142   GraphArea() {
143
144     setType (LABELSBOTTOM);
145     setGraphValues (new int[0][0]);
146     setBarLowValues (new int[0][0]);
147     setAllowComponentAlignment (false);
148
149     setAutoSizes (false, false);
150     setAutoJustifys (false, false);
151     setBackgroundColor (Color.lightGray);
152     setBorderAssociations (false, false, true, true, false, false);
153     setBorderCornerAssociations (LEFT, LEFT, RIGHT, RIGHT);
154     setBorderColors (Color.black, Color.gray, Color.gray, Color.black);
155
156     setXTicks (new Rectangle[0]);
157     setYTicks (new Rectangle[0]);
158
159     setLinesThicknessAssociation (true);
160     setHorizontalLinesExistence (true);
161     setHorizontalLinesThicknessModel (2);
162     setHorizontalLinesStyle (CONTINUOUS);
163     setHorizontalLinesColor (Color.gray);
164     setVerticalLinesExistence (false);
165     setVerticalLinesThicknessModel (2);
166     setVerticalLinesStyle (CONTINUOUS);
167     setVerticalLinesColor (Color.gray);
168
169     setBarsExistence (true);
170     setBarsThicknessModel (10);
171     setBarColors (new Color[0]);
172     setBarsExcessSpaceFeedbackRatio (.75f);
173     setBarsWithinCategoryOverlapRatio (.5f);
174
175     setDotsExistence (false);
176     setDotsThicknessModel (8);
177     setDotColors (new Color[0]);
178     setDotsExcessSpaceFeedbackRatio (0f);
179     setDotsWithinCategoryOverlapRatio (.5f);
180
181     setLinesExistence (false);
182     setLinesThicknessModel (4);
183     setLineColors (new Color[0]);
184     setLinesFillInterior (false);
185     setLinesFillInteriorBaseValue (0);
186     setLinesExcessSpaceFeedbackRatio (0f);
187     setLinesWithinCategoryOverlapRatio (.5f);
188
189     setBetweenComponentsGapExistence (true);
190     setBetweenComponentsGapThicknessModel (2);
191     setLabelsAxisTicksAlignment (BETWEEN);
192
193     setGapExistence (false);
194     setOutlineComponents (true);
195     setOutlineComponentsColor (Color.black);
196
197     setBarRoundingRatio (.25f);
198     setComponentsLightSource (FancyShape.LEFT);
199     setComponentsLightType (COMPONENT);
200
201     setClip (true);
202     setComponentsColoringByCat (false);
203     setComponentsColorsByCat (new Color[0]);
204
205     resetGraphAreaModel (true);
206     needsUpdate = true;
207   }
208
209
210   /**
211    * Sets the actual AlphaComposite object to use on the Graphics2D object context for painting the
212    * graph components managed by this GraphProperties object. By passing different AlphaComposite
213    * objects, the graph components can take on a blending or transparency effect. Underneath
214    * components can be seen through components painted over them. This is especially useful for
215    * "line area" or "filled line" charts because top lines can paint over underneath lines if not
216    * using a "stacked" dataset object.
217    * @param a The AlphaComposite object to use.
218    */

219   public final void setComponentsAlphaComposite (AlphaComposite a) {
220
221     componentsAlphaComposite = a;
222     needsUpdate = true;
223   }
224
225
226   /**
227    * Gets the actual AlphaComposite object to use on the Graphics2D object context for painting the
228    * graph components managed by this GraphProperties object. By passing different AlphaComposite
229    * objects, the graph components can take on a blending or transparency effect. Underneath
230    * components can be seen through components painted over them. This is especially useful for
231    * "line area" or "filled line" charts because top lines can paint over underneath lines if not
232    * using a "stacked" dataset object.
233    * @return The AlphaComposite object to use.
234    */

235   public final AlphaComposite getComponentsAlphaComposite() {
236     return componentsAlphaComposite;
237   }
238
239
240   /**
241    * Sets which kinds of the data is graphed.
242    * Use POS for non-negative data.
243    * Use NEG for non-positive data.
244    * Use MIX for both positive and negative data.
245    * @param sign The sign of the data.
246    */

247   final void setDataSign (int sign) {
248
249     dataSign = sign;
250     needsUpdate = true;
251   }
252
253
254   /**
255    * Gets which kinds of the data is graphed.
256    * Use POS for non-negative data.
257    * Use NEG for non-positive data.
258    * Use MIX for both positive and negative data.
259    * @return The sign of the data.
260    */

261   final int getDataSign() {
262
263     return dataSign;
264   }
265
266
267   /**
268    * Sets whether the graph components are colored by category or by set.
269    * @param b If true, then colored by category.
270    */

271   final void setComponentsColoringByCat (boolean b) {
272     needsUpdate = true;
273     componentsColoringByCat = b;
274   }
275
276
277   /**
278    * Sets the color array for the category coloring.
279    * @param c The color array.
280    */

281   final void setComponentsColorsByCat (Color[] c) {
282     needsUpdate = true;
283     componentsColorsByCat = c;
284   }
285
286
287   /**
288    * Sets the whether the overpaint of the graph components are clipped or not.
289    * @param c If true then the components are clipped.
290    */

291   final void setClip (boolean c) {
292     needsUpdate = true;
293     clip = c;
294   }
295
296
297   /**
298    * Sets the warning regions vector for applying to the graph background and the graph components.
299    * @param v The warning regions vector.
300    */

301   final void setWarningRegions (Vector v) {
302     warningRegions = v;
303     needsUpdate = true;
304   }
305
306
307   /**
308    * Sets the ratio of the rounding arc to the thickness of the bar.
309    * Values need to be between zero and one. Zero is square. One is perfectly round.
310    * @param r The ratio.
311    */

312   final void setBarRoundingRatio (float r) {
313     barRoundingRatio = r;
314     needsUpdate = true;
315   }
316
317
318   /**
319    * Sets the side from which the lighting affect originates.
320    * all components for each set).
321    * For specifying the side, use the fields of FancyShape:
322    * TOP, BOTTOM, LEFT, RIGHT, TOPLEFT, BOTTOMRIGHT, and NONE.
323    * Added for Siperian.
324    * @param s The side.
325    */

326   final void setComponentsLightSource (int s) {
327     lightSource = s;
328     needsUpdate = true;
329   }
330
331
332   /**
333    * Sets the type of lighting affect.
334    * Type refers to whether the lighting should begin and end by component or by graph (meaning
335    * all components for each set).
336    * For specifying the type use the fields COMPONENT and GRAPH.
337    * Added for Siperian.
338    * @param t The type.
339    */

340   final void setComponentsLightType (int t) {
341     lightType = t;
342     needsUpdate = true;
343   }
344
345
346   /**
347    * Indicates whether bars, lines, and/or dots should have a thin black
348    * outline around them.
349    * @param outline If true, then there will be an outline.
350    */

351    final void setOutlineComponents (boolean outline) {
352
353     needsUpdate = true;
354     outlineComponents = outline;
355    }
356
357
358   /**
359    * Indicates the color of the components outline if it exists.
360    * @param color The color for the outline.
361    */

362    final void setOutlineComponentsColor (Color color) {
363
364     needsUpdate = true;
365     outlineComponentsColor = color;
366    }
367
368
369   /**
370    * Placement of the graph components (bars, dots, or line points) depends
371    * to some degree on placement of the ticks. (It shouldn't, but it does in
372    * order to have things lined up within 1 pixel error). Pass the alignment
373    * setting of the ticks of the axis that has the data description "labels".
374    * @param alignment A value of either Area.BETWEEN or Area.CENTERED
375    */

376    final void setLabelsAxisTicksAlignment (int alignment) {
377     needsUpdate = true;
378     ticksAlignment = alignment;
379    }
380
381
382   /**
383    * The type of the graph area. There exist two types of graph areas. One
384    * has the data descriptors on the bottom (i.e. vertical bar chart); the other
385    * has them on the left (i.e. horizontal bar chart).
386    * @param type The type of the graph area. [LABELSBOTTOM or LABELSLEFT]
387    */

388   final void setType (int type) {
389
390     needsUpdate = true;
391     this.type = type;
392   }
393
394
395   /**
396    * Specifies whether graph components, bars, lines, or dots are offset from
397    * eachother. Generally, var charts are not aligned, and line and dot charts
398    * are.
399    * @param allow If true, then aligns the components.
400    */

401   final void setAllowComponentAlignment (boolean allow) {
402
403     needsUpdate = true;
404     allowComponentAlignment = allow;
405   }
406
407
408   /**
409    * The heights/widths of the components. This is respective to the bottom of
410    * the graph area, but above the border/to the left of the graph area. This
411    * is an array of arrays of values. The first array contains data sets. The
412    * inner arrays contains the heights/widths for each set. Heights are used
413    * for when the type of graph area is LABELSBOTTOM. Otherwise, widths.
414    * @param values The offsets of the components from the data descriptor axis.
415    */

416   final void setGraphValues (int[][] values) {
417
418     needsUpdate = true;
419     graphValues = values;
420   }
421
422
423   /**
424    * Determines where bars of bar charts begin. Generally bars begin at zero,
425    * but with stackable charts, bars sometimes need to start at the tops of
426    * other bars. Also, bars can be used to signify uncertainty (i.e. 3+-2) can
427    * be signified by a bar that starts at 1 and goes to 5.
428    * @param values The low values normalized the graph area (i.e. not the actual
429    * data set values).
430    */

431    final void setBarLowValues (int[][] values) {
432
433     needsUpdate = true;
434     barLowValues = values;
435    }
436
437
438   /**
439    * Sets the ticks of the x axis. This is necessary in order to make sure the
440    * components area exactly where they should be, either between the ticks or
441    * aligned exactly respective to the middle of them.
442    * @param ticks The bounds of the ticks, location and size.
443    */

444   final void setXTicks (Rectangle[] ticks) {
445
446     needsUpdate = true;
447     this.xTicks = ticks;
448   }
449
450
451   /**
452    * Sets the ticks of the x axis. This is necessary in order to make sure the
453    * components area exactly where they should be, either between the ticks or
454    * aligned exactly respective to the middle of them.
455    * @param ticks The bounds of the ticks, location and size.
456    */

457   final void setYTicks (Rectangle[] ticks) {
458
459     needsUpdate = true;
460     this.yTicks = ticks;
461   }
462
463
464   /**
465    * Specifies whether the vertical and/or horizontal lines should maintain
466    * the same size. The vertical/horizontal lines are do not represent the
467    * data sets. These lines are either perfectly horizontal or perfectly
468    * vertical and mark out the graph area.
469    * @param association If true, then the lines thicknesses will be equal.
470    */

471   final void setLinesThicknessAssociation (boolean association) {
472
473     needsUpdate = true;
474     linesThicknessAssociation = association;
475   }
476
477
478   /**
479    * Whether the horizontal lines exist.
480    * @param existence If true, then they do.
481    */

482   final void setHorizontalLinesExistence (boolean existence) {
483
484     needsUpdate = true;
485     horizontalLinesExistence = existence;
486   }
487
488
489   /**
490    * The model thickness for the horizontal lines. If auto maximum sizing
491    * is enabled,
492    * then the actual thickness size can grow and shrink; in this case a ratio
493    * based
494    * on the maximum area size / model area size is computed and applied to the
495    * model thickness in order to find the actual thickness. With maximum sizing
496    * disabled, the actual thickness is the model thickness.
497    * @param thickness The model thickness for the horizontal lines.
498    */

499   final void setHorizontalLinesThicknessModel (int thickness) {
500
501     needsUpdate = true;
502     horizontalLinesThicknessModel = thickness;
503   }
504
505
506   /**
507    * The style of the horizontal lines. Lines may be continuous, dashed and
508    * dotted. Or something other. See BasicStroke for more information.
509    * @param style The style of the lines [CONTINOUS, DASHED, DOTTED]
510    */

511   final void setHorizontalLinesStyle (float[] style) {
512
513     needsUpdate = true;
514     horizontalLinesStyle = style;
515   }
516
517
518   /**
519    * The color of the horizontal lines.
520    * @param color Some Color.
521    */

522   final void setHorizontalLinesColor (Color color) {
523
524     needsUpdate = true;
525     horizontalLinesColor = color;
526   }
527
528
529   /**
530    * Whether the vertical lines exist.
531    * @param existence If true, then they do.
532    */

533   final void setVerticalLinesExistence (boolean existence) {
534
535     needsUpdate = true;
536     verticalLinesExistence = existence;
537   }
538
539
540   /**
541    * The model thickness for the vertical lines. If auto maximum sizing
542    * is enabled,
543    * then the actual thickness size can grow and shrink; in this case a ratio
544    * based
545    * on the maximum area size / model area size is computed and applied to the
546    * model thickness in order to find the actual thickness. With maximum sizing
547    * disabled, the actual thickness is the model thickness.
548    * @param thickness The model thickness for the vertical lines.
549    */

550   final void setVerticalLinesThicknessModel (int thickness) {
551
552     needsUpdate = true;
553     verticalLinesThicknessModel = thickness;
554   }
555
556
557   /**
558    * The style of the vertical lines. Lines may be continuous, dashed and
559    * dotted. Or something other. See BasicStroke for more information.
560    * @param style The style of the lines [CONTINOUS, DASHED, DOTTED]
561    */

562   final void setVerticalLinesStyle (float[] style) {
563
564     needsUpdate = true;
565     verticalLinesStyle = style;
566   }
567
568
569   /**
570    * The color of the vertical lines.
571    * @param color Some Color.
572    */

573   final void setVerticalLinesColor (Color color) {
574
575     needsUpdate = true;
576     verticalLinesColor = color;
577   }
578
579
580   /**
581    * Whether to paint bars representing the graph values. If they do not exist
582    * then they will not be included in calculations or in painting.
583    * @param existence If true, then they exist.
584    */

585   final void setBarsExistence (boolean existence) {
586
587     needsUpdate = true;
588     barsExistence = existence;
589   }
590
591
592   /**
593    * The model thickness for the bars. If auto maximum sizing
594    * is enabled,
595    * then the actual thickness size can grow and shrink; in this case a ratio
596    * based
597    * on the maximum area size / model area size is computed and applied to the
598    * model thickness in order to find the actual thickness. With maximum sizing
599    * disabled, the actual thickness is the model thickness.
600    * @param thickness The model thickness for the bars.
601    */

602   final void setBarsThicknessModel (int thickness) {
603
604     needsUpdate = true;
605     barsThicknessModel = thickness;
606   }
607
608
609   /**
610    * The colors of the bar sets. Each data set has its own color. In every
611    * set of bars, the left most bar (or first bar painted when components are
612    * aligned) will be the color in the lowest order array position.
613    * @param colors The colors for the data sets.
614    */

615   final void setBarColors (Color[] colors) {
616
617     needsUpdate = true;
618     barColors = colors;
619   }
620
621
622   /**
623    * Specifies the amount of the excess space to feed back to bars thickness.
624    * Frequently the graphs are larger than necessary, the excess space can
625    * be fedback to the bars, making them larger. The ratio is the amount of
626    * space to feed back to the bars, to the total amount of space.
627    * @param ratio The ratio on the total amount of space to feedback.
628    */

629   final void setBarsExcessSpaceFeedbackRatio (float ratio) {
630
631     needsUpdate = true;
632     barsExcessSpaceFeedbackRatio = ratio;
633   }
634
635
636   /**
637    * Specifies how much the bars can overlap eachother when there are multiple
638    * data values per data set and per data category.
639    * @param ratio The ratio on the thickness of the bar for overlap.
640    */

641    final void setBarsWithinCategoryOverlapRatio (float ratio) {
642     needsUpdate = true;
643     barsWithinCategoryOverlapRatio = ratio;
644   }
645
646
647   /**
648    * Whether to paint dots representing the graph values. If they do not exist
649    * then they will not be included in calculations or in painting.
650    * @param existence If true, then they exist.
651    */

652   final void setDotsExistence (boolean existence) {
653
654     needsUpdate = true;
655     dotsExistence = existence;
656   }
657
658
659   /**
660    * The model thickness for the dots. If auto maximum sizing
661    * is enabled,
662    * then the actual thickness size can grow and shrink; in this case a ratio
663    * based
664    * on the maximum area size / model area size is computed and applied to the
665    * model thickness in order to find the actual thickness. With maximum sizing
666    * disabled, the actual thickness is the model thickness.
667    * @param thickness The model thickness for the dots.
668    */

669   final void setDotsThicknessModel (int thickness) {
670
671     needsUpdate = true;
672     dotsThicknessModel = thickness;
673   }
674
675
676   /**
677    * Specifies how much the dots can overlap eachother when there are multiple
678    * data values per data set and per data category.
679    * @param ratio The ratio on the thickness of the dot for overlap.
680    */

681    final void setDotsWithinCategoryOverlapRatio (float ratio) {
682     needsUpdate = true;
683     dotsWithinCategoryOverlapRatio = ratio;
684   }
685
686
687   /**
688    * The colors of the dot sets. Each data set has its own color. In every
689    * set of dots, the left most dot (or first dot painted when components are
690    * aligned) will be the color in the lowest order array position.
691    * @param colors The colors for the data sets.
692    */

693   final void setDotColors (Color[] colors) {
694
695     needsUpdate = true;
696     dotColors = colors;
697   }
698
699
700   /**
701    * Specifies the amount of the excess space to feed back to dots thickness.
702    * Frequently the graphs are larger than necessary, the excess space can
703    * be fedback to the dots, making them larger. The ratio is the amount of
704    * space to feed back to the dots, to the total amount of space.
705    * @param ratio The ratio on the total amount of space to feedback.
706    */

707   final void setDotsExcessSpaceFeedbackRatio (float ratio) {
708
709     needsUpdate = true;
710     dotsExcessSpaceFeedbackRatio = ratio;
711   }
712
713
714   /**
715    * Whether to paint lines representing the graph values. If they do not exist
716    * then they will not be included in calculations or in painting.
717    * @param existence If true, then they exist.
718    */

719   final void setLinesExistence (boolean existence) {
720
721     needsUpdate = true;
722     linesExistence = existence;
723   }
724
725
726   /**
727    * The model thickness for the lines. If auto maximum sizing
728    * is enabled,
729    * then the actual thickness size can grow and shrink; in this case a ratio
730    * based
731    * on the maximum area size / model area size is computed and applied to the
732    * model thickness in order to find the actual thickness. With maximum sizing
733    * disabled, the actual thickness is the model thickness.
734    * @param thickness The model thickness for the lines.
735    */

736   final void setLinesThicknessModel (int thickness) {
737
738     needsUpdate = true;
739     linesThicknessModel = thickness;
740   }
741
742
743   /**
744    * Indicates whether the region between the lines and between its baseline
745    * should be filled in.
746    * @param fill If true, then the region under/above the lines will be filled.
747    */

748   final void setLinesFillInterior (boolean fill) {
749
750     needsUpdate = true;
751     linesFillInterior = fill;
752   }
753
754
755   /**
756    * Indicates the length across the graph length, in the same direction of the
757    * meaning of the graph values, that the forms the base for the filled region.
758    * @param int The base value for the region.
759    */

760   final void setLinesFillInteriorBaseValue (int value) {
761
762     needsUpdate = true;
763     linesFillInteriorBaseValue = value;
764   }
765
766
767   /**
768    * The colors of the line sets. Each data set has its own color. In every
769    * set of lines, the left most line (or first line painted when components are
770    * aligned) will be the color in the lowest order array position.
771    * @param colors The colors for the data sets.
772    */

773   final void setLineColors (Color[] colors) {
774
775     needsUpdate = true;
776     lineColors = colors;
777   }
778
779
780   /**
781    * Specifies the amount of the excess space to feed back to lines thickness.
782    * Frequently the graphs are larger than necessary, the excess space can
783    * be fedback to the lines, making them larger. The ratio is the amount of
784    * space to feed back to the lines, to the total amount of space.
785    * @param ratio The ratio on the total amount of space to feedback.
786    */

787   final void setLinesExcessSpaceFeedbackRatio (float ratio) {
788
789     needsUpdate = true;
790     linesExcessSpaceFeedbackRatio = ratio;
791   }
792
793
794   /**
795    * Specifies how much the lines can overlap eachother when there are multiple
796    * data values per data set and per data category.
797    * @param ratio The ratio on the thickness of the line for overlap.
798    */

799    final void setLinesWithinCategoryOverlapRatio (float ratio) {
800     needsUpdate = true;
801     linesWithinCategoryOverlapRatio = ratio;
802   }
803
804
805   /**
806    * Whether there exists a gap between plotted data sets. For instance, after
807    * plotting a single bar from each data set, the gap between these and the
808    * next bars from the next location within the data sets.
809    * @param existence If true, then it does.
810    */

811   final void setBetweenComponentsGapExistence (boolean existence) {
812
813     needsUpdate = true;
814     betweenComponentsGapExistence = existence;
815   }
816
817
818   /**
819    * The model thickness for the gap. If auto maximum sizing
820    * is enabled,
821    * then the actual thickness size can grow and shrink; in this case a ratio
822    * based
823    * on the maximum area size / model area size is computed and applied to the
824    * model thickness in order to find the actual thickness. With maximum sizing
825    * disabled, the actual thickness is the model thickness.
826    * @param thickness The model thickness for the gap.
827    */

828   final void setBetweenComponentsGapThicknessModel (int thickness) {
829
830     needsUpdate = true;
831     betweenComponentsGapThicknessModel = thickness;
832   }
833
834
835   /**
836    * Gets the ratio of the rounding arc to the thickness of the bar.
837    * Values need to be between zero and one. Zero is square. One is perfectly round.
838    * @return The ratio.
839    */

840   final float getBarRoundingRatio() {
841     return barRoundingRatio;
842   }
843
844
845   /**
846    * Gets the side from which the lighting affect originates.
847    * Use the fields of FancyShape: TOP, BOTTOM, LEFT, RIGHT, TOPLEFT, BOTTOMRIGHT, and NONE.
848    * Added for Siperian.
849    * @return int The side.
850    */

851   final int getComponentsLightSource() {
852     return lightSource;
853   }
854
855
856   /**
857    * Gets the type of lighting affect.
858    * Type refers to whether the lighting should begin and end by component or by graph (meaning
859    * all components for each set).
860    * For specifying the type use the fields COMPONENT and GRAPH.
861    * Added for Siperian.
862    * @return int The type.
863    */

864   final int getComponentsLightType() {
865     return lightType;
866   }
867
868
869   /**
870    * Gets the warning regions vector for applying to the graph background and the graph components.
871    * @return The warning regions vector.
872    */

873   final Vector getWarningRegions() {
874     return warningRegions;
875   }
876
877
878   /**
879    * Gets the whether the overpaint of the graph components are clipped or not.
880    * @return If true then the components are clipped.
881    */

882   final boolean getClip() {
883     return clip;
884   }
885
886
887   /**
888    * Gets the color array for the category coloring.
889    * @return The color array.
890    */

891   final Color[] getComponentsColorsByCat() {
892     return componentsColorsByCat;
893   }
894
895
896   /**
897    * Gets whether the graph components are colored by category or by set.
898    * @return If true, then colored by category.
899    */

900   final boolean getComponentsColoringByCat() {
901     return componentsColoringByCat;
902   }
903
904
905   /**
906    * Returns whether bars, lines, and/or dots should have a thin black
907    * outline around them.
908    * @return boolean If true, then outline.
909    */

910    final boolean getOutlineComponents() {
911
912     return outlineComponents;
913    }
914
915
916   /**
917    * Returns the color of the components outline if it exists.
918    * @return Color The color of the outline.
919    */

920    final Color getOutlineComponentsColor() {
921
922     return outlineComponentsColor;
923    }
924
925
926   /**
927    * Returns the type of graph.
928    * @return The type of graph. [LABELSBOTTOM or LABELSLEFT]
929    */

930   final int getType() {
931
932     return type;
933   }
934
935
936   /**
937    * Returns whether the bars, lines or dots are aligned.
938    * @return If true, then they are.
939    */

940   final boolean getAllowComponentAlignment() {
941
942     return allowComponentAlignment;
943   }
944
945
946   /**
947    * Returns the graph values for the bars, dots, and lines.
948    * @return The graph values, heights or widths respective to the bottom or
949    * side of the graph area.
950    */

951   final int[][] getGraphValues() {
952
953     return graphValues;
954   }
955
956
957   /**
958    * Returns the low graph values for bars.
959    * @return int[][] The low values.
960    */

961    final int[][] getBarLowValues() {
962
963     return barLowValues;
964    }
965
966
967   /**
968    * Returns the ticks of the x axis. Actually these mereley are the bounds of
969    * the ticks, locations and sizes.
970    * @return Bounds for the x axis ticks.
971    */

972   final Rectangle[] getXTicks() {
973
974     return xTicks;
975   }
976
977
978   /**
979    * Returns the ticks of the y axis. Actually these mereley are the bounds of
980    * the ticks, locations and sizes.
981    * @return Bounds for the y axis ticks.
982    */

983   final Rectangle[] getYTicks() {
984
985     return yTicks;
986   }
987
988
989   /**
990    * Indicates whether the ticks are aligned between each pair of labels or in
991    * the center of the each label of the labels axis.
992    * @return int With the value of either Area.CENTERED or Area.BETWEEN
993    */

994    final int getLabelsAxisTicksAlignment() {
995
996     return ticksAlignment;
997    }
998
999
1000  /**
1001   * Returns this property.
1002   * @return If true, then they do.
1003   */

1004  final boolean getBarsExistence() {
1005
1006    return barsExistence;
1007  }
1008
1009
1010  /**
1011   * Returns this property.
1012   * @return The model thickness of the bars.
1013   */

1014  final int getBarsThicknessModel() {
1015
1016    return barsThicknessModel;
1017  }
1018
1019
1020  /**
1021   * Returns this property.
1022   * @return The colors of the bars.
1023   */

1024  final Color[] getBarColors() {
1025
1026    return barColors;
1027  }
1028
1029
1030  /**
1031   * Returns the amount of the excess space to feed back to bars thickness.
1032   * @return float The ratio on the total amount of space to feedback.
1033   */

1034  final float getBarsExcessSpaceFeedbackRatio() {
1035    return barsExcessSpaceFeedbackRatio;
1036  }
1037
1038
1039  /**
1040   * Returns how much the bars can overlap eachother when there are multiple
1041   * data values per data set and per data category.
1042   * @return float The ratio on the thickness of the bar for overlap.
1043   */

1044   final float getBarsWithinCategoryOverlapRatio() {
1045    return barsWithinCategoryOverlapRatio;
1046  }
1047
1048
1049  /**
1050   * Returns this property.
1051   * @return If true, then they do.
1052   */

1053  final boolean getDotsExistence() {
1054
1055    return dotsExistence;
1056  }
1057
1058
1059  /**
1060   * Returns this property.
1061   * @return The model thickness of the dots.
1062   */

1063  final int getDotsThicknessModel() {
1064
1065    return dotsThicknessModel;
1066  }
1067
1068
1069  /**
1070   * Returns this property.
1071   * @return The colors of the dots.
1072   */

1073  final Color[] getDotColors() {
1074
1075    return dotColors;
1076  }
1077
1078
1079  /**
1080   * Returns the amount of the excess space to feed back to dots thickness.
1081   * @return float The ratio on the total amount of space to feedback.
1082   */

1083  final float getDotsExcessSpaceFeedbackRatio() {
1084    return dotsExcessSpaceFeedbackRatio;
1085  }
1086
1087
1088  /**
1089   * Returns how much the dots can overlap eachother when there are multiple
1090   * data values per data set and per data category.
1091   * @return float The ratio on the thickness of the dot for overlap.
1092   */

1093   final float getDotsWithinCategoryOverlapRatio() {
1094    return dotsWithinCategoryOverlapRatio;
1095  }
1096
1097
1098  /**
1099   * Returns this property.
1100   * @return If true, then they do.
1101   */

1102  final boolean getLinesExistence() {
1103
1104    return linesExistence;
1105  }
1106
1107
1108  /**
1109   * Returns this property.
1110   * @return The model thickness of the lines.
1111   */

1112  final int getLinesThicknessModel() {
1113
1114    return linesThicknessModel;
1115  }
1116
1117
1118  /**
1119   * Returns whether the region between the lines and between its baseline
1120   * should be filled in.
1121   * @return boolean If true, then the region under/above the lines will be
1122   * filled.
1123   */

1124  final boolean getLinesFillInterior() {
1125
1126    return linesFillInterior;
1127  }
1128
1129
1130  /**
1131   * Returns the length across the graph length, in the same direction of the
1132   * meaning of the graph values, that the forms the base for the filled region.
1133   * @return The base value for the region.
1134   */

1135  final int getLinesFillInteriorBaseValue() {
1136
1137    return linesFillInteriorBaseValue;
1138  }
1139
1140
1141  /**
1142   * Returns this property.
1143   * @return The colors of the lines.
1144   */

1145  final Color[] getLineColors() {
1146
1147    return lineColors;
1148  }
1149
1150
1151  /**
1152   * Returns the amount of the excess space to feed back to lines thickness.
1153   * @return float The ratio on the total amount of space to feedback.
1154   */

1155  final float getLinesExcessSpaceFeedbackRatio() {
1156    return linesExcessSpaceFeedbackRatio;
1157  }
1158
1159
1160  /**
1161   * Returns how much the lines can overlap eachother when there are multiple
1162   * data values per data set and per data category.
1163   * @return float The ratio on the thickness of the line for overlap.
1164   */

1165   final float getLinesWithinCategoryOverlapRatio() {
1166    return linesWithinCategoryOverlapRatio;
1167  }
1168
1169
1170  /**
1171   * Returns this property.
1172   * @return If true, then it does.
1173   */

1174  final boolean getBetweenComponentsGapExistence() {
1175
1176    return betweenComponentsGapExistence;
1177  }
1178
1179
1180  /**
1181   * Returns this property.
1182   * @return The model thickness of this gap.
1183   */

1184  final int getBetweenComponentsGapThicknessModel() {
1185
1186    return betweenComponentsGapThicknessModel;
1187  }
1188
1189
1190  /**
1191   * Returns a value indicating existence of vertical lines on the graph.
1192   * @return True if vertical lines exist.
1193   */

1194  final boolean getVerticalLinesExistence() {
1195
1196    return verticalLinesExistence;
1197  }
1198
1199
1200  /**
1201   * Returns a value of the vertical lines model thickness.
1202   * @return The model thickness of this vertical lines.
1203   */

1204  final int getVerticalLinesThicknessModel() {
1205
1206    return verticalLinesThicknessModel;
1207  }
1208
1209
1210  /**
1211   * Returns a value of the vertical lines thickness.
1212   * @return The thickness of this vertical lines.
1213   */

1214  final int getVerticalLinesThickness() {
1215
1216    updateGraphArea();
1217    return verticalLinesThickness;
1218  }
1219
1220
1221  /**
1222   * Returns a value of the color of the vertical lines.
1223   * @return The color of the vertical lines.
1224   */

1225  final Color getVerticalLinesColor() {
1226
1227    return verticalLinesColor;
1228  }
1229
1230
1231  /**
1232   * Returns a value of the style of the vertical lines.
1233   * Possible values are CONTINUOUS, DASHED, and DOTTED.
1234   * @return The style of the vertical lines.
1235   */

1236  final float[] getVerticalLinesStyle() {
1237
1238    return verticalLinesStyle;
1239  }
1240
1241
1242  /**
1243   * Returns a value indicating existence of horizontal lines on the graph.
1244   * @return True if horizontal lines exist.
1245   */

1246  final boolean getHorizontalLinesExistence() {
1247
1248    return horizontalLinesExistence;
1249  }
1250
1251
1252  /**
1253   * Returns a value of the horizontal lines model thickness.
1254   * @return The model thickness of this horizontal lines.
1255   */

1256  final int getHorizontalLinesThicknessModel() {
1257
1258    return horizontalLinesThicknessModel;
1259  }
1260
1261
1262  /**
1263   * Returns a value of the horizontal lines thickness.
1264   * @return The thickness of this horizontal lines.
1265   */

1266  final int getHorizontalLinesThickness() {
1267
1268    updateGraphArea();
1269    return horizontalLinesThickness;
1270  }
1271
1272
1273  /**
1274   * Returns a value of the color of the horizontal lines.
1275   * @return The color of the horizontal lines.
1276   */

1277  final Color getHorizontalLinesColor() {
1278
1279    return horizontalLinesColor;
1280  }
1281
1282
1283  /**
1284   * Returns a value of the style of the horizontal lines.
1285   * Possible values are CONTINUOUS, DASHED, and DOTTED.
1286   * @return The style of the horizontal lines.
1287   */

1288  final float[] getHorizontalLinesStyle() {
1289
1290    return horizontalLinesStyle;
1291  }
1292
1293
1294  /**
1295   * Returns an array of the indexes, that is a sorted view of the array
1296   * graphValues[i][barIndex] i ranges from 0 to graphValues.length and
1297   * where barIndex is constant. This is used for creating stacked bar charts
1298   * where the tallest bars must be graphed first.
1299   * @param graphValues An int[][] of heights of bars...
1300   * @param barIndex The grouping of bars to work on/sort.
1301   */

1302  int[] stackedBarSort (int[][] graphValues, int barIndex) {
1303
1304    boolean[] used = new boolean[graphValues.length];
1305    for (int i = 0; i < graphValues.length; ++i) {
1306      used[i] = false;
1307    }
1308
1309    int[] sorted = new int[graphValues.length];
1310    for (int doing = 0; doing < graphValues.length; ++doing) {
1311
1312      int lowestValue = Integer.MIN_VALUE;
1313      int lowestIndex = -1;
1314      for (int i = graphValues.length - 1; i >= 0 ; --i) {
1315        if (!used[i] && (graphValues[i][barIndex] > lowestValue)) {
1316          lowestIndex = i;
1317          lowestValue = graphValues[i][barIndex];
1318        }
1319      }
1320      sorted[doing] = lowestIndex;
1321      used[lowestIndex] = true;
1322    }
1323    return sorted;
1324  }
1325
1326
1327  /**
1328   * Converts an array of graph values -- values indicating how far across
1329   * a graph a bar should go into an array that the method sortStackedBar can
1330   * use. For graphs that plot negative values, the graph values that indicate
1331   * negative bars, must be converted to be negative values so that they
1332   * can be sorted properly in an array with values of positive bars.
1333   */

1334  int[][] stackedBarConvert (int[][] graphValues, int[][] lowBarValues) {
1335
1336    int[][] convertedValues =
1337      new int[graphValues.length][graphValues[0].length];
1338    for (int i = 0; i < graphValues.length; ++i) {
1339      for (int j = 0; j < graphValues[0].length; ++j) {
1340        convertedValues[i][j] = graphValues[i][j] < lowBarValues[i][j] ?
1341          -graphValues[i][j] :graphValues[i][j];
1342      }
1343    }
1344    return convertedValues;
1345  }
1346
1347
1348  /**
1349   * Resets the model for this class. The model is used for shrinking and
1350   * growing of its components based on the maximum size of this class. If this
1351   * method is called, then the next time the maximum size is set, this classes
1352   * model maximum size will be made equal to the new maximum size. Effectively
1353   * what this does is ensure that whenever this objects maximum size is equal
1354   * to the one given, then all of the components will take on their default
1355   * model sizes. Note: This is only useful when auto model max sizing is
1356   * disabled.
1357   * @param reset True causes the max model size to be set upon the next max
1358   * sizing.
1359   */

1360  final void resetGraphAreaModel (boolean reset) {
1361
1362    needsUpdate = true;
1363    resetAreaModel (reset);
1364  }
1365
1366
1367  /**
1368   * Indicates whether some property of this class has changed.
1369   * @return True if some property has changed.
1370   */

1371  final boolean getGraphAreaNeedsUpdate() {
1372    return (needsUpdate || getAreaNeedsUpdate());
1373  }
1374
1375
1376  /**
1377   * Updates this parent's variables, and this' variables.
1378   * @param g2D The graphics context to use for calculations.
1379   */

1380  final void updateGraphArea() {
1381
1382    if (getGraphAreaNeedsUpdate()) {
1383
1384      updateArea();
1385      update();
1386    }
1387    needsUpdate = false;
1388  }
1389
1390
1391  /**
1392   * Paints all the components of this class. First all variables are updated.
1393   * @param g2D The graphics context for calculations and painting.
1394   */

1395  void paintComponent (Graphics2D g2D) {
1396
1397    updateGraphArea();
1398    super.paintComponent (g2D);
1399
1400    Color oldColor = g2D.getColor();
1401    Stroke oldStroke = g2D.getStroke();
1402
1403    if (horizontalLinesThickness > 0 && horizontalLinesExistence && horizontalLines.length > 0) {
1404      g2D.setColor (horizontalLinesColor);
1405      g2D.setStroke (horizontalLinesStroke);
1406      for (int i = 0; i < horizontalLines.length; ++i) g2D.draw (horizontalLines[i]);
1407    }
1408
1409    if (verticalLinesThickness > 0 && verticalLinesExistence && verticalLines.length > 0) {
1410      g2D.setColor (verticalLinesColor);
1411      g2D.setStroke (verticalLinesStroke);
1412      for (int i = 0; i < verticalLines.length; ++i) g2D.draw (verticalLines[i]);
1413    }
1414
1415    g2D.setColor (oldColor);
1416    g2D.setStroke (oldStroke);
1417  }
1418
1419
1420  private void update() {
1421
1422    horizontalLinesThickness = 0;
1423    int numHorizontalLines = type == LABELSBOTTOM ?
1424      yTicks.length - 2 : yTicks.length;
1425    int availableHeight = getSpaceSize (MIN).height;
1426    if (horizontalLinesExistence && numHorizontalLines > 0) {
1427      horizontalLinesThickness =
1428        applyRatio (horizontalLinesThicknessModel, getRatio (HEIGHT));
1429      horizontalLinesThickness =
1430        numHorizontalLines * horizontalLinesThickness <= availableHeight ?
1431        horizontalLinesThickness : availableHeight / numHorizontalLines;
1432    }
1433    else numHorizontalLines = 0;
1434
1435    verticalLinesThickness = 0;
1436    int numVerticalLines = type == LABELSBOTTOM ?
1437      xTicks.length : xTicks.length - 2;
1438    int availableWidth = getSpaceSize (MIN).width;
1439    if (verticalLinesExistence && numVerticalLines > 0) {
1440      verticalLinesThickness =
1441        applyRatio (verticalLinesThicknessModel, getRatio (WIDTH));
1442      verticalLinesThickness =
1443        numVerticalLines * verticalLinesThickness <= availableWidth ?
1444        verticalLinesThickness : availableWidth / numVerticalLines;
1445    }
1446    else numVerticalLines = 0;
1447
1448    if (linesThicknessAssociation) {
1449      verticalLinesThickness =
1450        horizontalLinesThickness < verticalLinesThickness &&
1451        horizontalLinesExistence ?
1452        horizontalLinesThickness : verticalLinesThickness;
1453      horizontalLinesThickness =
1454        verticalLinesThickness < horizontalLinesThickness &&
1455        verticalLinesExistence ?
1456        verticalLinesThickness : horizontalLinesThickness;
1457    }
1458
1459    horizontalLinesStroke =
1460      new BasicStroke ((float)horizontalLinesThickness,
1461        BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 10.0f,
1462        horizontalLinesStyle, 0.0f);
1463    verticalLinesStroke =
1464      new BasicStroke ((float)verticalLinesThickness,
1465        BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 10.0f,
1466        verticalLinesStyle, 0.0f);
1467
1468    int x1,x2,y1,y2;
1469
1470    horizontalLines = new Line2D.Double[numHorizontalLines];
1471    int horizontalLinesOffset = 0;
1472    if (horizontalLinesExistence && yTicks.length > 0) {
1473      horizontalLinesOffset = +yTicks[0].height / 2;
1474    }
1475    x1 = getSpaceSizeLocation (MIN).x;
1476    x2 = x1 + getSpaceSize (MIN).width;
1477    int offsetI = type == LABELSBOTTOM ? 1 : 0;
1478    for (int i = 0; i < numHorizontalLines; ++i) {
1479      y1 = yTicks[i + offsetI].y + horizontalLinesOffset;
1480      y2 = y1;
1481      horizontalLines[i] =
1482        new Line2D.Double ((double)x1, (double)y1, (double)x2, (double)y2);
1483    }
1484
1485    verticalLines = new Line2D.Double[numVerticalLines];
1486    int verticalLinesOffset = 0;
1487    if (verticalLinesExistence && xTicks.length > 0) {
1488      verticalLinesOffset = xTicks[0].width / 2;
1489    }
1490
1491    y1 = getSpaceSizeLocation (MIN).y;
1492    y2 = y1 + getSpaceSize (MIN).height;
1493    offsetI = type == LABELSBOTTOM ? 0 : 1;
1494    for (int i = 0; i < numVerticalLines; ++i) {
1495      x1 = xTicks[i + offsetI].x + verticalLinesOffset;
1496      x2 = x1;
1497      verticalLines[i] = new Line2D.Double ((double)x1, (double)y1, (double)x2, (double)y2);
1498    }
1499  }
1500}
Popular Tags