1:
52:
53: package ;
54:
55: import ;
56: import ;
57: import ;
58: import ;
59: import ;
60: import ;
61: import ;
62: import ;
63: import ;
64:
65: import ;
66: import ;
67: import ;
68: import ;
69: import ;
70: import ;
71: import ;
72: import ;
73: import ;
74: import ;
75: import ;
76: import ;
77: import ;
78:
79:
84: public class StatisticalLineAndShapeRenderer extends LineAndShapeRenderer
85: implements Cloneable, PublicCloneable, Serializable {
86:
87:
88: private static final long serialVersionUID = -3557517173697777579L;
89:
90:
91: private transient Paint errorIndicatorPaint;
92:
93:
96: public StatisticalLineAndShapeRenderer() {
97: this(true, true);
98: }
99:
100:
106: public StatisticalLineAndShapeRenderer(boolean linesVisible,
107: boolean shapesVisible) {
108: super(linesVisible, shapesVisible);
109: this.errorIndicatorPaint = null;
110: }
111:
112:
120: public Paint getErrorIndicatorPaint() {
121: return this.errorIndicatorPaint;
122: }
123:
124:
133: public void setErrorIndicatorPaint(Paint paint) {
134: this.errorIndicatorPaint = paint;
135: notifyListeners(new RendererChangeEvent(this));
136: }
137:
138:
153: public void drawItem(Graphics2D g2,
154: CategoryItemRendererState state,
155: Rectangle2D dataArea,
156: CategoryPlot plot,
157: CategoryAxis domainAxis,
158: ValueAxis rangeAxis,
159: CategoryDataset dataset,
160: int row,
161: int column,
162: int pass) {
163:
164:
165: if (!getItemVisible(row, column)) {
166: return;
167: }
168:
169:
170: Number v = dataset.getValue(row, column);
171: if (v == null) {
172: return;
173: }
174:
175:
176:
177: if (!(dataset instanceof StatisticalCategoryDataset)) {
178: super.drawItem(g2, state, dataArea, plot, domainAxis, rangeAxis,
179: dataset, row, column, pass);
180: return;
181: }
182:
183: StatisticalCategoryDataset statData
184: = (StatisticalCategoryDataset) dataset;
185:
186: Number meanValue = statData.getMeanValue(row, column);
187:
188: PlotOrientation orientation = plot.getOrientation();
189:
190:
191: double x1;
192: if (getUseSeriesOffset()) {
193: x1 = domainAxis.getCategorySeriesMiddle(dataset.getColumnKey(
194: column), dataset.getRowKey(row), dataset, getItemMargin(),
195: dataArea, plot.getDomainAxisEdge());
196: }
197: else {
198: x1 = domainAxis.getCategoryMiddle(column, getColumnCount(),
199: dataArea, plot.getDomainAxisEdge());
200: }
201:
202: double y1 = rangeAxis.valueToJava2D(meanValue.doubleValue(), dataArea,
203: plot.getRangeAxisEdge());
204:
205: Shape shape = getItemShape(row, column);
206: if (orientation == PlotOrientation.HORIZONTAL) {
207: shape = ShapeUtilities.createTranslatedShape(shape, y1, x1);
208: }
209: else if (orientation == PlotOrientation.VERTICAL) {
210: shape = ShapeUtilities.createTranslatedShape(shape, x1, y1);
211: }
212: if (getItemShapeVisible(row, column)) {
213:
214: if (getItemShapeFilled(row, column)) {
215: g2.setPaint(getItemPaint(row, column));
216: g2.fill(shape);
217: }
218: else {
219: if (getUseOutlinePaint()) {
220: g2.setPaint(getItemOutlinePaint(row, column));
221: }
222: else {
223: g2.setPaint(getItemPaint(row, column));
224: }
225: g2.setStroke(getItemOutlineStroke(row, column));
226: g2.draw(shape);
227: }
228: }
229:
230: if (getItemLineVisible(row, column)) {
231: if (column != 0) {
232:
233: Number previousValue = statData.getValue(row, column - 1);
234: if (previousValue != null) {
235:
236:
237: double previous = previousValue.doubleValue();
238: double x0;
239: if (getUseSeriesOffset()) {
240: x0 = domainAxis.getCategorySeriesMiddle(
241: dataset.getColumnKey(column - 1),
242: dataset.getRowKey(row), dataset,
243: getItemMargin(), dataArea,
244: plot.getDomainAxisEdge());
245: }
246: else {
247: x0 = domainAxis.getCategoryMiddle(column - 1,
248: getColumnCount(), dataArea,
249: plot.getDomainAxisEdge());
250: }
251: double y0 = rangeAxis.valueToJava2D(previous, dataArea,
252: plot.getRangeAxisEdge());
253:
254: Line2D line = null;
255: if (orientation == PlotOrientation.HORIZONTAL) {
256: line = new Line2D.Double(y0, x0, y1, x1);
257: }
258: else if (orientation == PlotOrientation.VERTICAL) {
259: line = new Line2D.Double(x0, y0, x1, y1);
260: }
261: g2.setPaint(getItemPaint(row, column));
262: g2.setStroke(getItemStroke(row, column));
263: g2.draw(line);
264: }
265: }
266: }
267:
268: RectangleEdge yAxisLocation = plot.getRangeAxisEdge();
269: g2.setPaint(getItemPaint(row, column));
270:
271:
272: double valueDelta = statData.getStdDevValue(row, column).doubleValue();
273:
274: double highVal, lowVal;
275: if ((meanValue.doubleValue() + valueDelta)
276: > rangeAxis.getRange().getUpperBound()) {
277: highVal = rangeAxis.valueToJava2D(
278: rangeAxis.getRange().getUpperBound(), dataArea,
279: yAxisLocation);
280: }
281: else {
282: highVal = rangeAxis.valueToJava2D(meanValue.doubleValue()
283: + valueDelta, dataArea, yAxisLocation);
284: }
285:
286: if ((meanValue.doubleValue() + valueDelta)
287: < rangeAxis.getRange().getLowerBound()) {
288: lowVal = rangeAxis.valueToJava2D(
289: rangeAxis.getRange().getLowerBound(), dataArea,
290: yAxisLocation);
291: }
292: else {
293: lowVal = rangeAxis.valueToJava2D(meanValue.doubleValue()
294: - valueDelta, dataArea, yAxisLocation);
295: }
296:
297: if (this.errorIndicatorPaint != null) {
298: g2.setPaint(this.errorIndicatorPaint);
299: }
300: else {
301: g2.setPaint(getItemPaint(row, column));
302: }
303: Line2D line = new Line2D.Double();
304: if (orientation == PlotOrientation.HORIZONTAL) {
305: line.setLine(lowVal, x1, highVal, x1);
306: g2.draw(line);
307: line.setLine(lowVal, x1 - 5.0d, lowVal, x1 + 5.0d);
308: g2.draw(line);
309: line.setLine(highVal, x1 - 5.0d, highVal, x1 + 5.0d);
310: g2.draw(line);
311: }
312: else {
313: line.setLine(x1, lowVal, x1, highVal);
314: g2.draw(line);
315: line.setLine(x1 - 5.0d, highVal, x1 + 5.0d, highVal);
316: g2.draw(line);
317: line.setLine(x1 - 5.0d, lowVal, x1 + 5.0d, lowVal);
318: g2.draw(line);
319: }
320:
321:
322: if (isItemLabelVisible(row, column)) {
323: if (orientation == PlotOrientation.HORIZONTAL) {
324: drawItemLabel(g2, orientation, dataset, row, column,
325: y1, x1, (meanValue.doubleValue() < 0.0));
326: }
327: else if (orientation == PlotOrientation.VERTICAL) {
328: drawItemLabel(g2, orientation, dataset, row, column,
329: x1, y1, (meanValue.doubleValue() < 0.0));
330: }
331: }
332:
333:
334: EntityCollection entities = state.getEntityCollection();
335: if (entities != null && shape != null) {
336: addItemEntity(entities, dataset, row, column, shape);
337: }
338:
339: }
340:
341:
348: public boolean equals(Object obj) {
349: if (obj == this) {
350: return true;
351: }
352: if (!(obj instanceof StatisticalLineAndShapeRenderer)) {
353: return false;
354: }
355: StatisticalLineAndShapeRenderer that
356: = (StatisticalLineAndShapeRenderer) obj;
357: if (!PaintUtilities.equal(this.errorIndicatorPaint,
358: that.errorIndicatorPaint)) {
359: return false;
360: }
361: return super.equals(obj);
362: }
363:
364:
371: private void writeObject(ObjectOutputStream stream) throws IOException {
372: stream.defaultWriteObject();
373: SerialUtilities.writePaint(this.errorIndicatorPaint, stream);
374: }
375:
376:
384: private void readObject(ObjectInputStream stream)
385: throws IOException, ClassNotFoundException {
386: stream.defaultReadObject();
387: this.errorIndicatorPaint = SerialUtilities.readPaint(stream);
388: }
389:
390: }