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 implements Serializable {
80:
81:
82: private static final long serialVersionUID = -8716572894780469487L;
83:
84:
85: protected ObjectList seriesBarWidthList;
86:
87:
90: public LayeredBarRenderer() {
91: super();
92: this.seriesBarWidthList = new ObjectList();
93: }
94:
95:
103: public double getSeriesBarWidth(int series) {
104: double result = Double.NaN;
105: Number n = (Number) this.seriesBarWidthList.get(series);
106: if (n != null) {
107: result = n.doubleValue();
108: }
109: return result;
110: }
111:
112:
119: public void setSeriesBarWidth(int series, double width) {
120: this.seriesBarWidthList.set(series, new Double(width));
121: }
122:
123:
131: protected void calculateBarWidth(CategoryPlot plot,
132: Rectangle2D dataArea,
133: int rendererIndex,
134: CategoryItemRendererState state) {
135:
136:
137:
138:
139:
140: CategoryAxis domainAxis = getDomainAxis(plot, rendererIndex);
141: CategoryDataset dataset = plot.getDataset(rendererIndex);
142: if (dataset != null) {
143: int columns = dataset.getColumnCount();
144: int rows = dataset.getRowCount();
145: double space = 0.0;
146: PlotOrientation orientation = plot.getOrientation();
147: if (orientation == PlotOrientation.HORIZONTAL) {
148: space = dataArea.getHeight();
149: }
150: else if (orientation == PlotOrientation.VERTICAL) {
151: space = dataArea.getWidth();
152: }
153: double maxWidth = space * getMaximumBarWidth();
154: double categoryMargin = 0.0;
155: if (columns > 1) {
156: categoryMargin = domainAxis.getCategoryMargin();
157: }
158: double used = space * (1 - domainAxis.getLowerMargin()
159: - domainAxis.getUpperMargin() - categoryMargin);
160: if ((rows * columns) > 0) {
161: state.setBarWidth(Math.min(used / (dataset.getColumnCount()),
162: maxWidth));
163: }
164: else {
165: state.setBarWidth(Math.min(used, maxWidth));
166: }
167: }
168: }
169:
170:
184: public void drawItem(Graphics2D g2,
185: CategoryItemRendererState state,
186: Rectangle2D dataArea,
187: CategoryPlot plot,
188: CategoryAxis domainAxis,
189: ValueAxis rangeAxis,
190: CategoryDataset data,
191: int row,
192: int column,
193: int pass) {
194:
195: PlotOrientation orientation = plot.getOrientation();
196: if (orientation == PlotOrientation.HORIZONTAL) {
197: drawHorizontalItem(g2, state, dataArea, plot, domainAxis,
198: rangeAxis, data, row, column);
199: }
200: else if (orientation == PlotOrientation.VERTICAL) {
201: drawVerticalItem(g2, state, dataArea, plot, domainAxis, rangeAxis,
202: data, row, column);
203: }
204:
205: }
206:
207:
220: protected void drawHorizontalItem(Graphics2D g2,
221: CategoryItemRendererState state,
222: Rectangle2D dataArea,
223: CategoryPlot plot,
224: CategoryAxis domainAxis,
225: ValueAxis rangeAxis,
226: CategoryDataset data,
227: int row,
228: int column) {
229:
230:
231: Number dataValue = data.getValue(row, column);
232: if (dataValue == null) {
233: return;
234: }
235:
236:
237: double value = dataValue.doubleValue();
238: double base = 0.0;
239: double lclip = getLowerClip();
240: double uclip = getUpperClip();
241: if (uclip <= 0.0) {
242: if (value >= uclip) {
243: return;
244: }
245: base = uclip;
246: if (value <= lclip) {
247: value = lclip;
248: }
249: }
250: else if (lclip <= 0.0) {
251: if (value >= uclip) {
252: value = uclip;
253: }
254: else {
255: if (value <= lclip) {
256: value = lclip;
257: }
258: }
259: }
260: else {
261: if (value <= lclip) {
262: return;
263: }
264: base = lclip;
265: if (value >= uclip) {
266: value = uclip;
267: }
268: }
269:
270: RectangleEdge edge = plot.getRangeAxisEdge();
271: double transX1 = rangeAxis.valueToJava2D(base, dataArea, edge);
272: double transX2 = rangeAxis.valueToJava2D(value, dataArea, edge);
273: double rectX = Math.min(transX1, transX2);
274: double rectWidth = Math.abs(transX2 - transX1);
275:
276:
277: double rectY = domainAxis.getCategoryMiddle(column, getColumnCount(),
278: dataArea, plot.getDomainAxisEdge()) - state.getBarWidth() / 2.0;
279:
280: int seriesCount = getRowCount();
281:
282:
283: double shift = 0.0;
284: double rectHeight = 0.0;
285: double widthFactor = 1.0;
286: double seriesBarWidth = getSeriesBarWidth(row);
287: if (!Double.isNaN(seriesBarWidth)) {
288: widthFactor = seriesBarWidth;
289: }
290: rectHeight = widthFactor * state.getBarWidth();
291: rectY = rectY + (1 - widthFactor) * state.getBarWidth() / 2.0;
292: if (seriesCount > 1) {
293: shift = rectHeight * 0.20 / (seriesCount - 1);
294: }
295:
296: Rectangle2D bar = new Rectangle2D.Double(rectX,
297: (rectY + ((seriesCount - 1 - row) * shift)), rectWidth,
298: (rectHeight - (seriesCount - 1 - row) * shift * 2));
299:
300: Paint itemPaint = getItemPaint(row, column);
301: GradientPaintTransformer t = getGradientPaintTransformer();
302: if (t != null && itemPaint instanceof GradientPaint) {
303: itemPaint = t.transform((GradientPaint) itemPaint, bar);
304: }
305: g2.setPaint(itemPaint);
306: g2.fill(bar);
307:
308:
309: if (isDrawBarOutline()
310: && state.getBarWidth() > BAR_OUTLINE_WIDTH_THRESHOLD) {
311: Stroke stroke = getItemOutlineStroke(row, column);
312: Paint paint = getItemOutlinePaint(row, column);
313: if (stroke != null && paint != null) {
314: g2.setStroke(stroke);
315: g2.setPaint(paint);
316: g2.draw(bar);
317: }
318: }
319:
320: CategoryItemLabelGenerator generator
321: = getItemLabelGenerator(row, column);
322: if (generator != null && isItemLabelVisible(row, column)) {
323: drawItemLabel(g2, data, row, column, plot, generator, bar,
324: (transX1 > transX2));
325: }
326:
327:
328: if (state.getInfo() != null) {
329: EntityCollection entities = state.getEntityCollection();
330: if (entities != null) {
331: String tip = null;
332: CategoryToolTipGenerator tipster
333: = getToolTipGenerator(row, column);
334: if (tipster != null) {
335: tip = tipster.generateToolTip(data, row, column);
336: }
337: String url = null;
338: if (getItemURLGenerator(row, column) != null) {
339: url = getItemURLGenerator(row, column).generateURL(data,
340: row, column);
341: }
342: CategoryItemEntity entity = new CategoryItemEntity(bar, tip,
343: url, data, data.getRowKey(row),
344: data.getColumnKey(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, data.getRowKey(row),
494: data.getColumnKey(column));
495: entities.add(entity);
496: }
497: }
498: }
499:
500: }