1:
52:
53: package ;
54:
55: import ;
56: import ;
57: import ;
58: import ;
59: import ;
60: import ;
61:
62: import ;
63: import ;
64: import ;
65: import ;
66: import ;
67: import ;
68: import ;
69: import ;
70: import ;
71: import ;
72: import ;
73: import ;
74:
75:
79: public class LayeredBarRenderer extends BarRenderer
80: implements Serializable {
81:
82:
83: private static final long serialVersionUID = -8716572894780469487L;
84:
85:
86: protected ObjectList seriesBarWidthList;
87:
88:
91: public LayeredBarRenderer() {
92: super();
93: this.seriesBarWidthList = new ObjectList();
94: }
95:
96:
104: public double getSeriesBarWidth(int series) {
105: double result = Double.NaN;
106: Number n = (Number) this.seriesBarWidthList.get(series);
107: if (n != null) {
108: result = n.doubleValue();
109: }
110: return result;
111: }
112:
113:
120: public void setSeriesBarWidth(int series, double width) {
121: this.seriesBarWidthList.set(series, new Double(width));
122: }
123:
124:
132: protected void calculateBarWidth(CategoryPlot plot,
133: Rectangle2D dataArea,
134: int rendererIndex,
135: CategoryItemRendererState state) {
136:
137:
138:
139:
140:
141: CategoryAxis domainAxis = getDomainAxis(plot, rendererIndex);
142: CategoryDataset dataset = plot.getDataset(rendererIndex);
143: if (dataset != null) {
144: int columns = dataset.getColumnCount();
145: int rows = dataset.getRowCount();
146: double space = 0.0;
147: PlotOrientation orientation = plot.getOrientation();
148: if (orientation == PlotOrientation.HORIZONTAL) {
149: space = dataArea.getHeight();
150: }
151: else if (orientation == PlotOrientation.VERTICAL) {
152: space = dataArea.getWidth();
153: }
154: double maxWidth = space * getMaximumBarWidth();
155: double categoryMargin = 0.0;
156: if (columns > 1) {
157: categoryMargin = domainAxis.getCategoryMargin();
158: }
159: double used = space * (1 - domainAxis.getLowerMargin()
160: - domainAxis.getUpperMargin() - categoryMargin);
161: if ((rows * columns) > 0) {
162: state.setBarWidth(Math.min(used / (dataset.getColumnCount()),
163: maxWidth));
164: }
165: else {
166: state.setBarWidth(Math.min(used, maxWidth));
167: }
168: }
169: }
170:
171:
185: public void drawItem(Graphics2D g2,
186: CategoryItemRendererState state,
187: Rectangle2D dataArea,
188: CategoryPlot plot,
189: CategoryAxis domainAxis,
190: ValueAxis rangeAxis,
191: CategoryDataset data,
192: int row,
193: int column,
194: int pass) {
195:
196: PlotOrientation orientation = plot.getOrientation();
197: if (orientation == PlotOrientation.HORIZONTAL) {
198: drawHorizontalItem(g2, state, dataArea, plot, domainAxis, rangeAxis,
199: data, row, column);
200: }
201: else if (orientation == PlotOrientation.VERTICAL) {
202: drawVerticalItem(g2, state, dataArea, plot, domainAxis, rangeAxis,
203: data, row, column);
204: }
205:
206: }
207:
208:
221: protected void drawHorizontalItem(Graphics2D g2,
222: CategoryItemRendererState state,
223: Rectangle2D dataArea,
224: CategoryPlot plot,
225: CategoryAxis domainAxis,
226: ValueAxis rangeAxis,
227: CategoryDataset data,
228: int row,
229: int column) {
230:
231:
232: Number dataValue = data.getValue(row, column);
233: if (dataValue == null) {
234: return;
235: }
236:
237:
238: double value = dataValue.doubleValue();
239: double base = 0.0;
240: double lclip = getLowerClip();
241: double uclip = getUpperClip();
242: if (uclip <= 0.0) {
243: if (value >= uclip) {
244: return;
245: }
246: base = uclip;
247: if (value <= lclip) {
248: value = lclip;
249: }
250: }
251: else if (lclip <= 0.0) {
252: if (value >= uclip) {
253: value = uclip;
254: }
255: else {
256: if (value <= lclip) {
257: value = lclip;
258: }
259: }
260: }
261: else {
262: if (value <= lclip) {
263: return;
264: }
265: base = lclip;
266: if (value >= uclip) {
267: value = uclip;
268: }
269: }
270:
271: RectangleEdge edge = plot.getRangeAxisEdge();
272: double transX1 = rangeAxis.valueToJava2D(base, dataArea, edge);
273: double transX2 = rangeAxis.valueToJava2D(value, dataArea, edge);
274: double rectX = Math.min(transX1, transX2);
275: double rectWidth = Math.abs(transX2 - transX1);
276:
277:
278: double rectY = domainAxis.getCategoryMiddle(column, getColumnCount(),
279: dataArea, plot.getDomainAxisEdge()) - state.getBarWidth() / 2.0;
280:
281: int seriesCount = getRowCount();
282:
283:
284: double shift = 0.0;
285: double rectHeight = 0.0;
286: double widthFactor = 1.0;
287: double seriesBarWidth = getSeriesBarWidth(row);
288: if (!Double.isNaN(seriesBarWidth)) {
289: widthFactor = seriesBarWidth;
290: }
291: rectHeight = widthFactor * state.getBarWidth();
292: rectY = rectY + (1 - widthFactor) * state.getBarWidth() / 2.0;
293: if (seriesCount > 1) {
294: shift = rectHeight * 0.20 / (seriesCount - 1);
295: }
296:
297: Rectangle2D bar = new Rectangle2D.Double(rectX,
298: (rectY + ((seriesCount - 1 - row) * shift)), rectWidth,
299: (rectHeight - (seriesCount - 1 - row) * shift * 2));
300:
301: Paint itemPaint = getItemPaint(row, column);
302: GradientPaintTransformer t = getGradientPaintTransformer();
303: if (t != null && itemPaint instanceof GradientPaint) {
304: itemPaint = t.transform((GradientPaint) itemPaint, bar);
305: }
306: g2.setPaint(itemPaint);
307: g2.fill(bar);
308:
309:
310: if (isDrawBarOutline()
311: && state.getBarWidth() > BAR_OUTLINE_WIDTH_THRESHOLD) {
312: Stroke stroke = getItemOutlineStroke(row, column);
313: Paint paint = getItemOutlinePaint(row, column);
314: if (stroke != null && paint != null) {
315: g2.setStroke(stroke);
316: g2.setPaint(paint);
317: g2.draw(bar);
318: }
319: }
320:
321: CategoryItemLabelGenerator generator
322: = getItemLabelGenerator(row, column);
323: if (generator != null && isItemLabelVisible(row, column)) {
324: drawItemLabel(g2, data, row, column, plot, generator, bar,
325: (transX1 > transX2));
326: }
327:
328:
329: if (state.getInfo() != null) {
330: EntityCollection entities = state.getEntityCollection();
331: if (entities != null) {
332: String tip = null;
333: CategoryToolTipGenerator tipster
334: = getToolTipGenerator(row, column);
335: if (tipster != null) {
336: tip = tipster.generateToolTip(data, row, column);
337: }
338: String url = null;
339: if (getItemURLGenerator(row, column) != null) {
340: url = getItemURLGenerator(row, column).generateURL(data,
341: row, column);
342: }
343: CategoryItemEntity entity = new CategoryItemEntity(bar, tip,
344: url, data, row, data.getColumnKey(column), column);
345: entities.add(entity);
346: }
347: }
348: }
349:
350:
363: protected void drawVerticalItem(Graphics2D g2,
364: CategoryItemRendererState state,
365: Rectangle2D dataArea,
366: CategoryPlot plot,
367: CategoryAxis domainAxis,
368: ValueAxis rangeAxis,
369: CategoryDataset data,
370: int row,
371: int column) {
372:
373:
374: Number dataValue = data.getValue(row, column);
375: if (dataValue == null) {
376: return;
377: }
378:
379:
380: double rectX = domainAxis.getCategoryMiddle(column, getColumnCount(),
381: dataArea, plot.getDomainAxisEdge()) - state.getBarWidth() / 2.0;
382:
383: int seriesCount = getRowCount();
384:
385:
386: double value = dataValue.doubleValue();
387: double base = 0.0;
388: double lclip = getLowerClip();
389: double uclip = getUpperClip();
390:
391: if (uclip <= 0.0) {
392: if (value >= uclip) {
393: return;
394: }
395: base = uclip;
396: if (value <= lclip) {
397: value = lclip;
398: }
399: }
400: else if (lclip <= 0.0) {
401: if (value >= uclip) {
402: value = uclip;
403: }
404: else {
405: if (value <= lclip) {
406: value = lclip;
407: }
408: }
409: }
410: else {
411: if (value <= lclip) {
412: return;
413: }
414: base = getLowerClip();
415: if (value >= uclip) {
416: value = uclip;
417: }
418: }
419:
420: RectangleEdge edge = plot.getRangeAxisEdge();
421: double transY1 = rangeAxis.valueToJava2D(base, dataArea, edge);
422: double transY2 = rangeAxis.valueToJava2D(value, dataArea, edge);
423: double rectY = Math.min(transY2, transY1);
424:
425: double rectWidth = state.getBarWidth();
426: double rectHeight = Math.abs(transY2 - transY1);
427:
428:
429: double shift = 0.0;
430: rectWidth = 0.0;
431: double widthFactor = 1.0;
432: double seriesBarWidth = getSeriesBarWidth(row);
433: if (!Double.isNaN(seriesBarWidth)) {
434: widthFactor = seriesBarWidth;
435: }
436: rectWidth = widthFactor * state.getBarWidth();
437: rectX = rectX + (1 - widthFactor) * state.getBarWidth() / 2.0;
438: if (seriesCount > 1) {
439:
440: shift = rectWidth * 0.20 / (seriesCount - 1);
441: }
442:
443: Rectangle2D bar = new Rectangle2D.Double(
444: (rectX + ((seriesCount - 1 - row) * shift)), rectY,
445: (rectWidth - (seriesCount - 1 - row) * shift * 2), rectHeight);
446: Paint itemPaint = getItemPaint(row, column);
447: GradientPaintTransformer t = getGradientPaintTransformer();
448: if (t != null && itemPaint instanceof GradientPaint) {
449: itemPaint = t.transform((GradientPaint) itemPaint, bar);
450: }
451: g2.setPaint(itemPaint);
452: g2.fill(bar);
453:
454:
455: if (isDrawBarOutline()
456: && state.getBarWidth() > BAR_OUTLINE_WIDTH_THRESHOLD) {
457: Stroke stroke = getItemOutlineStroke(row, column);
458: Paint paint = getItemOutlinePaint(row, column);
459: if (stroke != null && paint != null) {
460: g2.setStroke(stroke);
461: g2.setPaint(paint);
462: g2.draw(bar);
463: }
464: }
465:
466:
467: double transX1 = rangeAxis.valueToJava2D(base, dataArea, edge);
468: double transX2 = rangeAxis.valueToJava2D(value, dataArea, edge);
469:
470: CategoryItemLabelGenerator generator
471: = getItemLabelGenerator(row, column);
472: if (generator != null && isItemLabelVisible(row, column)) {
473: drawItemLabel(g2, data, row, column, plot, generator, bar,
474: (transX1 > transX2));
475: }
476:
477:
478: if (state.getInfo() != null) {
479: EntityCollection entities = state.getEntityCollection();
480: if (entities != null) {
481: String tip = null;
482: CategoryToolTipGenerator tipster
483: = getToolTipGenerator(row, column);
484: if (tipster != null) {
485: tip = tipster.generateToolTip(data, row, column);
486: }
487: String url = null;
488: if (getItemURLGenerator(row, column) != null) {
489: url = getItemURLGenerator(row, column).generateURL(
490: data, row, column);
491: }
492: CategoryItemEntity entity = new CategoryItemEntity(bar, tip,
493: url, data, row, data.getColumnKey(column), column);
494: entities.add(entity);
495: }
496: }
497: }
498:
499: }