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