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.IAxisChartDataSet;
036: import org.krysalis.jcharts.chartData.interfaces.IDataSeries;
037: import org.krysalis.jcharts.imageMap.CircleMapArea;
038: import org.krysalis.jcharts.properties.*;
039:
040: import java.awt.*;
041: import java.awt.geom.*;
042:
043: /*************************************************************************************
044: *
045: * @author Nathaniel Auvil
046: * @version $Id: LineChart.java,v 1.3 2003/09/26 00:44:02 nathaniel_auvil Exp $
047: ************************************************************************************/
048: abstract class LineChart {
049:
050: /********************************************************************************************
051: * Draws the chart
052: *
053: * @param axisChart
054: * @param iAxisChartDataSet
055: * @throws PropertyException
056: *********************************************************************************************/
057: static void render(AxisChart axisChart,
058: IAxisChartDataSet iAxisChartDataSet)
059: throws PropertyException {
060: Graphics2D g2d = axisChart.getGraphics2D();
061:
062: LineChartProperties lineChartProperties = (LineChartProperties) iAxisChartDataSet
063: .getChartTypeProperties();
064: lineChartProperties.validate(iAxisChartDataSet);
065:
066: //DataAxisProperties dataAxisProperties= (DataAxisProperties) axisChart.getAxisProperties().getYAxisProperties();
067: IDataSeries iDataSeries = (IDataSeries) axisChart
068: .getIAxisDataSeries();
069:
070: //---cache the computed values
071: float[][] yAxisCoordinates = new float[iAxisChartDataSet
072: .getNumberOfDataSets()][iAxisChartDataSet
073: .getNumberOfDataItems()];
074:
075: //---need this for image map calculation
076: float xMapCoordinate = axisChart.getXAxis().getTickStart();
077:
078: //LOOP
079: for (int j = 0; j < iAxisChartDataSet.getNumberOfDataItems(); j++) {
080: //LOOP
081: for (int i = 0; i < yAxisCoordinates.length; i++) {
082: if (iAxisChartDataSet.getValue(i, j) != Double.NaN) {
083: // Dual Y axis changes integrated CMC 25Aug03
084: //yAxisCoordinates[ i ][ j ]= axisChart.getYAxis().computeAxisCoordinate( axisChart.getYAxis().getOrigin(),
085: // iAxisChartDataSet.getValue( i, j ),
086: // axisChart.getYAxis().getScaleCalculator().getMinValue() );
087:
088: // The coordinates of the line charts are drawn with the default scale and
089: // multiplicate with the second scale for the right axis (by default equal 1)
090: // if the second scale at the right is unchanged then there will be no impact
091: yAxisCoordinates[i][j] = axisChart
092: .getYAxis()
093: .computeAxisCoordinate(
094: axisChart.getYAxis().getOrigin(),
095: iAxisChartDataSet.getValue(i, j)
096: * axisChart.axisProperties
097: .getYAxisProperties()
098: .getSecondScaleRight(),
099: axisChart.getYAxis()
100: .getScaleCalculator()
101: .getMinValue());
102:
103: //---if we are generating an ImageMap, store the image coordinates
104: if (axisChart.getGenerateImageMapFlag()) {
105: String label;
106: if (axisChart.getXAxis().getAxisLabelsGroup() != null) {
107: label = axisChart.getXAxis()
108: .getAxisLabelsGroup().getTextTag(j)
109: .getText();
110: } else {
111: label = null;
112: }
113:
114: axisChart.getImageMap().addImageMapArea(
115: new CircleMapArea(xMapCoordinate,
116: yAxisCoordinates[i][j],
117: iAxisChartDataSet
118: .getValue(i, j), label,
119: iAxisChartDataSet
120: .getLegendLabel(i)));
121: }
122: } else {
123: yAxisCoordinates[i][j] = Float.NaN;
124: }
125: }
126:
127: xMapCoordinate += axisChart.getXAxis().getScalePixelWidth();
128: }
129:
130: AffineTransform originalTransform = null;
131: double[] cornerXOffset = null;
132: double[] cornerYOffset = null;
133:
134: //---check if there are any points to display
135: if (lineChartProperties.getShapes() != null) {
136: //---when centering the shapes on the points, need x and y offset to do this
137: cornerXOffset = new double[iAxisChartDataSet
138: .getNumberOfDataSets()];
139: cornerYOffset = new double[iAxisChartDataSet
140: .getNumberOfDataSets()];
141:
142: //---get the original transform so can reset it.
143: originalTransform = g2d.getTransform();
144:
145: Rectangle2D rectangle;
146:
147: //LOOP
148: //---pre-compute the dimensions of each Shape so do not do it in loop.
149: for (int i = 0; i < iAxisChartDataSet.getNumberOfDataSets(); i++) {
150: if (lineChartProperties.getShapes()[i] != null) {
151: rectangle = lineChartProperties.getShapes()[i]
152: .getBounds2D();
153: cornerXOffset[i] = rectangle.getWidth() / 2;
154: cornerYOffset[i] = rectangle.getHeight() / 2;
155: }
156: }
157: }
158:
159: //---init for first segment
160: Line2D.Float line = new Line2D.Float(axisChart.getXAxis()
161: .getTickStart(), yAxisCoordinates[0][0], axisChart
162: .getXAxis().getTickStart(), yAxisCoordinates[0][0]);
163: //---make sure not plotting a chart with only one data point.
164: if (yAxisCoordinates[0].length > 1) {
165: line.y2 = yAxisCoordinates[0][1];
166: }
167:
168: //LOOP
169: //---draw each line to the image
170: for (int i = 0; i < yAxisCoordinates.length; i++) {
171: line.x1 = axisChart.getXAxis().getTickStart();
172: line.y1 = yAxisCoordinates[i][0];
173: line.x2 = line.x1;
174:
175: //LOOP
176: for (int j = 1; j < yAxisCoordinates[0].length; j++) {
177: //---if current point on line should be drawn
178: if (!Float.isNaN(yAxisCoordinates[i][j])) {
179: //---if the previous point was not drawn, no line
180: if (Float.isNaN(yAxisCoordinates[i][j - 1])) {
181: line.x2 += axisChart.getXAxis()
182: .getScalePixelWidth();
183: line.x1 = line.x2;
184: line.y1 = yAxisCoordinates[i][j];
185: line.y2 = yAxisCoordinates[i][j];
186:
187: continue;
188: }
189:
190: line.x2 += axisChart.getXAxis()
191: .getScalePixelWidth();
192: line.y2 = yAxisCoordinates[i][j];
193:
194: g2d.setPaint(iAxisChartDataSet.getPaint(i));
195: g2d
196: .setStroke(lineChartProperties
197: .getLineStrokes()[i]);
198: g2d.draw(line);
199:
200: //---plot the Point
201: if (lineChartProperties.getShapes()[i] != null) {
202: //---translate the Shape into position.
203: g2d.translate(line.x1 - cornerXOffset[i],
204: line.y1 - cornerYOffset[i]);
205:
206: g2d.setPaint(iAxisChartDataSet.getPaint(i));
207: g2d.fill(lineChartProperties.getShapes()[i]);
208:
209: //---translate back to the original position
210: g2d.setTransform(originalTransform);
211: }
212:
213: line.x1 = line.x2;
214: line.y1 = line.y2;
215: } else {
216: if ((!Float.isNaN(yAxisCoordinates[i][j - 1]))
217: && (lineChartProperties.getShapes()[i] != null)) {
218: //---translate the Shape into position.
219: g2d.translate(line.x1 - cornerXOffset[i],
220: line.y1 - cornerYOffset[i]);
221:
222: g2d.setPaint(iAxisChartDataSet.getPaint(i));
223: g2d.fill(lineChartProperties.getShapes()[i]);
224:
225: //---translate back to the original position
226: g2d.setTransform(originalTransform);
227: }
228:
229: line.x2 += axisChart.getXAxis()
230: .getScalePixelWidth();
231: line.x1 = line.x2;
232: }
233: }
234:
235: //---put the last shape on the line
236: if ((!Float
237: .isNaN(yAxisCoordinates[i][yAxisCoordinates[i].length - 1]))
238: && (lineChartProperties.getShapes()[i] != null)) {
239: //---translate the Shape into position.
240: g2d.translate(line.x2 - cornerXOffset[i], line.y2
241: - cornerYOffset[i]);
242:
243: g2d.setPaint(iAxisChartDataSet.getPaint(i));
244: g2d.fill(lineChartProperties.getShapes()[i]);
245:
246: //---translate back to the original position
247: g2d.setTransform(originalTransform);
248: }
249: }
250: }
251:
252: }
|