1:
45:
46: package ;
47:
48: import ;
49: import ;
50: import ;
51: import ;
52: import ;
53: import ;
54:
55: import ;
56: import ;
57: import ;
58: import ;
59: import ;
60: import ;
61: import ;
62: import ;
63: import ;
64: import ;
65: import ;
66: import ;
67: import ;
68:
69:
73: public class LevelRenderer extends AbstractCategoryItemRenderer
74: implements Cloneable, PublicCloneable, Serializable {
75:
76:
77: private static final long serialVersionUID = -8204856624355025117L;
78:
79:
80: public static final double DEFAULT_ITEM_MARGIN = 0.20;
81:
82:
83: private double itemMargin;
84:
85:
86: private double maxItemWidth;
87:
88:
91: public LevelRenderer() {
92: super();
93: this.itemMargin = DEFAULT_ITEM_MARGIN;
94: this.maxItemWidth = 1.0;
95:
96: }
97:
98:
103: public double getItemMargin() {
104: return this.itemMargin;
105: }
106:
107:
115: public void setItemMargin(double percent) {
116: this.itemMargin = percent;
117: fireChangeEvent();
118: }
119:
120:
128: public double getMaxItemWidth() {
129: return this.maxItemWidth;
130: }
131:
132:
141: public void setMaxItemWidth(double percent) {
142: this.maxItemWidth = percent;
143: fireChangeEvent();
144: }
145:
146:
152: public double getMaximumItemWidth() {
153: return getMaxItemWidth();
154: }
155:
156:
163: public void setMaximumItemWidth(double percent) {
164: setMaxItemWidth(percent);
165: }
166:
167:
183: public CategoryItemRendererState initialise(Graphics2D g2,
184: Rectangle2D dataArea,
185: CategoryPlot plot,
186: int rendererIndex,
187: PlotRenderingInfo info) {
188:
189: CategoryItemRendererState state = super.initialise(g2, dataArea, plot,
190: rendererIndex, info);
191: calculateItemWidth(plot, dataArea, rendererIndex, state);
192: return state;
193:
194: }
195:
196:
204: protected void calculateItemWidth(CategoryPlot plot,
205: Rectangle2D dataArea,
206: int rendererIndex,
207: CategoryItemRendererState state) {
208:
209: CategoryAxis domainAxis = getDomainAxis(plot, rendererIndex);
210: CategoryDataset dataset = plot.getDataset(rendererIndex);
211: if (dataset != null) {
212: int columns = dataset.getColumnCount();
213: int rows = dataset.getRowCount();
214: double space = 0.0;
215: PlotOrientation orientation = plot.getOrientation();
216: if (orientation == PlotOrientation.HORIZONTAL) {
217: space = dataArea.getHeight();
218: }
219: else if (orientation == PlotOrientation.VERTICAL) {
220: space = dataArea.getWidth();
221: }
222: double maxWidth = space * getMaxItemWidth();
223: double categoryMargin = 0.0;
224: double currentItemMargin = 0.0;
225: if (columns > 1) {
226: categoryMargin = domainAxis.getCategoryMargin();
227: }
228: if (rows > 1) {
229: currentItemMargin = getItemMargin();
230: }
231: double used = space * (1 - domainAxis.getLowerMargin()
232: - domainAxis.getUpperMargin()
233: - categoryMargin - currentItemMargin);
234: if ((rows * columns) > 0) {
235: state.setBarWidth(Math.min(used / (rows * columns), maxWidth));
236: }
237: else {
238: state.setBarWidth(Math.min(used, maxWidth));
239: }
240: }
241: }
242:
243:
258: protected double calculateBarW0(CategoryPlot plot,
259: PlotOrientation orientation,
260: Rectangle2D dataArea,
261: CategoryAxis domainAxis,
262: CategoryItemRendererState state,
263: int row,
264: int column) {
265:
266: double space = 0.0;
267: if (orientation == PlotOrientation.HORIZONTAL) {
268: space = dataArea.getHeight();
269: }
270: else {
271: space = dataArea.getWidth();
272: }
273: double barW0 = domainAxis.getCategoryStart(column, getColumnCount(),
274: dataArea, plot.getDomainAxisEdge());
275: int seriesCount = getRowCount();
276: int categoryCount = getColumnCount();
277: if (seriesCount > 1) {
278: double seriesGap = space * getItemMargin()
279: / (categoryCount * (seriesCount - 1));
280: double seriesW = calculateSeriesWidth(space, domainAxis,
281: categoryCount, seriesCount);
282: barW0 = barW0 + row * (seriesW + seriesGap)
283: + (seriesW / 2.0) - (state.getBarWidth() / 2.0);
284: }
285: else {
286: barW0 = domainAxis.getCategoryMiddle(column, getColumnCount(),
287: dataArea, plot.getDomainAxisEdge()) - state.getBarWidth()
288: / 2.0;
289: }
290: return barW0;
291: }
292:
293:
307: public void drawItem(Graphics2D g2, CategoryItemRendererState state,
308: Rectangle2D dataArea, CategoryPlot plot, CategoryAxis domainAxis,
309: ValueAxis rangeAxis, CategoryDataset dataset, int row, int column,
310: int pass) {
311:
312:
313: Number dataValue = dataset.getValue(row, column);
314: if (dataValue == null) {
315: return;
316: }
317:
318: double value = dataValue.doubleValue();
319:
320: PlotOrientation orientation = plot.getOrientation();
321: double barW0 = calculateBarW0(plot, orientation, dataArea, domainAxis,
322: state, row, column);
323: RectangleEdge edge = plot.getRangeAxisEdge();
324: double barL = rangeAxis.valueToJava2D(value, dataArea, edge);
325:
326:
327: Line2D line = null;
328: double x = 0.0;
329: double y = 0.0;
330: if (orientation == PlotOrientation.HORIZONTAL) {
331: x = barL;
332: y = barW0 + state.getBarWidth() / 2.0;
333: line = new Line2D.Double(barL, barW0, barL,
334: barW0 + state.getBarWidth());
335: }
336: else {
337: x = barW0 + state.getBarWidth() / 2.0;
338: y = barL;
339: line = new Line2D.Double(barW0, barL, barW0 + state.getBarWidth(),
340: barL);
341: }
342: Stroke itemStroke = getItemStroke(row, column);
343: Paint itemPaint = getItemPaint(row, column);
344: g2.setStroke(itemStroke);
345: g2.setPaint(itemPaint);
346: g2.draw(line);
347:
348: CategoryItemLabelGenerator generator = getItemLabelGenerator(row,
349: column);
350: if (generator != null && isItemLabelVisible(row, column)) {
351: drawItemLabel(g2, orientation, dataset, row, column, x, y,
352: (value < 0.0));
353: }
354:
355:
356: if (state.getInfo() != null) {
357: EntityCollection entities = state.getEntityCollection();
358: if (entities != null) {
359: String tip = null;
360: CategoryToolTipGenerator tipster = getToolTipGenerator(row,
361: column);
362: if (tipster != null) {
363: tip = tipster.generateToolTip(dataset, row, column);
364: }
365: String url = null;
366: if (getItemURLGenerator(row, column) != null) {
367: url = getItemURLGenerator(row, column).generateURL(dataset,
368: row, column);
369: }
370: CategoryItemEntity entity = new CategoryItemEntity(
371: line.getBounds(), tip, url, dataset,
372: dataset.getRowKey(row), dataset.getColumnKey(column));
373: entities.add(entity);
374: }
375:
376: }
377:
378: }
379:
380:
390: protected double calculateSeriesWidth(double space, CategoryAxis axis,
391: int categories, int series) {
392: double factor = 1.0 - getItemMargin() - axis.getLowerMargin()
393: - axis.getUpperMargin();
394: if (categories > 1) {
395: factor = factor - axis.getCategoryMargin();
396: }
397: return (space * factor) / (categories * series);
398: }
399:
400:
407: public boolean equals(Object obj) {
408: if (obj == this) {
409: return true;
410: }
411: if (!(obj instanceof LevelRenderer)) {
412: return false;
413: }
414: if (!super.equals(obj)) {
415: return false;
416: }
417: LevelRenderer that = (LevelRenderer) obj;
418: if (this.itemMargin != that.itemMargin) {
419: return false;
420: }
421: if (this.maxItemWidth != that.maxItemWidth) {
422: return false;
423: }
424: return true;
425: }
426:
427: }