1:
51:
52: package ;
53:
54: import ;
55: import ;
56: import ;
57: import ;
58: import ;
59: import ;
60:
61: import ;
62: import ;
63: import ;
64: import ;
65: import ;
66: import ;
67: import ;
68: import ;
69: import ;
70: import ;
71: import ;
72: import ;
73:
74:
77: public class GanttRenderer extends IntervalBarRenderer
78: implements Serializable {
79:
80:
81: private static final long serialVersionUID = -4010349116350119512L;
82:
83:
84: private Paint completePaint;
85:
86:
87: private Paint incompletePaint;
88:
89:
93: private double startPercent;
94:
95:
99: private double endPercent;
100:
101:
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:
118: public Paint getCompletePaint() {
119: return this.completePaint;
120: }
121:
122:
128: public void setCompletePaint(Paint paint) {
129: if (paint == null) {
130: throw new IllegalArgumentException("Null 'paint' argument.");
131: }
132: this.completePaint = paint;
133: notifyListeners(new RendererChangeEvent(this));
134: }
135:
136:
141: public Paint getIncompletePaint() {
142: return this.incompletePaint;
143: }
144:
145:
151: public void setIncompletePaint(Paint paint) {
152: if (paint == null) {
153: throw new IllegalArgumentException("Null 'paint' argument.");
154: }
155: this.incompletePaint = paint;
156: notifyListeners(new RendererChangeEvent(this));
157: }
158:
159:
165: public double getStartPercent() {
166: return this.startPercent;
167: }
168:
169:
175: public void setStartPercent(double percent) {
176: this.startPercent = percent;
177: notifyListeners(new RendererChangeEvent(this));
178: }
179:
180:
186: public double getEndPercent() {
187: return this.endPercent;
188: }
189:
190:
196: public void setEndPercent(double percent) {
197: this.endPercent = percent;
198: notifyListeners(new RendererChangeEvent(this));
199: }
200:
201:
215: public void drawItem(Graphics2D g2,
216: CategoryItemRendererState state,
217: Rectangle2D 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 {
234: super.drawItem(
235: g2, state, dataArea, plot, domainAxis, rangeAxis,
236: dataset, row, column, pass
237: );
238: }
239:
240: }
241:
242:
255: protected void drawTasks(Graphics2D g2,
256: CategoryItemRendererState state,
257: Rectangle2D 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:
278: Number 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:
287: Number 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:
309: Rectangle2D bar = null;
310:
311: if (plot.getOrientation() == PlotOrientation.HORIZONTAL) {
312: bar = new Rectangle2D.Double(
313: translatedValue0, rectStart, rectLength, rectBreadth
314: );
315: }
316: else if (plot.getOrientation() == PlotOrientation.VERTICAL) {
317: bar = new Rectangle2D.Double(
318: rectStart, translatedValue0, rectBreadth, rectLength
319: );
320: }
321:
322: Rectangle2D completeBar = null;
323: Rectangle2D incompleteBar = null;
324: Number 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(
333: translatedValue0,
334: rectStart + start * rectBreadth,
335: rectLength * p,
336: rectBreadth * (end - start)
337: );
338: incompleteBar = new Rectangle2D.Double(
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(
347: rectStart + start * rectBreadth,
348: translatedValue0 + rectLength * (1 - p),
349: rectBreadth * (end - start),
350: rectLength * p
351: );
352: incompleteBar = new Rectangle2D.Double(
353: rectStart + start * rectBreadth,
354: translatedValue0,
355: rectBreadth * (end - start),
356: rectLength * (1 - p)
357: );
358: }
359:
360: }
361:
362: Paint 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:
381: if (state.getInfo() != null) {
382: EntityCollection entities = state.getEntityCollection();
383: if (entities != null) {
384: String tip = null;
385: if (getToolTipGenerator(row, column) != null) {
386: tip = getToolTipGenerator(row, column).generateToolTip(
387: dataset, row, column
388: );
389: }
390: String 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:
419: protected void drawTask(Graphics2D g2,
420: CategoryItemRendererState state,
421: Rectangle2D 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:
434: Number 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:
443: Number 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 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 bar = null;
467: if (orientation == PlotOrientation.HORIZONTAL) {
468: bar = new Rectangle2D.Double(
469: java2dValue0, rectStart, rectLength, rectBreadth
470: );
471: }
472: else if (orientation == PlotOrientation.VERTICAL) {
473: bar = new Rectangle2D.Double(
474: rectStart, java2dValue1, rectBreadth, rectLength
475: );
476: }
477:
478: Rectangle2D completeBar = null;
479: Rectangle2D incompleteBar = null;
480: Number 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(
487: java2dValue0,
488: rectStart + start * rectBreadth,
489: rectLength * p,
490: rectBreadth * (end - start)
491: );
492: incompleteBar = new Rectangle2D.Double(
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(
501: rectStart + start * rectBreadth,
502: java2dValue1 + rectLength * (1 - p),
503: rectBreadth * (end - start),
504: rectLength * p
505: );
506: incompleteBar = new Rectangle2D.Double(
507: rectStart + start * rectBreadth,
508: java2dValue1,
509: rectBreadth * (end - start),
510: rectLength * (1 - p)
511: );
512: }
513:
514: }
515:
516: Paint 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:
530: if (isDrawBarOutline()
531: && state.getBarWidth() > BAR_OUTLINE_WIDTH_THRESHOLD) {
532: Stroke stroke = getItemOutlineStroke(row, column);
533: Paint 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:
550: if (state.getInfo() != null) {
551: EntityCollection entities = state.getEntityCollection();
552: if (entities != null) {
553: String tip = null;
554: CategoryToolTipGenerator tipster = getToolTipGenerator(
555: row, column
556: );
557: if (tipster != null) {
558: tip = tipster.generateToolTip(dataset, row, column);
559: }
560: String 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: }