001: /*
002: * Copyright 2007 Pentaho Corporation. All rights reserved.
003: * This software was developed by Pentaho Corporation and is provided under the terms
004: * of the Mozilla Public License, Version 1.1, or any later version. You may not use
005: * this file except in compliance with the license. If you need a copy of the license,
006: * please go to http://www.mozilla.org/MPL/MPL-1.1.txt. The Original Code is the Pentaho
007: * BI Platform. The Initial Developer is Pentaho Corporation.
008: *
009: * Software distributed under the Mozilla Public License is distributed on an "AS IS"
010: * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. Please refer to
011: * the license for the specific language governing your rights and limitations.
012: *
013: */
014: package org.pentaho.plugin.jfreechart;
015:
016: import org.jfree.chart.renderer.xy.XYBubbleRenderer;
017: import java.awt.Graphics2D;
018: import java.awt.geom.Ellipse2D;
019: import java.awt.geom.Rectangle2D;
020:
021: import org.jfree.chart.axis.ValueAxis;
022: import org.jfree.chart.entity.EntityCollection;
023: import org.jfree.chart.entity.XYItemEntity;
024: import org.jfree.chart.labels.XYToolTipGenerator;
025: import org.jfree.chart.plot.CrosshairState;
026: import org.jfree.chart.plot.PlotOrientation;
027: import org.jfree.chart.plot.PlotRenderingInfo;
028: import org.jfree.chart.plot.XYPlot;
029: import org.jfree.data.xy.XYDataset;
030: import org.jfree.data.xy.XYZDataset;
031: import org.jfree.ui.RectangleEdge;
032: import org.jfree.chart.renderer.xy.XYItemRendererState;
033:
034: /**
035: * @author klosei
036: *
037: */
038: public class BubbleRenderer extends XYBubbleRenderer {
039: /**
040: *
041: */
042: private static final long serialVersionUID = -216587271628618807L;
043:
044: private double maxSize = 0;
045:
046: private double maxZ = 0;
047:
048: public BubbleRenderer() {
049: super ();
050: }
051:
052: /**
053: * Draws the visual representation of a single data item.
054: *
055: * @param g2 the graphics device.
056: * @param state the renderer state.
057: * @param dataArea the area within which the data is being drawn.
058: * @param info collects information about the drawing.
059: * @param plot the plot (can be used to obtain standard color
060: * information etc).
061: * @param domainAxis the domain (horizontal) axis.
062: * @param rangeAxis the range (vertical) axis.
063: * @param dataset the dataset (an {@link XYZDataset} is expected).
064: * @param series the series index (zero-based).
065: * @param item the item index (zero-based).
066: * @param crosshairState crosshair information for the plot
067: * (<code>null</code> permitted).
068: * @param pass the pass index.
069: */
070: public void drawItem(Graphics2D g2, XYItemRendererState state,
071: Rectangle2D dataArea, PlotRenderingInfo info, XYPlot plot,
072: ValueAxis domainAxis, ValueAxis rangeAxis,
073: XYDataset dataset, int series, int item,
074: CrosshairState crosshairState, int pass) {
075:
076: PlotOrientation orientation = plot.getOrientation();
077:
078: // get the data point...
079: double x = dataset.getXValue(series, item);
080: double y = dataset.getYValue(series, item);
081: double z = Double.NaN;
082: if (dataset instanceof XYZDataset) {
083: XYZDataset xyzData = (XYZDataset) dataset;
084: z = xyzData.getZValue(series, item);
085: }
086: if (!Double.isNaN(z)) {
087: RectangleEdge domainAxisLocation = plot.getDomainAxisEdge();
088: RectangleEdge rangeAxisLocation = plot.getRangeAxisEdge();
089: double transX = domainAxis.valueToJava2D(x, dataArea,
090: domainAxisLocation);
091: double transY = rangeAxis.valueToJava2D(y, dataArea,
092: rangeAxisLocation);
093:
094: double circleSize;
095:
096: circleSize = maxSize * (z / maxZ);
097:
098: circleSize = Math.abs(circleSize);
099:
100: Ellipse2D circle = null;
101: if (orientation == PlotOrientation.VERTICAL) {
102: circle = new Ellipse2D.Double(
103: transX - circleSize / 2.0, transY - circleSize
104: / 2.0, circleSize, circleSize);
105: } else if (orientation == PlotOrientation.HORIZONTAL) {
106: circle = new Ellipse2D.Double(
107: transY - circleSize / 2.0, transX - circleSize
108: / 2.0, circleSize, circleSize);
109: }
110: g2.setPaint(getItemPaint(series, item));
111: g2.fill(circle);
112: g2.setStroke(getItemOutlineStroke(series, item));
113: g2.setPaint(getItemOutlinePaint(series, item));
114: g2.draw(circle);
115:
116: if (isItemLabelVisible(series, item)) {
117: if (orientation == PlotOrientation.VERTICAL) {
118: drawItemLabel(g2, orientation, dataset, series,
119: item, transX, transY, false);
120: } else if (orientation == PlotOrientation.HORIZONTAL) {
121: drawItemLabel(g2, orientation, dataset, series,
122: item, transY, transX, false);
123: }
124: }
125:
126: // setup for collecting optional entity info...
127: EntityCollection entities = null;
128: if (info != null) {
129: entities = info.getOwner().getEntityCollection();
130: }
131:
132: // add an entity for the item...
133: if (entities != null) {
134: String tip = null;
135: XYToolTipGenerator generator = getToolTipGenerator(
136: series, item);
137: if (generator != null) {
138: tip = generator.generateToolTip(dataset, series,
139: item);
140: }
141: String url = null;
142: if (getURLGenerator() != null) {
143: url = getURLGenerator().generateURL(dataset,
144: series, item);
145: }
146: XYItemEntity entity = new XYItemEntity(circle, dataset,
147: series, item, tip, url);
148: entities.add(entity);
149: }
150:
151: int domainAxisIndex = plot.getDomainAxisIndex(domainAxis);
152: int rangeAxisIndex = plot.getRangeAxisIndex(rangeAxis);
153: updateCrosshairValues(crosshairState, x, y,
154: domainAxisIndex, rangeAxisIndex, transX, transY,
155: orientation);
156: }
157:
158: }
159:
160: /**
161: * @return
162: */
163: public double getMaxZ() {
164: return maxZ;
165: }
166:
167: /**
168: * @param maxZ
169: */
170: public void setMaxZ(double maxZ) {
171: this .maxZ = maxZ;
172: }
173:
174: /**
175: * @return
176: */
177: public double getMaxSize() {
178: return maxSize;
179: }
180:
181: /**
182: * @param size
183: */
184: public void setMaxSize(double size) {
185: this.maxSize = size;
186: }
187:
188: }
|