From: Chris M. <ki...@us...> - 2004-06-14 04:59:19
|
Update of /cvsroot/jcharts/krysalis-jcharts/src/java/org/krysalis/jcharts/axisChart In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv3118/src/java/org/krysalis/jcharts/axisChart Modified Files: AxisChart.java Added Files: StackedBarChart3D.java Log Message: 3D stacked bar chart functionality added --- NEW FILE: StackedBarChart3D.java --- /*********************************************************************************************** * 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 ************************************************************************************************/ package org.krysalis.jcharts.axisChart; import org.krysalis.jcharts.chartData.ChartDataException; import org.krysalis.jcharts.chartData.interfaces.IAxisChartDataSet; import org.krysalis.jcharts.imageMap.RectMapArea; import org.krysalis.jcharts.properties.DataAxisProperties; import org.krysalis.jcharts.properties.StackedBarChart3DProperties; import java.awt.*; import java.awt.geom.GeneralPath; import java.awt.geom.Rectangle2D; /************************************************************************************* * * @author Steve Skillcorn/Chris McKay * @version $Id: StackedBarChart3D.java,v 1.1 2004/06/14 04:59:09 kiwicmc Exp $ ************************************************************************************/ abstract class StackedBarChart3D { /******************************************************************************************** * Draws the chart * * @param axisChart *********************************************************************************************/ static void render( AxisChart axisChart, IAxisChartDataSet iAxisChartDataSet ) throws ChartDataException { Graphics2D g2d = axisChart.getGraphics2D(); StackedBarChart3DProperties stackedBarChart3DProperties = (StackedBarChart3DProperties) iAxisChartDataSet.getChartTypeProperties(); float barWidth; //---y axis position on screen to start drawing. float startingX; float startingY; float width; float height; DataAxisProperties dataAxisProperties; if( axisChart.getAxisProperties().isPlotHorizontal() ) { dataAxisProperties = (DataAxisProperties) axisChart.getAxisProperties().getXAxisProperties(); barWidth = axisChart.getYAxis().getScalePixelWidth() * stackedBarChart3DProperties.getPercentage(); startingX = axisChart.getXAxis().getZeroLineCoordinate(); startingY = axisChart.getYAxis().getLastTickY() - (barWidth / 2); width = 0; height = barWidth; Rectangle2D.Float rectangle = new Rectangle2D.Float( startingX, startingY, width, height ); StackedBarChart3D.horizontalPlot( axisChart, iAxisChartDataSet, stackedBarChart3DProperties, dataAxisProperties, g2d, rectangle, startingX ); } else { dataAxisProperties = (DataAxisProperties) axisChart.getAxisProperties().getYAxisProperties(); barWidth = axisChart.getXAxis().getScalePixelWidth() * stackedBarChart3DProperties.getPercentage(); startingX = axisChart.getXAxis().getTickStart() - (barWidth / 2); startingY = axisChart.getYAxis().getZeroLineCoordinate(); width = barWidth; height = 0; Rectangle2D.Float rectangle = new Rectangle2D.Float( startingX, startingY, width, height ); StackedBarChart3D.verticalPlot( axisChart, iAxisChartDataSet, stackedBarChart3DProperties, dataAxisProperties, g2d, rectangle, startingY ); } } /************************************************************************************** * * @param axisChart * @param iAxisChartDataSet * @param stackedBarChartProperties * @param dataAxisProperties * @param g2d * @param rectangle * @param startingX **************************************************************************************/ private static void horizontalPlot( AxisChart axisChart, IAxisChartDataSet iAxisChartDataSet, StackedBarChart3DProperties stackedBarChart3DProperties, DataAxisProperties dataAxisProperties, Graphics2D g2d, Rectangle2D.Float rectangle, float startingX ) throws ChartDataException { int imageMapLabelIndex = axisChart.getYAxis().getNumberOfScaleItems() - 1; //LOOP //---initial postion of each line. for( int i = 0; i < iAxisChartDataSet.getNumberOfDataItems(); i++ ) { //---draw each bar in stack for( int j = 0; j < iAxisChartDataSet.getNumberOfDataSets(); j++ ) { //---if segment has a zero value, draw nothing. if( iAxisChartDataSet.getValue( j, i ) == 0 ) { continue; } else if( iAxisChartDataSet.getValue( j, i ) < 0 ) { //todo i think we could support this, but it can wait throw new ChartDataException( "Negative values in Stacked Bar charts are not supported yet... Coming soon..." ); /* rectangle.x = axisChart.getXAxis().computeAxisCoordinate( axisChart.getXAxis().getOrigin(), iAxisChartDataSet.getValue( 0, i ), dataAxisProperties.getScaleCalculator().getMinValue() ); rectangle.width = startingX - rectangle.x; */ } else { rectangle.width = BarChart.computeScaleHeightOfValue( iAxisChartDataSet.getValue( j, i ), axisChart.getXAxis().getOneUnitPixelSize() ); //rectangle.x = startingX; //rectangle.width = BarChart.computeScaleHeightOfValue( iAxisChartDataSet.getValue( j, i ), axisChart.getXAxis().getOneUnitPixelSize() ); } g2d.setPaint( iAxisChartDataSet.getPaint( j ) ); g2d.fill( rectangle ); if( stackedBarChart3DProperties.getShowOutlinesFlag() ) { stackedBarChart3DProperties.getBarOutlineStroke().draw( g2d, rectangle ); } //---if we are generating an ImageMap, store the image coordinates if( axisChart.getGenerateImageMapFlag() ) { String label = null; if( axisChart.getYAxis().getAxisLabelsGroup() != null ) { label = axisChart.getYAxis().getAxisLabelsGroup().getTextTag( imageMapLabelIndex ).getText(); } /* TODO this fix to be added later for combo charts and the ability todetermine which image map relates to what DataSet RectMapArea area = new RectMapArea(rectangle, iAxisChartDataSet.getValue(j, i), label, iAxisChartDataSet.getLegendLabel(j)); int[] index = new int[2]; index[0] = j; index[1] = i; area.setIndex(index); area.setKey("StackedBarChart3D"); axisChart.getImageMap().addImageMapArea(area); */ } rectangle.x += rectangle.width; } imageMapLabelIndex--; rectangle.y += axisChart.getYAxis().getScalePixelWidth(); rectangle.x = startingX; } } /************************************************************************************** * * @param axisChart * @param iAxisChartDataSet * @param stackedBarChartProperties * @param dataAxisProperties * @param g2d * @param rectangle * @param startingY **************************************************************************************/ private static void verticalPlot( AxisChart axisChart, IAxisChartDataSet iAxisChartDataSet, StackedBarChart3DProperties stackedBarChart3DProperties, DataAxisProperties dataAxisProperties, Graphics2D g2d, Rectangle2D.Float rectangle, float startingY ) { //IDataSeries iDataSeries= (IDataSeries) axisChart.getIAxisDataSeries(); //LOOP //---initial postion of each line. for( int i = 0; i < iAxisChartDataSet.getNumberOfDataItems(); i++ ) { //---draw each bar in stack for( int j = 0; j < iAxisChartDataSet.getNumberOfDataSets(); j++ ) { //---if segment has a zero value, draw nothing. if( iAxisChartDataSet.getValue( j, i ) == 0 ) { continue; } rectangle.height = BarChart.computeScaleHeightOfValue( iAxisChartDataSet.getValue( j, i ), axisChart.getYAxis().getOneUnitPixelSize() ); rectangle.y -= rectangle.height; draw3DRect(g2d, rectangle, iAxisChartDataSet.getPaint(j), stackedBarChart3DProperties); if( stackedBarChart3DProperties.getShowOutlinesFlag()) { stackedBarChart3DProperties.getBarOutlineStroke().draw( g2d, rectangle ); } //---if we are generating an ImageMap, store the image coordinates if( axisChart.getGenerateImageMapFlag() ) { String label = null; if( axisChart.getXAxis().getAxisLabelsGroup() != null ) { label = axisChart.getXAxis().getAxisLabelsGroup().getTextTag( i ).getText(); } /* TODO this fix to be added later for combo charts and the ability todetermine which image map relates to what DataSet a = new RectMapArea(rectangle, iAxisChartDataSet.getValue(j, i), label, iAxisChartDataSet.getLegendLabel(j)); int[] index = new int[2]; index[0] = j; index[1] = i; area.setIndex(index); area.setKey("StackedBarChart3D"); axisChart.getImageMap().addImageMapArea(area); */ } } rectangle.x += axisChart.getXAxis().getScalePixelWidth(); rectangle.y = startingY; } } private static void draw3DRect(Graphics2D g2d, Rectangle2D.Float rectangle, Paint paint, StackedBarChart3DProperties props) { GeneralPath poly; float x, y, depth, width, height, offset; Color color; //The rounding stops a lighter shade possibily appearing at the join of the //bar and the z axis side due to antialiasing at cross pixel points. x = Math.round(rectangle.x); width = Math.round(rectangle.width); y = rectangle.y; depth = props.getDepth(); height = rectangle.height; offset = depth; //The bar g2d.setPaint(paint); g2d.fill(new Rectangle2D.Float(x, y, width, height)); color = (Color) paint; g2d.setPaint(getTopColor(color)); //The top poly = new GeneralPath(); poly.moveTo(x, y); poly.lineTo(x + offset, y - offset); poly.lineTo(x + offset + width, y - offset); poly.lineTo(x + width, y); poly.closePath(); g2d.fill(poly); if (props.getShowOutlinesFlag()) { props.getBarOutlineStroke().draw(g2d, poly); } //The side g2d.setPaint(getBackColor(color)); poly = new GeneralPath(); poly.moveTo(x + width, y); poly.lineTo(x + width + offset, y - offset); poly.lineTo(x + width + offset, y - offset + height); poly.lineTo(x + width, y + height); poly.closePath(); g2d.fill(poly); if (props.getShowOutlinesFlag()) { props.getBarOutlineStroke().draw(g2d, poly); } if (props.getShowOutlinesFlag()) { props.getBarOutlineStroke().draw(g2d, new Rectangle2D.Float(x, y, width, height)); } } private static Color getTopColor(Color color) { double lightness = lightness(color); if (lightness >= 0.90) { return (darken(color.getRed(), color.getGreen(), color.getBlue(), 0.100)); } if (lightness <= 0.20) { return (lighten(color.getRed(), color.getGreen(), color.getBlue(), 0.600)); } return (lighten(color.getRed(), color.getGreen(), color.getBlue(), 0.600)); } public static Color getBackColor(Color color) { double lightness = lightness(color); if (color == null) { return null; } if (lightness >= 0.90) { return (darken(color.getRed(), color.getGreen(), color.getBlue(), 0.250)); } if (lightness <= 0.20) { return (lighten(color.getRed(), color.getGreen(), color.getBlue(), 0.200)); } return (darken(color.getRed(), color.getGreen(), color.getBlue(), 0.250)); } private static Color darken(int red, int green, int blue, double percent) throws IllegalArgumentException { return new Color(Math.max((int) (red * (1 - percent)), 0), Math.max((int) (green * (1 - percent)), 0), Math.max((int) (blue * (1 - percent)), 0)); } private static Color lighten(int red, int green, int blue, double percent) throws IllegalArgumentException { int adjustedRed, adjustedGreen, adjustedBlue; adjustedRed = red + (int) ((255 - red) * percent); adjustedGreen = green + (int) ((255 - green) * percent); adjustedBlue = blue + (int) ((255 - blue) * percent); return new Color(adjustedRed, adjustedGreen, adjustedBlue); } private static double lightness(Color color) { double red, green, blue, max, min; if (color == null) { return 0; } red = color.getRed(); green = color.getGreen(); blue = color.getBlue(); max = (Math.max(red, Math.max(green, blue)) / 255) / 2; min = (Math.min(red, Math.min(green, blue)) / 255) / 2; return (max + min); } } Index: AxisChart.java =================================================================== RCS file: /cvsroot/jcharts/krysalis-jcharts/src/java/org/krysalis/jcharts/axisChart/AxisChart.java,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** AxisChart.java 31 May 2004 16:23:46 -0000 1.7 --- AxisChart.java 14 Jun 2004 04:59:09 -0000 1.8 *************** *** 584,587 **** --- 584,593 ---- StackedBarChart.render( this, ( IAxisChartDataSet ) iAxisPlotDataSet ); } + iAxisPlotDataSet = this.iAxisDataSeries.getIAxisPlotDataSet( ChartType.BAR_STACKED_3D ); + if( iAxisPlotDataSet != null ) + { + StackedBarChart3D.render( this, ( IAxisChartDataSet ) iAxisPlotDataSet ); + } + iAxisPlotDataSet = this.iAxisDataSeries.getIAxisPlotDataSet( ChartType.BAR_CLUSTERED ); if( iAxisPlotDataSet != null ) |