KickJava   Java API By Example, From Geeks To Geeks.

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


1 /* ======================================
2  * JFreeChart : a free Java chart library
3  * ======================================
4  *
5  * Project Info: http://www.jfree.org/jfreechart/index.html
6  * Project Lead: David Gilbert (david.gilbert@object-refinery.com);
7  *
8  * (C) Copyright 2000-2003, by Object Refinery Limited and Contributors.
9  *
10  * This library is free software; you can redistribute it and/or modify it under the terms
11  * of the GNU Lesser General Public License as published by the Free Software Foundation;
12  * either version 2.1 of the License, or (at your option) any later version.
13  *
14  * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
15  * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
16  * See the GNU Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public License along with this
19  * library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
20  * Boston, MA 02111-1307, USA.
21  *
22  * ------------------
23  * GanttRenderer.java
24  * ------------------
25  * (C) Copyright 2003 by Object Refinery Limited.
26  *
27  * Original Author: David Gilbert (for Object Refinery Limited);
28  * Contributor(s): -;
29  *
30  * $Id: GanttRenderer.java,v 1.6 2003/11/03 14:21:27 mungady Exp $
31  *
32  * Changes
33  * -------
34  * 16-Sep-2003 : Version 1 (DG);
35  * 23-Sep-2003 : Fixed Checkstyle issues (DG);
36  * 21-Oct-2003 : Bar width moved into CategoryItemRendererState (DG);
37  *
38  */

39
40 package org.jfree.chart.renderer;
41
42 import java.awt.Color JavaDoc;
43 import java.awt.Graphics2D JavaDoc;
44 import java.awt.Paint JavaDoc;
45 import java.awt.Stroke JavaDoc;
46 import java.awt.geom.Rectangle2D JavaDoc;
47
48 import org.jfree.chart.axis.CategoryAxis;
49 import org.jfree.chart.axis.ValueAxis;
50 import org.jfree.chart.entity.CategoryItemEntity;
51 import org.jfree.chart.entity.EntityCollection;
52 import org.jfree.chart.labels.CategoryItemLabelGenerator;
53 import org.jfree.chart.plot.CategoryPlot;
54 import org.jfree.chart.plot.PlotOrientation;
55 import org.jfree.data.CategoryDataset;
56 import org.jfree.data.gantt.GanttCategoryDataset;
57 import org.jfree.ui.RectangleEdge;
58
59 /**
60  * A renderer for simple Gantt charts.
61  *
62  * @author David Gilbert.
63  */

64 public class GanttRenderer extends IntervalBarRenderer {
65     
66     /** The paint for displaying the percentage complete. */
67     private Paint JavaDoc completePaint;
68     
69     /** The paint for displaying the incomplete part of a task. */
70     private Paint JavaDoc incompletePaint;
71     
72     /**
73      * Controls the starting edge of the progress indicator (expressed as a percentage of the
74      * overall bar width.
75      */

76     private double startPercent = 0.35;
77     
78     /**
79      * Controls the ending edge of the progress indicator (expressed as a percentage of the
80      * overall bar width.
81      */

82     private double endPercent = 0.65;
83     
84     /**
85      * Creates a new renderer.
86      *
87      */

88     public GanttRenderer() {
89         super();
90         this.completePaint = Color.green;
91         this.incompletePaint = Color.red;
92     }
93     
94     /**
95      * Draws the bar for a single (series, category) data item.
96      *
97      * @param g2 the graphics device.
98      * @param state the renderer state.
99      * @param dataArea the data area.
100      * @param plot the plot.
101      * @param domainAxis the domain axis.
102      * @param rangeAxis the range axis.
103      * @param dataset the dataset.
104      * @param row the row index (zero-based).
105      * @param column the column index (zero-based).
106      */

107     public void drawItem(Graphics2D JavaDoc g2,
108                          CategoryItemRendererState state,
109                          Rectangle2D JavaDoc dataArea,
110                          CategoryPlot plot,
111                          CategoryAxis domainAxis,
112                          ValueAxis rangeAxis,
113                          CategoryDataset dataset,
114                          int row,
115                          int column) {
116
117          if (dataset instanceof GanttCategoryDataset) {
118              GanttCategoryDataset gcd = (GanttCategoryDataset) dataset;
119              drawTasks(g2, state, dataArea, plot, domainAxis, rangeAxis, gcd, row, column);
120          }
121          else { // let the superclass handle it...
122
super.drawItem(g2, state, dataArea, plot, domainAxis, rangeAxis, dataset, row, column);
123          }
124  
125      }
126                           
127     /**
128      * Draws the tasks/subtasks for one item.
129      *
130      * @param g2 the graphics device.
131      * @param state the renderer state.
132      * @param dataArea the data plot area.
133      * @param plot the plot.
134      * @param domainAxis the domain axis.
135      * @param rangeAxis the range axis.
136      * @param dataset the data.
137      * @param row the row index (zero-based).
138      * @param column the column index (zero-based).
139      */

140     protected void drawTasks(Graphics2D JavaDoc g2,
141                              CategoryItemRendererState state,
142                              Rectangle2D JavaDoc dataArea,
143                              CategoryPlot plot,
144                              CategoryAxis domainAxis,
145                              ValueAxis rangeAxis,
146                              GanttCategoryDataset dataset,
147                              int row,
148                              int column) {
149
150         int count = dataset.getSubIntervalCount(row, column);
151         if (count == 0) {
152             drawTask(g2, state, dataArea, plot, domainAxis, rangeAxis, dataset, row, column);
153         }
154
155         for (int subinterval = 0; subinterval < count; subinterval++) {
156             
157             RectangleEdge domainAxisLocation = plot.getDomainAxisEdge();
158             RectangleEdge rangeAxisLocation = plot.getRangeAxisEdge();
159
160             // value 0
161
Number JavaDoc value0 = dataset.getStartValue(row, column, subinterval);
162             if (value0 == null) {
163                 return;
164             }
165             double translatedValue0 = rangeAxis.translateValueToJava2D(value0.doubleValue(),
166                                                                        dataArea,
167                                                                        rangeAxisLocation);
168     
169             // value 1
170
Number JavaDoc value1 = dataset.getEndValue(row, column, subinterval);
171             if (value1 == null) {
172                 return;
173             }
174             double translatedValue1 = rangeAxis.translateValueToJava2D(value1.doubleValue(),
175                                                                        dataArea,
176                                                                        rangeAxisLocation);
177     
178             if (translatedValue1 < translatedValue0) {
179                 double temp = translatedValue1;
180                 translatedValue1 = translatedValue0;
181                 translatedValue0 = temp;
182             }
183     
184             // rectStart
185
double rectStart = domainAxis.getCategoryStart(column, getColumnCount(), dataArea,
186                                                            domainAxisLocation);
187     
188             int rows = getRowCount();
189             int columns = getColumnCount();
190             if (rows > 1) {
191                 double seriesGap = dataArea.getHeight() * getItemMargin()
192                                    / (columns * (rows - 1));
193                 rectStart = rectStart + row * (state.getBarWidth() + seriesGap);
194             }
195             else {
196                 rectStart = rectStart + row * state.getBarWidth();
197             }
198     
199             // LENGTH
200
double rectLength = Math.abs(translatedValue1 - translatedValue0);
201     
202             // BREADTH
203
double rectBreadth = state.getBarWidth();
204     
205             // DRAW THE BARS...
206
Rectangle2D JavaDoc bar = null;
207             
208             if (plot.getOrientation() == PlotOrientation.HORIZONTAL) {
209                 bar = new Rectangle2D.Double JavaDoc(translatedValue0, rectStart, rectLength, rectBreadth);
210             }
211             else if (plot.getOrientation() == PlotOrientation.VERTICAL) {
212                 bar = new Rectangle2D.Double JavaDoc(rectStart, translatedValue0, rectBreadth, rectLength);
213             }
214     
215             Rectangle2D JavaDoc completeBar = null;
216             Rectangle2D JavaDoc incompleteBar = null;
217             Number JavaDoc percent = dataset.getPercentComplete(row, column, subinterval);
218             if (percent != null) {
219                 double p = percent.doubleValue();
220                 if (plot.getOrientation() == PlotOrientation.HORIZONTAL) {
221                     completeBar = new Rectangle2D.Double JavaDoc(
222                         translatedValue0,
223                         rectStart + this.startPercent * rectBreadth,
224                         rectLength * p,
225                         rectBreadth * (this.endPercent - this.startPercent)
226                     );
227                     incompleteBar = new Rectangle2D.Double JavaDoc(
228                         translatedValue0 + rectLength * p,
229                         rectStart + this.startPercent * rectBreadth,
230                         rectLength * (1 - p),
231                         rectBreadth * (this.endPercent - this.startPercent)
232                     );
233                 }
234                 else if (plot.getOrientation() == PlotOrientation.VERTICAL) {
235                     completeBar = new Rectangle2D.Double JavaDoc(
236                         rectStart + this.startPercent * rectBreadth,
237                         translatedValue0 + rectLength * (1 - p),
238                         rectBreadth * (this.endPercent - this.startPercent),
239                         rectLength * p
240                     );
241                     incompleteBar = new Rectangle2D.Double JavaDoc(
242                         rectStart + this.startPercent * rectBreadth,
243                         translatedValue0,
244                         rectBreadth * (this.endPercent - this.startPercent),
245                         rectLength * (1 - p)
246                     );
247                 }
248                 
249             }
250
251             Paint JavaDoc seriesPaint = getItemPaint(row, column);
252             g2.setPaint(seriesPaint);
253             g2.fill(bar);
254             if (completeBar != null) {
255                 g2.setPaint(this.completePaint);
256                 g2.fill(completeBar);
257             }
258             if (incompleteBar != null) {
259                 g2.setPaint(this.incompletePaint);
260                 g2.fill(incompleteBar);
261             }
262             if (state.getBarWidth() > BAR_OUTLINE_WIDTH_THRESHOLD) {
263                 g2.setStroke(getItemStroke(row, column));
264                 g2.setPaint(getItemOutlinePaint(row, column));
265                 g2.draw(bar);
266             }
267     
268             // collect entity and tool tip information...
269
if (state.getInfo() != null) {
270                 EntityCollection entities = state.getInfo().getOwner().getEntityCollection();
271                 if (entities != null) {
272                     String JavaDoc tip = null;
273                     if (getItemLabelGenerator(row, column) != null) {
274                         tip = getItemLabelGenerator(row, column).generateToolTip(dataset,
275                                                                           row, column);
276                     }
277                     String JavaDoc url = null;
278                     if (getItemURLGenerator(row, column) != null) {
279                         url = getItemURLGenerator(row, column).generateURL(dataset, row, column);
280                     }
281                     CategoryItemEntity entity = new CategoryItemEntity(
282                         bar, tip, url, dataset, row, dataset.getColumnKey(column), column
283                     );
284                     entities.addEntity(entity);
285                 }
286             }
287         }
288     }
289     
290     /**
291      * Draws a single task.
292      *
293      * @param g2 the graphics device.
294      * @param state the renderer state.
295      * @param dataArea the data plot area.
296      * @param plot the plot.
297      * @param domainAxis the domain axis.
298      * @param rangeAxis the range axis.
299      * @param dataset the data.
300      * @param row the row index (zero-based).
301      * @param column the column index (zero-based).
302      */

303     protected void drawTask(Graphics2D JavaDoc g2,
304                             CategoryItemRendererState state,
305                             Rectangle2D JavaDoc dataArea,
306                             CategoryPlot plot,
307                             CategoryAxis domainAxis,
308                             ValueAxis rangeAxis,
309                             GanttCategoryDataset dataset,
310                             int row,
311                             int column) {
312
313         int seriesCount = getRowCount();
314         int categoryCount = getColumnCount();
315
316         PlotOrientation orientation = plot.getOrientation();
317
318         RectangleEdge domainAxisLocation = plot.getDomainAxisEdge();
319         RectangleEdge rangeAxisLocation = plot.getRangeAxisEdge();
320         
321         // Y0
322
Number JavaDoc value0 = dataset.getEndValue(row, column);
323         if (value0 == null) {
324             return;
325         }
326         double java2dValue0 = rangeAxis.translateValueToJava2D(value0.doubleValue(), dataArea,
327                                                                rangeAxisLocation);
328
329         // Y1
330
Number JavaDoc value1 = dataset.getStartValue(row, column);
331         if (value1 == null) {
332             return;
333         }
334         double java2dValue1 = rangeAxis.translateValueToJava2D(value1.doubleValue(), dataArea,
335                                                                rangeAxisLocation);
336
337         if (java2dValue1 < java2dValue0) {
338             double temp = java2dValue1;
339             java2dValue1 = java2dValue0;
340             java2dValue0 = temp;
341             Number JavaDoc tempNum = value1;
342             value1 = value0;
343             value0 = tempNum;
344         }
345
346         double rectStart = domainAxis.getCategoryStart(column, getColumnCount(), dataArea,
347                                                        domainAxisLocation);
348
349         // BREADTH
350
double rectBreadth = state.getBarWidth();
351
352         // BAR HEIGHT
353
double rectLength = Math.abs(java2dValue1 - java2dValue0);
354         
355         Rectangle2D JavaDoc bar = null;
356         if (orientation == PlotOrientation.HORIZONTAL) {
357             if (seriesCount > 1) {
358                 double seriesGap = dataArea.getHeight() * getItemMargin()
359                                    / (categoryCount * (seriesCount - 1));
360                 rectStart = rectStart + row * (state.getBarWidth() + seriesGap);
361             }
362             else {
363                 rectStart = rectStart + row * state.getBarWidth();
364             }
365             bar = new Rectangle2D.Double JavaDoc(java2dValue0, rectStart, rectLength, rectBreadth);
366         }
367         else if (orientation == PlotOrientation.VERTICAL) {
368             if (seriesCount > 1) {
369                 double seriesGap = dataArea.getWidth() * getItemMargin()
370                                    / (categoryCount * (seriesCount - 1));
371                 rectStart = rectStart + row * (state.getBarWidth() + seriesGap);
372             }
373             else {
374                 rectStart = rectStart + row * state.getBarWidth();
375             }
376             bar = new Rectangle2D.Double JavaDoc(rectStart, java2dValue1, rectBreadth, rectLength);
377         }
378
379         Rectangle2D JavaDoc completeBar = null;
380         Rectangle2D JavaDoc incompleteBar = null;
381         Number JavaDoc percent = dataset.getPercentComplete(row, column);
382         if (percent != null) {
383             double p = percent.doubleValue();
384             if (plot.getOrientation() == PlotOrientation.HORIZONTAL) {
385                 completeBar = new Rectangle2D.Double JavaDoc(
386                     java2dValue0,
387                     rectStart + this.startPercent * rectBreadth,
388                     rectLength * p,
389                     rectBreadth * (this.endPercent - this.startPercent)
390                 );
391                 incompleteBar = new Rectangle2D.Double JavaDoc(
392                     java2dValue0 + rectLength * p,
393                     rectStart + this.startPercent * rectBreadth,
394                     rectLength * (1 - p),
395                     rectBreadth * (this.endPercent - this.startPercent)
396                 );
397             }
398             else if (plot.getOrientation() == PlotOrientation.VERTICAL) {
399                 completeBar = new Rectangle2D.Double JavaDoc(
400                     rectStart + this.startPercent * rectBreadth,
401                     java2dValue1 + rectLength * (1 - p),
402                     rectBreadth * (this.endPercent - this.startPercent),
403                     rectLength * p
404                 );
405                 incompleteBar = new Rectangle2D.Double JavaDoc(
406                     rectStart + this.startPercent * rectBreadth,
407                     java2dValue1,
408                     rectBreadth * (this.endPercent - this.startPercent),
409                     rectLength * (1 - p)
410                 );
411             }
412                 
413         }
414
415         Paint JavaDoc seriesPaint = getItemPaint(row, column);
416         g2.setPaint(seriesPaint);
417         g2.fill(bar);
418
419         if (completeBar != null) {
420             g2.setPaint(this.completePaint);
421             g2.fill(completeBar);
422         }
423         if (incompleteBar != null) {
424             g2.setPaint(this.incompletePaint);
425             g2.fill(incompleteBar);
426         }
427         
428         // draw the outline...
429
if (state.getBarWidth() > BAR_OUTLINE_WIDTH_THRESHOLD) {
430             Stroke JavaDoc stroke = getItemOutlineStroke(row, column);
431             Paint JavaDoc paint = getItemOutlinePaint(row, column);
432             if (stroke != null && paint != null) {
433                 g2.setStroke(stroke);
434                 g2.setPaint(paint);
435                 g2.draw(bar);
436             }
437         }
438         
439         CategoryItemLabelGenerator generator = getItemLabelGenerator(row, column);
440         if (generator != null && isItemLabelVisible(row, column)) {
441             drawItemLabel(g2, dataset, row, column, plot, generator, bar, false);
442         }
443
444         // collect entity and tool tip information...
445
if (state.getInfo() != null) {
446             EntityCollection entities = state.getInfo().getOwner().getEntityCollection();
447             if (entities != null) {
448                 String JavaDoc tip = null;
449                 if (generator != null) {
450                     tip = generator.generateToolTip(dataset, row, column);
451                 }
452                 String JavaDoc url = null;
453                 if (getItemURLGenerator(row, column) != null) {
454                     url = getItemURLGenerator(row, column).generateURL(dataset, row, column);
455                 }
456                 CategoryItemEntity entity = new CategoryItemEntity(
457                     bar, tip, url, dataset, row, dataset.getColumnKey(column), column
458                 );
459                 entities.addEntity(entity);
460             }
461         }
462
463     }
464     
465
466 }
467
Popular Tags