001: /***********************************************************************************************
002: * Copyright 2002 (C) Nathaniel G. Auvil. All Rights Reserved.
003: *
004: * Redistribution and use of this software and associated documentation ("Software"), with or
005: * without modification, are permitted provided that the following conditions are met:
006: *
007: * 1. Redistributions of source code must retain copyright statements and notices.
008: * Redistributions must also contain a copy of this document.
009: *
010: * 2. Redistributions in binary form must reproduce the above copyright notice, this list of
011: * conditions and the following disclaimer in the documentation and/or other materials
012: * provided with the distribution.
013: *
014: * 3. The name "jCharts" or "Nathaniel G. Auvil" must not be used to endorse or promote
015: * products derived from this Software without prior written permission of Nathaniel G.
016: * Auvil. For written permission, please contact nathaniel_auvil@users.sourceforge.net
017: *
018: * 4. Products derived from this Software may not be called "jCharts" nor may "jCharts" appear
019: * in their names without prior written permission of Nathaniel G. Auvil. jCharts is a
020: * registered trademark of Nathaniel G. Auvil.
021: *
022: * 5. Due credit should be given to the jCharts Project (http://jcharts.sourceforge.net/).
023: *
024: * THIS SOFTWARE IS PROVIDED BY Nathaniel G. Auvil AND CONTRIBUTORS ``AS IS'' AND ANY
025: * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
026: * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
027: * jCharts OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
028: * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
029: * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
030: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,STRICT LIABILITY, OR TORT
031: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
032: * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
033: ************************************************************************************************/package org.krysalis.jcharts.axisChart;
034:
035: import org.krysalis.jcharts.chartData.interfaces.*;
036: import org.krysalis.jcharts.imageMap.CircleMapArea;
037: import org.krysalis.jcharts.properties.*;
038:
039: import java.awt.*;
040: import java.awt.geom.*;
041:
042: /*************************************************************************************
043: *
044: * @author Nathaniel Auvil
045: * @version $Id: ScatterPlotChart.java,v 1.2 2003/11/02 13:34:17 nathaniel_auvil Exp $
046: ************************************************************************************/
047: abstract class ScatterPlotChart {
048:
049: /********************************************************************************************
050: * Draws the chart
051: *
052: * @param scatterPlotAxisChart
053: * @param iScatterPlotDataSet
054: *********************************************************************************************/
055: static void render(ScatterPlotAxisChart scatterPlotAxisChart,
056: IScatterPlotDataSet iScatterPlotDataSet) {
057: //---cache the computed values
058: float[][] xAxisCoordinates = new float[iScatterPlotDataSet
059: .getNumberOfDataSets()][iScatterPlotDataSet
060: .getNumberOfDataItems()];
061: float[][] yAxisCoordinates = new float[iScatterPlotDataSet
062: .getNumberOfDataSets()][iScatterPlotDataSet
063: .getNumberOfDataItems()];
064:
065: //System.out.println( "x origin= " + scatterPlotAxisChart.getXAxis().getOrigin() + " y origin= " + scatterPlotAxisChart.getYAxis().getOrigin() );
066:
067: //LOOP
068: for (int index = 0; index < iScatterPlotDataSet
069: .getNumberOfDataItems(); index++) {
070: //LOOP
071: for (int dataSet = 0; dataSet < yAxisCoordinates.length; dataSet++) {
072: if (iScatterPlotDataSet.getValue(dataSet, index) != null) {
073: xAxisCoordinates[dataSet][index] = scatterPlotAxisChart
074: .getXAxis().computeAxisCoordinate(
075: scatterPlotAxisChart.getXAxis()
076: .getOrigin(),
077: iScatterPlotDataSet.getValue(
078: dataSet, index).getX(),
079: scatterPlotAxisChart.getXAxis()
080: .getScaleCalculator()
081: .getMinValue());
082:
083: yAxisCoordinates[dataSet][index] = scatterPlotAxisChart
084: .getYAxis().computeAxisCoordinate(
085: scatterPlotAxisChart.getYAxis()
086: .getOrigin(),
087: iScatterPlotDataSet.getValue(
088: dataSet, index).getY(),
089: scatterPlotAxisChart.getYAxis()
090: .getScaleCalculator()
091: .getMinValue());
092:
093: //System.out.println( "x= " + xAxisCoordinates[ dataSet ][ index ] + " y= " + yAxisCoordinates[ dataSet ][ index ] );
094:
095: //---if we are generating an ImageMap, store the image coordinates
096: if (scatterPlotAxisChart.getGenerateImageMapFlag()) {
097: scatterPlotAxisChart
098: .getImageMap()
099: .addImageMapArea(
100: new CircleMapArea(
101: xAxisCoordinates[dataSet][index],
102: yAxisCoordinates[dataSet][index],
103: iScatterPlotDataSet
104: .getValue(
105: dataSet,
106: index),
107: iScatterPlotDataSet
108: .getLegendLabel(dataSet)));
109: }
110: } else {
111: xAxisCoordinates[dataSet][index] = Float.NaN;
112: yAxisCoordinates[dataSet][index] = Float.NaN;
113: }
114: }
115: }
116:
117: ScatterPlotProperties scatterPlotProperties = (ScatterPlotProperties) iScatterPlotDataSet
118: .getChartTypeProperties();
119: //DataAxisProperties xAxisProperties = (DataAxisProperties) scatterPlotAxisChart.getAxisProperties().getXAxisProperties();
120: //DataAxisProperties yAxisProperties = (DataAxisProperties) scatterPlotAxisChart.getAxisProperties().getYAxisProperties();
121:
122: Graphics2D g2d = scatterPlotAxisChart.getGraphics2D();
123: AffineTransform originalTransform = null;
124: double[] cornerXOffset = null;
125: double[] cornerYOffset = null;
126:
127: //---check if there are any points to display
128: if (scatterPlotProperties.getShapes() != null) {
129: //---when centering the shapes on the points, need x and y offset to do this
130: cornerXOffset = new double[iScatterPlotDataSet
131: .getNumberOfDataSets()];
132: cornerYOffset = new double[iScatterPlotDataSet
133: .getNumberOfDataSets()];
134:
135: //---get the original transform so can reset it.
136: originalTransform = g2d.getTransform();
137:
138: Rectangle2D rectangle;
139:
140: //LOOP
141: //---pre-compute the dimensions of each Shape so do not do it in loop.
142: for (int i = 0; i < iScatterPlotDataSet
143: .getNumberOfDataSets(); i++) {
144: if (scatterPlotProperties.getShapes()[i] != null) {
145: rectangle = scatterPlotProperties.getShapes()[i]
146: .getBounds2D();
147: cornerXOffset[i] = rectangle.getWidth() / 2;
148: cornerYOffset[i] = rectangle.getHeight() / 2;
149: }
150: }
151: }
152:
153: //---init for first segment
154: Line2D.Float line = new Line2D.Float(xAxisCoordinates[0][0],
155: yAxisCoordinates[0][0], xAxisCoordinates[0][1],
156: yAxisCoordinates[0][1]);
157: //---make sure not plotting a chart with only one data point.
158: if (yAxisCoordinates[0].length > 1) {
159: //todo what is this for?
160: line.y2 = yAxisCoordinates[0][1];
161: }
162:
163: //LOOP
164: //---draw each line to the image
165: for (int i = 0; i < yAxisCoordinates.length; i++) {
166: line.x1 = xAxisCoordinates[i][0];
167: line.y1 = yAxisCoordinates[i][0];
168: line.x2 = line.x1;
169:
170: //LOOP
171: for (int j = 1; j < yAxisCoordinates[0].length; j++) {
172: //---if current point on line should be drawn
173: if (!Float.isNaN(yAxisCoordinates[i][j])) {
174: //---if the previous point was not drawn, no line
175: if (Float.isNaN(yAxisCoordinates[i][j - 1])) {
176: line.x1 = xAxisCoordinates[i][j];
177: line.y1 = yAxisCoordinates[i][j];
178: line.x2 = xAxisCoordinates[i][j];
179: line.y2 = yAxisCoordinates[i][j];
180: continue;
181: }
182:
183: line.x2 = xAxisCoordinates[i][j];
184: line.y2 = yAxisCoordinates[i][j];
185:
186: g2d.setPaint(iScatterPlotDataSet.getPaint(i));
187: g2d.setStroke(scatterPlotProperties
188: .getLineStrokes()[i]);
189: g2d.draw(line);
190:
191: //---plot the Point
192: if (scatterPlotProperties.getShapes()[i] != null) {
193: //---translate the Shape into position.
194: g2d.translate(line.x1 - cornerXOffset[i],
195: line.y1 - cornerYOffset[i]);
196:
197: g2d.setPaint(iScatterPlotDataSet.getPaint(i));
198: g2d.fill(scatterPlotProperties.getShapes()[i]);
199:
200: //---translate back to the original position
201: g2d.setTransform(originalTransform);
202: }
203:
204: line.x1 = line.x2;
205: line.y1 = line.y2;
206: } else {
207: if ((!Float.isNaN(yAxisCoordinates[i][j - 1]))
208: && (scatterPlotProperties.getShapes()[i] != null)) {
209: //---translate the Shape into position.
210: g2d.translate(line.x1 - cornerXOffset[i],
211: line.y1 - cornerYOffset[i]);
212:
213: g2d.setPaint(iScatterPlotDataSet.getPaint(i));
214: g2d.fill(scatterPlotProperties.getShapes()[i]);
215:
216: //---translate back to the original position
217: g2d.setTransform(originalTransform);
218: }
219:
220: line.x2 = scatterPlotAxisChart.getXAxis()
221: .getScalePixelWidth();
222: line.x1 = line.x2;
223: }
224: }
225:
226: //---put the last shape on the line
227: if ((!Float
228: .isNaN(yAxisCoordinates[i][yAxisCoordinates[i].length - 1]))
229: && (scatterPlotProperties.getShapes()[i] != null)) {
230: //---translate the Shape into position.
231: g2d.translate(line.x2 - cornerXOffset[i], line.y2
232: - cornerYOffset[i]);
233:
234: g2d.setPaint(iScatterPlotDataSet.getPaint(i));
235: g2d.fill(scatterPlotProperties.getShapes()[i]);
236:
237: //---translate back to the original position
238: g2d.setTransform(originalTransform);
239: }
240: }
241: }
242:
243: }
|