001: /***********************************************************************************************
002: * File Info: $Id: DualYAxis.java,v 1.2 2003/08/28 01:18:02 nathaniel_auvil Exp $
003: * Copyright (C) 2002
004: * Author: Nathaniel G. Auvil
005: * Contributor(s):
006: *
007: * Copyright 2002 (C) Nathaniel G. Auvil. All Rights Reserved.
008: *
009: * Redistribution and use of this software and associated documentation ("Software"), with or
010: * without modification, are permitted provided that the following conditions are met:
011: *
012: * 1. Redistributions of source code must retain copyright statements and notices.
013: * Redistributions must also contain a copy of this document.
014: *
015: * 2. Redistributions in binary form must reproduce the above copyright notice, this list of
016: * conditions and the following disclaimer in the documentation and/or other materials
017: * provided with the distribution.
018: *
019: * 3. The name "jCharts" or "Nathaniel G. Auvil" must not be used to endorse or promote
020: * products derived from this Software without prior written permission of Nathaniel G.
021: * Auvil. For written permission, please contact nathaniel_auvil@users.sourceforge.net
022: *
023: * 4. Products derived from this Software may not be called "jCharts" nor may "jCharts" appear
024: * in their names without prior written permission of Nathaniel G. Auvil. jCharts is a
025: * registered trademark of Nathaniel G. Auvil.
026: *
027: * 5. Due credit should be given to the jCharts Project (http://jcharts.sourceforge.net/).
028: *
029: * THIS SOFTWARE IS PROVIDED BY Nathaniel G. Auvil AND CONTRIBUTORS ``AS IS'' AND ANY
030: * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
031: * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
032: * jCharts OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
033: * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
034: * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
035: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,STRICT LIABILITY, OR TORT
036: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
037: * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
038: ************************************************************************************************/package org.krysalis.jcharts.demo.simpleservlet;
039:
040: import org.krysalis.jcharts.axisChart.AxisChart;
041: import org.krysalis.jcharts.chartData.AxisChartDataSet;
042: import org.krysalis.jcharts.chartData.DataSeries;
043: import org.krysalis.jcharts.chartData.interfaces.IAxisDataSeries;
044: import org.krysalis.jcharts.encoders.ServletEncoderHelper;
045: import org.krysalis.jcharts.properties.AxisProperties;
046: import org.krysalis.jcharts.properties.ChartProperties;
047: import org.krysalis.jcharts.properties.ClusteredBarChartProperties;
048: import org.krysalis.jcharts.properties.DataAxisProperties;
049: import org.krysalis.jcharts.properties.LegendProperties;
050: import org.krysalis.jcharts.properties.LineChartProperties;
051: import org.krysalis.jcharts.properties.PointChartProperties;
052: import org.krysalis.jcharts.properties.util.ChartFont;
053: import org.krysalis.jcharts.types.ChartType;
054:
055: import javax.servlet.ServletException;
056: import javax.servlet.http.HttpServletRequest;
057: import javax.servlet.http.HttpServletResponse;
058: import java.awt.*;
059: import java.io.IOException;
060:
061: // Dual Y axis changes courtesy of St�phane NGUYEN integrated by CMC 25Aug03
062: // French translation courtesy of my good wife Jacki ...
063: public class DualYAxis extends ChartServlet {
064:
065: //---all of the charts will have some properties.
066: private LineChartProperties lineChartProperties;
067: private ClusteredBarChartProperties clusteredBarChartProperties;
068:
069: protected LegendProperties legendProperties;
070: protected ChartProperties chartProperties;
071: protected AxisProperties axisProperties;
072:
073: //---all of the charts have the same size
074: protected int width = 750;
075: protected int height = 430;
076:
077: public void init() {
078:
079: //---------------------Font & Police----------------------------------------
080:
081: legendProperties = new LegendProperties();
082: chartProperties = new ChartProperties();
083: axisProperties = new AxisProperties(false);
084:
085: ChartFont axisScaleFont = new ChartFont(new Font(
086: "Arial Narrow", Font.PLAIN, 10), Color.black);
087: axisProperties.getXAxisProperties().setScaleChartFont(
088: axisScaleFont);
089: axisProperties.getYAxisProperties().setScaleChartFont(
090: axisScaleFont);
091:
092: ChartFont axisTitleFont = new ChartFont(new Font(
093: "Arial Narrow", Font.PLAIN, 13), Color.black);
094: axisProperties.getXAxisProperties().setTitleChartFont(
095: axisTitleFont);
096: axisProperties.getYAxisProperties().setTitleChartFont(
097: axisTitleFont);
098:
099: ChartFont titleFont = new ChartFont(new Font(
100: "Georgia Negreta cursiva", Font.PLAIN, 15), Color.black);
101: chartProperties.setTitleFont(titleFont);
102:
103: //On fixe la marge avec le cadre
104: // Set the margin within the frame
105: chartProperties.setEdgePadding(2f);
106:
107: //On met le graphe sur un fond gris clair
108: // Set the chart against a plain grey background
109: axisProperties.setBackgroundPaint(new Color(245, 245, 245));
110:
111: //Param�trage de la bo�te de l�gende
112: //Parameters for the legend box
113: //legendProperties.setPlacement(LegendAreaProperties.RIGHT);
114: //legendProperties.setNumColumns(1);
115: //legendProperties.setFont( new Font("Arial Narrow", Font.PLAIN, 13) );
116: //legendProperties.setFontPaint(Color.black);
117: ChartFont legendFont = new ChartFont(new Font("Arial Narrow",
118: Font.PLAIN, 13), Color.black);
119: legendProperties.setChartFont(legendFont);
120: legendProperties.setChartPadding(10);
121:
122: //Arrondi � la puissance 10
123: //Round up to the power of 10
124: DataAxisProperties dataAxisProperties = (DataAxisProperties) axisProperties
125: .getYAxisProperties();
126: dataAxisProperties.setRoundToNearest(1);
127:
128: //Parametrage du nombre de graduation sur l'axe des ordonn�es
129: //Set the number of ticks(?) for the ordinal axis
130: dataAxisProperties.setNumItems(6);
131:
132: //utilisation de la virgule s'il y a lieu (normalement non)
133: // Set the use of the comma if there are any (usually not)
134: dataAxisProperties.setUseCommas(false);
135:
136: //Ne pas afficher les bordures sup�rieur et droite du chart
137: // Don't attach upper borders and the right of the chart
138: axisProperties.getYAxisProperties().setShowEndBorder(false);
139: axisProperties.getXAxisProperties().setShowEndBorder(false);
140:
141: Stroke[] strokes = { LineChartProperties.DEFAULT_LINE_STROKE };
142: //Shape[] shapes = {null};
143: Shape[] shapes = { PointChartProperties.SHAPE_TRIANGLE };
144: lineChartProperties = new LineChartProperties(strokes, shapes);
145:
146: clusteredBarChartProperties = new ClusteredBarChartProperties();
147:
148: //Param�trage de la largeur des barres de l'histogramme et non affichage des contours
149: //Set the width of the bars and don't show the outline
150: clusteredBarChartProperties.setWidthPercentage(0.70f);
151: clusteredBarChartProperties.setShowOutlinesFlag(false);
152: }
153:
154: /**********************************************************************************************
155: *
156: **********************************************************************************************/
157: public void service(HttpServletRequest req,
158: HttpServletResponse httpServletResponse)
159: throws ServletException, IOException {
160: //---Some charts will need a second scale to render some values and then will
161: //---need to render an axis at the right of the charts with it
162: long secondScale = 1;
163:
164: //---specific variable use to render negative value in all case
165: double maxDataClustAbs = 0;
166: double maxDataLineAbs = 0;
167: int numberOfNegativ = 0;
168: int numberOfZero = 0;
169:
170: try {
171:
172: String[] xAxisLabels = { "MAR", "APR", "MAY", "JUN", "JUL",
173: "AUG", "SEP", "OCT", "NOV", "DEC", "JAN", "FEB" };
174:
175: double[][] dataClust = new double[][] {
176: { 3533, 101265, 76076, 86664, 135567, 87729, 85309,
177: 143423, 18732, 111842, 39534, 11980 },
178: { 0, 103400, 65000, 88500, 143000, 80000, 88500,
179: 143500, 99000, 118500, 38500, 18000 } };
180: double[][] dataLine = new double[][] { { 21, 4, 1, 2, 3, 2,
181: 3, 2, 93, 18, 54, 0 } };
182:
183: String title = "Chart Title";
184: String legendLabel1 = "Legend Label 1";
185: String legendLabel2 = "Legend Label 2";
186: String legendLabel3 = "Legend Label 3";
187:
188: //IAxisDataSeries dataSeries = new DataSeries( xAxisLabels, null, null, title );
189: IAxisDataSeries dataSeries = new DataSeries(xAxisLabels,
190: "X Axis title", "Left Y Axis title", title);
191:
192: String[] legendLabelsClust = { legendLabel1, legendLabel2 };
193: Paint[] clustPaints = new Paint[] { Color.pink, Color.blue };
194:
195: String[] legendLabelsLine = { legendLabel3 };
196: Paint[] linePaints = new Paint[] { Color.green };
197:
198: //------------On r�cup�re une 2�me �chelle "secondScale"------------------
199: //------------et on fait un traitement pour les nombres n�gatifs----------
200: //------------We get back the 2nd scale "secondScale"---------------------
201: //-------------and we handle the negative numbers---------------------
202: //On identifie la valeur maximum absolue des data Clustered Bar
203: //et on compte le nombre de z�ro et le nombre de chiffres n�gatifs
204: // We identify the absolute maximum value of the data in the Clustered Bar
205: // and we count the number of zero and negative digits
206: for (int k = 0; k < 2; k++) {
207:
208: for (int j = 0; j < xAxisLabels.length; j++) {
209: if (maxDataClustAbs < (Math.abs(dataClust[k][j]))
210: && (dataClust[k][j] != 0)) {
211: maxDataClustAbs = (Math.abs(dataClust[k][j]));
212: }
213: if (dataClust[k][j] < 0) {
214: numberOfNegativ += 1;
215: }
216: if (dataClust[k][j] == 0) {
217: numberOfZero += 1;
218: }
219: }
220: }
221:
222: //On identifie la valeur maximum absolue des data Line
223: //et on compte le nombre de z�ro et le nombre de chiffres n�gatifs
224: // We identify the absolute maximum value of the data lines
225: // and we count the number of zero and negative digits
226: for (int j = 0; j < xAxisLabels.length; j++) {
227: if (maxDataLineAbs < (Math.abs(dataLine[0][j]))
228: && (dataLine[0][j] != 0)) {
229: maxDataLineAbs = (Math.abs(dataLine[0][j]));
230: }
231: if (dataLine[0][j] < 0) {
232: numberOfNegativ += 1;
233: }
234: if (dataLine[0][j] == 0) {
235: numberOfZero += 1;
236: }
237: }
238:
239: //On d�finit la valeur de la seconde �chelle si les ordres de grandeurs
240: //sont tr�s diff�rent (de l'ordre de 10).
241: //We define the value of the second scale if the increment is an order of
242: //magnitude greater
243: if (maxDataClustAbs > 10 * maxDataLineAbs) {
244: axisProperties.getYAxisProperties().setShowRightAxis(
245: true);
246: secondScale = Math.round(maxDataClustAbs
247: / (maxDataLineAbs));
248: axisProperties.getYAxisProperties()
249: .setSecondScaleRight((float) (secondScale));
250: ChartFont axisScaleFontRight = new ChartFont(new Font(
251: "Arial Narrow", Font.PLAIN, 10), Color.green
252: .darker());
253: axisProperties.getYAxisProperties()
254: .setScaleChartFontRight(axisScaleFontRight);
255: }
256:
257: //On v�rifie s'il y a des valeurs n�gatives
258: // Check if there are negative numbers
259: if (numberOfNegativ > 0) {
260: if ((maxDataLineAbs * secondScale) > maxDataClustAbs) {
261: axisProperties
262: .getYAxisProperties()
263: .setMinRightAxis(
264: (double) (-maxDataLineAbs * secondScale));
265: //Si les valeurs ne sont pas toutes n�gatives on affiche l'axe des ordonn�es
266: //de mani�re a ce que le z�ro soit centr�
267: // If the numbers are not all negative we center the ordinal axis around zero
268: if (numberOfNegativ != (3 * xAxisLabels.length - numberOfZero)) {
269: axisProperties
270: .getYAxisProperties()
271: .setMaxRightAxis(
272: (double) (maxDataLineAbs * secondScale));
273: }
274: } else {
275: axisProperties.getYAxisProperties()
276: .setMinRightAxis(
277: (double) (-maxDataClustAbs));
278: if (numberOfNegativ != (3 * xAxisLabels.length - numberOfZero)) {
279: axisProperties.getYAxisProperties()
280: .setMaxRightAxis(
281: (double) (maxDataClustAbs));
282: }
283: }
284: }
285:
286: dataSeries.addIAxisPlotDataSet(new AxisChartDataSet(
287: dataClust, legendLabelsClust, clustPaints,
288: ChartType.BAR_CLUSTERED,
289: clusteredBarChartProperties));
290: dataSeries.addIAxisPlotDataSet(new AxisChartDataSet(
291: dataLine, legendLabelsLine, linePaints,
292: ChartType.LINE, lineChartProperties));
293: AxisChart axisChart = new AxisChart(dataSeries,
294: chartProperties, axisProperties, legendProperties,
295: width, height);
296:
297: ServletEncoderHelper.encodeJPEG13(axisChart, 1.0f,
298: httpServletResponse);
299: } catch (Throwable throwable) {
300: //HACK do your error handling here...
301: throwable.printStackTrace();
302: }
303: }
304:
305: }
|