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:
114: public void setItemMargin(double percent) {
115: this.itemMargin = percent;
116: notifyListeners(new RendererChangeEvent(this));
117: }
118:
119:
127: public double getMaxItemWidth() {
128: return this.maxItemWidth;
129: }
130:
131:
140: public void setMaxItemWidth(double percent) {
141: this.maxItemWidth = percent;
142: notifyListeners(new RendererChangeEvent(this));
143: }
144:
145:
151: public double getMaximumItemWidth() {
152: return getMaxItemWidth();
153: }
154:
155:
162: public void setMaximumItemWidth(double percent) {
163: setMaxItemWidth(percent);
164: }
165:
166:
182: public CategoryItemRendererState initialise(Graphics2D g2,
183: Rectangle2D dataArea,
184: CategoryPlot plot,
185: int rendererIndex,
186: PlotRenderingInfo info) {
187:
188: CategoryItemRendererState state = super.initialise(g2, dataArea, plot,
189: rendererIndex, info);
190: calculateItemWidth(plot, dataArea, rendererIndex, state);
191: return state;
192:
193: }
194:
195:
203: protected void calculateItemWidth(CategoryPlot plot,
204: Rectangle2D dataArea,
205: int rendererIndex,
206: CategoryItemRendererState state) {
207:
208: CategoryAxis domainAxis = getDomainAxis(plot, rendererIndex);
209: CategoryDataset dataset = plot.getDataset(rendererIndex);
210: if (dataset != null) {
211: int columns = dataset.getColumnCount();
212: int rows = dataset.getRowCount();
213: double space = 0.0;
214: PlotOrientation orientation = plot.getOrientation();
215: if (orientation == PlotOrientation.HORIZONTAL) {
216: space = dataArea.getHeight();
217: }
218: else if (orientation == PlotOrientation.VERTICAL) {
219: space = dataArea.getWidth();
220: }
221: double maxWidth = space * getMaxItemWidth();
222: double categoryMargin = 0.0;
223: double currentItemMargin = 0.0;
224: if (columns > 1) {
225: categoryMargin = domainAxis.getCategoryMargin();
226: }
227: if (rows > 1) {
228: currentItemMargin = getItemMargin();
229: }
230: double used = space * (1 - domainAxis.getLowerMargin()
231: - domainAxis.getUpperMargin()
232: - categoryMargin - currentItemMargin);
233: if ((rows * columns) > 0) {
234: state.setBarWidth(Math.min(used / (rows * columns), maxWidth));
235: }
236: else {
237: state.setBarWidth(Math.min(used, maxWidth));
238: }
239: }
240: }
241:
242:
257: protected double calculateBarW0(CategoryPlot plot,
258: PlotOrientation orientation,
259: Rectangle2D dataArea,
260: CategoryAxis domainAxis,
261: CategoryItemRendererState state,
262: int row,
263: int column) {
264:
265: double space = 0.0;
266: if (orientation == PlotOrientation.HORIZONTAL) {
267: space = dataArea.getHeight();
268: }
269: else {
270: space = dataArea.getWidth();
271: }
272: double barW0 = domainAxis.getCategoryStart(column, getColumnCount(),
273: dataArea, plot.getDomainAxisEdge());
274: int seriesCount = getRowCount();
275: int categoryCount = getColumnCount();
276: if (seriesCount > 1) {
277: double seriesGap = space * getItemMargin()
278: / (categoryCount * (seriesCount - 1));
279: double seriesW = calculateSeriesWidth(space, domainAxis,
280: categoryCount, seriesCount);
281: barW0 = barW0 + row * (seriesW + seriesGap)
282: + (seriesW / 2.0) - (state.getBarWidth() / 2.0);
283: }
284: else {
285: barW0 = domainAxis.getCategoryMiddle(column, getColumnCount(),
286: dataArea, plot.getDomainAxisEdge()) - state.getBarWidth()
287: / 2.0;
288: }
289: return barW0;
290: }
291:
292:
306: public void drawItem(Graphics2D g2, CategoryItemRendererState state,
307: Rectangle2D dataArea, CategoryPlot plot, CategoryAxis domainAxis,
308: ValueAxis rangeAxis, CategoryDataset dataset, int row, int column,
309: int pass) {
310:
311:
312: Number dataValue = dataset.getValue(row, column);
313: if (dataValue == null) {
314: return;
315: }
316:
317: double value = dataValue.doubleValue();
318:
319: PlotOrientation orientation = plot.getOrientation();
320: double barW0 = calculateBarW0(plot, orientation, dataArea, domainAxis,
321: state, row, column);
322: RectangleEdge edge = plot.getRangeAxisEdge();
323: double barL = rangeAxis.valueToJava2D(value, dataArea, edge);
324:
325:
326: Line2D line = null;
327: double x = 0.0;
328: double y = 0.0;
329: if (orientation == PlotOrientation.HORIZONTAL) {
330: x = barL;
331: y = barW0 + state.getBarWidth() / 2.0;
332: line = new Line2D.Double(barL, barW0, barL,
333: barW0 + state.getBarWidth());
334: }
335: else {
336: x = barW0 + state.getBarWidth() / 2.0;
337: y = barL;
338: line = new Line2D.Double(barW0, barL, barW0 + state.getBarWidth(),
339: barL);
340: }
341: Stroke itemStroke = getItemStroke(row, column);
342: Paint itemPaint = getItemPaint(row, column);
343: g2.setStroke(itemStroke);
344: g2.setPaint(itemPaint);
345: g2.draw(line);
346:
347: CategoryItemLabelGenerator generator = getItemLabelGenerator(row,
348: column);
349: if (generator != null && isItemLabelVisible(row, column)) {
350: drawItemLabel(g2, orientation, dataset, row, column, x, y,
351: (value < 0.0));
352: }
353:
354:
355: if (state.getInfo() != null) {
356: EntityCollection entities = state.getEntityCollection();
357: if (entities != null) {
358: String tip = null;
359: CategoryToolTipGenerator tipster = getToolTipGenerator(row,
360: column);
361: if (tipster != null) {
362: tip = tipster.generateToolTip(dataset, row, column);
363: }
364: String url = null;
365: if (getItemURLGenerator(row, column) != null) {
366: url = getItemURLGenerator(row, column).generateURL(dataset,
367: row, column);
368: }
369: CategoryItemEntity entity = new CategoryItemEntity(
370: line.getBounds(), tip, url, dataset,
371: dataset.getRowKey(row), dataset.getColumnKey(column));
372: entities.add(entity);
373: }
374:
375: }
376:
377: }
378:
379:
389: protected double calculateSeriesWidth(double space, CategoryAxis axis,
390: int categories, int series) {
391: double factor = 1.0 - getItemMargin() - axis.getLowerMargin()
392: - axis.getUpperMargin();
393: if (categories > 1) {
394: factor = factor - axis.getCategoryMargin();
395: }
396: return (space * factor) / (categories * series);
397: }
398:
399:
406: public boolean equals(Object obj) {
407: if (obj == this) {
408: return true;
409: }
410: if (!(obj instanceof LevelRenderer)) {
411: return false;
412: }
413: if (!super.equals(obj)) {
414: return false;
415: }
416: LevelRenderer that = (LevelRenderer) obj;
417: if (this.itemMargin != that.itemMargin) {
418: return false;
419: }
420: if (this.maxItemWidth != that.maxItemWidth) {
421: return false;
422: }
423: return true;
424: }
425:
426: }