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