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.axisChart.axis.*;
036: import org.krysalis.jcharts.axisChart.axis.scale.*;
037: import org.krysalis.jcharts.chartData.interfaces.*;
038: import org.krysalis.jcharts.chartData.processors.AxisChartDataProcessor;
039: import org.krysalis.jcharts.chartData.processors.ScatterPlotDataProcessor;
040: import org.krysalis.jcharts.chartText.NumericTagGroup;
041: import org.krysalis.jcharts.imageMap.ImageMap;
042: import org.krysalis.jcharts.properties.*;
043: import org.krysalis.jcharts.test.HTMLChartTestable;
044: import org.krysalis.jcharts.test.HTMLGenerator;
045: import org.krysalis.jcharts.types.ChartType;
046:
047: import java.awt.font.FontRenderContext;
048:
049: /**************************************************************************************
050: * This Class is used to create all axis chart types. This class knows how to render
051: * charts based on the ChartType specified in on the iAxisChartDataSet.
052: *
053: * @author Nathaniel Auvil
054: * @version $Id: ScatterPlotAxisChart.java,v 1.2 2003/06/20 01:54:58 nathaniel_auvil Exp $
055: ************************************************************************************/
056: public class ScatterPlotAxisChart extends AxisChart implements
057: HTMLChartTestable {
058:
059: /**************************************************************************************************
060: * Constructor
061: *
062: * @param iScatterPlotDataSeries
063: * @param chartProperties
064: * @param axisProperties
065: * @param legendProperties if no legend is desired, pass NULL
066: * @param pixelWidth
067: * @param pixelHeight
068: ***************************************************************************************************/
069: public ScatterPlotAxisChart(
070: IScatterPlotDataSeries iScatterPlotDataSeries,
071: ChartProperties chartProperties,
072: AxisProperties axisProperties,
073: LegendProperties legendProperties, int pixelWidth,
074: int pixelHeight) {
075: super (iScatterPlotDataSeries, chartProperties, axisProperties,
076: legendProperties, pixelWidth, pixelHeight);
077: }
078:
079: /********************************************************************************************
080: * ScatterPlots create a subclass of AxisChartDataProcessor so we need this method so we can
081: * overload it.
082: *
083: * @return AxisChartDataProcessor
084: ********************************************************************************************/
085: public AxisChartDataProcessor createAxisChartDataProcessor() {
086: return new ScatterPlotDataProcessor();
087: }
088:
089: /************************************************************************************************
090: * Once we determine which axis is the data axis, the logic to set it up is the same whether it
091: * is a horizontal or vertical plot.
092: *
093: * @param dataAxisProperties
094: * @param axisChartDataProcessor
095: * @param fontRenderContext
096: * @return NumericTagGroup need to set this on the right axis
097: ************************************************************************************************/
098: protected NumericTagGroup setupDataAxisProperties(Axis axis,
099: DataAxisProperties dataAxisProperties,
100: AxisChartDataProcessor axisChartDataProcessor,
101: FontRenderContext fontRenderContext) {
102: //---we know this is of this type
103: ScatterPlotDataProcessor scatterPlotDataProcessor = (ScatterPlotDataProcessor) axisChartDataProcessor;
104:
105: if (dataAxisProperties.getScaleCalculator() == null) {
106: ScaleCalculator s;
107:
108: if (dataAxisProperties.hasUserDefinedScale()) {
109: s = new UserDefinedScaleCalculator(dataAxisProperties
110: .getUserDefinedMinimumValue(),
111: dataAxisProperties.getUserDefinedIncrement());
112: } else {
113: s = new AutomaticScaleCalculator();
114: if (axis instanceof XAxis) {
115: s.setMaxValue(scatterPlotDataProcessor
116: .getMaxValue());
117: s.setMinValue(scatterPlotDataProcessor
118: .getMinValue());
119: } else {
120: s.setMaxValue(scatterPlotDataProcessor.getyMax());
121: s.setMinValue(scatterPlotDataProcessor.getyMin());
122: }
123: }
124:
125: axis.setScaleCalculator(s);
126: } else {
127: axis.setScaleCalculator(dataAxisProperties
128: .getScaleCalculator());
129:
130: if (axis instanceof XAxis) {
131: axis.getScaleCalculator().setMaxValue(
132: scatterPlotDataProcessor.getMaxValue());
133: axis.getScaleCalculator().setMinValue(
134: scatterPlotDataProcessor.getMinValue());
135: } else {
136: axis.getScaleCalculator().setMaxValue(
137: scatterPlotDataProcessor.getyMax());
138: axis.getScaleCalculator().setMinValue(
139: scatterPlotDataProcessor.getyMin());
140: }
141: }
142:
143: axis.getScaleCalculator().setRoundingPowerOfTen(
144: dataAxisProperties.getRoundToNearest());
145: axis.getScaleCalculator().setNumberOfScaleItems(
146: dataAxisProperties.getNumItems());
147: axis.getScaleCalculator().computeScaleValues();
148:
149: //TODO what if they do not want to display axis labels?
150: NumericTagGroup numericTagGroup = new NumericTagGroup(
151: dataAxisProperties.getScaleChartFont(),
152: fontRenderContext, dataAxisProperties.useDollarSigns(),
153: dataAxisProperties.usePercentSigns(),
154: dataAxisProperties.useCommas(), dataAxisProperties
155: .getRoundToNearest());
156:
157: numericTagGroup
158: .createAxisScaleLabels(axis.getScaleCalculator());
159:
160: return numericTagGroup;
161: }
162:
163: /***************************************************************************************
164: *
165: *
166: * @param axisChartDataProcessor
167: * @param fontRenderContext
168: **************************************************************************************/
169: protected void setupAxis(
170: AxisChartDataProcessor axisChartDataProcessor,
171: FontRenderContext fontRenderContext) {
172: //---X AXIS---------------------------------------------------------------------------
173: DataAxisProperties dataAxisProperties = (DataAxisProperties) this
174: .getAxisProperties().getXAxisProperties();
175: this .xAxis = new XAxis(this , dataAxisProperties.getNumItems());
176: NumericTagGroup numericTagGroup = this .setupDataAxisProperties(
177: this .xAxis, dataAxisProperties, axisChartDataProcessor,
178: fontRenderContext);
179: this .xAxis.setAxisLabelsGroup(numericTagGroup);
180:
181: //---Y AXIS---------------------------------------------------------------------------
182: dataAxisProperties = (DataAxisProperties) this
183: .getAxisProperties().getYAxisProperties();
184: this .yAxis = new YAxis(this , dataAxisProperties.getNumItems());
185: numericTagGroup = this .setupDataAxisProperties(this .yAxis,
186: dataAxisProperties, axisChartDataProcessor,
187: fontRenderContext);
188: this .yAxis.setAxisLabelsGroup(numericTagGroup);
189:
190: //---if yAxisTitle is null, do not show title
191: this .yAxis.computeMinimumWidthNeeded(super .getIAxisDataSeries()
192: .getYAxisTitle());
193: this .xAxis.computeMinimumHeightNeeded(super
194: .getIAxisDataSeries().getXAxisTitle());
195: }
196:
197: /******************************************************************************************
198: *
199: *****************************************************************************************/
200: protected void deriveAxisValues() {
201: //---Determine how many labels will fit on the x-axis
202: //TODO should we do this also for the YAxis?
203: //todo what if they do not want labels on the x-axis?
204: this .xAxis.computeLabelFilter();
205:
206: this .xAxis.computeShouldTickStartAtYAxis(super
207: .getIAxisDataSeries(), this .axisProperties
208: .getXAxisProperties());
209:
210: //---X Axis--------------------
211: //DataAxisProperties dataAxisProperties = (DataAxisProperties) this.axisProperties.getXAxisProperties();
212: this .xAxis.computeScalePixelWidthDataAxis(this .axisProperties
213: .getXAxisProperties());
214: this .xAxis.computeOneUnitPixelSize(this .xAxis
215: .getScalePixelWidth(), this .xAxis.getScaleCalculator()
216: .getIncrement());
217:
218: //---we ADD to the origin position when doing x-axis
219: float zeroLineCoordinate = (float) (this .xAxis.getOrigin() + (this .xAxis
220: .getScalePixelWidth() * (-this .xAxis
221: .getScaleCalculator().getMinValue()))
222: / this .xAxis.getScaleCalculator().getIncrement());
223: this .xAxis.setZeroLineCoordinate(zeroLineCoordinate);
224:
225: //---Y Axis--------------------
226: //dataAxisProperties = (DataAxisProperties) this.axisProperties.getYAxisProperties();
227: this .yAxis.computeScalePixelWidthDataAxis(this .axisProperties
228: .getYAxisProperties());
229: this .yAxis.computeOneUnitPixelSize(this .yAxis
230: .getScalePixelWidth(), this .yAxis.getScaleCalculator()
231: .getIncrement());
232:
233: //---we SUBTRACT to the origin position when doing y-axis
234: zeroLineCoordinate = (float) (this .yAxis.getOrigin() - (this .yAxis
235: .getScalePixelWidth() * (-this .yAxis
236: .getScaleCalculator().getMinValue()))
237: / this .yAxis.getScaleCalculator().getIncrement());
238: this .yAxis.setZeroLineCoordinate(zeroLineCoordinate);
239:
240: this .xAxis.computeTickStart();
241: }
242:
243: /********************************************************************************************
244: * Draws the charts over the axis. We have to render in a specific order so combo charts
245: * get drawn correctly
246: *
247: * @throws PropertyException
248: ******************************************************************************************/
249: protected void overlayCharts() throws PropertyException {
250: IAxisPlotDataSet iAxisPlotDataSet = super .getIAxisDataSeries()
251: .getIAxisPlotDataSet(ChartType.SCATTER_PLOT);
252: ScatterPlotChart.render(this ,
253: (IScatterPlotDataSet) iAxisPlotDataSet);
254: }
255:
256: /**********************************************************************************************
257: * Enables the testing routines to display the contents of this Object. Override Chart
258: * implementation as PieCharts use AreaProperties directly rather than a child.
259: *
260: * @param htmlGenerator
261: * @param imageFileName
262: * @param imageMap if this is NULL we are not creating image map data in html
263: **********************************************************************************************/
264: public void toHTML(HTMLGenerator htmlGenerator,
265: String imageFileName, ImageMap imageMap) {
266: htmlGenerator.chartTableStart(this .getClass().getName(),
267: imageFileName, imageMap);
268:
269: /*
270: if( iDataSeries instanceof HTMLTestable )
271: {
272: ( ( HTMLTestable ) this.iDataSeries ).toHTML( htmlGenerator );
273: }
274: */
275:
276: //---AxisProperties
277: htmlGenerator.chartTableRowStart();
278: this .axisProperties.toHTML(htmlGenerator);
279: htmlGenerator.chartTableRowEnd();
280:
281: //---XAxis
282: htmlGenerator.chartTableRowStart();
283: this .xAxis.toHTML(htmlGenerator);
284: htmlGenerator.chartTableRowEnd();
285:
286: //---YAxis
287: htmlGenerator.chartTableRowStart();
288: this .yAxis.toHTML(htmlGenerator);
289: htmlGenerator.chartTableRowEnd();
290:
291: //---ChartProperties
292: htmlGenerator.chartTableRowStart();
293: super.getChartProperties().toHTML(htmlGenerator);
294: htmlGenerator.chartTableRowEnd();
295:
296: if (super.getLegend() != null) {
297: htmlGenerator.chartTableRowStart();
298: this.getLegend().toHTML(htmlGenerator);
299: htmlGenerator.chartTableRowEnd();
300: }
301:
302: htmlGenerator.chartTableEnd();
303: }
304:
305: }
|