KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jfree > chart > renderer > category > GanttRenderer


1 /* ===========================================================
2  * JFreeChart : a free chart library for the Java(tm) platform
3  * ===========================================================
4  *
5  * (C) Copyright 2000-2006, by Object Refinery Limited and Contributors.
6  *
7  * Project Info: http://www.jfree.org/jfreechart/index.html
8  *
9  * This library is free software; you can redistribute it and/or modify it
10  * under the terms of the GNU Lesser General Public License as published by
11  * the Free Software Foundation; either version 2.1 of the License, or
12  * (at your option) any later version.
13  *
14  * This library is distributed in the hope that it will be useful, but
15  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16  * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
17  * License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with this library; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
22  * USA.
23  *
24  * [Java is a trademark or registered trademark of Sun Microsystems, Inc.
25  * in the United States and other countries.]
26  *
27  * ------------------
28  * GanttRenderer.java
29  * ------------------
30  * (C) Copyright 2003-2006, by Object Refinery Limited.
31  *
32  * Original Author: David Gilbert (for Object Refinery Limited);
33  * Contributor(s): -;
34  *
35  * $Id: GanttRenderer.java,v 1.6.2.4 2006/01/18 14:22:51 mungady Exp $
36  *
37  * Changes
38  * -------
39  * 16-Sep-2003 : Version 1 (DG);
40  * 23-Sep-2003 : Fixed Checkstyle issues (DG);
41  * 21-Oct-2003 : Bar width moved into CategoryItemRendererState (DG);
42  * 03-Feb-2004 : Added get/set methods for attributes (DG);
43  * 12-Aug-2004 : Fixed rendering problem with maxBarWidth attribute (DG);
44  * 05-Nov-2004 : Modified drawItem() signature (DG);
45  * 20-Apr-2005 : Renamed CategoryLabelGenerator
46  * --> CategoryItemLabelGenerator (DG);
47  * 01-Dec-2005 : Fix for bug 1369954, drawBarOutline flag ignored (DG);
48  * 17-Jan-2006 : Set includeBaseInRange flag to false (DG);
49  *
50  */

51
52 package org.jfree.chart.renderer.category;
53
54 import java.awt.Color JavaDoc;
55 import java.awt.Graphics2D JavaDoc;
56 import java.awt.Paint JavaDoc;
57 import java.awt.Stroke JavaDoc;
58 import java.awt.geom.Rectangle2D JavaDoc;
59 import java.io.Serializable JavaDoc;
60
61 import org.jfree.chart.axis.CategoryAxis;
62 import org.jfree.chart.axis.ValueAxis;
63 import org.jfree.chart.entity.CategoryItemEntity;
64 import org.jfree.chart.entity.EntityCollection;
65 import org.jfree.chart.event.RendererChangeEvent;
66 import org.jfree.chart.labels.CategoryItemLabelGenerator;
67 import org.jfree.chart.labels.CategoryToolTipGenerator;
68 import org.jfree.chart.plot.CategoryPlot;
69 import org.jfree.chart.plot.PlotOrientation;
70 import org.jfree.data.category.CategoryDataset;
71 import org.jfree.data.gantt.GanttCategoryDataset;
72 import org.jfree.ui.RectangleEdge;
73
74 /**
75  * A renderer for simple Gantt charts.
76  */

77 public class GanttRenderer extends IntervalBarRenderer
78                            implements Serializable JavaDoc {
79     
80     /** For serialization. */
81     private static final long serialVersionUID = -4010349116350119512L;
82     
83     /** The paint for displaying the percentage complete. */
84     private Paint JavaDoc completePaint;
85     
86     /** The paint for displaying the incomplete part of a task. */
87     private Paint JavaDoc incompletePaint;
88     
89     /**
90      * Controls the starting edge of the progress indicator (expressed as a
91      * percentage of the overall bar width).
92      */

93     private double startPercent;
94     
95     /**
96      * Controls the ending edge of the progress indicator (expressed as a
97      * percentage of the overall bar width).
98      */

99     private double endPercent;
100     
101     /**
102      * Creates a new renderer.
103      */

104     public GanttRenderer() {
105         super();
106         setIncludeBaseInRange(false);
107         this.completePaint = Color.green;
108         this.incompletePaint = Color.red;
109         this.startPercent = 0.35;
110         this.endPercent = 0.65;
111     }
112     
113     /**
114      * Returns the paint used to show the percentage complete.
115      *
116      * @return The paint (never <code>null</code>.
117      */

118     public Paint JavaDoc getCompletePaint() {
119         return this.completePaint;
120     }
121     
122     /**
123      * Sets the paint used to show the percentage complete and sends a
124      * {@link RendererChangeEvent} to all registered listeners.
125      *
126      * @param paint the paint (<code>null</code> not permitted).
127      */

128     public void setCompletePaint(Paint JavaDoc paint) {
129         if (paint == null) {
130             throw new IllegalArgumentException JavaDoc("Null 'paint' argument.");
131         }
132         this.completePaint = paint;
133         notifyListeners(new RendererChangeEvent(this));
134     }
135     
136     /**
137      * Returns the paint used to show the percentage incomplete.
138      *
139      * @return The paint (never <code>null</code>).
140      */

141     public Paint JavaDoc getIncompletePaint() {
142         return this.incompletePaint;
143     }
144     
145     /**
146      * Sets the paint used to show the percentage incomplete and sends a
147      * {@link RendererChangeEvent} to all registered listeners.
148      *
149      * @param paint the paint (<code>null</code> not permitted).
150      */

151     public void setIncompletePaint(Paint JavaDoc paint) {
152         if (paint == null) {
153             throw new IllegalArgumentException JavaDoc("Null 'paint' argument.");
154         }
155         this.incompletePaint = paint;
156         notifyListeners(new RendererChangeEvent(this));
157     }
158     
159     /**
160      * Returns the position of the start of the progress indicator, as a
161      * percentage of the bar width.
162      *
163      * @return The start percent.
164      */

165     public double getStartPercent() {
166         return this.startPercent;
167     }
168     
169     /**
170      * Sets the position of the start of the progress indicator, as a
171      * percentage of the bar width.
172      *
173      * @param percent the percent.
174      */

175     public void setStartPercent(double percent) {
176         this.startPercent = percent;
177         notifyListeners(new RendererChangeEvent(this));
178     }
179     
180     /**
181      * Returns the position of the end of the progress indicator, as a
182      * percentage of the bar width.
183      *
184      * @return The end percent.
185      */

186     public double getEndPercent() {
187         return this.endPercent;
188     }
189     
190     /**
191      * Sets the position of the end of the progress indicator, as a percentage
192      * of the bar width.
193      *
194      * @param percent the percent.
195      */

196     public void setEndPercent(double percent) {
197         this.endPercent = percent;
198         notifyListeners(new RendererChangeEvent(this));
199     }
200     
201     /**
202      * Draws the bar for a single (series, category) data item.
203      *
204      * @param g2 the graphics device.
205      * @param state the renderer state.
206      * @param dataArea the data area.
207      * @param plot the plot.
208      * @param domainAxis the domain axis.
209      * @param rangeAxis the range axis.
210      * @param dataset the dataset.
211      * @param row the row index (zero-based).
212      * @param column the column index (zero-based).
213      * @param pass the pass index.
214      */

215     public void drawItem(Graphics2D JavaDoc g2,
216                          CategoryItemRendererState state,
217                          Rectangle2D JavaDoc dataArea,
218                          CategoryPlot plot,
219                          CategoryAxis domainAxis,
220                          ValueAxis rangeAxis,
221                          CategoryDataset dataset,
222                          int row,
223                          int column,
224                          int pass) {
225
226          if (dataset instanceof GanttCategoryDataset) {
227              GanttCategoryDataset gcd = (GanttCategoryDataset) dataset;
228              drawTasks(
229                 g2, state, dataArea, plot, domainAxis, rangeAxis, gcd,
230                 row, column
231              );
232          }
233          else { // let the superclass handle it...
234
super.drawItem(
235                  g2, state, dataArea, plot, domainAxis, rangeAxis,
236                  dataset, row, column, pass
237              );
238          }
239  
240      }
241                           
242     /**
243      * Draws the tasks/subtasks for one item.
244      *
245      * @param g2 the graphics device.
246      * @param state the renderer state.
247      * @param dataArea the data plot area.
248      * @param plot the plot.
249      * @param domainAxis the domain axis.
250      * @param rangeAxis the range axis.
251      * @param dataset the data.
252      * @param row the row index (zero-based).
253      * @param column the column index (zero-based).
254      */

255     protected void drawTasks(Graphics2D JavaDoc g2,
256                              CategoryItemRendererState state,
257                              Rectangle2D JavaDoc dataArea,
258                              CategoryPlot plot,
259                              CategoryAxis domainAxis,
260                              ValueAxis rangeAxis,
261                              GanttCategoryDataset dataset,
262                              int row,
263                              int column) {
264
265         int count = dataset.getSubIntervalCount(row, column);
266         if (count == 0) {
267             drawTask(
268                 g2, state, dataArea, plot, domainAxis, rangeAxis,
269                 dataset, row, column
270             );
271         }
272
273         for (int subinterval = 0; subinterval < count; subinterval++) {
274             
275             RectangleEdge rangeAxisLocation = plot.getRangeAxisEdge();
276
277             // value 0
278
Number JavaDoc value0 = dataset.getStartValue(row, column, subinterval);
279             if (value0 == null) {
280                 return;
281             }
282             double translatedValue0 = rangeAxis.valueToJava2D(
283                 value0.doubleValue(), dataArea, rangeAxisLocation
284             );
285     
286             // value 1
287
Number JavaDoc value1 = dataset.getEndValue(row, column, subinterval);
288             if (value1 == null) {
289                 return;
290             }
291             double translatedValue1 = rangeAxis.valueToJava2D(
292                 value1.doubleValue(), dataArea, rangeAxisLocation
293             );
294     
295             if (translatedValue1 < translatedValue0) {
296                 double temp = translatedValue1;
297                 translatedValue1 = translatedValue0;
298                 translatedValue0 = temp;
299             }
300     
301             double rectStart = calculateBarW0(
302                 plot, plot.getOrientation(), dataArea, domainAxis, state,
303                 row, column
304             );
305             double rectLength = Math.abs(translatedValue1 - translatedValue0);
306             double rectBreadth = state.getBarWidth();
307     
308             // DRAW THE BARS...
309
Rectangle2D JavaDoc bar = null;
310             
311             if (plot.getOrientation() == PlotOrientation.HORIZONTAL) {
312                 bar = new Rectangle2D.Double JavaDoc(
313                     translatedValue0, rectStart, rectLength, rectBreadth
314                 );
315             }
316             else if (plot.getOrientation() == PlotOrientation.VERTICAL) {
317                 bar = new Rectangle2D.Double JavaDoc(
318                     rectStart, translatedValue0, rectBreadth, rectLength
319                 );
320             }
321     
322             Rectangle2D JavaDoc completeBar = null;
323             Rectangle2D JavaDoc incompleteBar = null;
324             Number JavaDoc percent = dataset.getPercentComplete(
325                 row, column, subinterval
326             );
327             double start = getStartPercent();
328             double end = getEndPercent();
329             if (percent != null) {
330                 double p = percent.doubleValue();
331                 if (plot.getOrientation() == PlotOrientation.HORIZONTAL) {
332                     completeBar = new Rectangle2D.Double JavaDoc(
333                         translatedValue0,
334                         rectStart + start * rectBreadth,
335                         rectLength * p,
336                         rectBreadth * (end - start)
337                     );
338                     incompleteBar = new Rectangle2D.Double JavaDoc(
339                         translatedValue0 + rectLength * p,
340                         rectStart + start * rectBreadth,
341                         rectLength * (1 - p),
342                         rectBreadth * (end - start)
343                     );
344                 }
345                 else if (plot.getOrientation() == PlotOrientation.VERTICAL) {
346                     completeBar = new Rectangle2D.Double JavaDoc(
347                         rectStart + start * rectBreadth,
348                         translatedValue0 + rectLength * (1 - p),
349                         rectBreadth * (end - start),
350                         rectLength * p
351                     );
352                     incompleteBar = new Rectangle2D.Double JavaDoc(
353                         rectStart + start * rectBreadth,
354                         translatedValue0,
355                         rectBreadth * (end - start),
356                         rectLength * (1 - p)
357                     );
358                 }
359                 
360             }
361
362             Paint JavaDoc seriesPaint = getItemPaint(row, column);
363             g2.setPaint(seriesPaint);
364             g2.fill(bar);
365             if (completeBar != null) {
366                 g2.setPaint(getCompletePaint());
367                 g2.fill(completeBar);
368             }
369             if (incompleteBar != null) {
370                 g2.setPaint(getIncompletePaint());
371                 g2.fill(incompleteBar);
372             }
373             if (isDrawBarOutline()
374                     && state.getBarWidth() > BAR_OUTLINE_WIDTH_THRESHOLD) {
375                 g2.setStroke(getItemStroke(row, column));
376                 g2.setPaint(getItemOutlinePaint(row, column));
377                 g2.draw(bar);
378             }
379     
380             // collect entity and tool tip information...
381
if (state.getInfo() != null) {
382                 EntityCollection entities = state.getEntityCollection();
383                 if (entities != null) {
384                     String JavaDoc tip = null;
385                     if (getToolTipGenerator(row, column) != null) {
386                         tip = getToolTipGenerator(row, column).generateToolTip(
387                             dataset, row, column
388                         );
389                     }
390                     String JavaDoc url = null;
391                     if (getItemURLGenerator(row, column) != null) {
392                         url = getItemURLGenerator(row, column).generateURL(
393                             dataset, row, column
394                         );
395                     }
396                     CategoryItemEntity entity = new CategoryItemEntity(
397                         bar, tip, url, dataset, row,
398                         dataset.getColumnKey(column), column
399                     );
400                     entities.add(entity);
401                 }
402             }
403         }
404     }
405     
406     /**
407      * Draws a single task.
408      *
409      * @param g2 the graphics device.
410      * @param state the renderer state.
411      * @param dataArea the data plot area.
412      * @param plot the plot.
413      * @param domainAxis the domain axis.
414      * @param rangeAxis the range axis.
415      * @param dataset the data.
416      * @param row the row index (zero-based).
417      * @param column the column index (zero-based).
418      */

419     protected void drawTask(Graphics2D JavaDoc g2,
420                             CategoryItemRendererState state,
421                             Rectangle2D JavaDoc dataArea,
422                             CategoryPlot plot,
423                             CategoryAxis domainAxis,
424                             ValueAxis rangeAxis,
425                             GanttCategoryDataset dataset,
426                             int row,
427                             int column) {
428
429         PlotOrientation orientation = plot.getOrientation();
430
431         RectangleEdge rangeAxisLocation = plot.getRangeAxisEdge();
432         
433         // Y0
434
Number JavaDoc value0 = dataset.getEndValue(row, column);
435         if (value0 == null) {
436             return;
437         }
438         double java2dValue0 = rangeAxis.valueToJava2D(
439             value0.doubleValue(), dataArea, rangeAxisLocation
440         );
441
442         // Y1
443
Number JavaDoc value1 = dataset.getStartValue(row, column);
444         if (value1 == null) {
445             return;
446         }
447         double java2dValue1 = rangeAxis.valueToJava2D(
448             value1.doubleValue(), dataArea, rangeAxisLocation
449         );
450
451         if (java2dValue1 < java2dValue0) {
452             double temp = java2dValue1;
453             java2dValue1 = java2dValue0;
454             java2dValue0 = temp;
455             Number JavaDoc tempNum = value1;
456             value1 = value0;
457             value0 = tempNum;
458         }
459
460         double rectStart = calculateBarW0(
461             plot, orientation, dataArea, domainAxis, state, row, column
462         );
463         double rectBreadth = state.getBarWidth();
464         double rectLength = Math.abs(java2dValue1 - java2dValue0);
465         
466         Rectangle2D JavaDoc bar = null;
467         if (orientation == PlotOrientation.HORIZONTAL) {
468             bar = new Rectangle2D.Double JavaDoc(
469                 java2dValue0, rectStart, rectLength, rectBreadth
470             );
471         }
472         else if (orientation == PlotOrientation.VERTICAL) {
473             bar = new Rectangle2D.Double JavaDoc(
474                 rectStart, java2dValue1, rectBreadth, rectLength
475             );
476         }
477
478         Rectangle2D JavaDoc completeBar = null;
479         Rectangle2D JavaDoc incompleteBar = null;
480         Number JavaDoc percent = dataset.getPercentComplete(row, column);
481         double start = getStartPercent();
482         double end = getEndPercent();
483         if (percent != null) {
484             double p = percent.doubleValue();
485             if (plot.getOrientation() == PlotOrientation.HORIZONTAL) {
486                 completeBar = new Rectangle2D.Double JavaDoc(
487                     java2dValue0,
488                     rectStart + start * rectBreadth,
489                     rectLength * p,
490                     rectBreadth * (end - start)
491                 );
492                 incompleteBar = new Rectangle2D.Double JavaDoc(
493                     java2dValue0 + rectLength * p,
494                     rectStart + start * rectBreadth,
495                     rectLength * (1 - p),
496                     rectBreadth * (end - start)
497                 );
498             }
499             else if (plot.getOrientation() == PlotOrientation.VERTICAL) {
500                 completeBar = new Rectangle2D.Double JavaDoc(
501                     rectStart + start * rectBreadth,
502                     java2dValue1 + rectLength * (1 - p),
503                     rectBreadth * (end - start),
504                     rectLength * p
505                 );
506                 incompleteBar = new Rectangle2D.Double JavaDoc(
507                     rectStart + start * rectBreadth,
508                     java2dValue1,
509                     rectBreadth * (end - start),
510                     rectLength * (1 - p)
511                 );
512             }
513                 
514         }
515
516         Paint JavaDoc seriesPaint = getItemPaint(row, column);
517         g2.setPaint(seriesPaint);
518         g2.fill(bar);
519
520         if (completeBar != null) {
521             g2.setPaint(getCompletePaint());
522             g2.fill(completeBar);
523         }
524         if (incompleteBar != null) {
525             g2.setPaint(getIncompletePaint());
526             g2.fill(incompleteBar);
527         }
528         
529         // draw the outline...
530
if (isDrawBarOutline()
531                 && state.getBarWidth() > BAR_OUTLINE_WIDTH_THRESHOLD) {
532             Stroke JavaDoc stroke = getItemOutlineStroke(row, column);
533             Paint JavaDoc paint = getItemOutlinePaint(row, column);
534             if (stroke != null && paint != null) {
535                 g2.setStroke(stroke);
536                 g2.setPaint(paint);
537                 g2.draw(bar);
538             }
539         }
540         
541         CategoryItemLabelGenerator generator
542             = getItemLabelGenerator(row, column);
543         if (generator != null && isItemLabelVisible(row, column)) {
544             drawItemLabel(
545                 g2, dataset, row, column, plot, generator, bar, false
546             );
547         }
548
549         // collect entity and tool tip information...
550
if (state.getInfo() != null) {
551             EntityCollection entities = state.getEntityCollection();
552             if (entities != null) {
553                 String JavaDoc tip = null;
554                 CategoryToolTipGenerator tipster = getToolTipGenerator(
555                     row, column
556                 );
557                 if (tipster != null) {
558                     tip = tipster.generateToolTip(dataset, row, column);
559                 }
560                 String JavaDoc url = null;
561                 if (getItemURLGenerator(row, column) != null) {
562                     url = getItemURLGenerator(row, column).generateURL(
563                         dataset, row, column
564                     );
565                 }
566                 CategoryItemEntity entity = new CategoryItemEntity(
567                     bar, tip, url, dataset, row,
568                     dataset.getColumnKey(column), column
569                 );
570                 entities.add(entity);
571             }
572         }
573
574     }
575     
576 }
577
Popular Tags