1:
60:
61: package ;
62:
63: import ;
64: import ;
65: import ;
66: import ;
67: import ;
68: import ;
69: import ;
70:
71: import ;
72: import ;
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: PlotOrientation orientation = plot.getOrientation();
176:
177:
178: double x = dataset.getXValue(series, item);
179: double y = dataset.getYValue(series, item);
180: double z = Double.NaN;
181: if (dataset instanceof XYZDataset) {
182: XYZDataset xyzData = (XYZDataset) dataset;
183: z = xyzData.getZValue(series, item);
184: }
185: if (!Double.isNaN(z)) {
186: RectangleEdge domainAxisLocation = plot.getDomainAxisEdge();
187: RectangleEdge rangeAxisLocation = plot.getRangeAxisEdge();
188: double transX = domainAxis.valueToJava2D(x, dataArea,
189: domainAxisLocation);
190: double transY = rangeAxis.valueToJava2D(y, dataArea,
191: rangeAxisLocation);
192:
193: double transDomain = 0.0;
194: double transRange = 0.0;
195: double zero;
196:
197: switch(getScaleType()) {
198: case SCALE_ON_DOMAIN_AXIS:
199: zero = domainAxis.valueToJava2D(0.0, dataArea,
200: domainAxisLocation);
201: transDomain = domainAxis.valueToJava2D(z, dataArea,
202: domainAxisLocation) - zero;
203: transRange = transDomain;
204: break;
205: case SCALE_ON_RANGE_AXIS:
206: zero = rangeAxis.valueToJava2D(0.0, dataArea,
207: rangeAxisLocation);
208: transRange = zero - rangeAxis.valueToJava2D(z, dataArea,
209: rangeAxisLocation);
210: transDomain = transRange;
211: break;
212: default:
213: double zero1 = domainAxis.valueToJava2D(0.0, dataArea,
214: domainAxisLocation);
215: double zero2 = rangeAxis.valueToJava2D(0.0, dataArea,
216: rangeAxisLocation);
217: transDomain = domainAxis.valueToJava2D(z, dataArea,
218: domainAxisLocation) - zero1;
219: transRange = zero2 - rangeAxis.valueToJava2D(z, dataArea,
220: rangeAxisLocation);
221: }
222: transDomain = Math.abs(transDomain);
223: transRange = Math.abs(transRange);
224: Ellipse2D circle = null;
225: if (orientation == PlotOrientation.VERTICAL) {
226: circle = new Ellipse2D.Double(transX - transDomain / 2.0,
227: transY - transRange / 2.0, transDomain, transRange);
228: }
229: else if (orientation == PlotOrientation.HORIZONTAL) {
230: circle = new Ellipse2D.Double(transY - transRange / 2.0,
231: transX - transDomain / 2.0, transRange, transDomain);
232: }
233: g2.setPaint(getItemPaint(series, item));
234: g2.fill(circle);
235: g2.setStroke(getItemOutlineStroke(series, item));
236: g2.setPaint(getItemOutlinePaint(series, item));
237: g2.draw(circle);
238:
239: if (isItemLabelVisible(series, item)) {
240: if (orientation == PlotOrientation.VERTICAL) {
241: drawItemLabel(g2, orientation, dataset, series, item,
242: transX, transY, false);
243: }
244: else if (orientation == PlotOrientation.HORIZONTAL) {
245: drawItemLabel(g2, orientation, dataset, series, item,
246: transY, transX, false);
247: }
248: }
249:
250:
251: EntityCollection entities = null;
252: if (info != null) {
253: entities = info.getOwner().getEntityCollection();
254: }
255:
256:
257: if (entities != null) {
258: String tip = null;
259: XYToolTipGenerator generator
260: = getToolTipGenerator(series, item);
261: if (generator != null) {
262: tip = generator.generateToolTip(dataset, series, item);
263: }
264: String url = null;
265: if (getURLGenerator() != null) {
266: url = getURLGenerator().generateURL(dataset, series, item);
267: }
268: XYItemEntity entity = new XYItemEntity(circle, dataset, series,
269: item, tip, url);
270: entities.add(entity);
271: }
272:
273: int domainAxisIndex = plot.getDomainAxisIndex(domainAxis);
274: int rangeAxisIndex = plot.getRangeAxisIndex(rangeAxis);
275: updateCrosshairValues(crosshairState, x, y, domainAxisIndex,
276: rangeAxisIndex, transX, transY, orientation);
277: }
278:
279: }
280:
281:
290: public LegendItem getLegendItem(int datasetIndex, int series) {
291: LegendItem result = null;
292: XYPlot xyplot = getPlot();
293: if (xyplot != null) {
294: XYDataset dataset = xyplot.getDataset(datasetIndex);
295: if (dataset != null) {
296: if (getItemVisible(series, 0)) {
297: String label = getLegendItemLabelGenerator().generateLabel(
298: dataset, series);
299: String description = label;
300: String toolTipText = null;
301: if (getLegendItemToolTipGenerator() != null) {
302: toolTipText
303: = getLegendItemToolTipGenerator().generateLabel(
304: dataset, series);
305: }
306: String urlText = null;
307: if (getLegendItemURLGenerator() != null) {
308: urlText = getLegendItemURLGenerator().generateLabel(
309: dataset, series);
310: }
311: Shape shape = new Ellipse2D.Double(-4.0, -4.0, 8.0, 8.0);
312: Paint paint = getSeriesPaint(series);
313: Paint outlinePaint = getSeriesOutlinePaint(series);
314: Stroke outlineStroke = getSeriesOutlineStroke(series);
315: result = new LegendItem(label, description,
316: toolTipText, urlText, shape, paint,
317: outlineStroke, outlinePaint);
318: }
319: }
320:
321: }
322: return result;
323: }
324:
325:
332: public boolean equals(Object obj) {
333: if (obj == this) {
334: return true;
335: }
336: if (!(obj instanceof XYBubbleRenderer)) {
337: return false;
338: }
339: XYBubbleRenderer that = (XYBubbleRenderer) obj;
340: if (this.scaleType != that.scaleType) {
341: return false;
342: }
343: return super.equals(obj);
344: }
345:
346:
353: public Object clone() throws CloneNotSupportedException {
354: return super.clone();
355: }
356:
357: }