1. /* ===========================================================
  2. * JFreeChart : a free chart library for the Java(tm) platform
  3. * ===========================================================
  4. *
  5. * (C) Copyright 2000-2005, by Object Refinery Limited and Contributors.
  6. *
  7. * Project Info: http://www.jfree.org/jfreechart/index.html
  8. *
  9. * This library is free software; you can redistribute it and/or modify it
  10. * under the terms of the GNU Lesser General Public License as published by
  11. * the Free Software Foundation; either version 2.1 of the License, or
  12. * (at your option) any later version.
  13. *
  14. * This library is distributed in the hope that it will be useful, but
  15. * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  16. * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
  17. * License for more details.
  18. *
  19. * You should have received a copy of the GNU Lesser General Public License
  20. * along with this library; if not, write to the Free Software Foundation,
  21. * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
  22. *
  23. * [Java is a trademark or registered trademark of Sun Microsystems, Inc.
  24. * in the United States and other countries.]
  25. *
  26. * -----------------------------
  27. * DefaultPolarItemRenderer.java
  28. * -----------------------------
  29. * (C) Copyright 2004, by Solution Engineering, Inc. and Contributors.
  30. *
  31. * Original Author: Daniel Bridenbecker, Solution Engineering, Inc.;
  32. * Contributor(s): David Gilbert (for Object Refinery Limited);
  33. *
  34. * $Id: DefaultPolarItemRenderer.java,v 1.5 2005/02/23 22:45:05 mungady Exp $
  35. *
  36. * Changes
  37. * -------
  38. * 19-Jan-2004 : Version 1, contributed by DB with minor changes by DG (DG);
  39. * 15-Jul-2004 : Switched getX() with getXValue() and getY() with
  40. * getYValue() (DG);
  41. * 04-Oct-2004 : Renamed BooleanUtils --> BooleanUtilities (DG);
  42. *
  43. */
  44. package org.jfree.chart.renderer;
  45. import java.awt.AlphaComposite;
  46. import java.awt.Composite;
  47. import java.awt.Graphics2D;
  48. import java.awt.Paint;
  49. import java.awt.Point;
  50. import java.awt.Polygon;
  51. import java.awt.Shape;
  52. import java.awt.Stroke;
  53. import java.awt.geom.Ellipse2D;
  54. import java.awt.geom.Rectangle2D;
  55. import java.util.Iterator;
  56. import java.util.List;
  57. import org.jfree.chart.LegendItem;
  58. import org.jfree.chart.axis.NumberTick;
  59. import org.jfree.chart.axis.ValueAxis;
  60. import org.jfree.chart.plot.DrawingSupplier;
  61. import org.jfree.chart.plot.PlotRenderingInfo;
  62. import org.jfree.chart.plot.PolarPlot;
  63. import org.jfree.data.xy.XYDataset;
  64. import org.jfree.text.TextUtilities;
  65. import org.jfree.ui.TextAnchor;
  66. import org.jfree.util.BooleanList;
  67. import org.jfree.util.BooleanUtilities;
  68. /**
  69. * A renderer that can be used with the {@link PolarPlot} class.
  70. *
  71. * @author Daniel Bridenbecker, Solution Engineering, Inc.
  72. */
  73. public class DefaultPolarItemRenderer extends AbstractRenderer
  74. implements PolarItemRenderer {
  75. /** The plot that the renderer is assigned to. */
  76. private PolarPlot plot;
  77. /** Flags that control whether the renderer fills each series or not. */
  78. private BooleanList seriesFilled;
  79. /**
  80. * Creates a new instance of DefaultPolarItemRenderer
  81. */
  82. public DefaultPolarItemRenderer() {
  83. this.seriesFilled = new BooleanList();
  84. }
  85. // --------------------------------
  86. // --- AbstractRenderer Methods ---
  87. // --------------------------------
  88. /**
  89. * Returns the drawing supplier from the plot.
  90. *
  91. * @return The drawing supplier.
  92. */
  93. public DrawingSupplier getDrawingSupplier() {
  94. DrawingSupplier result = null;
  95. PolarPlot p = getPlot();
  96. if (p != null) {
  97. result = p.getDrawingSupplier();
  98. }
  99. return result;
  100. }
  101. // ----------------------
  102. // --- Public Methods ---
  103. // ----------------------
  104. /**
  105. * Set the plot associated with this renderer.
  106. *
  107. * @param plot the plot.
  108. */
  109. public void setPlot(PolarPlot plot) {
  110. this.plot = plot;
  111. }
  112. /**
  113. * Return the plot associated with this renderer.
  114. *
  115. * @return The plot.
  116. */
  117. public PolarPlot getPlot() {
  118. return this.plot;
  119. }
  120. /**
  121. * Plots the data for a given series.
  122. *
  123. * @param g2 the drawing surface.
  124. * @param dataArea the data area.
  125. * @param info collects plot rendering info.
  126. * @param plot the plot.
  127. * @param dataset the dataset.
  128. * @param seriesIndex the series index.
  129. */
  130. public void drawSeries(Graphics2D g2,
  131. Rectangle2D dataArea,
  132. PlotRenderingInfo info,
  133. PolarPlot plot,
  134. XYDataset dataset,
  135. int seriesIndex) {
  136. Polygon poly = new Polygon();
  137. int numPoints = dataset.getItemCount(seriesIndex);
  138. for (int i = 0; i < numPoints; i++) {
  139. double theta = dataset.getXValue(seriesIndex, i);
  140. double radius = dataset.getYValue(seriesIndex, i);
  141. Point p = plot.translateValueThetaRadiusToJava2D(
  142. theta, radius, dataArea
  143. );
  144. poly.addPoint(p.x, p.y);
  145. }
  146. g2.setPaint(getSeriesPaint(seriesIndex));
  147. g2.setStroke(getSeriesStroke(seriesIndex));
  148. if (isSeriesFilled(seriesIndex)) {
  149. Composite savedComposite = g2.getComposite();
  150. g2.setComposite(
  151. AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.5f)
  152. );
  153. g2.fill(poly);
  154. g2.setComposite(savedComposite);
  155. }
  156. else {
  157. g2.draw(poly);
  158. }
  159. }
  160. /**
  161. * Returns <code>true</code> if the renderer should fill the specified
  162. * series, and <code>false</code> otherwise.
  163. *
  164. * @param series the series index (zero-based).
  165. *
  166. * @return A boolean.
  167. */
  168. public boolean isSeriesFilled(int series) {
  169. boolean result = false;
  170. Boolean b = this.seriesFilled.getBoolean(series);
  171. if (b != null) {
  172. result = b.booleanValue();
  173. }
  174. return result;
  175. }
  176. /**
  177. * Sets a flag that controls whether or not a series is filled.
  178. *
  179. * @param series the series index.
  180. * @param filled the flag.
  181. */
  182. public void setSeriesFilled(int series, boolean filled) {
  183. this.seriesFilled.setBoolean(series, BooleanUtilities.valueOf(filled));
  184. }
  185. /**
  186. * Draw the angular gridlines - the spokes.
  187. *
  188. * @param g2 the drawing surface.
  189. * @param plot the plot.
  190. * @param ticks the ticks.
  191. * @param dataArea the data area.
  192. */
  193. public void drawAngularGridLines(Graphics2D g2,
  194. PolarPlot plot,
  195. List ticks,
  196. Rectangle2D dataArea) {
  197. g2.setFont(plot.getAngleLabelFont());
  198. g2.setStroke(plot.getAngleGridlineStroke());
  199. g2.setPaint(plot.getAngleGridlinePaint());
  200. double axisMin = plot.getAxis().getLowerBound();
  201. double maxRadius = plot.getMaxRadius();
  202. Point center = plot.translateValueThetaRadiusToJava2D(
  203. axisMin, axisMin, dataArea
  204. );
  205. Iterator iterator = ticks.iterator();
  206. while (iterator.hasNext()) {
  207. NumberTick tick = (NumberTick) iterator.next();
  208. Point p = plot.translateValueThetaRadiusToJava2D(
  209. tick.getNumber().doubleValue(), maxRadius, dataArea
  210. );
  211. g2.setPaint(plot.getAngleGridlinePaint());
  212. g2.drawLine(center.x, center.y, p.x, p.y);
  213. if (plot.isAngleLabelsVisible()) {
  214. int x = p.x;
  215. int y = p.y;
  216. g2.setPaint(plot.getAngleLabelPaint());
  217. TextUtilities.drawAlignedString(
  218. tick.getText(), g2, x, y, TextAnchor.CENTER
  219. );
  220. }
  221. }
  222. }
  223. /**
  224. * Draw the radial gridlines - the rings.
  225. *
  226. * @param g2 the drawing surface.
  227. * @param plot the plot.
  228. * @param radialAxis the radial axis.
  229. * @param ticks the ticks.
  230. * @param dataArea the data area.
  231. */
  232. public void drawRadialGridLines(Graphics2D g2,
  233. PolarPlot plot,
  234. ValueAxis radialAxis,
  235. List ticks,
  236. Rectangle2D dataArea) {
  237. g2.setFont(radialAxis.getTickLabelFont());
  238. g2.setPaint(plot.getRadiusGridlinePaint());
  239. g2.setStroke(plot.getRadiusGridlineStroke());
  240. double axisMin = radialAxis.getLowerBound();
  241. Point center = plot.translateValueThetaRadiusToJava2D(
  242. axisMin, axisMin, dataArea
  243. );
  244. Iterator iterator = ticks.iterator();
  245. while (iterator.hasNext()) {
  246. NumberTick tick = (NumberTick) iterator.next();
  247. Point p = plot.translateValueThetaRadiusToJava2D(
  248. 90.0, tick.getNumber().doubleValue(), dataArea
  249. );
  250. int r = p.x - center.x;
  251. int upperLeftX = center.x - r;
  252. int upperLeftY = center.y - r;
  253. int d = 2 * r;
  254. Ellipse2D ring = new Ellipse2D.Double(upperLeftX, upperLeftY, d, d);
  255. g2.setPaint(plot.getRadiusGridlinePaint());
  256. g2.draw(ring);
  257. }
  258. }
  259. /**
  260. * Return the legend for the given series.
  261. *
  262. * @param series the series index.
  263. *
  264. * @return The legend item.
  265. */
  266. public LegendItem getLegendItem(int series) {
  267. LegendItem result = null;
  268. PolarPlot polarPlot = getPlot();
  269. if (polarPlot != null) {
  270. XYDataset dataset;
  271. dataset = polarPlot.getDataset();
  272. if (dataset != null) {
  273. String label = dataset.getSeriesName(series);
  274. String description = label;
  275. Shape shape = getSeriesShape(series);
  276. Paint paint = getSeriesPaint(series);
  277. Paint outlinePaint = getSeriesOutlinePaint(series);
  278. Stroke outlineStroke = getSeriesOutlineStroke(series);
  279. result = new LegendItem(
  280. label, description, shape, paint,
  281. outlineStroke, outlinePaint
  282. );
  283. }
  284. }
  285. return result;
  286. }
  287. }