From: <ki...@us...> - 2003-08-27 04:38:04
|
Update of /cvsroot/jcharts/krysalis-jcharts/src/java/org/krysalis/jcharts/demo/simpleservlet In directory sc8-pr-cvs1:/tmp/cvs-serv23576/demo/simpleservlet Added Files: DualYAxis.java Log Message: Integration of the Dual Y axis code that was submitted to Nathaniel by Romain SEGUY. These are new properties added to the AxisTypeProperties class ChartFont AxisTypeProperties.getScaleChartFontRight() void AxisTypeProperties.setScaleChartFontRight( ChartFont scaleChartFontRight ) void AxisTypeProperties.setShowRightAxis( boolean showRightAxis ) float AxisTypeProperties.getSecondScaleRight() void AxisTypeProperties.setSecondScaleRight(float secondScaleRight) double AxisTypeProperties.getMinRightAxis() void AxisTypeProperties.setMinRightAxis(double minRightAxis) double AxisTypeProperties.getMaxRightAxis() void AxisTypeProperties.setMaxRightAxis(double maxRightAxis) Added to Axis class TextTagGroup Axis.getAxisLabelsGroupRight() void Axis.setAxisLabelsGroupRight( TextTagGroup axisLabelsGroupRight ) There is a demonstration servlet in org\krysalis\jcharts\demo\simpleservlet called DualYAxis.java --- NEW FILE: DualYAxis.java --- package org.krysalis.jcharts.demo; /*********************************************************************************************** * File Info: $Id: DualYAxis.java,v 1.1 2003/08/27 04:37:44 kiwicmc Exp $ * Copyright (C) 2002 * Author: Nathaniel G. Auvil * Contributor(s): * * Copyright 2002 (C) Nathaniel G. Auvil. All Rights Reserved. * * Redistribution and use of this software and associated documentation ("Software"), with or * without modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain copyright statements and notices. * Redistributions must also contain a copy of this document. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials * provided with the distribution. * * 3. The name "jCharts" or "Nathaniel G. Auvil" must not be used to endorse or promote * products derived from this Software without prior written permission of Nathaniel G. * Auvil. For written permission, please contact nat...@us... * * 4. Products derived from this Software may not be called "jCharts" nor may "jCharts" appear * in their names without prior written permission of Nathaniel G. Auvil. jCharts is a * registered trademark of Nathaniel G. Auvil. * * 5. Due credit should be given to the jCharts Project (http://jcharts.sourceforge.net/). * * THIS SOFTWARE IS PROVIDED BY Nathaniel G. Auvil AND CONTRIBUTORS ``AS IS'' AND ANY * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL * jCharts OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE ************************************************************************************************/ import java.awt.*; import org.krysalis.jcharts.axisChart.*; import org.krysalis.jcharts.chartData.*; import org.krysalis.jcharts.chartData.interfaces.*; import org.krysalis.jcharts.encoders.ServletEncoderHelper; import org.krysalis.jcharts.properties.*; import org.krysalis.jcharts.properties.util.*; import org.krysalis.jcharts.types.*; import java.util.*; import javax.servlet.*; import javax.servlet.http.*; import java.io.IOException; // Dual Y axis changes courtesy of Stéphane NGUYEN integrated by CMC 25Aug03 // French translation courtesy of my good wife Jacki ... public class DualYAxis extends ChartServlet { //---all of the charts will have some properties. private LineChartProperties lineChartProperties; private ClusteredBarChartProperties clusteredBarChartProperties; protected LegendProperties legendProperties; protected ChartProperties chartProperties; protected AxisProperties axisProperties; //---all of the charts have the same size protected int width = 750; protected int height = 430; public void init() { //---------------------Font & Police---------------------------------------- legendProperties = new LegendProperties(); chartProperties = new ChartProperties(); axisProperties = new AxisProperties(false); ChartFont axisScaleFont = new ChartFont(new Font("Arial Narrow", Font.PLAIN, 10), Color.black); axisProperties.getXAxisProperties().setScaleChartFont(axisScaleFont); axisProperties.getYAxisProperties().setScaleChartFont(axisScaleFont); ChartFont axisTitleFont = new ChartFont(new Font("Arial Narrow", Font.PLAIN, 13), Color.black); axisProperties.getXAxisProperties().setTitleChartFont(axisTitleFont); axisProperties.getYAxisProperties().setTitleChartFont(axisTitleFont); ChartFont titleFont = new ChartFont(new Font("Georgia Negreta cursiva", Font.PLAIN, 15), Color.black); chartProperties.setTitleFont(titleFont); //On fixe la marge avec le cadre // Set the margin within the frame chartProperties.setEdgePadding(2f); //On met le graphe sur un fond gris clair // Set the chart against a plain grey background axisProperties.setBackgroundPaint(new Color (245, 245, 245)); //Paramétrage de la boîte de légende //Parameters for the legend box //legendProperties.setPlacement(LegendAreaProperties.RIGHT); //legendProperties.setNumColumns(1); //legendProperties.setFont( new Font("Arial Narrow", Font.PLAIN, 13) ); //legendProperties.setFontPaint(Color.black); ChartFont legendFont = new ChartFont(new Font("Arial Narrow", Font.PLAIN, 13), Color.black); legendProperties.setChartFont(legendFont); legendProperties.setChartPadding(10); //Arrondi à la puissance 10 //Round up to the power of 10 DataAxisProperties dataAxisProperties= (DataAxisProperties) axisProperties.getYAxisProperties(); dataAxisProperties.setRoundToNearest(1); //Parametrage du nombre de graduation sur l'axe des ordonnées //Set the number of ticks(?) for the ordinal axis dataAxisProperties.setNumItems(6); //utilisation de la virgule s'il y a lieu (normalement non) // Set the use of the comma if there are any (usually not) dataAxisProperties.setUseCommas(false); //Ne pas afficher les bordures supérieur et droite du chart // Don't attach upper borders and the right of the chart axisProperties.getYAxisProperties().setShowEndBorder(false); axisProperties.getXAxisProperties().setShowEndBorder(false); Stroke[] strokes = {LineChartProperties.DEFAULT_LINE_STROKE}; //Shape[] shapes = {null}; Shape[] shapes= { PointChartProperties.SHAPE_TRIANGLE }; lineChartProperties = new LineChartProperties(strokes, shapes); clusteredBarChartProperties = new ClusteredBarChartProperties(); //Paramètrage de la largeur des barres de l'histogramme et non affichage des contours //Set the width of the bars and don't show the outline clusteredBarChartProperties.setWidthPercentage( 0.70f ); clusteredBarChartProperties.setShowOutlinesFlag( false ); } /********************************************************************************************** * **********************************************************************************************/ public void service( HttpServletRequest req, HttpServletResponse httpServletResponse ) throws ServletException, IOException { //---Some charts will need a second scale to render some values and then will //---need to render an axis at the right of the charts with it long secondScale=1; //---specific variable use to render negative value in all case double maxDataClustAbs = 0; double maxDataLineAbs = 0; int numberOfNegativ=0; int numberOfZero=0; try { String[] xAxisLabels = {"MAR", "APR", "MAY", "JUN", "JUL", "AUG", "SEP", "OCT", "NOV", "DEC", "JAN", "FEB"}; double[][] dataClust = new double[][]{ {3533, 101265, 76076, 86664, 135567, 87729, 85309, 143423, 18732, 111842, 39534, 11980} , {0, 103400, 65000, 88500, 143000, 80000, 88500, 143500, 99000, 118500, 38500, 18000} }; double[][] dataLine = new double[][]{ {21, 4, 1, 2, 3, 2, 3, 2, 93, 18, 54, 0} }; String title = "Chart Title"; String legendLabel1 = "Legend Label 1"; String legendLabel2 = "Legend Label 2"; String legendLabel3 = "Legend Label 3"; //IAxisDataSeries dataSeries = new DataSeries( xAxisLabels, null, null, title ); IAxisDataSeries dataSeries = new DataSeries( xAxisLabels, "X Axis title", "Left Y Axis title", title ); String[] legendLabelsClust = {legendLabel1, legendLabel2}; Paint[] clustPaints = new Paint[]{Color.pink, Color.blue}; String[] legendLabelsLine = {legendLabel3}; Paint[] linePaints = new Paint[]{Color.green}; //------------On récupère une 2ème échelle "secondScale"------------------ //------------et on fait un traitement pour les nombres négatifs---------- //------------We get back the 2nd scale "secondScale"--------------------- //-------------and we handle the negative numbers--------------------- //On identifie la valeur maximum absolue des data Clustered Bar //et on compte le nombre de zéro et le nombre de chiffres négatifs // We identify the absolute maximum value of the data in the Clustered Bar // and we count the number of zero and negative digits for (int k=0; k<2; k++) { for (int j=0; j<xAxisLabels.length; j++) { if (maxDataClustAbs < (Math.abs(dataClust[k][j])) && (dataClust[k][j]!=0) ) { maxDataClustAbs=(Math.abs(dataClust[k][j])); } if (dataClust[k][j]<0) { numberOfNegativ+=1; } if (dataClust[k][j]==0) { numberOfZero+=1; } } } //On identifie la valeur maximum absolue des data Line //et on compte le nombre de zéro et le nombre de chiffres négatifs // We identify the absolute maximum value of the data lines // and we count the number of zero and negative digits for (int j=0; j<xAxisLabels.length; j++) { if (maxDataLineAbs < (Math.abs(dataLine[0][j])) && (dataLine[0][j]!=0) ) { maxDataLineAbs=(Math.abs(dataLine[0][j])); } if (dataLine[0][j]<0) { numberOfNegativ+=1; } if (dataLine[0][j]==0) { numberOfZero+=1; } } //On définit la valeur de la seconde échelle si les ordres de grandeurs //sont très différent (de l'ordre de 10). //We define the value of the second scale if the increment is an order of //magnitude greater if (maxDataClustAbs>10*maxDataLineAbs) { axisProperties.getYAxisProperties().setShowRightAxis(true); secondScale=Math.round(maxDataClustAbs/(maxDataLineAbs)); axisProperties.getYAxisProperties().setSecondScaleRight((float) (secondScale) ); ChartFont axisScaleFontRight = new ChartFont( new Font("Arial Narrow", Font.PLAIN, 10), Color.green.darker() ); axisProperties.getYAxisProperties().setScaleChartFontRight( axisScaleFontRight ); } //On vérifie s'il y a des valeurs négatives // Check if there are negative numbers if (numberOfNegativ>0) { if ((maxDataLineAbs*secondScale)>maxDataClustAbs) { axisProperties.getYAxisProperties().setMinRightAxis((double) (-maxDataLineAbs*secondScale)); //Si les valeurs ne sont pas toutes négatives on affiche l'axe des ordonnées //de manière a ce que le zéro soit centré // If the numbers are not all negative we center the ordinal axis around zero if (numberOfNegativ!=(3*xAxisLabels.length-numberOfZero)) { axisProperties.getYAxisProperties().setMaxRightAxis((double) (maxDataLineAbs*secondScale)); } } else { axisProperties.getYAxisProperties().setMinRightAxis((double) (-maxDataClustAbs)); if (numberOfNegativ!=(3*xAxisLabels.length-numberOfZero)) { axisProperties.getYAxisProperties().setMaxRightAxis((double) (maxDataClustAbs)); } } } dataSeries.addIAxisPlotDataSet( new AxisChartDataSet( dataClust, legendLabelsClust, clustPaints, ChartType.BAR_CLUSTERED, clusteredBarChartProperties ) ); dataSeries.addIAxisPlotDataSet( new AxisChartDataSet( dataLine, legendLabelsLine, linePaints, ChartType.LINE, lineChartProperties ) ); AxisChart axisChart = new AxisChart( dataSeries, chartProperties, axisProperties, legendProperties, width, height ); ServletEncoderHelper.encodeJPEG13( axisChart, 1.0f, httpServletResponse ); } catch( Throwable throwable ) { //HACK do your error handling here... throwable.printStackTrace(); } } } |