1:
48:
49: package ;
50:
51: import ;
52: import ;
53: import ;
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: import ;
74: import ;
75: import ;
76:
77:
82: public class StatisticalLineAndShapeRenderer extends LineAndShapeRenderer
83: implements Cloneable, PublicCloneable, Serializable {
84:
85:
86: private static final long serialVersionUID = -3557517173697777579L;
87:
88:
89: private transient Paint errorIndicatorPaint;
90:
91:
94: public StatisticalLineAndShapeRenderer() {
95: this(true, true);
96: }
97:
98:
104: public StatisticalLineAndShapeRenderer(boolean linesVisible,
105: boolean shapesVisible) {
106: super(linesVisible, shapesVisible);
107: this.errorIndicatorPaint = null;
108: }
109:
110:
116: public Paint getErrorIndicatorPaint() {
117: return this.errorIndicatorPaint;
118: }
119:
120:
126: public void setErrorIndicatorPaint(Paint paint) {
127: this.errorIndicatorPaint = paint;
128: notifyListeners(new RendererChangeEvent(this));
129: }
130:
131:
146: public void drawItem(Graphics2D g2,
147: CategoryItemRendererState state,
148: Rectangle2D dataArea,
149: CategoryPlot plot,
150: CategoryAxis domainAxis,
151: ValueAxis rangeAxis,
152: CategoryDataset dataset,
153: int row,
154: int column,
155: int pass) {
156:
157:
158: Number v = dataset.getValue(row, column);
159: if (v == null) {
160: return;
161: }
162:
163: StatisticalCategoryDataset statData
164: = (StatisticalCategoryDataset) dataset;
165:
166: Number meanValue = statData.getMeanValue(row, column);
167:
168: PlotOrientation orientation = plot.getOrientation();
169:
170:
171: double x1 = domainAxis.getCategoryMiddle(column, getColumnCount(),
172: dataArea, plot.getDomainAxisEdge());
173:
174: double y1 = rangeAxis.valueToJava2D(meanValue.doubleValue(), dataArea,
175: plot.getRangeAxisEdge());
176:
177: Shape shape = getItemShape(row, column);
178: if (orientation == PlotOrientation.HORIZONTAL) {
179: shape = ShapeUtilities.createTranslatedShape(shape, y1, x1);
180: }
181: else if (orientation == PlotOrientation.VERTICAL) {
182: shape = ShapeUtilities.createTranslatedShape(shape, x1, y1);
183: }
184: if (getItemShapeVisible(row, column)) {
185:
186: if (getItemShapeFilled(row, column)) {
187: g2.setPaint(getItemPaint(row, column));
188: g2.fill(shape);
189: }
190: else {
191: if (getUseOutlinePaint()) {
192: g2.setPaint(getItemOutlinePaint(row, column));
193: }
194: else {
195: g2.setPaint(getItemPaint(row, column));
196: }
197: g2.setStroke(getItemOutlineStroke(row, column));
198: g2.draw(shape);
199: }
200: }
201:
202: if (getItemLineVisible(row, column)) {
203: if (column != 0) {
204:
205: Number previousValue = statData.getValue(row, column - 1);
206: if (previousValue != null) {
207:
208:
209: double previous = previousValue.doubleValue();
210: double x0 = domainAxis.getCategoryMiddle(column - 1,
211: getColumnCount(), dataArea,
212: plot.getDomainAxisEdge());
213: double y0 = rangeAxis.valueToJava2D(previous, dataArea,
214: plot.getRangeAxisEdge());
215:
216: Line2D line = null;
217: if (orientation == PlotOrientation.HORIZONTAL) {
218: line = new Line2D.Double(y0, x0, y1, x1);
219: }
220: else if (orientation == PlotOrientation.VERTICAL) {
221: line = new Line2D.Double(x0, y0, x1, y1);
222: }
223: g2.setPaint(getItemPaint(row, column));
224: g2.setStroke(getItemStroke(row, column));
225: g2.draw(line);
226: }
227: }
228: }
229:
230: RectangleEdge yAxisLocation = plot.getRangeAxisEdge();
231: RectangleEdge xAxisLocation = plot.getDomainAxisEdge();
232: double rectX = domainAxis.getCategoryStart(column, getColumnCount(),
233: dataArea, xAxisLocation);
234:
235: rectX = rectX + row * state.getBarWidth();
236:
237: g2.setPaint(getItemPaint(row, column));
238:
239:
240: double valueDelta = statData.getStdDevValue(row, column).doubleValue();
241:
242: double highVal, lowVal;
243: if ((meanValue.doubleValue() + valueDelta)
244: > rangeAxis.getRange().getUpperBound()) {
245: highVal = rangeAxis.valueToJava2D(
246: rangeAxis.getRange().getUpperBound(), dataArea,
247: yAxisLocation);
248: }
249: else {
250: highVal = rangeAxis.valueToJava2D(meanValue.doubleValue()
251: + valueDelta, dataArea, yAxisLocation);
252: }
253:
254: if ((meanValue.doubleValue() + valueDelta)
255: < rangeAxis.getRange().getLowerBound()) {
256: lowVal = rangeAxis.valueToJava2D(
257: rangeAxis.getRange().getLowerBound(), dataArea,
258: yAxisLocation);
259: }
260: else {
261: lowVal = rangeAxis.valueToJava2D(meanValue.doubleValue()
262: - valueDelta, dataArea, yAxisLocation);
263: }
264:
265: if (this.errorIndicatorPaint != null) {
266: g2.setPaint(this.errorIndicatorPaint);
267: }
268: else {
269: g2.setPaint(getItemPaint(row, column));
270: }
271: Line2D line = new Line2D.Double();
272: if (orientation == PlotOrientation.HORIZONTAL) {
273: line.setLine(lowVal, x1, highVal, x1);
274: g2.draw(line);
275: line.setLine(lowVal, x1 - 5.0d, lowVal, x1 + 5.0d);
276: g2.draw(line);
277: line.setLine(highVal, x1 - 5.0d, highVal, x1 + 5.0d);
278: g2.draw(line);
279: }
280: else {
281: line.setLine(x1, lowVal, x1, highVal);
282: g2.draw(line);
283: line.setLine(x1 - 5.0d, highVal, x1 + 5.0d, highVal);
284: g2.draw(line);
285: line.setLine(x1 - 5.0d, lowVal, x1 + 5.0d, lowVal);
286: g2.draw(line);
287: }
288:
289:
290: if (isItemLabelVisible(row, column)) {
291: if (orientation == PlotOrientation.HORIZONTAL) {
292: drawItemLabel(g2, orientation, dataset, row, column,
293: y1, x1, (meanValue.doubleValue() < 0.0));
294: }
295: else if (orientation == PlotOrientation.VERTICAL) {
296: drawItemLabel(g2, orientation, dataset, row, column,
297: x1, y1, (meanValue.doubleValue() < 0.0));
298: }
299: }
300:
301:
302: if (state.getInfo() != null) {
303: EntityCollection entities = state.getEntityCollection();
304: if (entities != null && shape != null) {
305: String tip = null;
306: CategoryToolTipGenerator tipster = getToolTipGenerator(row,
307: column);
308: if (tipster != null) {
309: tip = tipster.generateToolTip(dataset, row, column);
310: }
311: String url = null;
312: if (getItemURLGenerator(row, column) != null) {
313: url = getItemURLGenerator(row, column).generateURL(
314: dataset, row, column);
315: }
316: CategoryItemEntity entity = new CategoryItemEntity(shape, tip,
317: url, dataset, row, dataset.getColumnKey(column),
318: column);
319: entities.add(entity);
320:
321: }
322:
323: }
324:
325: }
326:
327:
334: public boolean equals(Object obj) {
335: if (obj == this) {
336: return true;
337: }
338: if (!(obj instanceof StatisticalLineAndShapeRenderer)) {
339: return false;
340: }
341: if (!super.equals(obj)) {
342: return false;
343: }
344: StatisticalLineAndShapeRenderer that
345: = (StatisticalLineAndShapeRenderer) obj;
346: if (!PaintUtilities.equal(this.errorIndicatorPaint,
347: that.errorIndicatorPaint)) {
348: return false;
349: }
350: return true;
351: }
352:
353:
360: private void writeObject(ObjectOutputStream stream) throws IOException {
361: stream.defaultWriteObject();
362: SerialUtilities.writePaint(this.errorIndicatorPaint, stream);
363: }
364:
365:
373: private void readObject(ObjectInputStream stream)
374: throws IOException, ClassNotFoundException {
375: stream.defaultReadObject();
376: this.errorIndicatorPaint = SerialUtilities.readPaint(stream);
377: }
378:
379: }