1:
62:
63: package ;
64:
65: import ;
66: import ;
67: import ;
68: import ;
69: import ;
70: import ;
71: import ;
72:
73: import ;
74: import ;
75: import ;
76: import ;
77: import ;
78: import ;
79: import ;
80: import ;
81: import ;
82: import ;
83: import ;
84:
85:
90: public class XYBubbleRenderer extends AbstractXYItemRenderer
91: implements XYItemRenderer,
92: Cloneable,
93: PublicCloneable,
94: Serializable {
95:
96:
97: public static final long serialVersionUID = -5221991598674249125L;
98:
99:
103: public static final int SCALE_ON_BOTH_AXES = 0;
104:
105:
109: public static final int SCALE_ON_DOMAIN_AXIS = 1;
110:
111:
115: public static final int SCALE_ON_RANGE_AXIS = 2;
116:
117:
118: private int scaleType;
119:
120:
123: public XYBubbleRenderer() {
124: this(SCALE_ON_BOTH_AXES);
125: }
126:
127:
134: public XYBubbleRenderer(int scaleType) {
135: super();
136: if (scaleType < 0 || scaleType > 2) {
137: throw new IllegalArgumentException("Invalid 'scaleType'.");
138: }
139: this.scaleType = scaleType;
140: }
141:
142:
148: public int getScaleType() {
149: return this.scaleType;
150: }
151:
152:
170: public void drawItem(Graphics2D g2, XYItemRendererState state,
171: Rectangle2D dataArea, PlotRenderingInfo info, XYPlot plot,
172: ValueAxis domainAxis, ValueAxis rangeAxis, XYDataset dataset,
173: int series, int item, CrosshairState crosshairState, int pass) {
174:
175:
176: if (!getItemVisible(series, item)) {
177: return;
178: }
179:
180: PlotOrientation orientation = plot.getOrientation();
181:
182:
183: double x = dataset.getXValue(series, item);
184: double y = dataset.getYValue(series, item);
185: double z = Double.NaN;
186: if (dataset instanceof XYZDataset) {
187: XYZDataset xyzData = (XYZDataset) dataset;
188: z = xyzData.getZValue(series, item);
189: }
190: if (!Double.isNaN(z)) {
191: RectangleEdge domainAxisLocation = plot.getDomainAxisEdge();
192: RectangleEdge rangeAxisLocation = plot.getRangeAxisEdge();
193: double transX = domainAxis.valueToJava2D(x, dataArea,
194: domainAxisLocation);
195: double transY = rangeAxis.valueToJava2D(y, dataArea,
196: rangeAxisLocation);
197:
198: double transDomain = 0.0;
199: double transRange = 0.0;
200: double zero;
201:
202: switch(getScaleType()) {
203: case SCALE_ON_DOMAIN_AXIS:
204: zero = domainAxis.valueToJava2D(0.0, dataArea,
205: domainAxisLocation);
206: transDomain = domainAxis.valueToJava2D(z, dataArea,
207: domainAxisLocation) - zero;
208: transRange = transDomain;
209: break;
210: case SCALE_ON_RANGE_AXIS:
211: zero = rangeAxis.valueToJava2D(0.0, dataArea,
212: rangeAxisLocation);
213: transRange = zero - rangeAxis.valueToJava2D(z, dataArea,
214: rangeAxisLocation);
215: transDomain = transRange;
216: break;
217: default:
218: double zero1 = domainAxis.valueToJava2D(0.0, dataArea,
219: domainAxisLocation);
220: double zero2 = rangeAxis.valueToJava2D(0.0, dataArea,
221: rangeAxisLocation);
222: transDomain = domainAxis.valueToJava2D(z, dataArea,
223: domainAxisLocation) - zero1;
224: transRange = zero2 - rangeAxis.valueToJava2D(z, dataArea,
225: rangeAxisLocation);
226: }
227: transDomain = Math.abs(transDomain);
228: transRange = Math.abs(transRange);
229: Ellipse2D circle = null;
230: if (orientation == PlotOrientation.VERTICAL) {
231: circle = new Ellipse2D.Double(transX - transDomain / 2.0,
232: transY - transRange / 2.0, transDomain, transRange);
233: }
234: else if (orientation == PlotOrientation.HORIZONTAL) {
235: circle = new Ellipse2D.Double(transY - transRange / 2.0,
236: transX - transDomain / 2.0, transRange, transDomain);
237: }
238: g2.setPaint(getItemPaint(series, item));
239: g2.fill(circle);
240: g2.setStroke(getItemOutlineStroke(series, item));
241: g2.setPaint(getItemOutlinePaint(series, item));
242: g2.draw(circle);
243:
244: if (isItemLabelVisible(series, item)) {
245: if (orientation == PlotOrientation.VERTICAL) {
246: drawItemLabel(g2, orientation, dataset, series, item,
247: transX, transY, false);
248: }
249: else if (orientation == PlotOrientation.HORIZONTAL) {
250: drawItemLabel(g2, orientation, dataset, series, item,
251: transY, transX, false);
252: }
253: }
254:
255:
256: EntityCollection entities = null;
257: if (info != null) {
258: entities = info.getOwner().getEntityCollection();
259: if (entities != null && circle.intersects(dataArea)) {
260: addEntity(entities, circle, dataset, series, item,
261: circle.getCenterX(), circle.getCenterY());
262: }
263: }
264:
265: int domainAxisIndex = plot.getDomainAxisIndex(domainAxis);
266: int rangeAxisIndex = plot.getRangeAxisIndex(rangeAxis);
267: updateCrosshairValues(crosshairState, x, y, domainAxisIndex,
268: rangeAxisIndex, transX, transY, orientation);
269: }
270:
271: }
272:
273:
282: public LegendItem getLegendItem(int datasetIndex, int series) {
283: LegendItem result = null;
284: XYPlot plot = getPlot();
285: if (plot == null) {
286: return null;
287: }
288:
289: XYDataset dataset = plot.getDataset(datasetIndex);
290: if (dataset != null) {
291: if (getItemVisible(series, 0)) {
292: String label = getLegendItemLabelGenerator().generateLabel(
293: dataset, series);
294: String description = label;
295: String toolTipText = null;
296: if (getLegendItemToolTipGenerator() != null) {
297: toolTipText = getLegendItemToolTipGenerator().generateLabel(
298: dataset, series);
299: }
300: String urlText = null;
301: if (getLegendItemURLGenerator() != null) {
302: urlText = getLegendItemURLGenerator().generateLabel(
303: dataset, series);
304: }
305: Shape shape = new Ellipse2D.Double(-4.0, -4.0, 8.0, 8.0);
306: Paint paint = lookupSeriesPaint(series);
307: Paint outlinePaint = lookupSeriesOutlinePaint(series);
308: Stroke outlineStroke = lookupSeriesOutlineStroke(series);
309: result = new LegendItem(label, description, toolTipText,
310: urlText, shape, paint, outlineStroke, outlinePaint);
311: result.setDataset(dataset);
312: result.setDatasetIndex(datasetIndex);
313: result.setSeriesKey(dataset.getSeriesKey(series));
314: result.setSeriesIndex(series);
315: }
316: }
317: return result;
318: }
319:
320:
327: public boolean equals(Object obj) {
328: if (obj == this) {
329: return true;
330: }
331: if (!(obj instanceof XYBubbleRenderer)) {
332: return false;
333: }
334: XYBubbleRenderer that = (XYBubbleRenderer) obj;
335: if (this.scaleType != that.scaleType) {
336: return false;
337: }
338: return super.equals(obj);
339: }
340:
341:
348: public Object clone() throws CloneNotSupportedException {
349: return super.clone();
350: }
351:
352: }