OW2 Consortium ofccharts

Compare Revisions

Ignore whitespace Rev 4 → Rev 5

/trunk/project/ofccharts/build.xml
New file
0,0 → 1,359
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE project [
 
<!ENTITY versionEntity "3.1">
]
>
 
<!-- ============================================================================================== -->
<!-- -->
<!-- OFC-Charts build file -->
<!-- -->
<!-- Targets are: -->
<!-- -->
<!-- o init : inits all the needed variables -->
<!-- o info (Default): print available targets -->
<!-- o debug: see the value of variables used by Ant -->
<!-- o compile: compile the ofc API -->
<!-- o javadoc: make javadoc for the packaged application -->
<!-- o clean: cleans the docs and classes directories -->
<!-- o clean-all: clean, distrib-clean -->
<!-- o jar: creates the jar files -->
<!-- o all: clean, compile, javadoc, jar -->
<!-- o distrib-clean: cleans the distrib directory -->
<!-- o distrib-copydocs: copy the docs to the distrib directory -->
<!-- o distrib-copysample: copies all the sample needed files to distrib -->
<!-- o distrib: makes distrib-clean, distrib-copydocs, -->
<!-- + zipping the distrib files -->
<!-- ============================================================================================== -->
 
<project name="OFC Charts" default="info" basedir=".">
 
<!-- ======================================================================= -->
<!-- INIT: set project environment -->
<!-- ======================================================================= -->
<target name="init">
<tstamp/>
<property name="ant.home" value="." />
<!-- project variables -->
<property name="project.name" value="OFC Charts" />
<property name="product.name" value="Charts" />
<property name="version" value="&versionEntity;" />
<property name="date" value="${DSTAMP}_${TSTAMP}" />
<!-- project paths -->
<property name="ofc.home" value="${basedir}" />
<property name="ofc.lib" value="${basedir}/lib" />
<property name="ofc.src.dir" value="${basedir}/src" />
<property name="ofc.classes.dir" value="${basedir}/classes" />
<property name="ofc.javadoc.dir" value="${basedir}/docs/api" />
<property name="ofc.distrib.dir" value="${basedir}/distrib" />
<property name="ofc.tmp.dir" value="${basedir}/tmp" />
<property name="ofc.etc.dir" value="${basedir}/etc" />
<!-- java librairies -->
<property name="project.classpath" value="${lib.all}" />
<!-- uncomment if you want to use jikes (must be in your path) -->
<!--property name="build.compiler" value="jikes" /-->
<echo message="==============================================================" />
<echo message="" />
<echo message="** Project: ${project.name} ** " />
<echo message="** Version: ${version} **" />
<echo message="** ${TODAY} : ${TSTAMP} **" />
<echo message="** Basedir: ${basedir}" />
<echo message="" />
<echo message="==============================================================" />
<mkdir dir="${ofc.classes.dir}" />
<mkdir dir="${ofc.javadoc.dir}" />
<mkdir dir="${ofc.distrib.dir}" />
<mkdir dir="${ofc.tmp.dir}" />
 
</target>
 
<!-- ======================================================================= -->
<!-- INFO: print available targets -->
<!-- ======================================================================= -->
<target name="info" depends="init">
<echo message="" />
<echo message="Targets are : " />
<echo message="" />
<echo message=" o init : inits all the needed variables" />
<echo message=" o info (Default): print available targets" />
<echo message=" o debug: see the value of variables used by Ant" />
<echo message=" o compile: compile the ofc API, the samples and the Apps" />
<echo message=" o clean: cleans the docs and classes directories" />
<echo message=" o clean-all: clean, distrib-clean" />
<echo message=" o all: clean, compile, javadoc, jar" />
<echo message=" o distrib-clean: cleans the distrib directory" />
<echo message=" o distrib-copydocs: copy the docs to the distrib directory" />
<echo message=" o distrib: makes distrib-clean," />
<echo message=" distrib-copydocs, distrib-copysample" />
<echo message=" + zipping the distrib files" />
<echo message=" o javadoc : generates the javadoc of connection" />
<echo message=" o jar : create the jar files of connection" />
<echo message="" />
</target>
 
<!-- ======================================================================= -->
<!-- ALL: compile and javadoc -->
<!-- ======================================================================= -->
<target name="all" depends="clean, jar, javadoc">
</target>
<!-- ======================================================================= -->
<!-- DEBUG: print debug info -->
<!-- ======================================================================= -->
<target name="debug" depends="init">
<echo message="################################################" />
<echo message="Debug information" />
<echo message="################################################" />
<echo message="-- Project" />
<echo message=" version = ${version}" />
<echo message=" date = ${TODAY} : ${TSTAMP} " />
<echo message="################################################" />
<echo message="-- Paths" />
<echo message=" ofc.src.dir = ${ofc.src.dir}" />
<echo message=" ofc.classes.dir = ${ofc.classes.dir}" />
<echo message=" ofc.javadoc.dir = ${ofc.javadoc.dir}" />
<echo message=" ofc.lib = ${ofc.lib}" />
<echo message="################################################" />
<echo message="-- Librairies" />
<echo message=" lib.all = ${lib.all}" />
<echo message="################################################" />
<echo message="-- Classpath" />
<echo message=" project.classpath = ${project.classpath}" />
<echo message="################################################" />
<echo message="--------------------------------------------------" />
</target>
 
<!-- ========================================================================== -->
<!-- GENERATE-VERSION: generate the version class with the parameter ${version} -->
<!-- ========================================================================== -->
<target name="generate-version" depends="init">
<java classname="generateVersion" fork="yes" classpath="./etc">
<arg line="
-Product=${product.name}
-Version=${version}
-Package=
" />
</java>
</target>
 
<!-- ======================================================================= -->
<!-- COMPILE: compile all source files (default with javac) -->
<!-- ======================================================================= -->
<target name="compile" depends="init, clean">
<echo message="################################################" />
<mkdir dir="${ofc.classes.dir}" />
 
<echo message="---------- Compiling the API ----------------" />
<javac srcdir="${ofc.src.dir}"
destdir="${ofc.classes.dir}"
classpath="${project.classpath}"
excludes="**/CVS/**, **/Cvs/**"
depend="yes"
/>
<echo message="################################################" />
</target>
 
<!-- ======================================================================= -->
<!-- CLEAN: delete the classes directory and the docs -->
<!-- ======================================================================= -->
<target name="clean" depends="init">
<echo message="################################################" />
<delete dir="${ofc.classes.dir}"/>
<delete>
<fileset dir="${ofc.javadoc.dir}" excludes="**/CVS/**, **/Cvs/**" />
</delete>
<echo message="################################################" />
</target>
 
<!-- ======================================================================= -->
<!-- DISTRIB-CLEAN : clean distribution directory -->
<!-- ======================================================================= -->
<target name="distrib-clean" depends="init">
<echo message="################################################" />
<echo message="---------- Deleting the distrib directory ----------------" />
<delete dir="${ofc.distrib.dir}" />
<echo message="---------- Creating the distrib directory ----------------" />
<mkdir dir="${ofc.distrib.dir}" />
<echo message="################################################" />
</target>
<!-- ======================================================================= -->
<!-- DISTRIB-COPYJAR : copy ofcCharts.jar to the distrib -->
<!-- ======================================================================= -->
<target name="distrib-copyjar" depends="init,jar">
<echo message="################################################" />
<echo message="-------------- Copying the ofcCharts.jar ------------------" />
<copy todir="${ofc.distrib.dir}" file="${ofc.classes.dir}/ofcCharts.jar" />
<echo message="################################################" />
</target>
 
<!-- ======================================================================= -->
<!-- DISTRIB-COPYDOCS : copy the docs to the distrib -->
<!-- ======================================================================= -->
<target name="distrib-copydocs" depends="init,javadoc">
<echo message="################################################" />
<echo message="-------------- Copying the doc files ------------------" />
<copy todir="${ofc.distrib.dir}/docs" >
<fileset dir="${ofc.home}/docs" excludes="**/*.doc"/>
</copy>
<echo message="################################################" />
</target>
 
 
<!-- ======================================================================= -->
<!-- DISTRIB-COPYLIBS : copy the external librairies -->
<!-- ======================================================================= -->
<target name="distrib-copylibs" depends="init">
<echo message="################################################" />
<echo message="------------- Copying the extern librairies files ----------------" />
<mkdir dir="${ofc.distrib.dir}/lib" />
<copy todir="${ofc.distrib.dir}/lib" file="${ofc.lib}/js.jar" />
<copy todir="${ofc.distrib.dir}/lib" file="${ofc.lib}/crimson-parser.jar" />
<copy todir="${ofc.distrib.dir}/lib" file="${ofc.lib}/crimson.jar" />
<copy todir="${ofc.distrib.dir}/lib" file="${ofc.lib}/jaxp.jar" />
<copy todir="${ofc.distrib.dir}/lib" file="${ofc.lib}/batik-xml.jar" />
<copy todir="${ofc.distrib.dir}/lib" file="${ofc.lib}/batik-util.jar" />
<copy todir="${ofc.distrib.dir}/lib" file="${ofc.lib}/batik-transcoder.jar" />
<copy todir="${ofc.distrib.dir}/lib" file="${ofc.lib}/batik-svggen.jar" />
<copy todir="${ofc.distrib.dir}/lib" file="${ofc.lib}/batik-svg-dom.jar" />
<copy todir="${ofc.distrib.dir}/lib" file="${ofc.lib}/batik-script.jar" />
<copy todir="${ofc.distrib.dir}/lib" file="${ofc.lib}/batik-parser.jar" />
<copy todir="${ofc.distrib.dir}/lib" file="${ofc.lib}/batik-gvt.jar" />
<copy todir="${ofc.distrib.dir}/lib" file="${ofc.lib}/batik-gui-util.jar" />
<copy todir="${ofc.distrib.dir}/lib" file="${ofc.lib}/batik-extension.jar" />
<copy todir="${ofc.distrib.dir}/lib" file="${ofc.lib}/batik-ext.jar" />
<copy todir="${ofc.distrib.dir}/lib" file="${ofc.lib}/batik-dom.jar" />
<copy todir="${ofc.distrib.dir}/lib" file="${ofc.lib}/batik-css.jar" />
<copy todir="${ofc.distrib.dir}/lib" file="${ofc.lib}/batik-bridge.jar" />
<copy todir="${ofc.distrib.dir}/lib" file="${ofc.lib}/batik-awt-util.jar" />
<echo message="################################################" />
</target>
 
<!-- ======================================================================= -->
<!-- DISTRIB : makes the distribution release -->
<!-- ======================================================================= -->
<target name="distrib" depends="clean-all, distrib-libs, distrib-docs">
<echo message="################################################" />
<echo message="----------------- Ziping the files --------------------" />
<zip zipfile="${ofc.distrib.dir}/ofcChartsDocs.zip" basedir="${ofc.distrib.dir}" includes="docs/**" />
<echo message="################################################" />
</target>
<!-- ======================================================================= -->
<!-- DISTRIB-LIBS : makes the distribution release -->
<!-- ======================================================================= -->
<target name="distrib-libs" depends="distrib-copyjar, distrib-copylibs">
<echo message="################################################" />
<echo message="----------------- Ziping the files --------------------" />
<zip zipfile="${ofc.distrib.dir}/ofcChartsLibs.zip" basedir="${ofc.distrib.dir}" includes="ofcCharts.jar, lib/** " />
<echo message="################################################" />
</target>
 
<!-- ======================================================================= -->
<!-- DISTRIB-DOCS : makes the distribution release -->
<!-- ======================================================================= -->
<target name="distrib-docs" depends="distrib-copydocs">
<echo message="################################################" />
<echo message="----------------- Ziping the files --------------------" />
<zip zipfile="${ofc.distrib.dir}/ofcChartsDocs.zip" basedir="${ofc.distrib.dir}" includes="docs/**" />
<echo message="################################################" />
</target>
 
<!-- ======================================================================= -->
<!-- CLEAN-ALL : cleans all the stuff -->
<!-- ======================================================================= -->
<target name="clean-all" depends="clean, distrib-clean">
</target>
<!-- ======================================================================= -->
<!-- JAVADOC: make external javadoc -->
<!-- ======================================================================= -->
<target name="javadoc" depends="init">
<echo message="################################################" />
<mkdir dir="${ofc.javadoc.dir}" />
<javadoc packagenames="
com.oxymel.ofc.charts,
com.oxymel.ofc.charts.exception, com.oxymel.ofc.charts.data,
com.oxymel.ofc.charts.animation,
com.oxymel.ofc.charts.data.grid.Grid,
com.oxymel.ofc.charts.data.grid.GridNode,
com.oxymel.ofc.charts.data.grid.IrregularGrid,
com.oxymel.ofc.charts.data.grid.RegularGrid,
com.oxymel.ofc.charts.animation.Contour2DAnimator,
com.oxymel.ofc.charts.animation.SVGAnimationContext,
com.oxymel.ofc.charts.animation.ChartAnimator,
com.oxymel.ofc.charts.series"
sourcepath="${ofc.src.dir}"
classpath="${project.classpath}"
destdir="${ofc.javadoc.dir}"
author="false"
version="false"
public="true"
windowtitle="${project.name} API Documentation"
>
 
<header><![CDATA[<h4> ${project.name} ${version}</h4>]]> </header>
<doctitle><![CDATA[ ${project.name} <br>
API Specification <br>
<h5> This document is the API specification for the ${project.name} component, version ${version} </h5> ]]>
</doctitle>
<bottom><![CDATA[<i>Copyright &#169; 2006 Oxymel SA All Rights Reserved.</i>]]></bottom>
</javadoc>
<echo message="################################################" />
</target>
<!-- ======================================================================= -->
<!-- JAR: creates the jar files -->
<!-- ======================================================================= -->
 
<target name="jar" depends="compile">
<echo message="################################################" />
<delete file="${ofc.classes.dir}/ofcCharts.jar" />
 
<jar jarfile="${ofc.classes.dir}/ofcCharts.jar">
<fileset dir="${ofc.classes.dir}" includes=" com/oxymel/ofc/**/*.class" />
<include name="build"/>
<manifest>
<attribute name="Built-By" value="Oxymel"/>
<section name=" OFC-Charts ${version}, ${TODAY} "/>
</manifest>
</jar>
 
<delete dir="${ofc.tmp.dir}/ofccharts" />
<echo message="################################################" />
</target>
 
</project>
/trunk/project/ofccharts/build.bat.ref
New file
0,0 → 1,39
@echo off
 
rem =================================================================================
rem
rem build.bat
rem
rem ant launcher for OFC-Charts
rem
rem
rem =================================================================================
 
rem Give the correct path to the JAVA_HOME (without white space)
 
set JAVA_HOME=%JAVA_HOME%
 
rem =================================================================================
 
 
set OFC_HOME=.
set CLASSPATH=%OFC_HOME%\lib\ant.jar;%JAVA_HOME%\lib\tools.jar;%OFC_HOME%\lib\;%JAVA_HOME%\jre\lib\rt.jar
set CLASSPATH=%OFC_HOME%\lib\jaxp.jar;%OFC_HOME%\lib\crimson.jar;%CLASSPATH%
set CLASSPATH=%OFC_HOME%\lib\js.jar;%OFC_HOME%\lib\crimson-parser.jar;%OFC_HOME%\lib\batik-xml.jar;%CLASSPATH%
set CLASSPATH=%OFC_HOME%\lib\batik-util.jar;%OFC_HOME%\lib\batik-transcoder.jar;%OFC_HOME%\lib\batik-svggen.jar;%CLASSPATH%
set CLASSPATH=%OFC_HOME%\lib\batik-svg-dom.jar;%OFC_HOME%\lib\batik-script.jar;%CLASSPATH%
set CLASSPATH=%OFC_HOME%\lib\batik-parser.jar;%OFC_HOME%\lib\batik-gvt.jar;%OFC_HOME%\lib\batik-gui-util.jar;%CLASSPATH%
set CLASSPATH=%OFC_HOME%\lib\batik-extension.jar;%OFC_HOME%\lib\batik-ext.jar;%CLASSPATH%
set CLASSPATH=%OFC_HOME%\lib\batik-dom.jar;%OFC_HOME%\lib\batik-css.jar;%OFC_HOME%\lib\batik-bridge.jar;%CLASSPATH%
set CLASSPATH=%OFC_HOME%\lib\batik-awt-util.jar;%OFC_HOME%\lib\;%CLASSPATH%
 
set ANT_PARAMETER=-Djava.home=%JAVA_HOME%
set ANT_PARAMETER=%ANT_PARAMETER% -Dlib.all=%CLASSPATH%
set PATH=%PATH%;%OFC_HOME%\bin;%JAVA_HOME%\bin
 
echo %JAVA_HOME%
 
%JAVA_HOME%\bin\java -Dofc.home=%OFC_HOME% -classpath "%CLASSPATH%" org.apache.tools.ant.Main %ANT_PARAMETER% %1 %2 %3 %4 %5 %6 %7 %8 %9
goto exit
 
:exit
/trunk/project/ofccharts/lib/crimson.jar
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+ application/octet-stream
/trunk/project/ofccharts/lib/js.jar
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+ application/octet-stream
/trunk/project/ofccharts/lib/batik-css.jar
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+ application/octet-stream
/trunk/project/ofccharts/lib/batik-svggen.jar
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+ application/octet-stream
/trunk/project/ofccharts/lib/ant.jar
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+ application/octet-stream
/trunk/project/ofccharts/lib/batik-bridge.jar
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+ application/octet-stream
/trunk/project/ofccharts/lib/batik-parser.jar
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+ application/octet-stream
/trunk/project/ofccharts/lib/batik-gui-util.jar
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+ application/octet-stream
/trunk/project/ofccharts/lib/batik-ext.jar
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+ application/octet-stream
/trunk/project/ofccharts/lib/batik-gvt.jar
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+ application/octet-stream
/trunk/project/ofccharts/lib/batik-xml.jar
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+ application/octet-stream
/trunk/project/ofccharts/lib/batik-script.jar
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+ application/octet-stream
/trunk/project/ofccharts/lib/batik-transcoder.jar
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+ application/octet-stream
/trunk/project/ofccharts/lib/batik-awt-util.jar
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+ application/octet-stream
/trunk/project/ofccharts/lib/jaxp.jar
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+ application/octet-stream
/trunk/project/ofccharts/lib/crimson-parser.jar
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+ application/octet-stream
/trunk/project/ofccharts/lib/batik-extension.jar
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+ application/octet-stream
/trunk/project/ofccharts/lib/batik-svg-dom.jar
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+ application/octet-stream
/trunk/project/ofccharts/lib/batik-util.jar
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+ application/octet-stream
/trunk/project/ofccharts/lib/batik-dom.jar
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+ application/octet-stream
/trunk/project/ofccharts/src/com/oxymel/ofc/charts/BubbleChart.java
New file
0,0 → 1,205
package com.oxymel.ofc.charts;
/*
* Copyright (c) 2006 Oxymel SA.
* All rights reserved.
*
* This software is the confidential and proprietary information of Oxymel SA
* ("Confidential Information"). You shall not disclose such Confidential
* Information and shall use it only in accordance with the terms of the license
* agreement you entered into with Oxymel SA.
*/
 
//java
import java.util.Vector;
import java.util.Enumeration;
import java.io.OutputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.FileOutputStream;
import java.io.FileWriter;
 
import java.awt.Graphics2D;
import java.awt.Font;
import java.awt.Stroke;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.geom.Arc2D;
 
 
//ofc
import com.oxymel.ofc.charts.series.BubbleSeries;
import com.oxymel.ofc.charts.series.BubbleValues;
import com.oxymel.ofc.charts.exception.OFCChartsException;
import com.oxymel.ofc.charts.data.Point2D;
import com.oxymel.ofc.charts.util.Graphics2DTools;
import com.oxymel.ofc.charts.series.BubbleSeriesContainer;
import com.oxymel.ofc.charts.series.SeriesContainer;
 
 
/**
* This class provides a bubble chart
*/
public class BubbleChart extends ChartWithAxisXY
{
private VerticalNumberAxis _axisY;
private HorizontalNumberAxis _axisX;
 
private double _maxRadiusCircle = 0;
private double _maxRadiusRatio = 0.05;
private float _epaisseur = 1.0f;
 
// private boolean _defineAsBubblesRadius = false;
 
private BubbleSeriesContainer _bubbleSeriesContainer;
 
/**
* Constructor
* @param chartWidth Width of vertical bar chart
* @param chartHeight Height of vertical bar chart
* @param axisX Horizontal axis to display categories
* @param axisY Vertical number axis
* @param point2DSeriesContainer All series of couple category-value
*/
public BubbleChart(int chartWidth, int chartHeight,
HorizontalNumberAxis axisX, VerticalNumberAxis axisY,
BubbleSeriesContainer bubbleSeriesContainer)
{
super(chartWidth, chartHeight);
_legend.setDisplayAsBar(false);
_axisX = axisX;
_axisY = axisY;
setBubbleSeriesContainer(bubbleSeriesContainer);
_maxRadiusCircle = _maxRadiusRatio*Math.min(chartWidth,chartHeight);
}
 
 
/**
* this ratio defines bigger default circle. This ratio is applyed on minimum of
* chartWidth or chartHeigth.
*/
public void setRadiusImageRatio(double ratio)
{
_maxRadiusRatio = ratio;
_maxRadiusCircle = _maxRadiusRatio*Math.min(getChartWidth(),getChartHeight());
}
 
public void setEpaisseur(float f)
{
_epaisseur = f;
}
 
/**
* Change data used to draw chart
* @param point2DSeriesContainer All series of couple category-value
*/
public void setBubbleSeriesContainer(BubbleSeriesContainer bubbleSeriesContainer)
{
_bubbleSeriesContainer = bubbleSeriesContainer;
setAllSeriesColorFromPalette(bubbleSeriesContainer);
}
 
protected SeriesContainer getSeriesContainer(){return _bubbleSeriesContainer;}
protected Axis getAxisX(){return _axisX;}
protected Axis getAxisY(){return _axisY;}
 
protected void setAxisParameters() throws OFCChartsException
{
_axisX.setMinValue(_bubbleSeriesContainer.getXMinOfAllSeries());
_axisX.setMaxValue(_bubbleSeriesContainer.getXMaxOfAllSeries());
_axisX.setFontSize(9);
 
_axisY.setMinValue(_bubbleSeriesContainer.getYMinOfAllSeries());
_axisY.setMaxValue(_bubbleSeriesContainer.getYMaxOfAllSeries());
_axisY.setNbGapMax(10);
}
 
 
protected void drawGraphic(int xTopLeftGraphic, int yTopLeftGraphic, int graphicWidth, int graphicHeight,
int xOrigine, int yOrigine, Graphics2D graphics2D)
{
int sizeOfGapOnY = graphicHeight / _axisY.getNbGap();
int sizeOfGapOnX = graphicWidth / _axisX.getNbGap();
int gapValueOnX = _axisX.getGapValue();
int gapValueOnY = _axisY.getGapValue();
 
//_maxRadiusCircle = Math.max(sizeOfGapOnY,sizeOfGapOnX);
 
Enumeration enumAllSeries = _bubbleSeriesContainer.getEnumAllSeriesOrderByDisplayNumber();
while(enumAllSeries.hasMoreElements()){
BubbleSeries bubbleSeries = (BubbleSeries)enumAllSeries.nextElement();
if(bubbleSeries.isVisible())
{
drawBubble(xOrigine, yOrigine, bubbleSeries, gapValueOnX, sizeOfGapOnX,
gapValueOnY, sizeOfGapOnY, graphics2D);
}
}
 
}
 
 
private void drawBubble(int xOrigine, int yOrigine, BubbleSeries bubbleSeries, int gapValueOnX, int sizeOfGapOnX,
int gapValueOnY, int sizeOfGapOnY, Graphics2D graphics2D)
{
graphics2D.setColor(bubbleSeries.getColor());
graphics2D.setStroke(new BasicStroke(_epaisseur));
Enumeration enumAllBubbleValues = bubbleSeries.getEnumAllValues();
if(!enumAllBubbleValues.hasMoreElements()){
return;
}
Point2D finalPoint=null;
//int sumValuesSeries = bubbleSeries.getSumAllValues();
int maxValuesSeries = 0;
try{
maxValuesSeries = _bubbleSeriesContainer.getValueMaxOfAllSeries();
}
catch(Exception e)
{maxValuesSeries = bubbleSeries.getValueMax();}
 
while(enumAllBubbleValues.hasMoreElements()){
BubbleValues bubbleValue = (BubbleValues)enumAllBubbleValues.nextElement();
Point2D point = bubbleValue.getPoint();
int value = bubbleValue.getValue();
if(finalPoint==null)
finalPoint = point;
int x1 = xOrigine + Graphics2DTools.getRelativeSizeOfValue(point.getX(), gapValueOnX, sizeOfGapOnX);
int y1 = yOrigine - Graphics2DTools.getRelativeSizeOfValue(point.getY(), gapValueOnY, sizeOfGapOnY);
int x2 = xOrigine + Graphics2DTools.getRelativeSizeOfValue(finalPoint.getX(), gapValueOnX, sizeOfGapOnX);
int y2 = yOrigine - Graphics2DTools.getRelativeSizeOfValue(finalPoint.getY(), gapValueOnY, sizeOfGapOnY);
 
if(bubbleSeries.isLineJoin())
graphics2D.drawLine(x1, y1, x2, y2);
 
int valueX = 0;
int valueY = 0;
 
double ratioValue = (double)(((double)value)/((double)maxValuesSeries));
value = (int)(ratioValue*_maxRadiusCircle);
 
if(bubbleSeries.isCircle())
{
java.awt.geom.Ellipse2D.Double ellipse = new java.awt.geom.Ellipse2D.Double();
ellipse.setFrameFromCenter(x1,y1,x1-value,y1-value);
graphics2D.draw(ellipse);
}
else
{
java.awt.geom.Rectangle2D.Double square = new java.awt.geom.Rectangle2D.Double();
square.setFrameFromCenter(x1,y1,x1-value,y1-value);
graphics2D.draw(square);
}
finalPoint = point;
}
}
 
 
protected int getNbPixelFreeArroundGraphic()
{
return (int)_maxRadiusCircle;
}
 
/*
public static void main(String[] argv) throws Exception
{
}
*/
}
/trunk/project/ofccharts/src/com/oxymel/ofc/charts/NumberAxis.java
New file
0,0 → 1,308
package com.oxymel.ofc.charts;
/*
* Copyright (c) 2006 Oxymel SA.
* All rights reserved.
*
* This software is the confidential and proprietary information of Oxymel SA
* ("Confidential Information"). You shall not disclose such Confidential
* Information and shall use it only in accordance with the terms of the license
* agreement you entered into with Oxymel SA.
*/
 
public class NumberAxis
{
 
/**
* Offset the origin of the axis
*/
static public int MOVE_ORIGIN_VALUE = 0;
 
/**
* Offset the lowest value on the axis
*/
static public int MOVE_FIRST_VALUE = 1;
 
/**
* Offset the highest value on the axis
*/
 
static public int MOVE_LAST_VALUE = 2;
 
private int _valueToMove = 0;
private int _nbPixelsOfMove = 0;
 
private Axis _axis;
 
private double _maxValue;
private double _minValue;
private boolean _isMaxMinSetByUser = false;
 
public NumberAxis(Axis axis)
{
_axis = axis;
}
 
protected void setNbPixelsOfMove(int nbPixelsOfMove){
_nbPixelsOfMove = nbPixelsOfMove;
}
 
protected int getNbPixelsOfMove(){
return _nbPixelsOfMove;
}
 
protected void setValueToMove(int valueToMove){
_valueToMove = valueToMove;
}
 
protected int getValueToMove(){
return _valueToMove;
}
 
 
void setExternalMinMaxValue(int minValue, int maxValue)
{
_maxValue = maxValue;
_minValue = minValue;
_isMaxMinSetByUser = true;
}
 
void setMinValue(double minValue)
{
if(!_isMaxMinSetByUser){
_minValue = minValue;
}
}
 
void setMaxValue(double maxValue)
{
if(!_isMaxMinSetByUser){
_maxValue = maxValue;
}
}
 
double getMinValue()
{
return _minValue;
}
 
double getMaxValue()
{
return _maxValue;
}
 
int getNbGap()
{
 
double intervalOfValues = getIntervalMaxOfAllValue();
int gapValue = getGapValue(intervalOfValues, _axis.getNbGapMax());
int nbGap = (int)(intervalOfValues/gapValue);
 
//System.out.println("gapValue = " + gapValue);
 
int nbNegativeGapToIncludeMinValue = getNbNegativeGapToIncludeMinValue();
 
int nbPositiveGap = nbGap - nbNegativeGapToIncludeMinValue;
 
if((nbPositiveGap * gapValue) >= _maxValue){
if(nbGap == 0){
nbGap++;
}
return nbGap;
}else{
int nbGapToAdd = 0;
while((nbPositiveGap * gapValue) < _maxValue){
nbGapToAdd ++;
nbPositiveGap ++;
}
return nbGap + nbGapToAdd;
}
 
 
/*
if(_maxValue < 0){
int gapValue = getGapValue(_minValue, _axis.getNbGapMax());
int nbGap = (int)(_minValue/gapValue);
 
if((nbGap * gapValue) >= _maxValue){
if(nbGap == 0){
nbGap++;
}
return nbGap;
}else{
return nbGap + 1;
}
}
 
int gapValue = getGapValue(_minValue, _axis.getNbGapMax());
int nbGapToIncludePositiveValue = getNbGapToIncludePositiveValue(_maxValue, getGapValue());
int nbNegativeGapToIncludeMinValue = getNbNegativeGapToIncludeMinValue();
 
return nbGapToIncludePositiveValue + nbNegativeGapToIncludeMinValue;
*/
 
/*
int nbNegativeGap = getNbNegativeGapToIncludeMinValue();
int nbPositiveGap = nbGap - nbNegativeGap;
if((nbPositiveGap * gapValue) >= _maxValue){
if(nbGap == 0){
nbGap++;
}
return nbGap;
}else{
if(nbNegativeGap * gapValue <= _minValue){
return nbGap + 1;
}else{
return nbGap + 2;
}
}
*/
//return ( (int)(intervalOfValues/gapValue) + 1);
}
 
int getNbNegativeGapToIncludeMinValue()
{
return getNbGapToIncludeNegativeValue(_minValue, getGapValue());
}
 
int getGapValue()
{
return getGapValue(getIntervalMaxOfAllValue(), _axis.getNbGapMax());
}
 
 
int getFirstValueOnAxis()
{
int firstValueOnAxis = 0;
if(_axis.isContainsNegativeValue()){
firstValueOnAxis = getNbNegativeGapToIncludeMinValue() * getGapValue() * (-1);
}
return firstValueOnAxis;
}
 
int getLastValueOnAxis()
{
return getFirstValueOnAxis() + (getGapValue() * getNbGap());
}
 
String getLargerStringValue()
{
double negativeValue = 0;
if(getNbNegativeGapToIncludeMinValue() > 0){
negativeValue = getNbNegativeGapToIncludeMinValue() * getGapValue() * (-1);
}
double positiveValue = getNbGap() * getGapValue();
 
String strNegativeValue = "" + (int)negativeValue;
String strPositiveValue = "" + (int)positiveValue;
return (strPositiveValue.length() > strNegativeValue.length())? strPositiveValue : strNegativeValue;
}
 
 
int getIntervalGapSize(int graphicWidth)
{
int nbInterval = getNbIntervalOneGap();
if(nbInterval == 0){
return 0;
}
 
int sizeOfGap = graphicWidth / getNbGap();
int sizeInterval = sizeOfGap / nbInterval;
if(sizeInterval < 3){
return 0;
}
return sizeInterval;
}
 
int getNbIntervalOneGap()
{
int gapValue = getGapValue();
if((gapValue != 1) && (gapValue != 5) && (gapValue != 10)){
return 0;
}
 
int nbInterval;
 
switch(gapValue){
case 1:
case 10:
nbInterval = 10;
break;
case 5:
nbInterval = 5;
break;
default:
return 0;
}
 
return nbInterval;
}
 
 
private double getIntervalMaxOfAllValue()
{
double intervalMax = _maxValue;
if(_minValue < 0){
intervalMax += (_minValue * (-1));
}
return intervalMax;
}
 
private int getNbGapToIncludeNegativeValue(double negativeValue, int gapValue)
{
int nbGapToIncludeNegativeValue = 0;
if(negativeValue >= 0){
return nbGapToIncludeNegativeValue;
}
 
double absoluteValue = (negativeValue)*(-1);
nbGapToIncludeNegativeValue = (int)(absoluteValue/gapValue);
if((nbGapToIncludeNegativeValue * gapValue) != absoluteValue){
nbGapToIncludeNegativeValue ++;
}
return nbGapToIncludeNegativeValue;
}
 
 
private int getNbGapToIncludePositiveValue(double positiveValue, int gapValue)
{
int nbGapToIncludePositiveValue = 0;
if(positiveValue <= 0){
return nbGapToIncludePositiveValue;
}
 
nbGapToIncludePositiveValue = (int)(positiveValue/gapValue);
if((nbGapToIncludePositiveValue * gapValue) != positiveValue){
nbGapToIncludePositiveValue ++;
}
return nbGapToIncludePositiveValue;
}
 
 
private int getGapValue(double maxOfValues, int nbGapMax)
{
//find gap on Y
int gapValue = 1;
if((gapValue * nbGapMax) >= maxOfValues){
return gapValue;
}
gapValue = 5;
if((gapValue * nbGapMax) >= maxOfValues){
return gapValue;
}
gapValue = 10;
if((gapValue * nbGapMax) >= maxOfValues){
return gapValue;
}
gapValue = 25;
if((gapValue * nbGapMax) >= maxOfValues){
return gapValue;
}
int minGapOnY = 50;
gapValue = (int)(maxOfValues/nbGapMax);
if( ((gapValue/minGapOnY) * minGapOnY) != gapValue){
gapValue = ((gapValue/minGapOnY) + 1) * minGapOnY;
}
return gapValue;
}
 
}
/trunk/project/ofccharts/src/com/oxymel/ofc/charts/HorizontalLineInfo.java
New file
0,0 → 1,73
package com.oxymel.ofc.charts;
/*
* Copyright (c) 2006 Oxymel SA.
* All rights reserved.
*
* This software is the confidential and proprietary information of Oxymel SA
* ("Confidential Information"). You shall not disclose such Confidential
* Information and shall use it only in accordance with the terms of the license
* agreement you entered into with Oxymel SA.
*/
 
//java
import java.awt.*;
 
import com.oxymel.ofc.charts.util.*;
 
/**
* This class allows to draw an horizontal line in a graphic.
* This line has a label, the line and label colors can be cutomized
*/
public class HorizontalLineInfo
{
private String _label;
private double _value;
private VerticalNumberAxis _axisY;
private Color _labelColor = Color.black;
private Color _lineColor = Color.black;
 
/**
* Constructor
* @param label identifying the line
* @param value or line position in the graphic
*/
public HorizontalLineInfo(String label, double value)
{
_label = label;
_value = value;
}
 
/**
* Assign a given color to the label
* @param labelColor
*/
public void setLabelColor(Color labelColor){_labelColor = labelColor;}
 
/**
* Assign a given color to the line
* @param lineColor
*/
public void setLineColor(Color lineColor){_lineColor = lineColor;}
 
void setVerticalNumberAxis(VerticalNumberAxis axisY)
{
_axisY = axisY;
}
 
void draw(int graphicWidth, int graphicHeight, int xTopLeftGraphic,
int yTopLeftGraphic, int xOrigine, int yOrigine, Graphics2D graphics2D)
{
int sizeOfGapOnY = graphicHeight / _axisY.getNbGap();
int relativeSizeOfValue = Graphics2DTools.getRelativeSizeOfValue(_value, _axisY.getGapValue(), sizeOfGapOnY);
int y = yOrigine - relativeSizeOfValue;
 
graphics2D.setColor(_lineColor);
graphics2D.drawLine(xTopLeftGraphic ,y, xTopLeftGraphic + graphicWidth, y);
 
graphics2D.drawString(_label, Graphics2DTools.getXToAlignTxt(graphics2D, (xTopLeftGraphic + graphicWidth)/2, _label),
y - Graphics2DTools.getNbPixelHeightOfTxt(graphics2D, _label));
 
 
}
 
}
/trunk/project/ofccharts/src/com/oxymel/ofc/charts/BarChartRenderer.java
New file
0,0 → 1,114
package com.oxymel.ofc.charts;
/*
* Copyright (c) 2006 Oxymel SA.
* All rights reserved.
*
* This software is the confidential and proprietary information of Oxymel SA
* ("Confidential Information"). You shall not disclose such Confidential
* Information and shall use it only in accordance with the terms of the license
* agreement you entered into with Oxymel SA.
*/
 
//ofc
import com.oxymel.ofc.charts.series.CategoryValueSeriesContainer;
import com.oxymel.ofc.charts.series.SeriesContainer;
import com.oxymel.ofc.charts.util.OFCMath;
 
/**
* BarChartRenderer is the abstract superclass for all bar chart renderer
*/
abstract class BarChartRenderer extends ChartRenderer
{
/*
protected int _nbPixelBetweenEachBarHisto = 0;
protected int _nbPixelFreeBeforeSeries = 5;
protected int _nbPixelFreeAfterSeries = 5;
*/
/*
private int _sizeBetweenEachBarHisto = 0;
private int _sizeFreeBeforeSeries = 5;
private int _sizeFreeAfterSeries = 5;
*/
//all size are percentage from X gap interval
 
private int _sizeBetweenEachBarHisto = 15;
private int _sizeFreeBeforeSeries = 20;
private int _sizeFreeAfterSeries = 20;
 
private int _sizeMaxWidthOfBarHisto = 30;
private int _sizeMinWidthOfBarHisto = 10;
 
protected CategoryValueSeriesContainer _categoryValueSeriesContainer;
 
protected BarChartRenderer(CategoryValueSeriesContainer categoryValueSeriesContainer)
{
setCategoryValueSeriesContainer(categoryValueSeriesContainer);
}
 
/**
* Change data used to draw chart
* @param categoryValueSeriesContainer All series of couple category-value
*/
public void setCategoryValueSeriesContainer(CategoryValueSeriesContainer categoryValueSeriesContainer)
{
_categoryValueSeriesContainer = categoryValueSeriesContainer;
}
 
/**
* Get the container of couple category-value used to draw chart.
* @return CategoryValueSeriesContainer used to draw chart
*/
public CategoryValueSeriesContainer getCategoryValueSeriesContainer(){return _categoryValueSeriesContainer;}
 
/**
* Sets the percentage beetween each bar.
* 100% correspond to the size to display one category informations.
* This percentage value is not necessary accept if the general graphic look is not correct.
* @param percentageBetweenEachBarHisto the percentage beetween each bar
*/
public void setPercentageBetweenEachBarHisto(int percentageBetweenEachBarHisto){_sizeBetweenEachBarHisto = percentageBetweenEachBarHisto;}
 
/**
* Sets the percentage free before one bar series which correspond to a category.
* 100% correspond to the size to display one category informations.
* This percentage value is not necessary accept if the general graphic look is not correct.
* @param percentageFreeBeforeSeries the percentage free before one bar series
*/
public void setPercentageFreeBeforeSeries(int percentageFreeBeforeSeries){_sizeFreeBeforeSeries = percentageFreeBeforeSeries;}
 
/**
* Sets the percentage free after one bar series which correspond to a category.
* 100% correspond to the size to display one category informations.
* This percentage value is not necessary accept if the general graphic look is not correct.
* @param percentageFreeAfterSeries the percentage free after one bar series
*/
public void setPercentageFreeAfterSeries(int percentageFreeAfterSeries){_sizeFreeAfterSeries = percentageFreeAfterSeries;}
 
/**
* Sets the percentage of bar width max.
* 100% correspond to the size to display one category informations.
* This percentage value is not necessary accept if the general graphic look is not correct.
* @param percentageBarWidthMax the percentage of bar width max
*/
public void setPercentageBarWidthMax(int percentageBarWidthMax){_sizeMaxWidthOfBarHisto = percentageBarWidthMax;}
 
/**
* Sets the percentage of bar width min.
* 100% correspond to the size to display one category informations.
* This percentage value is not necessary accept if the general graphic look is not correct.
* @param percentageBarWidthMin the percentage of bar width min
*/
public void setPercentageBarWidthMin(int percentageBarWidthMin){_sizeMinWidthOfBarHisto = percentageBarWidthMin;}
 
protected int getNbPixelBetweenEachBarHisto(int sizeOfGapOnX){
return OFCMath.getValueFromPercentage(_sizeBetweenEachBarHisto, sizeOfGapOnX);}
protected int getNbPixelFreeBeforeSeries(int sizeOfGapOnX){
return OFCMath.getValueFromPercentage(_sizeFreeBeforeSeries, sizeOfGapOnX);}
protected int getNbPixelFreeAfterSeries(int sizeOfGapOnX){
return OFCMath.getValueFromPercentage(_sizeFreeAfterSeries, sizeOfGapOnX);}
protected int getNbPixelMaxWidthOfBarHisto(int sizeOfGapOnX){
return OFCMath.getValueFromPercentage(_sizeMaxWidthOfBarHisto, sizeOfGapOnX);}
protected int getNbPixelMinWidthOfBarHisto(int sizeOfGapOnX){
return OFCMath.getValueFromPercentage(_sizeMinWidthOfBarHisto, sizeOfGapOnX);}
 
}
/trunk/project/ofccharts/src/com/oxymel/ofc/charts/HorizontalAxis.java
New file
0,0 → 1,153
package com.oxymel.ofc.charts;
/*
* Copyright (c) 2006 Oxymel SA.
* All rights reserved.
*
* This software is the confidential and proprietary information of Oxymel SA
* ("Confidential Information"). You shall not disclose such Confidential
* Information and shall use it only in accordance with the terms of the license
* agreement you entered into with Oxymel SA.
*/
 
//java
import java.awt.*;
 
import com.oxymel.ofc.charts.exception.*;
import com.oxymel.ofc.charts.util.*;
 
/**
* This abstract class is the superclass of all classes managing horizontal axis
*/
abstract public class HorizontalAxis extends Axis
{
private int _labelPosition = LABEL_POSITION_HORIZONTAL_TOP;
 
protected HorizontalAxis(String label)
{
super(label);
}
 
/**
* Sets the label position
* @param labelPosition labelPosition
*/
public void setLabelPosition(int labelPosition){_labelPosition = labelPosition;}
 
//interface used by generic draw chart :
int getNbPixelUsedAtLeft(Graphics2D graphics2D)
{
Font font = graphics2D.getFont();
graphics2D.setFont(getFont(graphics2D));
//int nbPixelUsedAtAxisLeft =
// ((Graphics2DTools.getNbPixelWidthOfTxt(graphics2D, "" + _minValue))/2);
 
int nbPixelUsedAtAxisLeft =
((Graphics2DTools.getNbPixelWidthOfTxt(graphics2D, getLeftStringValue()))/2);
 
graphics2D.setFont(font);
return nbPixelUsedAtAxisLeft;
}
 
int getNbPixelUsedAtRight(Graphics2D graphics2D)
{
Font font = graphics2D.getFont();
graphics2D.setFont(getFont(graphics2D));
 
int nbPixelUsedAtAxisRight = getArrowLength();
 
switch(_labelPosition){
case LABEL_POSITION_HORIZONTAL_TOP :
nbPixelUsedAtAxisRight += getNbPixelUsedToDrawLabel(graphics2D);
break;
}
 
graphics2D.setFont(font);
return nbPixelUsedAtAxisRight;
}
 
int getNbPixelUsedAtTop(Graphics2D graphics2D){return 0;}
 
int getNbPixelUsedAtBottom(Graphics2D graphics2D) throws OFCChartsException
{
int nbPixelUsedAtBottom = 0;
Font font = graphics2D.getFont();
graphics2D.setFont(getFont(graphics2D));
nbPixelUsedAtBottom = getMaxNbPixelHeigthValues(graphics2D) +
+ _nbPixelBetweenValueAndGapIndicator + _nbPixelOfGapIndicator;
 
switch(_labelPosition){
case LABEL_POSITION_HORIZONTAL_RIGHT_CENTER :
nbPixelUsedAtBottom += getNbPixelUsedToDrawLabel(graphics2D);
break;
}
 
graphics2D.setFont(font);
 
return nbPixelUsedAtBottom;
}
 
//template pattern horrizontal axis:
abstract protected String getLeftStringValue();
abstract protected int getMaxNbPixelHeigthValues(Graphics2D graphics2D);
 
 
 
protected void drawAxisLine(int graphicWidth, int graphicHeight, int xTopLeftGraphic,
int yTopLeftGraphic, int xOrigine, int yOrigine, Graphics2D graphics2D)
{
graphics2D.drawLine(xTopLeftGraphic ,yOrigine, xTopLeftGraphic + graphicWidth, yOrigine);
 
}
 
protected void drawArrow(int graphicWidth, int graphicHeight, int xTopLeftGraphic,
int yTopLeftGraphic, int xOrigine, int yOrigine, Graphics2D graphics2D)
{
Graphics2DTools.drawEastWestArrow(getArrowLength(), xTopLeftGraphic + graphicWidth,
yOrigine, graphics2D);
}
 
protected void drawLabel(int graphicWidth, int graphicHeight, int xTopLeftGraphic,
int yTopLeftGraphic, int xOrigine, int yOrigine, Graphics2D graphics2D)
{
switch(_labelPosition){
case LABEL_POSITION_HORIZONTAL_TOP :
graphics2D.drawString(getLabel(), xTopLeftGraphic + graphicWidth + getArrowLength() + _nbPixelFreeBeforeLabel,
Graphics2DTools.getYToAlignTxt(graphics2D, yOrigine, getLabel()));
break;
case LABEL_POSITION_HORIZONTAL_RIGHT_CENTER:
graphics2D.drawString(getLabel(), Graphics2DTools.getXToAlignTxt(graphics2D, xTopLeftGraphic + (graphicWidth/2), getLabel()),
Graphics2DTools.getYToAlignTxt(graphics2D, yOrigine + _nbPixelOfGapIndicator + getMaxNbPixelHeigthValues(graphics2D) + _nbPixelFreeBeforeLabel, getLabel()));
break;
default:
throw new OFCChartsRuntimeException("Invalid label position = " + _labelPosition);
}
}
 
protected void drawGapIndicator(int graphicWidth, int graphicHeight, int xTopLeftGraphic,
int yTopLeftGraphic, int xOrigine, int yOrigine, Graphics2D graphics2D)
{
int nbGapOnX = getNbGap();
int sizeOfGapOnX = graphicWidth / nbGapOnX;
int xOfGap = xTopLeftGraphic;
graphics2D.setColor(getGapIndicatorColor());
for(int i=0; i<nbGapOnX + 1; i++){
graphics2D.drawLine(xOfGap , yOrigine - _nbPixelOfGapIndicator, xOfGap , yOrigine + _nbPixelOfGapIndicator);
xOfGap += sizeOfGapOnX;
}
}
 
 
protected int getNbPixelUsedByLabel(Graphics2D graphics2D)
{
switch(_labelPosition){
case LABEL_POSITION_HORIZONTAL_TOP :
return Graphics2DTools.getNbPixelWidthOfTxt(graphics2D, getLabel());
case LABEL_POSITION_HORIZONTAL_RIGHT_CENTER:
return Graphics2DTools.getNbPixelHeightOfTxt(graphics2D, getLabel());
default:
throw new OFCChartsRuntimeException("Invalid label position");
}
 
}
 
}
/trunk/project/ofccharts/src/com/oxymel/ofc/charts/exception/OFCChartsException.java
New file
0,0 → 1,33
package com.oxymel.ofc.charts.exception;
/*
* Copyright (c) 2006 Oxymel SA.
* All rights reserved.
*
* This software is the confidential and proprietary information of Oxymel SA
* ("Confidential Information"). You shall not disclose such Confidential
* Information and shall use it only in accordance with the terms of the license
* agreement you entered into with Oxymel SA.
*/
 
/**
* Super Class of OFC Chart exception
*/
public class OFCChartsException extends java.lang.Exception
{
/**
* Class constructor
* @param message The exception message
*/
public OFCChartsException(String message)
{
super(message);
}
 
/**
* Class constructor
*/
public OFCChartsException()
{
super();
}
}
/trunk/project/ofccharts/src/com/oxymel/ofc/charts/exception/OFCChartsRuntimeException.java
New file
0,0 → 1,33
package com.oxymel.ofc.charts.exception;
/*
* Copyright (c) 2006 Oxymel SA.
* All rights reserved.
*
* This software is the confidential and proprietary information of Oxymel SA
* ("Confidential Information"). You shall not disclose such Confidential
* Information and shall use it only in accordance with the terms of the license
* agreement you entered into with Oxymel SA.
*/
 
/**
* Super Class of OFC Chart runtime exception
*/
public class OFCChartsRuntimeException extends java.lang.RuntimeException
{
/**
* Class constructor
* @param message The exception message
*/
public OFCChartsRuntimeException(String message)
{
super(message);
}
 
/**
* Class constructor
*/
public OFCChartsRuntimeException()
{
super();
}
}
/trunk/project/ofccharts/src/com/oxymel/ofc/charts/VerticalStackedBarChart.java
New file
0,0 → 1,149
package com.oxymel.ofc.charts;
/*
* Copyright (c) 2006 Oxymel SA.
* All rights reserved.
*
* This software is the confidential and proprietary information of Oxymel SA
* ("Confidential Information"). You shall not disclose such Confidential
* Information and shall use it only in accordance with the terms of the license
* agreement you entered into with Oxymel SA.
*/
 
//java
import java.awt.*;
//ofc
import com.oxymel.ofc.charts.exception.*;
import com.oxymel.ofc.charts.series.*;
 
/**
* This class allows to present bar charts as stacked bar charts.
* In such a presentation one category is represented as one bar which is a stack,
* every part of the stack corresponds to the value of a series for the category.
*/
public class VerticalStackedBarChart extends VerticalBarChart
{
private VerticalStackedBarChartRenderer _renderer;
 
/**
* Constructor
* @param chartWidth Width of vertical bar chart
* @param chartHeight Height of vertical bar chart
* @param axisX Horizontal axis to display categories
* @param axisY Vertical number axis
* @param categoryValueSeriesContainer All series of couple category-value
*/
public VerticalStackedBarChart(int chartWidth, int chartHeight,
HorizontalCategoryAxis axisX, VerticalNumberAxis axisY,
CategoryValueSeriesContainer categoryValueSeriesContainer)
{
super(chartWidth, chartHeight, axisX, axisY, categoryValueSeriesContainer);
_renderer = new VerticalStackedBarChartRenderer(categoryValueSeriesContainer);
_renderer.setPercentageBetweenEachBarHisto(0);
_renderer.setPercentageFreeBeforeSeries(5);
_renderer.setPercentageFreeAfterSeries(5);
}
 
 
protected void setAxisParameters() throws OFCChartsException
{
_axisX.setAllCategoriesOrderByDisplayNumber(_categoryValueSeriesContainer.getAllCategoriesOrderByDisplayNumber());
_axisY.setMaxValue(_categoryValueSeriesContainer.getMaxPositiveSumCategoryValue());
_axisY.setMinValue(_categoryValueSeriesContainer.getMinNegativeSumCategoryValue());
}
 
protected BarChartRenderer getBarChartRenderer(){return _renderer;}
 
protected void drawGraphic(int xTopLeftGraphic, int yTopLeftGraphic, int graphicWidth, int graphicHeight,
int xOrigine, int yOrigine, Graphics2D graphics2D)
{
//VerticalStackedBarChartRenderer renderer = new VerticalStackedBarChartRenderer(getCategoryValueSeriesContainer());
VerticalStackedBarChartRenderer renderer = _renderer;
renderer.setNbGapOnX(_axisX.getNbGap());
renderer.setNbGapOnY(_axisY.getNbGap());
renderer.setGapValueOnY(_axisY.getGapValue());
//BEGIN_BLOCKER_CHART_3D
renderer.set3dEffectValue(get3dEffectValue());
//END_BLOCKER_CHART_3D
renderer.drawGraphic(xTopLeftGraphic, yTopLeftGraphic, graphicWidth, graphicHeight,
xOrigine, yOrigine, graphics2D);
}
 
/*
protected void drawGraphic(int xTopLeftGraphic, int yTopLeftGraphic, int graphicWidth, int graphicHeight,
int xOrigine, int yOrigine, Graphics2D graphics2D)
{
 
int sizeOfGapOnY = graphicHeight / _axisY.getNbGap();
int sizeOfGapOnX = graphicWidth / _axisX.getNbGap();
 
int widthOfBarHisto = sizeOfGapOnX - _nbPixelFreeBeforeSeries - _nbPixelFreeAfterSeries;
int nbSeries = _categoryValueSeriesContainer.getNbSeries();
 
Vector allCategories = _categoryValueSeriesContainer.getAllCategoriesOrderByDisplayNumber();
Vector allSeriesOrderByDisplayNumber = _categoryValueSeriesContainer.getAllSeriesOrderByDisplayNumber();
Vector allSeriesOrderByReverseDisplayNumber = _categoryValueSeriesContainer.getAllSeriesOrderByReverseDisplayNumber();
 
for(int i= 0; i<allCategories.size(); i++){
Category category = (Category)allCategories.elementAt(i);
int xBarTopLeft = xOrigine + (sizeOfGapOnX * i) + _nbPixelFreeBeforeSeries;
 
 
int yOrigineNegativeBar = yOrigine;
for(int j= 0; j<_categoryValueSeriesContainer.getNbSeries(); j++){
CategoryValueSeries categoryValueSeries = (CategoryValueSeries)allSeriesOrderByReverseDisplayNumber.elementAt(j);
if(categoryValueSeries.isVisible()){
double value = categoryValueSeries.getCategoryValueAsDouble(category.getId());
if(value != 0){
int relativeSizeOfValue = Graphics2DTools.getRelativeSizeOfValue(value, _axisY.getGapValue(), sizeOfGapOnY);
if(value < 0){
yOrigineNegativeBar -= relativeSizeOfValue;
}
}
}
}
 
if(yOrigineNegativeBar != yOrigine){
//value negative
for(int j= 0; j<_categoryValueSeriesContainer.getNbSeries(); j++){
CategoryValueSeries categoryValueSeries = (CategoryValueSeries)allSeriesOrderByReverseDisplayNumber.elementAt(j);
if(categoryValueSeries.isVisible()){
double value = categoryValueSeries.getCategoryValueAsDouble(category.getId());
if(value != 0){
int relativeSizeOfValue = Graphics2DTools.getRelativeSizeOfValue(value, _axisY.getGapValue(), sizeOfGapOnY);
if(value < 0){
yOrigineNegativeBar += relativeSizeOfValue;
drawBar(xBarTopLeft, yOrigineNegativeBar, widthOfBarHisto, relativeSizeOfValue,
categoryValueSeries, graphics2D);
}
}
}
}
}
 
int yOriginePositiveBar = yOrigine;
for(int j= 0; j<_categoryValueSeriesContainer.getNbSeries(); j++){
CategoryValueSeries categoryValueSeries = (CategoryValueSeries)allSeriesOrderByDisplayNumber.elementAt(j);
if(categoryValueSeries.isVisible()){
double value = categoryValueSeries.getCategoryValueAsDouble(category.getId());
if(value != 0){
int relativeSizeOfValue = Graphics2DTools.getRelativeSizeOfValue(value, _axisY.getGapValue(), sizeOfGapOnY);
if(value > 0){
drawBar(xBarTopLeft, yOriginePositiveBar, widthOfBarHisto, relativeSizeOfValue,
categoryValueSeries, graphics2D);
yOriginePositiveBar -= relativeSizeOfValue;
}
}
}
}
 
}
}
 
*/
 
/*
public static void main(String[] argv) throws Exception
{
}
*/
}
/trunk/project/ofccharts/src/com/oxymel/ofc/charts/HorizontalNumberAxis.java
New file
0,0 → 1,338
package com.oxymel.ofc.charts;
/*
* Copyright (c) 2006 Oxymel SA.
* All rights reserved.
*
* This software is the confidential and proprietary information of Oxymel SA
* ("Confidential Information"). You shall not disclose such Confidential
* Information and shall use it only in accordance with the terms of the license
* agreement you entered into with Oxymel SA.
*/
 
//java
import java.awt.*;
import java.awt.geom.*;
import com.oxymel.ofc.charts.util.*;
 
/**
* This class manages the horizontal axis with graduations
*/
public class HorizontalNumberAxis
extends HorizontalAxis {
 
/**
* Axis position "Center" indicates that <code>HorizontalNumberAxis</code> is
* positioned at the "0" of the <code>VerticalNumberAxis</code> (value=0).
*/
public static int AXIS_POSITION_CENTER = 0;
 
/**
* Axis position "Bottom" indicates that <code>HorizontalNumberAxis</code> is
* positioned at the "lowest point" of the <code>VerticalNumberAxis</code> (value=1).
*/
public static int AXIS_POSITION_BOTTOM = 1;
 
/**
* Axis position "top" indicates that <code>HorizontalNumberAxis</code> is
* positioned at the "highest point" of the <code>VerticalNumberAxis</code> (value=2).
*/
public static int AXIS_POSITION_TOP = 2;
 
/* Position de l'axe. Par défaut au centre */
 
private int axisPosition = AXIS_POSITION_CENTER;
 
/* Angle (en degrès) d'ecriture des valeurs sur l'axe. */
 
private int angleToWriteValues = 0;
 
/* Emplacement de l'axe des X sur l'axe des Y. sera calculé selon axisPosition*/
protected int positionOnYAxis = 0;
 
private NumberAxis _numberAxis = new NumberAxis(this);
private boolean _isIntermediaryGapIndicatorVisible = false;
 
/**
* Constructor
* @param label Axis Label
*/
public HorizontalNumberAxis(String label) {
super(label);
}
 
/**
* Sets intermediary gap mark visibility
* @param isIntermediaryGapIndicatorVisible If true intermediary gap mark is visible otherwise it is not
*/
public void setIntermediaryGapIndicatorVisible(boolean
isIntermediaryGapIndicatorVisible) {
_isIntermediaryGapIndicatorVisible = isIntermediaryGapIndicatorVisible;
}
 
/**
* Sets the minimum and maximum values on the axis.
* This feature can be used to explicitly set the minimum value and
* maximum value, by default they are automatically computed according
* to the data given as input to draw the graphic.
* Fixing these values externally may be useful to give the same look to
* several graphics.
* @param minValue min of value past
* @param maxValue max of value past
*/
public void setMinMaxValue(int minValue, int maxValue) {
_numberAxis.setExternalMinMaxValue(minValue, maxValue);
}
 
// NumberAxis interface
void setMinValue(double minValue) {
_numberAxis.setMinValue(minValue);
}
 
void setMaxValue(double maxValue) {
_numberAxis.setMaxValue(maxValue);
}
 
int getGapValue() {
return _numberAxis.getGapValue();
}
 
//axis drawing interface
int getNbGap() {
return _numberAxis.getNbGap();
}
 
int getNbNegativeGapToIncludeMinValue() {
return _numberAxis.getNbNegativeGapToIncludeMinValue();
}
 
void draw(int graphicWidth, int graphicHeight, int xTopLeftGraphic,
int yTopLeftGraphic,
int xOrigine, int yOrigine, Graphics2D graphics2D) {
 
AffineTransform initialTranform = graphics2D.getTransform();
AffineTransform trasform = new AffineTransform();
trasform.translate(0, this.positionOnYAxis);
graphics2D.setTransform(trasform);
super.draw(graphicWidth, graphicHeight, xTopLeftGraphic, yTopLeftGraphic,
xOrigine, yOrigine, graphics2D);
graphics2D.setTransform(initialTranform);
 
}
 
protected void drawValues(int graphicWidth, int graphicHeight,
int xTopLeftGraphic, int yTopLeftGraphic,
int xOrigine, int yOrigine, Graphics2D graphics2D) {
 
int nbGapOnX = getNbGap(); // nombre de gaps
int sizeOfGapOnX = graphicWidth / nbGapOnX; // taille d'un gap
Font font = graphics2D.getFont();
graphics2D.setFont(getFont(graphics2D));
graphics2D.setColor(getValueWriteColor());
// position du point gauche de l'axe (/ à l'origine)
int xLeftPosition = sizeOfGapOnX * getNbNegativeGapToIncludeMinValue();
 
AffineTransform initialTranform = graphics2D.getTransform();
AffineTransform trasform = new AffineTransform();
int gapValueOnX = getGapValue();
// première valeur sur l'axe
int currentGap = _numberAxis.getFirstValueOnAxis();
int nbPixelsBetweenTextAndAxis = Graphics2DTools.getNbPixelHeightOfTxt(
graphics2D,
"" + currentGap) + _nbPixelOfGapIndicator;
if (axisPosition == AXIS_POSITION_TOP) {
nbPixelsBetweenTextAndAxis = - (_nbPixelBetweenValueAndGapIndicator +
_nbPixelOfGapIndicator);
}
/* Partir au point d'ecriture du premier point avec prise en compte de la postion de l'axe,
* de l'espace entre les valeurs et l'axe et la taille des indicateurs de gaps
*/
trasform.translate(xOrigine - xLeftPosition,
yOrigine + positionOnYAxis + nbPixelsBetweenTextAndAxis);
graphics2D.setTransform(trasform);
int valueToMove = _numberAxis.getValueToMove();
int nbPixelsOfMove = _numberAxis.getNbPixelsOfMove();
RenderingHints render = graphics2D.getRenderingHints();
Object oldTextHits = render.get(RenderingHints.KEY_TEXT_ANTIALIASING);
if (this.angleToWriteValues != 0) {
render.put(RenderingHints.KEY_TEXT_ANTIALIASING,
RenderingHints.VALUE_TEXT_ANTIALIAS_DEFAULT);
}
for (int i = 0; i < nbGapOnX + 1; i++) {
AffineTransform trasform2 = (AffineTransform) trasform.clone();
trasform2.translate(i * sizeOfGapOnX, 0);
if ( (valueToMove == 1 && currentGap == _numberAxis.getFirstValueOnAxis())
|| (valueToMove == 0 && currentGap == 0) ||
(valueToMove == 2 && currentGap == _numberAxis.getLastValueOnAxis())) {
trasform2.translate(nbPixelsOfMove, 0);
}
if (this.angleToWriteValues == 0) {
//aligner au milieu
trasform2.translate(Graphics2DTools.getXToAlignTxt(graphics2D, 0,
"" + currentGap), 0);
}
else {
// Faire une rotation. Le sens dépend de la position de l'axe
trasform2.rotate(Math.toRadians( (axisPosition == AXIS_POSITION_TOP ?
-1 : 1) * angleToWriteValues));
}
graphics2D.setTransform(trasform2);
graphics2D.drawString("" + currentGap, 0, 0);
graphics2D.setTransform(trasform);
currentGap += gapValueOnX;
}
graphics2D.setTransform(initialTranform);
render.put(RenderingHints.KEY_TEXT_ANTIALIASING, oldTextHits);
graphics2D.setFont(font);
}
 
//template pattern implementation part to draw axis
protected void old_drawValues(int graphicWidth, int graphicHeight,
int xTopLeftGraphic, int yTopLeftGraphic,
int xOrigine, int yOrigine,
Graphics2D graphics2D) {
 
AffineTransform iinitialTranform = graphics2D.getTransform();
AffineTransform ttrasform = new AffineTransform();
ttrasform.translate(0, this.positionOnYAxis);
//graphics2D.setTransform(ttrasform);
 
int nbGapOnX = getNbGap();
int sizeOfGapOnX = graphicWidth / nbGapOnX;
Font font = graphics2D.getFont();
graphics2D.setFont(getFont(graphics2D));
int xOfGap = xTopLeftGraphic;
graphics2D.setColor(getValueWriteColor());
 
int gapValueOnX = getGapValue();
int currentGap = _numberAxis.getFirstValueOnAxis();
 
for (int i = 0; i < nbGapOnX + 1; i++) {
String szCurrentGap = "" + currentGap;
if (currentGap != 0) {
/* Transformation pour affichage 21/02/2005 */
AffineTransform initialTranform = graphics2D.getTransform();
AffineTransform trasform = new AffineTransform();
int positionX = xOfGap;
int positionY = yOrigine + _nbPixelOfGapIndicator +
Graphics2DTools.getNbPixelHeightOfTxt(graphics2D, szCurrentGap);
trasform.translate(positionX, positionY);
System.out.println("positionOnYAxis=" + positionX + "==" + positionY);
trasform.rotate(Math.toRadians(45));
graphics2D.setTransform(trasform);
graphics2D.drawString(szCurrentGap, 0, 0);
graphics2D.setTransform(initialTranform);
 
/* Transformation pour affichage 21/02/2005*/
/*graphics2D.drawString(szCurrentGap,
Graphics2DTools.getXToAlignTxt(graphics2D, xOfGap,
szCurrentGap),
yOrigine + _nbPixelOfGapIndicator +
Graphics2DTools.getNbPixelHeightOfTxt(graphics2D,
szCurrentGap));*/
}
 
currentGap += gapValueOnX;
xOfGap += sizeOfGapOnX;
}
graphics2D.setTransform(iinitialTranform);
graphics2D.setFont(font);
}
 
protected void drawGapIndicator(int graphicWidth, int graphicHeight,
int xTopLeftGraphic,
int yTopLeftGraphic, int xOrigine,
int yOrigine, Graphics2D graphics2D) {
super.drawGapIndicator(graphicWidth, graphicHeight, xTopLeftGraphic,
yTopLeftGraphic, xOrigine, yOrigine, graphics2D);
if (!_isIntermediaryGapIndicatorVisible) {
return;
}
 
int nbGapOnX = getNbGap();
int sizeOfGapOnX = graphicWidth / nbGapOnX;
int xOfGap = xTopLeftGraphic;
int xInterval = xOfGap;
int sizeInterval = _numberAxis.getIntervalGapSize(graphicWidth);
if (sizeInterval == 0) {
return;
}
int gapValueOnX = getGapValue();
graphics2D.setColor(getGapIndicatorColor());
int nbIntervalCurrent = _numberAxis.getNbIntervalOneGap();
int sizeOfGapCurrent = sizeOfGapOnX;
for (int i = 0; i < nbGapOnX; i++) {
for (int j = 0; j < _numberAxis.getNbIntervalOneGap() - 1; j++) {
xInterval += sizeInterval;
graphics2D.drawLine(xInterval, yOrigine - _nbPixelOfGapIndicator + 1,
xInterval, yOrigine + _nbPixelOfGapIndicator - 1);
nbIntervalCurrent--;
sizeOfGapCurrent -= sizeInterval;
sizeInterval = sizeOfGapCurrent / nbIntervalCurrent;
}
xOfGap += sizeOfGapOnX;
xInterval = xOfGap;
nbIntervalCurrent = _numberAxis.getNbIntervalOneGap();
sizeOfGapCurrent = sizeOfGapOnX;
}
}
 
//horizontal axis interface
protected int getMaxNbPixelHeigthValues(Graphics2D graphics2D) {
return Graphics2DTools.getNbPixelHeightOfTxt(graphics2D,
"" + (getGapValue() * getNbGap()));
}
 
protected String getLeftStringValue() {
return "" + _numberAxis.getFirstValueOnAxis();
}
 
/**
* Sets the position of the X axis on the Y axis : <ul>
* <li> 0 : Center, default value <li> 1 : Bottom <li> 2 : Top</ul>
*
* @param axisPosition position of the axis
*/
 
public void setAxisPosition(int axisPosition) {
this.axisPosition = axisPosition;
}
 
/**
* Returns the position of the X axis on the Y axis : <ul>
*
* @param axisPosition position of the axis
*/
 
public int getAxisPosition() {
return axisPosition;
}
 
protected void setPositionOnYAxis(int positionOnYAxis) {
this.positionOnYAxis = positionOnYAxis;
}
 
/**
* Sets the angle used to write values for the X axis (must be between 0° and 90°).
* @param angleToWriteValues value of angle used to write values
*/
 
public void setAngleToWriteValues(int angleToWriteValues) {
this.angleToWriteValues = angleToWriteValues;
}
 
/**
* Sets which value to offset, the number of pixels and the direction.
*
* @param valueToMove value to offset. Can be :<ul>
* <li> <code>NumberAxis.MOVE_ORIGIN_VALUE</code> : to offset the origin of the axis
* <li> <code>NumberAxis.MOVE_FIRST_VALUE</code> : to offset the lowest value on the axis
* <li> <code>NumberAxis.MOVE_LAST_VALUE</code> : to offset the highest value on the axis
*
* @param nbPixelsOfMove the number of pixels. The sign specifies the direction of the offset
*/
public void moveValueWithNbPixels(int valueToMove, int nbPixelsOfMove) {
_numberAxis.setValueToMove(valueToMove);
_numberAxis.setNbPixelsOfMove(nbPixelsOfMove);
}
 
}
/trunk/project/ofccharts/src/com/oxymel/ofc/charts/ChartRenderer.java
New file
0,0 → 1,49
package com.oxymel.ofc.charts;
/*
* Copyright (c) 2006 Oxymel SA.
* All rights reserved.
*
* This software is the confidential and proprietary information of Oxymel SA
* ("Confidential Information"). You shall not disclose such Confidential
* Information and shall use it only in accordance with the terms of the license
* agreement you entered into with Oxymel SA.
*/
 
//java
import java.awt.Graphics2D;
 
/**
* This class is the abstract superclass for all renderer.
*/
abstract class ChartRenderer
{
protected int _coeff3dEffect = 0;
protected int _nbPixelToMoveRendererStartPosition = 0;
 
/**
* set number of pixel to move renderer from start position
* @param nbPixelToMoveRendererStartPosition number of pixel to move renderer from start position
*/
public void setNbPixelToMoveRendererStartPosition(int nbPixelToMoveRendererStartPosition){_nbPixelToMoveRendererStartPosition = nbPixelToMoveRendererStartPosition;}
 
abstract void drawGraphic(int xTopLeftGraphic, int yTopLeftGraphic, int graphicWidth, int graphicHeight,
int xOrigine, int yOrigine, Graphics2D graphics2D);
 
/**
* Get chart 3d effect value
* @return 3d effect value
*/
int get3dEffectValue(){return _coeff3dEffect;}
 
/**
* Setter of chart 3d effect value
* @param coeff3dEffect
*/
void set3dEffectValue(int coeff3dEffect)
{
if(coeff3dEffect > 0){
_coeff3dEffect = coeff3dEffect;
}
}
 
}
/trunk/project/ofccharts/src/com/oxymel/ofc/charts/data/Point2D.java
New file
0,0 → 1,80
package com.oxymel.ofc.charts.data;
/*
* Copyright (c) 2006 Oxymel SA.
* All rights reserved.
*
* This software is the confidential and proprietary information of Oxymel SA
* ("Confidential Information"). You shall not disclose such Confidential
* Information and shall use it only in accordance with the terms of the license
* agreement you entered into with Oxymel SA.
*/
 
/**
* Manage Point2D
*/
public class Point2D
{
private double _x;
private double _y;
 
/**
* Constructor
* @param x X of point
* @param y Y of Point
*/
public Point2D(double x, double y)
{
_x = x;
_y = y;
 
}
 
/**
* Get X of point
* @return X of point
*/
public double getX()
{
return _x;
}
 
/**
* Get Y of point
* @return Y of point
*/
public double getY()
{
return _y;
}
 
/**
* Compare if point has same x, y
* @param x x to compare
* @param y y to compare
* @return true if point has same x, y
*/
public boolean isSameXY(double x, double y)
{
return ((x == getX()) && (y == getY()));
}
 
/**
* Compare if point has same x, y
* @param pointToCompare point to compare
* @return true if point has same x, y
*/
public boolean isSameXY(Point2D pointToCompare)
{
return ((pointToCompare.getX() == getX()) && (pointToCompare.getY() == getY()));
}
 
/**
* @return formated string with x and y values
*/
public String toString()
{
return "x = " + getX() + " - y = " + getY();
}
 
 
}
/trunk/project/ofccharts/src/com/oxymel/ofc/charts/data/grid/Ridge.java
New file
0,0 → 1,120
package com.oxymel.ofc.charts.data.grid;
/*
* Copyright (c) 2006 Oxymel SA.
* All rights reserved.
*
* This software is the confidential and proprietary information of Oxymel SA
* ("Confidential Information"). You shall not disclose such Confidential
* Information and shall use it only in accordance with the terms of the license
* agreement you entered into with Oxymel SA.
*/
 
//java
import java.util.Vector;
 
//ofc
import com.oxymel.ofc.charts.exception.OFCChartsRuntimeException;
 
public class Ridge
{
private int _lineNumberInitialNode;
private int _columnNumberInitialNode;
private int _positionType;
 
static final public int RIDGE_HORIZONTAL = 0;
static final public int RIDGE_VERTICAL = 1;
 
 
public Ridge(int lineNumberInitialNode, int columnNumberInitialNode, int positionType)
{
_lineNumberInitialNode = lineNumberInitialNode;
_columnNumberInitialNode = columnNumberInitialNode;
_positionType = positionType;
}
 
static public String getKey(int lineNumber, int columnNumber, int positionType)
{
StringBuffer key = new StringBuffer();
key.append("L");
key.append(lineNumber);
key.append("C");
key.append(columnNumber);
key.append("P");
key.append(positionType);
return key.toString();
}
 
public String getKey()
{
return getKey(_lineNumberInitialNode, _columnNumberInitialNode, _positionType);
}
 
public int getPositionType(){return _positionType;}
 
public boolean isRidgeNodeEqualsToZ(double z, Grid grid)
{
double zInitialNode = getZInitialNode(grid);
if(zInitialNode == z){
return true;
}
double zFinalNode = getZFinalNode(grid);
if(zFinalNode == z){
return true;
}
return false;
}
 
public double getXInitialNode(Grid grid)
{
return grid.getX(_lineNumberInitialNode, _columnNumberInitialNode);
}
public double getYInitialNode(Grid grid)
{
return grid.getY(_lineNumberInitialNode, _columnNumberInitialNode);
}
public double getZInitialNode(Grid grid)
{
return grid.getZ(_lineNumberInitialNode, _columnNumberInitialNode);
}
 
public double getXFinalNode(Grid grid)
{
return grid.getX(getLineNumberFinalNode(), getColumnNumberFinalNode());
}
public double getYFinalNode(Grid grid)
{
return grid.getY(getLineNumberFinalNode(), getColumnNumberFinalNode());
}
public double getZFinalNode(Grid grid)
{
return grid.getZ(getLineNumberFinalNode(), getColumnNumberFinalNode());
}
 
public int getLineNumberInitialNode(){return _lineNumberInitialNode;}
public int getColumnNumberInitialNode(){return _columnNumberInitialNode;}
 
public int getLineNumberFinalNode()
{
switch(_positionType){
case RIDGE_HORIZONTAL:
return _lineNumberInitialNode;
case RIDGE_VERTICAL:
return _lineNumberInitialNode + 1;
default:
throw new OFCChartsRuntimeException("Invalid Ridge type");
}
}
 
public int getColumnNumberFinalNode()
{
switch(_positionType){
case RIDGE_HORIZONTAL:
return _columnNumberInitialNode + 1;
case RIDGE_VERTICAL:
return _columnNumberInitialNode;
default:
throw new OFCChartsRuntimeException("Invalid Ridge type");
}
}
 
}
/trunk/project/ofccharts/src/com/oxymel/ofc/charts/data/grid/GridNode.java
New file
0,0 → 1,55
package com.oxymel.ofc.charts.data.grid;
 
/*
* Copyright (c) 2006 Oxymel SA.
* All rights reserved.
*
* This software is the confidential and proprietary information of Oxymel SA
* ("Confidential Information"). You shall not disclose such Confidential
* Information and shall use it only in accordance with the terms of the license
* agreement you entered into with Oxymel SA.
*/
 
import java.util.Vector;
 
 
/**
*
*/
public class GridNode
{
private double _x;
private double _y;
private double _z;
 
/**
* Constructor
* @param x X of node
* @param y Y of node
* @param z Z of node
*/
public GridNode(double x, double y, double z)
{
_x = x;
_y = y;
_z = z;
}
 
/**
* Get X of node
* @return X of node
*/
public double getX(){return _x;}
 
/**
* Get Y of node
* @return Y of node
*/
public double getY(){return _y;}
 
/**
* Get Z of node
* @return Z of node
*/
public double getZ(){return _z;}
}
/trunk/project/ofccharts/src/com/oxymel/ofc/charts/data/grid/IrregularGrid.java
New file
0,0 → 1,153
package com.oxymel.ofc.charts.data.grid;
/*
* Copyright (c) 2006 Oxymel SA.
* All rights reserved.
*
* This software is the confidential and proprietary information of Oxymel SA
* ("Confidential Information"). You shall not disclose such Confidential
* Information and shall use it only in accordance with the terms of the license
* agreement you entered into with Oxymel SA.
*/
 
//java
import java.util.Vector;
import java.util.Enumeration;
 
//ofc
import com.oxymel.ofc.charts.exception.OFCChartsException;
import com.oxymel.ofc.charts.data.Point2D;
 
 
/**
*
*/
public class IrregularGrid extends Grid
{
private Vector _allLine = new Vector();
 
/**
* Constructor
*/
public IrregularGrid()
{
}
 
/**
* Add Line
* @param allGridNodeOfNewLine Vector of all grid node of new line to add
* @throws OFCChartsException
*/
public void addLine(Vector allGridNodeOfNewLine) throws OFCChartsException
{
Vector firstGridLine = getFirstLine();
if(firstGridLine != null){
if(firstGridLine.size() != allGridNodeOfNewLine.size()){
throw new OFCChartsException("Number column of grid ( = " + firstGridLine.size() + " ) is different to number column of new line ( = " + allGridNodeOfNewLine.size() + " )");
}
}
_allLine.addElement(allGridNodeOfNewLine);
}
 
/**
* Get Number of line
* @return Number of line
*/
public int getNbLine(){return _allLine.size();}
 
/**
* Get Number of column
* @return Number of column
*/
public int getNbColumn()
{
Vector firstGridLine = getFirstLine();
if(firstGridLine == null){
return 0;
}
return firstGridLine.size();
}
 
/**
* Get X of node
* @param lineNumber Line number of Node
* @param columnNumber Column number of Node
* @return X of node
*/
public double getX(int lineNumber, int columnNumber)
{
return getGridNode(lineNumber, columnNumber).getX();
}
 
/**
* Get Y of node
* @param lineNumber Line number of Node
* @param columnNumber Column number of Node
* @return Y of node
*/
public double getY(int lineNumber, int columnNumber)
{
return getGridNode(lineNumber, columnNumber).getY();
}
 
/**
* Get Z of node
* @param lineNumber Line number of Node
* @param columnNumber Column number of Node
* @return Z of node
*/
public double getZ(int lineNumber, int columnNumber)
{
return getGridNode(lineNumber, columnNumber).getZ();
}
 
 
public Enumeration getEnumAllBorderPointInHorlogeDirection()
{
Vector allPointBorder = new Vector();
 
allPointBorder.addElement(new Point2D(getX(0,0), getY(0,0)));
 
int nbColumn = getNbColumn();
int nbLine = getNbLine();
for(int i=1; i< nbColumn; i++){
double xCurrent = getX(0,i);
double yCurrent = getY(0,i);
allPointBorder.addElement(new Point2D(xCurrent, yCurrent));
}
int numColumnLast = nbColumn - 1;
for(int i=1; i< nbLine; i++){
double xCurrent = getX(i, numColumnLast);
double yCurrent = getY(i, numColumnLast);
allPointBorder.addElement(new Point2D(xCurrent, yCurrent));
}
int numLineLast = nbLine - 1;
for(int i=numColumnLast - 1; i >= 0; i--){
double xCurrent = getX(numLineLast,i);
double yCurrent = getY(numLineLast,i);
allPointBorder.addElement(new Point2D(xCurrent, yCurrent));
}
for(int i=numLineLast - 1; i > 0; i--){
double xCurrent = getX(i, 0);
double yCurrent = getY(i, 0);
allPointBorder.addElement(new Point2D(xCurrent, yCurrent));
}
 
return allPointBorder.elements();
}
 
 
private GridNode getGridNode(int lineNumber, int columnNumber)
{
Vector gridLine = (Vector)_allLine.elementAt(lineNumber);
return (GridNode)gridLine.elementAt(columnNumber);
}
 
private Vector getFirstLine()
{
if(_allLine.size() == 0){
return null;
}
return (Vector)_allLine.elementAt(0);
}
 
}
/trunk/project/ofccharts/src/com/oxymel/ofc/charts/data/grid/Grid.java
New file
0,0 → 1,160
package com.oxymel.ofc.charts.data.grid;
/*
* Copyright (c) 2006 Oxymel SA.
* All rights reserved.
*
* This software is the confidential and proprietary information of Oxymel SA
* ("Confidential Information"). You shall not disclose such Confidential
* Information and shall use it only in accordance with the terms of the license
* agreement you entered into with Oxymel SA.
*/
 
import java.util.Enumeration;
 
/**
* Grid is the abstract superclass for all grid
*/
abstract public class Grid
{
protected Grid()
{
}
 
/**
* Get Number of line
* @return Number of line
*/
abstract public int getNbLine();
 
/**
* Get Number of column
* @return Number of column
*/
abstract public int getNbColumn();
 
/**
* Get all point on border of the grid order by the horloge direction from the grid left corner
* @return all point on border of the grid
*/
abstract public Enumeration getEnumAllBorderPointInHorlogeDirection();
 
/**
* Get X of node
* @param lineNumber Line number of Node
* @param columnNumber Column number of Node
* @return X of node
*/
abstract public double getX(int lineNumber, int columnNumber);
 
/**
* Get Y of node
* @param lineNumber Line number of Node
* @param columnNumber Column number of Node
* @return Y of node
*/
abstract public double getY(int lineNumber, int columnNumber);
 
/**
* Get Z of node
* @param lineNumber Line number of Node
* @param columnNumber Column number of Node
* @return Z of node
*/
abstract public double getZ(int lineNumber, int columnNumber);
 
/**
* Get Z max value
* @return Z max value
*/
public double getZMax()
{
double max = getZ(0,0);
for(int i = 0; i < getNbLine(); i ++){
for(int j = 0; j < getNbColumn(); j++){
if(getZ(i,j) > max){
max = getZ(i,j);
}
}
}
return max;
}
 
/**
* Get Z min value
* @return Z min value
*/
public double getZMin()
{
double min = getZ(0,0);
for(int i = 0; i < getNbLine(); i ++){
for(int j = 0; j <getNbColumn(); j++){
if(getZ(i,j) < min){
min = getZ(i,j);
}
}
}
return min;
}
 
 
/**
* Get X max value
* @return X max value
*/
public double getXMax()
{
double max = getX(0,0);
for(int i = 0; i < getNbLine(); i ++){
for(int j = 0; j < getNbColumn(); j++){
max = Math.max(getX(i,j), max);
}
}
return max;
}
 
/**
* Get X min value
* @return X min value
*/
public double getXMin()
{
double min = getX(0,0);
for(int i = 0; i < getNbLine(); i ++){
for(int j = 0; j <getNbColumn(); j++){
min = Math.min(getX(i,j), min);
}
}
return min;
}
 
/**
* Get Y max value
* @return Y max value
*/
public double getYMax()
{
double max = getY(0,0);
for(int i = 0; i < getNbLine(); i ++){
for(int j = 0; j < getNbColumn(); j++){
max = Math.max(getY(i,j), max);
}
}
return max;
}
 
/**
* Get Y min value
* @return Y min value
*/
public double getYMin()
{
double min = getY(0,0);
for(int i = 0; i < getNbLine(); i ++){
for(int j = 0; j <getNbColumn(); j++){
min = Math.min(getY(i,j), min);
}
}
return min;
}
 
}
/trunk/project/ofccharts/src/com/oxymel/ofc/charts/data/grid/RegularGrid.java
New file
0,0 → 1,593
package com.oxymel.ofc.charts.data.grid;
/*
* Copyright (c) 2006 Oxymel SA.
* All rights reserved.
*
* This software is the confidential and proprietary information of Oxymel SA
* ("Confidential Information"). You shall not disclose such Confidential
* Information and shall use it only in accordance with the terms of the license
* agreement you entered into with Oxymel SA.
*/
 
import java.util.Enumeration;
import java.util.Vector;
 
import com.oxymel.ofc.charts.data.Point2D;
import com.oxymel.ofc.charts.geographic.Rectangle;
import com.oxymel.ofc.charts.interpolation.InterpolationMethod;
import com.oxymel.ofc.charts.util.OFCMath;
 
public class RegularGrid extends Grid
{
private int _nbLine;
private int _nbColumn;
 
private double _stepX;
private double _stepY;
 
private double _xTopLeft;
private double _yTopLeft;
 
private double[][] _data;
 
/**
* Constructor
* @param nbLine Number of line of regular grid
* @param nbColumn Number of column of regular grid
* @param stepX Step of grid on X (Step for all columns)
* @param stepY Step of grid on Y (Step for all lines)
* @param xTopLeft x of node top left
* @param yTopLeft y of node top left
*/
public RegularGrid(int nbLine, int nbColumn, double stepX, double stepY,
double xTopLeft, double yTopLeft)
{
_nbLine = nbLine;
_nbColumn = nbColumn;
_data = new double[nbLine][nbColumn];
 
_stepX = stepX;
_stepY = stepY;
_xTopLeft = xTopLeft;
_yTopLeft = yTopLeft;
}
 
/**
* Set Z of node
* @param z new z of node
* @param lineNumber number of node
* @param columnNumber number of node
*/
public void setZ(double z, int lineNumber, int columnNumber)
{
_data[lineNumber][columnNumber] = z;
}
 
/**
* Get Number of line
* @return Number of line
*/
public int getNbLine(){return _nbLine;}
 
/**
* Get Number of column
* @return Number of column
*/
public int getNbColumn(){return _nbColumn;}
 
/**
* Get X of node
* @param lineNumber Line number of Node
* @param columnNumber Column number of Node
* @return X of node
*/
public double getX(int lineNumber, int columnNumber)
{
return _xTopLeft + (columnNumber * _stepX);
 
}
 
/**
* Get Y of node
* @param lineNumber Line number of Node
* @param columnNumber Column number of Node
* @return Y of node
*/
public double getY(int lineNumber, int columnNumber)
{
return _yTopLeft + (lineNumber * _stepY);
}
 
/**
* Get Z of node
* @param lineNumber Line number of Node
* @param columnNumber Column number of Node
* @return Z of node
*/
public double getZ(int lineNumber, int columnNumber)
{
return _data[lineNumber][columnNumber];
}
 
public Enumeration getEnumAllBorderPointInHorlogeDirection()
{
Vector allPointBorder = new Vector();
 
allPointBorder.addElement(new Point2D(getX(0,0), getY(0,0)));
 
allPointBorder.addElement(new Point2D(
getX(0, getNbColumn() - 1),
getY(0, getNbColumn() - 1)));
allPointBorder.addElement(new Point2D(
getX(getNbLine() - 1, getNbColumn() - 1),
getY(getNbLine() - 1, getNbColumn() - 1)));
allPointBorder.addElement(new Point2D(
getX(getNbLine() - 1, 0),
getY(getNbLine() - 1, 0)));
 
return allPointBorder.elements();
}
 
///// start Interpolation 1 :
///*
 
public void interpolateAllZ(Vector allPointDistant, InterpolationMethod interpolationMethod)
{
boolean test = false;
if(test){
for(int i = 0; i < getNbLine(); i ++){
for(int j = 0; j <getNbColumn(); j++){
double xCurrentNode = getX(i,j);
double yCurrentNode = getY(i,j);
setZ(interpolationMethod.getValue(xCurrentNode, yCurrentNode, allPointDistant,
interpolationMethod.getNbPointUsedToInterpolate()), i, j);
}
}
return;
}
 
int nbPointUsedToInterpolate = interpolationMethod.getNbPointUsedToInterpolate();
 
Vector allPointInSquare = new Vector();
Vector allPointOutSquare = new Vector();
Vector allPointOk = new Vector();
Vector allPointInSquareTMP = new Vector();
Vector allPointOutSquareTMP = new Vector();
 
Rectangle square = new Rectangle();
 
double stepValue;
int nbStepMaxToEnglobPointToInterpol;
if(_stepX > _stepY){
stepValue = _stepX;
nbStepMaxToEnglobPointToInterpol = _nbColumn;
}else{
stepValue = _stepY;
nbStepMaxToEnglobPointToInterpol = _nbLine;
}
 
for(int i = 0; i < getNbLine(); i ++){
for(int j = 0; j <getNbColumn(); j++){
//System.out.println(" i = " + i + " j = " + j);
 
double xCurrentNode = getX(i,j);
double yCurrentNode = getY(i,j);
int nbStepMin = 0;
int nbStepMax = nbStepMaxToEnglobPointToInterpol;
int nbStepCurrent = getNbStepByDichotomie(nbStepMax, nbStepMin);
//int nbStepCurrent = ((int)((nbStepMax - nbStepMin)/32));
setSquareToFindPoint(nbStepCurrent, stepValue, xCurrentNode, yCurrentNode, square);
allPointInSquare.clear();
allPointInSquareTMP.clear();
allPointOutSquare.clear();
allPointOk.clear();
initContainer(allPointDistant, square, allPointInSquare, allPointOutSquare);
 
boolean isCurrentZInterpolate = false;
while(!isCurrentZInterpolate){
int nbPointFindToInterpolate = allPointInSquare.size() + allPointOk.size();
if(((nbStepCurrent - nbStepMin) < 1) || (nbPointFindToInterpolate == nbPointUsedToInterpolate)){
setSquareToFindPointOnLimit(nbStepCurrent, stepValue, xCurrentNode, yCurrentNode, square);
addPointInSquare(square, allPointInSquare, allPointOutSquare);
allPointOk.addAll(allPointInSquare);
//do interpolation:
setZ(interpolationMethod.getValue(xCurrentNode, yCurrentNode, allPointOk, nbPointUsedToInterpolate), i, j);
isCurrentZInterpolate = true;
}else{
if(nbPointFindToInterpolate > nbPointUsedToInterpolate){
//start new method 2
setSquareToFindPointOnIncludCircle(nbStepCurrent, stepValue, xCurrentNode, yCurrentNode, square);
allPointInSquareTMP.clear();
allPointOutSquareTMP.clear();
initContainer(allPointInSquare, square, allPointInSquareTMP, allPointOutSquareTMP);
//System.out.println("*** allPointInSquare = " + allPointInSquareTMP.size());
if(allPointInSquareTMP.size() + allPointOk.size() >= nbPointUsedToInterpolate){
//System.out.println("allPointInSquare OK = " + allPointInSquareTMP.size());
Vector tmp;
tmp = allPointInSquare;
allPointInSquare = allPointInSquareTMP;
allPointInSquareTMP = tmp;
}else{
setSquareToFindPointOnLimit(nbStepCurrent, stepValue, xCurrentNode, yCurrentNode, square);
//System.out.println("allPointInSquare before = " + allPointInSquare.size());
addPointInSquare(square, allPointInSquare, allPointOutSquare);
//System.out.println("allPointInSquare after = " + allPointInSquare.size());
}
allPointOutSquare.clear();
nbStepMax = nbStepCurrent;
//end new method 2
 
/*start new method 1
int nbStepForIncludeCircle = getNbStepForIncludeCircle(nbStepCurrent, stepValue,
xCurrentNode, yCurrentNode);
if(nbStepForIncludeCircle > 0){
setSquareToFindPoint(nbStepForIncludeCircle, stepValue, xCurrentNode, yCurrentNode, square);
allPointInSquareTMP.clear();
allPointOutSquareTMP.clear();
initContainer(allPointInSquare, square, allPointInSquareTMP, allPointOutSquareTMP);
if(allPointInSquareTMP.size() >= nbPointUsedToInterpolate){
Vector tmp;
tmp = allPointInSquare;
allPointInSquare = allPointInSquareTMP;
allPointInSquareTMP = tmp;
nbStepCurrent = nbStepForIncludeCircle;
nbStepMax = nbStepCurrent;
}else{
setSquareToFindPointOnLimit(nbStepCurrent, stepValue, xCurrentNode, yCurrentNode, square);
//System.out.println("allPointInSquare before = " + allPointInSquare.size());
addPointInSquare(square, allPointInSquare, allPointOutSquare);
//System.out.println("allPointInSquare after = " + allPointInSquare.size());
allPointOutSquare.clear();
nbStepMax = nbStepCurrent;
}
}else{
setSquareToFindPointOnLimit(nbStepCurrent, stepValue, xCurrentNode, yCurrentNode, square);
//System.out.println("allPointInSquare before = " + allPointInSquare.size());
addPointInSquare(square, allPointInSquare, allPointOutSquare);
//System.out.println("allPointInSquare after = " + allPointInSquare.size());
allPointOutSquare.clear();
nbStepMax = nbStepCurrent;
}
//end new method 1 */
 
/* avant old methode
setSquareToFindPointOnLimit(nbStepCurrent, stepValue, xCurrentNode, yCurrentNode, square);
System.out.println("allPointInSquare before = " + allPointInSquare.size());
addPointInSquare(square, allPointInSquare, allPointOutSquare);
System.out.println("allPointInSquare after = " + allPointInSquare.size());
allPointOutSquare.clear();
nbStepMax = nbStepCurrent;
fin avant old methode*/
}else{
allPointOk.addAll(allPointInSquare);
allPointInSquare.clear();
Vector tmp = allPointInSquare;
allPointInSquare = allPointOutSquare;
allPointOutSquare = tmp;
nbStepMin = nbStepCurrent;
}
nbStepCurrent = getNbStepByDichotomie(nbStepMax, nbStepMin);
setSquareToFindPoint(nbStepCurrent, stepValue, xCurrentNode, yCurrentNode, square);
allPointInSquareTMP.clear();
initContainer(allPointInSquare, square, allPointInSquareTMP, allPointOutSquare);
Vector tmp = allPointInSquare;
allPointInSquare = allPointInSquareTMP;
allPointInSquareTMP = tmp;
//addPointOutSquare(square, allPointInSquare, allPointOutSquare);
}
}
}
}
}
 
 
private void setSquareToFindPointOnIncludCircle(int nbStepCurrent, double stepValue,
double xCurrentNode, double yCurrentNode, Rectangle square)
{
double squareWidth = nbStepCurrent * stepValue * 2;
double newSquareWidth = squareWidth / OFCMath.SQRT_2;
double gap = newSquareWidth/2;
square.setXMin(xCurrentNode - gap);
square.setYMin(yCurrentNode - gap);
square.setXMax(xCurrentNode + gap);
square.setYMax(yCurrentNode + gap);
}
 
private void setSquareToFindPoint(int nbStepCurrent, double stepValue,
double xCurrentNode, double yCurrentNode, Rectangle square)
{
double gap = nbStepCurrent * stepValue;
square.setXMin(xCurrentNode - gap);
square.setYMin(yCurrentNode - gap);
square.setXMax(xCurrentNode + gap);
square.setYMax(yCurrentNode + gap);
}
 
private void setSquareToFindPointOnLimit(int nbStepCurrent, double stepValue,
double xCurrentNode, double yCurrentNode, Rectangle square)
{
double squareWidth = nbStepCurrent * stepValue * 2;
double diameterCircleWitchContainsSquare = squareWidth * OFCMath.SQRT_2;
double radiusOfCircleWitchContainsSquare = diameterCircleWitchContainsSquare / 2;
 
square.setXMin(xCurrentNode - radiusOfCircleWitchContainsSquare);
square.setYMin(yCurrentNode - radiusOfCircleWitchContainsSquare);
square.setXMax(xCurrentNode + radiusOfCircleWitchContainsSquare);
square.setYMax(yCurrentNode + radiusOfCircleWitchContainsSquare);
}
 
private int getNbStepForIncludeCircle(int nbStepCurrent, double stepValue, double xCurrentNode, double yCurrentNode)
{
if(nbStepCurrent < 2){
return 0;
}
int nbStepToFind = nbStepCurrent - 1;
double diameterMax = nbStepCurrent * stepValue * 2;
while(nbStepToFind > 0){
double squareWidth = nbStepToFind * stepValue * 2;
double diameterCircleWitchContainsSquare = squareWidth * OFCMath.SQRT_2;
if(diameterCircleWitchContainsSquare <= diameterMax){
return nbStepCurrent;
}
nbStepToFind --;
}
 
return 0;
}
 
private void initContainer(Vector allPointDistant, Rectangle square, Vector allPointInSquare, Vector allPointOutSquare)
{
for(int i=0; i<allPointDistant.size(); i++){
Point2D point = (Point2D)allPointDistant.elementAt(i);
if(square.isContains(point)){
allPointInSquare.addElement(point);
}else{
allPointOutSquare.addElement(point);
}
}
}
 
private void addPointInSquare(Rectangle square, Vector allPointInSquare, Vector allPointOutSquare)
{
for(int i=0; i<allPointOutSquare.size(); i++){
Point2D point = (Point2D)allPointOutSquare.elementAt(i);
if(square.isContains(point)){
allPointInSquare.addElement(point);
}
}
}
 
 
private int getNbStepByDichotomie(int nbStepMax, int nbStepMin)
{
return ((int)((nbStepMax - nbStepMin)/2)) + nbStepMin;
}
//*/
/// end interpolaton 1
 
 
///// start Interpolation 2 :
/*
public void interpolateAllZ(Vector allPointDistant, InterpolationMethod interpolationMethod)
{
boolean test = false;
if(test){
for(int i = 0; i < getNbLine(); i ++){
for(int j = 0; j <getNbColumn(); j++){
double xCurrentNode = getX(i,j);
double yCurrentNode = getY(i,j);
setZ(interpolationMethod.getValue(xCurrentNode, yCurrentNode, allPointDistant,
interpolationMethod.getNbPointUsedToInterpolate()), i, j);
}
}
return;
}
 
int nbPointUsedToInterpolate = interpolationMethod.getNbPointUsedToInterpolate();
Hashtable allPointInMesh = getAllPointInMesh(allPointDistant);
int nbVector =0;
Enumeration enumAllVector = allPointInMesh.elements();
while(enumAllVector.hasMoreElements()){
nbVector ++;
Vector current = (Vector)enumAllVector.nextElement();
System.out.println("size = " + current.size());
}
System.out.println("nbVector = " + nbVector);
 
Vector allPointUsedToInterpolate = new Vector();
for(int i = 0; i < getNbLine(); i ++){
for(int j = 0; j <getNbColumn(); j++){
System.out.println("i = " + i + " j = " + j);
double xCurrentNode = getX(i,j);
double yCurrentNode = getY(i,j);
allPointUsedToInterpolate.clear();
setAllPointUsedToInterpolate(i, j, nbPointUsedToInterpolate, allPointInMesh, allPointUsedToInterpolate);
setZ(interpolationMethod.getValue(xCurrentNode, yCurrentNode,
allPointUsedToInterpolate, nbPointUsedToInterpolate), i, j);
}
}
 
}
 
private Hashtable getAllPointInMesh(Vector allPoint)
{
Hashtable allPointInMesh = new Hashtable();
for(int i= 0; i< allPoint.size(); i++){
Point2D point = (Point2D)allPoint.elementAt(i);
addPointInMesh(point, allPointInMesh);
}
return allPointInMesh;
}
 
private void addPointInMesh(Point2D point, Hashtable allPointInMesh)
{
int lineNodeTopOfMesh = getLineNodeTopOfMesh(point);
int columnNodeTopOfMesh = getColumnNodeTopOfMesh(point);
 
String meshKey = getMeshKey(lineNodeTopOfMesh, columnNodeTopOfMesh);
Vector allPoint = (Vector)allPointInMesh.get(meshKey);
if(allPoint == null){
allPoint = new Vector();
allPoint.addElement(point);
allPointInMesh.put(meshKey, allPoint);
}else{
allPoint.addElement(point);
}
 
}
 
private int getLineNodeTopOfMesh(Point2D point)
{
double yMin = getY(0, 0);
double yMax = yMin + _stepY;
 
double y = point.getY();
 
for(int i=0;i<_nbLine;i++){
if((y >= yMin)&&(y <= yMax)){
return i;
}
yMin = yMax;
yMax += _stepY;
}
return 0;
}
 
private int getColumnNodeTopOfMesh(Point2D point)
{
double xMin = getX(0, 0);
double xMax = xMin + _stepX;
 
double x = point.getX();
 
for(int i=0;i<_nbColumn;i++){
if((x >= xMin)&&(x <= xMax)){
return i;
}
xMin = xMax;
xMax += _stepX;
}
return 0;
}
 
private String getMeshKey(int line, int column)
{
StringBuffer strBuff = new StringBuffer();
strBuff.append(line);
strBuff.append("|");
strBuff.append(column);
return strBuff.toString();
}
 
private void setAllPointUsedToInterpolate(int lineNodeToInterpolate, int columnNodeToInterpolate,
int nbPointUsedToInterpolate, Hashtable allPointInMesh, Vector allPointUsedToInterpolate)
{
int nbDecalage = 1;
 
double stepValueMax;
double stepValueMin;
if(_stepX > _stepY){
stepValueMax = _stepX;
stepValueMin = _stepY;
}else{
stepValueMax = _stepY;
stepValueMin = _stepX;
}
 
int nbLoopMax = Math.max(getNbLine(), getNbColumn());
for(int i = 0; i <nbLoopMax ; i ++){
setAllPointUsedToInterpolate(nbDecalage, lineNodeToInterpolate, columnNodeToInterpolate,
nbPointUsedToInterpolate, allPointInMesh, allPointUsedToInterpolate);
 
if(allPointUsedToInterpolate.size() >= nbPointUsedToInterpolate){
double squareWidth = nbDecalage * stepValueMax * 2;
double diameterCircleWitchContainsSquare = squareWidth * SQRT_2;
double radiusOfCircleWitchContainsSquare = diameterCircleWitchContainsSquare / 2;
 
double radiusCurrentCircle = nbDecalage * stepValueMin;
int nbFinalDecalage = ((int)((radiusOfCircleWitchContainsSquare - radiusOfCircleWitchContainsSquare) / stepValueMin)) + 1;
for(int j=0; j<=nbFinalDecalage; j++){
setAllPointUsedToInterpolate(nbDecalage, lineNodeToInterpolate, columnNodeToInterpolate,
nbPointUsedToInterpolate, allPointInMesh, allPointUsedToInterpolate);
nbDecalage++;
}
 
return;
}
 
nbDecalage ++;
}
 
}
 
private void setAllPointUsedToInterpolate(int nbDecalage, int lineNodeToInterpolate, int columnNodeToInterpolate,
int nbPointUsedToInterpolate, Hashtable allPointInMesh, Vector allPointUsedToInterpolate)
{
int lineNumber = lineNodeToInterpolate - nbDecalage;
int initialColumnNumber = columnNodeToInterpolate - nbDecalage;
int finalColumnNumber = columnNodeToInterpolate + nbDecalage;
setAllPointUsedToInterpolateInLine(lineNumber, initialColumnNumber, finalColumnNumber,
allPointInMesh, allPointUsedToInterpolate);
 
lineNumber = lineNodeToInterpolate + nbDecalage - 1;
setAllPointUsedToInterpolateInLine(lineNumber, initialColumnNumber, finalColumnNumber,
allPointInMesh, allPointUsedToInterpolate);
 
int columnNumber = columnNodeToInterpolate - nbDecalage;
int initialLineNumber = lineNodeToInterpolate - nbDecalage + 1;
int finalLineNumber = lineNodeToInterpolate + nbDecalage - 1;
setAllPointUsedToInterpolateInColumn(columnNumber, initialLineNumber, finalLineNumber,
allPointInMesh, allPointUsedToInterpolate);
 
columnNumber = columnNodeToInterpolate + nbDecalage - 1;
setAllPointUsedToInterpolateInColumn(columnNumber, initialLineNumber, finalLineNumber,
allPointInMesh, allPointUsedToInterpolate);
}
 
private void setAllPointUsedToInterpolateInLine(int lineNumber, int initialColumnNumber, int finalColumnNumber,
Hashtable allPointInMesh, Vector allPointUsedToInterpolate)
{
if((lineNumber < 0) || (lineNumber > _nbLine - 1)){
return;
}
if(initialColumnNumber < 0){
initialColumnNumber = 0;
}
if(finalColumnNumber > _nbColumn){
finalColumnNumber = _nbColumn;
}
for(int j=initialColumnNumber; j<finalColumnNumber; j++){
String meshKey = getMeshKey(lineNumber, j);
Vector allPoint = (Vector)allPointInMesh.get(meshKey);
if(allPoint != null){
allPointUsedToInterpolate.addAll(allPoint);
}
}
}
 
private void setAllPointUsedToInterpolateInColumn(int columnNumber, int initialLineNumber, int finalLineNumber,
Hashtable allPointInMesh, Vector allPointUsedToInterpolate)
{
if((columnNumber < 0) || (columnNumber > _nbColumn - 1)){
return;
}
if(initialLineNumber < 0){
initialLineNumber = 0;
}
if(finalLineNumber > _nbLine){
finalLineNumber = _nbLine;
}
for(int i=initialLineNumber; i<finalLineNumber; i++){
String meshKey = getMeshKey(i, columnNumber);
Vector allPoint = (Vector)allPointInMesh.get(meshKey);
if(allPoint != null){
allPointUsedToInterpolate.addAll(allPoint);
}
}
}
 
 
*/
/// end interpolaton 2
 
}
/trunk/project/ofccharts/src/com/oxymel/ofc/charts/data/CategoryValue.java
New file
0,0 → 1,181
package com.oxymel.ofc.charts.data;
/*
* Copyright (c) 2006 Oxymel SA.
* All rights reserved.
*
* This software is the confidential and proprietary information of Oxymel SA
* ("Confidential Information"). You shall not disclose such Confidential
* Information and shall use it only in accordance with the terms of the license
* agreement you entered into with Oxymel SA.
*/
 
/**
* Manage a couple of category-value
*/
public class CategoryValue
{
/**
* No information associate to value is display
*/
public static final int VALUE_INFORMATION_DISPLAY_NONE = 0;
 
/**
* Information associate to value is display on top
*/
public static final int VALUE_INFORMATION_DISPLAY_ON_TOP = 1;
 
/**
* Information associate to value is display center
*/
public static final int VALUE_INFORMATION_DISPLAY_ON_CENTER = 2;
 
private String _categoryId;
private double _value;
private String _info = null;
private int _infoDisplayPosition = VALUE_INFORMATION_DISPLAY_NONE;
 
/**
* Constructor
* @param categoryId Category Id
* @param value Category Value
*/
public CategoryValue(String categoryId, double value)
{
_categoryId = categoryId;
_value = value;
 
}
 
/**
* Constructor
* @param categoryId Category Id
* @param value Category Value
* @param info information associate to value
*/
public CategoryValue(String categoryId, double value, String info)
{
_categoryId = categoryId;
_value = value;
_info = info;
}
 
/**
* Constructor
* @param categoryId Category Id
* @param value Category Value
* @param info information associate to value
* @param infoDisplayPosition Position to display information
*/
public CategoryValue(String categoryId, double value, String info,int infoDisplayPosition)
{
_categoryId = categoryId;
_value = value;
_info = info;
_infoDisplayPosition = infoDisplayPosition;
}
 
/**
* Get a cloned category value
* @return a cloned category value
*/
public Object clone()
{
return new CategoryValue(_categoryId, _value);
}
 
/**
* Get formated value as String with specified precision
* @param nbDecimals
* @return value as String
*/
public String getValueAsString(int nbDecimals)
{
String val = new String();
 
val = Double.toString(_value);
int idx = val.indexOf(".");
if((idx+nbDecimals+1) < val.length()){
return val.substring(0,idx+nbDecimals+1);
}else{
return val.substring(0,val.length());
}
}
 
/**
* Get formated value as String with specified precision
* @return value as String
*/
public String getValueAsStringTwoDecimals()
{
String val = new String();
val = Double.toString(_value);
 
int idx = val.indexOf(".");
return val.substring(0,idx+3);
}
 
/**
* Sets information associated to the value
* @param info information associated to the value
*/
public void setValueInformation(String info)
{
_info = info;
}
 
/**
* Sets display mode of information associated to the value
* @param mode
*/
public void setValueInformationDisplayMode(int mode)
{
_infoDisplayPosition = mode;
}
 
/**
* Get display mode of information associated to the value
* @return display mode of information associated to the value
*/
public int getValueInformationDisplayMode()
{
return _infoDisplayPosition;
}
 
/**
* Get information associated to the value
* @return information associated to the value
*/
public String getValueInformation()
{
return _info;
}
 
/**
* Get Value
* @return Category value
*/
public double getValue()
{
return _value;
}
 
/**
* Sets value
* @param value
*/
public void setValue(double value)
{
_value = value;
}
 
/**
* Get Category Id
* @return Category Id
*/
public String getCategoryId()
{
return _categoryId;
}
 
 
}
/trunk/project/ofccharts/src/com/oxymel/ofc/charts/data/Category.java
New file
0,0 → 1,65
package com.oxymel.ofc.charts.data;
/*
* Copyright (c) 2006 Oxymel SA.
* All rights reserved.
*
* This software is the confidential and proprietary information of Oxymel SA
* ("Confidential Information"). You shall not disclose such Confidential
* Information and shall use it only in accordance with the terms of the license
* agreement you entered into with Oxymel SA.
*/
 
/**
* Manage a category
*/
public class Category
{
private String _id;
private String _label;
private int _displayNumber;
 
/**
* Constructor
* @param id Category Id
* @param label Category label
*/
public Category(String id, String label)
{
_id = id;
_label = label;
}
 
/**
* Get a cloned category
* @return a cloned category
*/
public Object clone()
{
return new Category(_id, _label);
}
 
/**
* Get category Id
* @return Category Id
*/
public String getId(){return _id;}
 
/**
* Get label
* @return Category label
*/
public String getLabel(){return _label;}
 
/**
* Get category display number
* @return Display number
*/
public int getDisplayNumber(){return _displayNumber;}
 
/**
* Set category display number
* @param displayNumber Category display number
*/
public void setDisplayNumber(int displayNumber){_displayNumber = displayNumber;}
 
}
/trunk/project/ofccharts/src/com/oxymel/ofc/charts/VerticalLineChartRenderer.java
New file
0,0 → 1,285
package com.oxymel.ofc.charts;
/*
* Copyright (c) 2006 Oxymel SA.
* All rights reserved.
*
* This software is the confidential and proprietary information of Oxymel SA
* ("Confidential Information"). You shall not disclose such Confidential
* Information and shall use it only in accordance with the terms of the license
* agreement you entered into with Oxymel SA.
*/
 
//java
import java.util.*;
import java.awt.*;
import java.awt.geom.*;
//ofc
import com.oxymel.ofc.charts.data.*;
import com.oxymel.ofc.charts.series.*;
import com.oxymel.ofc.charts.util.*;
 
 
/**
* This class provides a vertical line chart renderer
*/
public class VerticalLineChartRenderer extends VerticalBarChartRenderer
{
private int InfoTagFreeSpace = 2;
/**
* Constructor
* @param categoryValueSeriesContainer all category value series
*/
public VerticalLineChartRenderer(CategoryValueSeriesContainer categoryValueSeriesContainer)
{
super(categoryValueSeriesContainer);
}
 
/*
void drawGraphic(int xTopLeftGraphic, int yTopLeftGraphic, int graphicWidth, int graphicHeight,
int xOrigine, int yOrigine, Graphics2D graphics2D)
{
int sizeOfGapOnY = graphicHeight / _nbGapOnY;
int sizeOfGapOnX = graphicWidth / _nbGapOnX;
 
Vector allCategories = _categoryValueSeriesContainer.getAllCategoriesOrderByDisplayNumber();
 
for(int i= 0; i<allCategories.size(); i++){
Category category = (Category)allCategories.elementAt(i);
int xCurrent = xOrigine + (sizeOfGapOnX * i) + (sizeOfGapOnX/2);
 
if(i <allCategories.size()-1){
Enumeration enumAllSeries = _categoryValueSeriesContainer.getEnumAllSeriesOrderByDisplayNumber();
boolean firstValue = true;
GeneralPath generalPath = new GeneralPath();
while(enumAllSeries.hasMoreElements()){
CategoryValueSeries categoryValueSeries = (CategoryValueSeries)enumAllSeries.nextElement();
if(!categoryValueSeries.isSeriesIndicatorOK()){
generalPath.moveTo(xCurrent, yOrigine);
}
if(categoryValueSeries.isVisible()){
double value = categoryValueSeries.getCategoryValueAsDouble(category.getId());
Category nextCategory = (Category) allCategories.elementAt(i+1);
double nextValue = categoryValueSeries.getCategoryValueAsDouble(nextCategory.getId());
//>>>
String info = categoryValueSeries.getCategoryValue(category.getId()).getInfo();
int displayInfo = categoryValueSeries.getCategoryValue(category.getId()).getInfoDisplayMode();
//<<<
//
if(categoryValueSeries.isSeriesIndicatorOK()){
drawLine(xCurrent, yOrigine, sizeOfGapOnX,
Graphics2DTools.getRelativeSizeOfValue(value, _gapValueOnY, sizeOfGapOnY),
Graphics2DTools.getRelativeSizeOfValue(nextValue, _gapValueOnY, sizeOfGapOnY),
categoryValueSeries, graphics2D);
}else{
drawLine(xCurrent, yOrigine, sizeOfGapOnX,
Graphics2DTools.getRelativeSizeOfValue(value, _gapValueOnY, sizeOfGapOnY),
Graphics2DTools.getRelativeSizeOfValue(nextValue, _gapValueOnY, sizeOfGapOnY),
categoryValueSeries, generalPath, firstValue);
}
 
if((!categoryValueSeries.isSeriesIndicatorOK()) && (!enumAllSeries.hasMoreElements())){
graphics2D.setColor(categoryValueSeries.getColor());
Stroke initialStroke = graphics2D.getStroke();
graphics2D.setStroke(new BasicStroke(2.0f));
graphics2D.draw(generalPath);
graphics2D.setStroke(initialStroke);
}
//>>>
if(displayInfo != CategoryValue.INFORMATION_DISPLAY_NONE && info != null)
{
drawInfoTag(xCurrent, yOrigine-Graphics2DTools.getRelativeSizeOfValue(value, _gapValueOnY, sizeOfGapOnY),
value, info, displayInfo, graphics2D);
if(i+1 >= (allCategories.size()-1))
{
info = categoryValueSeries.getCategoryValue(nextCategory.getId()).getInfo();
drawInfoTag(xCurrent+sizeOfGapOnX, yOrigine-Graphics2DTools.getRelativeSizeOfValue(nextValue, _gapValueOnY, sizeOfGapOnY),
nextValue, info, displayInfo, graphics2D);
}
}
//<<<
}
firstValue = false;
}
}
}
}
*/
 
void drawGraphic(int xTopLeftGraphic, int yTopLeftGraphic, int graphicWidth, int graphicHeight,
int xOrigine, int yOrigine, Graphics2D graphics2D)
{
int sizeOfGapOnY = graphicHeight / _nbGapOnY;
int sizeOfGapOnX = graphicWidth / _nbGapOnX;
 
Vector allCategories = _categoryValueSeriesContainer.getAllCategoriesOrderByDisplayNumber();
 
Enumeration enumAllSeries = _categoryValueSeriesContainer.getEnumAllSeriesOrderByDisplayNumber();
while(enumAllSeries.hasMoreElements()){
int xCurrent = xOrigine + (sizeOfGapOnX/2);
GeneralPath generalPath = new GeneralPath();
CategoryValueSeries categoryValueSeries = (CategoryValueSeries)enumAllSeries.nextElement();
if(categoryValueSeries.isVisible()){
boolean firstValue = true;
for(int i= 0; i<allCategories.size(); i++){
Category category = (Category)allCategories.elementAt(i);
xCurrent = xOrigine + (sizeOfGapOnX * i) + (sizeOfGapOnX/2);
double value = categoryValueSeries.getCategoryValueAsDouble(category.getId());
addLine(xCurrent, yOrigine, sizeOfGapOnX,
Graphics2DTools.getRelativeSizeOfValue(value, _gapValueOnY, sizeOfGapOnY),
categoryValueSeries, generalPath, firstValue);
firstValue = false;
}
//generalPath.lineTo(xCurrent, yOrigine);
 
//xCurrent = xOrigine + (sizeOfGapOnX/2);
//generalPath.lineTo(xCurrent, yOrigine);
graphics2D.setColor(categoryValueSeries.getColor());
Stroke initialStroke = graphics2D.getStroke();
graphics2D.setStroke(new BasicStroke(2.0f));
graphics2D.draw(generalPath);
graphics2D.setStroke(initialStroke);
 
if(categoryValueSeries.hasIndicator()){
drawIndicator(sizeOfGapOnX, sizeOfGapOnY,
xOrigine, yOrigine, graphics2D);
}
 
drawInfoTag(sizeOfGapOnX, sizeOfGapOnY, xOrigine, yOrigine, graphics2D);
}
}
 
}
 
private void addLine(int xCurrent, int yOrigine, int sizeOfGapOnX, int relativeSizeOfValue,
CategoryValueSeries series, GeneralPath generalPath, boolean firstValue)
{
int x1 = xCurrent;
int y1 = yOrigine - relativeSizeOfValue;
 
if(firstValue){
generalPath.moveTo(x1, y1);
}else{
generalPath.lineTo(x1, y1);
}
}
 
private void drawIndicator(int sizeOfGapOnX, int sizeOfGapOnY,
int xOrigine, int yOrigine, Graphics2D graphics2D)
{
Vector allCategories = _categoryValueSeriesContainer.getAllCategoriesOrderByDisplayNumber();
 
Enumeration enumAllSeries = _categoryValueSeriesContainer.getEnumAllSeriesOrderByDisplayNumber();
while(enumAllSeries.hasMoreElements()){
int xCurrent = xOrigine + (sizeOfGapOnX/2);
CategoryValueSeries categoryValueSeries = (CategoryValueSeries)enumAllSeries.nextElement();
graphics2D.setColor(categoryValueSeries.getColor());
if(categoryValueSeries.isVisible()){
for(int i= 0; i<allCategories.size(); i++){
Category category = (Category)allCategories.elementAt(i);
xCurrent = xOrigine + (sizeOfGapOnX * i) + (sizeOfGapOnX/2);
double value = categoryValueSeries.getCategoryValueAsDouble(category.getId());
int x1 = xCurrent;
int y1 = yOrigine - Graphics2DTools.getRelativeSizeOfValue(value, _gapValueOnY, sizeOfGapOnY);
categoryValueSeries.drawIndicator(x1, y1, graphics2D);
}
}
}
}
 
private void drawInfoTag(int sizeOfGapOnX, int sizeOfGapOnY,
int xOrigine, int yOrigine, Graphics2D graphics2D)
{
Vector allCategories = _categoryValueSeriesContainer.getAllCategoriesOrderByDisplayNumber();
 
Enumeration enumAllSeries = _categoryValueSeriesContainer.getEnumAllSeriesOrderByDisplayNumber();
while(enumAllSeries.hasMoreElements()){
int xCurrent = xOrigine + (sizeOfGapOnX/2);
CategoryValueSeries categoryValueSeries = (CategoryValueSeries)enumAllSeries.nextElement();
if(categoryValueSeries.isVisible()){
for(int i= 0; i<allCategories.size(); i++){
Category category = (Category)allCategories.elementAt(i);
xCurrent = xOrigine + (sizeOfGapOnX * i) + (sizeOfGapOnX/2);
double value = categoryValueSeries.getCategoryValueAsDouble(category.getId());
String info = categoryValueSeries.getCategoryValue(category.getId()).getValueInformation();
int displayInfo = categoryValueSeries.getCategoryValue(category.getId()).getValueInformationDisplayMode();
if(displayInfo != CategoryValue.VALUE_INFORMATION_DISPLAY_NONE && info != null){
drawInfoTag(xCurrent, yOrigine-Graphics2DTools.getRelativeSizeOfValue(value, _gapValueOnY, sizeOfGapOnY),
value, info, displayInfo, graphics2D);
}
}
}
}
}
 
 
private Dimension getLegendDimension(String s, Graphics2D graphics2D)
{
FontMetrics fm = graphics2D.getFontMetrics();
int wTmp = fm.stringWidth(s);
int hTmp = fm.getHeight();
Dimension d = new Dimension(wTmp,hTmp);
return d;
}
 
private void drawInfoTag(int x, int y, double value,String info,int displayInfo,Graphics2D graphics2D)
{
x = x - (((int)getLegendDimension(info,graphics2D).getWidth())/2);
if(value < 0.0 )
y = y + InfoTagFreeSpace + ((int)getLegendDimension(info,graphics2D).getHeight()/2);
else
y = y - InfoTagFreeSpace;
Color c = graphics2D.getColor();
Font font = graphics2D.getFont();
Font f = new Font(font.getName(), font.getStyle(), 9);
graphics2D.setFont(f);
graphics2D.setColor(Color.lightGray);
graphics2D.fillRect(x-2,y-(int)getLegendDimension(info,graphics2D).getHeight()+2,
(int)getLegendDimension(info,graphics2D).getWidth()+2,
(int)getLegendDimension(info,graphics2D).getHeight());
graphics2D.setColor(Color.black);
graphics2D.drawRect(x-2,y-(int)getLegendDimension(info,graphics2D).getHeight()+2,
(int)getLegendDimension(info,graphics2D).getWidth()+2,
(int)getLegendDimension(info,graphics2D).getHeight());
graphics2D.drawString(info,x,y);
graphics2D.setFont(font);
graphics2D.setColor(c);
}
 
/*
private void drawLine(int xCurrent, int yOrigine, int sizeOfGapOnX, int relativeSizeOfValue,
int relativeSizeOfNextValue, CategoryValueSeries series, Graphics2D graphics2D)
{
int x1 = xCurrent;
int x2 = x1 + sizeOfGapOnX;
 
int y1 = yOrigine - relativeSizeOfValue;
int y2 = yOrigine - relativeSizeOfNextValue;
graphics2D.setColor(series.getColor());
 
Stroke initialStroke = graphics2D.getStroke();
graphics2D.setStroke(new BasicStroke(2.0f));
graphics2D.drawLine(x1, y1, x2, y2);
graphics2D.setStroke(initialStroke);
series.drawIndicator(x1, y1, graphics2D);
series.drawIndicator(x2, y2, graphics2D);
}
*/
 
private void drawLine(int xCurrent, int yOrigine, int sizeOfGapOnX, int relativeSizeOfValue,
int relativeSizeOfNextValue, CategoryValueSeries series, GeneralPath generalPath, boolean first)
{
int x1 = xCurrent;
int x2 = x1 + sizeOfGapOnX;
 
int y1 = yOrigine - relativeSizeOfValue;
int y2 = yOrigine - relativeSizeOfNextValue;
 
if(first){
generalPath.moveTo(x1, y1);
}
generalPath.lineTo(x2, y2);
 
}
 
 
}
/trunk/project/ofccharts/src/com/oxymel/ofc/charts/DialChart.java
New file
0,0 → 1,430
package com.oxymel.ofc.charts;
/*
* Copyright (c) 2006 Oxymel SA.
* All rights reserved.
*
* This software is the confidential and proprietary information of Oxymel SA
* ("Confidential Information"). You shall not disclose such Confidential
* Information and shall use it only in accordance with the terms of the license
* agreement you entered into with Oxymel SA.
*/
 
//batik
import java.util.*;
 
import java.awt.*;
import java.awt.geom.*;
 
import org.apache.batik.svggen.*;
import com.oxymel.ofc.charts.animation.*;
import com.oxymel.ofc.charts.exception.*;
import com.oxymel.ofc.charts.series.*;
import com.oxymel.ofc.charts.util.*;
 
 
/**
* This class provides a dial chart management.
* It is an indicator which looks like a dial.
* It indicates a value and all colored zone (ie: all range value)
*/
public class DialChart extends Chart
{
private RangeValueSeriesContainer _rangeValueSeriesContainer;
private double _startValue;
private double _endValue;
private double _arrowValue;
private double _stepValue;
 
//
private int _nbPixelFreeArroundGraphic = 5;
private int _graduationSizePercentage = 102;
private int _arcCenterPercentage = 20;
private int _arrowWidth = 10;
 
public static final int GRADIENT_COLOR_LEFT_TO_RIGHT = 0;
public static final int GRADIENT_COLOR_RIGHT_TO_LEFT = 1;
public static final int GRADIENT_COLORE_NONE = 2;
 
private int _gradientColorMode = GRADIENT_COLORE_NONE;
 
/**
* Constructor
* @param chartWidth Width of vertical bar chart
* @param chartHeight Height of vertical bar chart
* @param rangeValueSeriesContainer data indicatator series
* @param startValue dial start value
* @param endValue dial end value
* @param stepValue dial step value
* @param arrowValue value to indicate
* @throws OFCChartsException
*/
public DialChart(int chartWidth, int chartHeight,
RangeValueSeriesContainer rangeValueSeriesContainer, double startValue, double endValue,
double stepValue, double arrowValue) throws OFCChartsException
{
super(chartWidth, chartHeight);
setRangeValueSeriesContainer(rangeValueSeriesContainer);
 
_startValue = startValue;
_endValue = endValue;
_arrowValue = arrowValue;
_stepValue = stepValue;
}
 
/**
* Sets gradient color mode
* @param gradientColorMode gradient color mode to set
*/
public void setGradientColorMode(int gradientColorMode){_gradientColorMode = gradientColorMode;}
 
/**
* Sets data used to draw chart
* @param rangeValueSeriesContainer All series of range value indicator
*/
public void setRangeValueSeriesContainer(RangeValueSeriesContainer rangeValueSeriesContainer)
{
_rangeValueSeriesContainer = rangeValueSeriesContainer;
setAllSeriesColorFromPalette(rangeValueSeriesContainer);
}
 
protected SeriesContainer getSeriesContainer(){return _rangeValueSeriesContainer;}
 
protected void doDrawChart(Graphics2D graphics2D) throws OFCChartsException
{
int xTopLeftGraphic = getXTopLeftGraphic(graphics2D);
int yTopLeftGraphic = getYTopLeftGraphic(graphics2D);
int graphicWidth = getGraphicWidth(graphics2D);
int graphicHeight = getGraphicHeight(graphics2D);
 
//drawGraphicBackground(xTopLeftGraphic, yTopLeftGraphic,
// graphicWidth, graphicHeight, graphics2D);
 
_legend.drawLegend(getXTopLeftLegend(graphics2D), getYTopLeftLegend(graphics2D),
getSeriesContainer().getAllSeriesOrderByDisplayNumber(), graphics2D);
 
/*bug à voir plus tard
_legend.drawLegend(
getXTopLeftLegend(xTopLeftGraphic, yTopLeftGraphic, graphicWidth, graphicHeight, graphics2D),
getYTopLeftLegend(xTopLeftGraphic, yTopLeftGraphic, graphicWidth, graphicHeight, graphics2D),
getSeriesContainer().getAllSeriesOrderByDisplayNumber(), graphics2D);
*/
 
drawGraphic(xTopLeftGraphic, yTopLeftGraphic, graphicWidth, graphicHeight, graphics2D, false, null);
}
 
protected void doDrawAnimateSVGChart(SVGGraphics2D graphics2D, SVGAnimationContext svgAnimationContext) throws OFCChartsException
{
int xTopLeftGraphic = getXTopLeftGraphic(graphics2D);
int yTopLeftGraphic = getYTopLeftGraphic(graphics2D);
int graphicWidth = getGraphicWidth(graphics2D);
int graphicHeight = getGraphicHeight(graphics2D);
 
_legend.drawLegend(getXTopLeftLegend(graphics2D), getYTopLeftLegend(graphics2D),
getSeriesContainer().getAllSeriesOrderByDisplayNumber(), graphics2D);
 
drawGraphic(xTopLeftGraphic, yTopLeftGraphic, graphicWidth, graphicHeight, graphics2D, true, svgAnimationContext);
}
 
 
private void drawGraphic(int xTopLeftGraphic, int yTopLeftGraphic, int graphicWidth, int graphicHeight,
Graphics2D graphics2D, boolean isAnimate, SVGAnimationContext svgAnimationContext)
{
Vector allValueSeries = _rangeValueSeriesContainer.getAllSeriesOrderByDisplayNumber();
 
int nbFreeToWriteGaduation = Math.max(Graphics2DTools.getNbPixelWidthOfTxt(graphics2D, "" + _endValue),
Graphics2DTools.getNbPixelWidthOfTxt(graphics2D, "" + _startValue));
 
int xTopLeftDialCorner = xTopLeftGraphic + (nbFreeToWriteGaduation/2) + (_nbPixelFreeArroundGraphic/2);
int yTopLeftDialCorner = yTopLeftGraphic + graphicHeight/4 ;
int widthDialCorner = graphicWidth - nbFreeToWriteGaduation - _nbPixelFreeArroundGraphic;
int heightDialCorner = graphicHeight;
 
//draw background
Arc2D arc = new Arc2D.Double((double)xTopLeftDialCorner, (double)yTopLeftDialCorner,
(double)widthDialCorner, (double)heightDialCorner, 350, 200, Arc2D.PIE);
arc.setArcType(Arc2D.OPEN);
graphics2D.setColor(Color.lightGray);
graphics2D.fill(arc);
Stroke initialStroke = graphics2D.getStroke();
graphics2D.setStroke(new BasicStroke(3.0f));
graphics2D.setColor(Color.black);
graphics2D.draw(arc);
 
graphics2D.setColor(Color.lightGray);
GeneralPath socle = new GeneralPath();
socle.moveTo((int)arc.getCenterX(), (int)arc.getCenterY());
socle.lineTo((int)arc.getStartPoint().getX(), (int)arc.getStartPoint().getY());
socle.lineTo((int)arc.getEndPoint().getX(), (int)arc.getEndPoint().getY());
socle.lineTo((int)arc.getCenterX(), (int)arc.getCenterY());
graphics2D.draw(socle);
graphics2D.fill(socle);
graphics2D.setColor(Color.black);
graphics2D.drawLine((int)arc.getStartPoint().getX(), (int)arc.getStartPoint().getY(),
(int)arc.getEndPoint().getX(), (int)arc.getEndPoint().getY());
 
graphics2D.setStroke(initialStroke);
 
//
drawSection(xTopLeftDialCorner, yTopLeftDialCorner, widthDialCorner,
heightDialCorner, graphics2D);
 
//
double intervalValue = Graphics2DTools.getIntervalValue(_startValue, _endValue);
drawGraduation(xTopLeftDialCorner, yTopLeftDialCorner, widthDialCorner,
heightDialCorner, _graduationSizePercentage, intervalValue, _stepValue, graphics2D);
 
//Draw arc contour
Arc2D arc2D = new Arc2D.Double((double)xTopLeftDialCorner, (double)yTopLeftDialCorner,
(double)widthDialCorner, (double)heightDialCorner, 0, 180, Arc2D.PIE);
 
//Draw arc center
graphics2D.setColor(Color.black);
Arc2D arc2DCenter = Graphics2DTools.getArcPercentageToAnother(arc2D, _arcCenterPercentage);
graphics2D.fill(arc2DCenter);
 
//Draw arrow
if(!isAnimate){
drawValue(_arrowValue, arc2DCenter, graphics2D);
drawArrow(_arrowValue, _arrowWidth, arc2D, arc2DCenter, graphics2D);
}else{
drawAnimateArrow(_arrowValue, _arrowWidth, arc2D, arc2DCenter, graphics2D, svgAnimationContext);
}
 
}
 
private void drawGraduation(int xTopLeftDialCorner, int yTopLeftDialCorner, int widthDialCorner,
int heightDialCorner, int graduationSizePercentage, double valueInterval, double step, Graphics2D graphics2D)
{
//System.out.println("step = " + step);
 
double angleAssociateToStep = (step * 180) / valueInterval;
int nbStep = (int)(180/angleAssociateToStep);
Arc2D arc2D = new Arc2D.Double((double)xTopLeftDialCorner, (double)yTopLeftDialCorner,
(double)widthDialCorner, (double)heightDialCorner, 0, 180, Arc2D.PIE);
Arc2D arc2DGraduation = Graphics2DTools.getArcPercentageToAnother(arc2D, graduationSizePercentage);
 
int startAngle = 0;
int arcAngle = (int)angleAssociateToStep;
double currentStep = _endValue;
for(int i= 0; i<nbStep; i++){
//graduation
arc2D.setAngleStart(startAngle);
arc2D.setAngleExtent(arcAngle);
arc2DGraduation.setAngleStart(startAngle);
arc2DGraduation.setAngleExtent(arcAngle);
 
Stroke initialStroke = graphics2D.getStroke();
graphics2D.setStroke(new BasicStroke(3.0f));
graphics2D.setColor(Color.black);
graphics2D.drawLine((int)arc2D.getStartPoint().getX(), (int)arc2D.getStartPoint().getY(),
(int)arc2DGraduation.getStartPoint().getX(), (int)arc2DGraduation.getStartPoint().getY());
graphics2D.drawLine((int)arc2D.getEndPoint().getX(), (int)arc2D.getEndPoint().getY(),
(int)arc2DGraduation.getEndPoint().getX(), (int)arc2DGraduation.getEndPoint().getY());
graphics2D.setStroke(initialStroke);
 
//debut txt graduation
drawGraduationValue(currentStep, startAngle, arc2DGraduation, graphics2D);
currentStep -= step;
//fin txt graduation
 
startAngle += arcAngle;
}
 
//draw first left graduation value
arc2DGraduation.setAngleStart(startAngle);
arc2DGraduation.setAngleExtent(arcAngle);
drawGraduationValue(currentStep, startAngle, arc2DGraduation, graphics2D);
}
 
private void drawGraduationValue(double currentStep, double startAngle, Arc2D arc2DGraduation, Graphics2D graphics2D)
{
String txt = "" + (int)currentStep;
if((startAngle >= 0) && (startAngle < 90)){
graphics2D.drawString(txt, (int)(arc2DGraduation.getStartPoint().getX()) + (Graphics2DTools.getNbPixelWidthOfTxt(graphics2D, txt)/4),
(int)arc2DGraduation.getStartPoint().getY());
}else{
if(startAngle ==90){
int xOfTxt = (int)(arc2DGraduation.getStartPoint().getX());
graphics2D.drawString(txt, Graphics2DTools.getXToAlignTxt(graphics2D, xOfTxt, txt) ,
(int)arc2DGraduation.getStartPoint().getY() - 2);
}else{
graphics2D.drawString(txt, (int)(arc2DGraduation.getStartPoint().getX()) - Graphics2DTools.getNbPixelWidthOfTxt(graphics2D, txt) - 2,
(int)arc2DGraduation.getStartPoint().getY());
}
}
}
 
private void drawSection(int xTopLeftDialCorner, int yTopLeftDialCorner, int widthDialCorner,
int heightDialCorner, Graphics2D graphics2D)
{
Vector allValueSeries = _rangeValueSeriesContainer.getAllSeriesOrderByReverseDisplayNumber();
 
Arc2D arc2D = new Arc2D.Double((double)xTopLeftDialCorner, (double)yTopLeftDialCorner,
(double)widthDialCorner, (double)heightDialCorner, 0, 180, Arc2D.PIE);
 
double dialIntervalValue = Graphics2DTools.getIntervalValue(_startValue, _endValue);
for(int i= 0; i<allValueSeries.size(); i++){
RangeValueSeries rangeValueSeries = (RangeValueSeries)allValueSeries.elementAt(i);
 
double maxOfCurrentRange = rangeValueSeries.getMax();
if(maxOfCurrentRange > _endValue){
maxOfCurrentRange = _endValue;
}
double minOfCurrentRange = rangeValueSeries.getMin();
if(minOfCurrentRange < _startValue){
minOfCurrentRange = _startValue;
}
 
if(rangeValueSeries.isVisible()){
double angleMinInterval = (Graphics2DTools.getValueAsPercentage(
Graphics2DTools.getIntervalValue(_startValue, minOfCurrentRange), dialIntervalValue) * 180f)/100;
double angleMaxInterval = (Graphics2DTools.getValueAsPercentage(
Graphics2DTools.getIntervalValue(_startValue, maxOfCurrentRange), dialIntervalValue) * 180f)/100;
 
double angleExtent = angleMaxInterval - angleMinInterval;
arc2D.setAngleStart(180 - angleMinInterval - angleExtent);
arc2D.setAngleExtent(angleExtent);
 
switch(_gradientColorMode){
case GRADIENT_COLOR_LEFT_TO_RIGHT:
{
Paint paint = graphics2D.getPaint();
GradientPaint gradientPaint;
gradientPaint = new GradientPaint(arc2D.getStartPoint(),
rangeValueSeries.getColor().darker(), arc2D.getEndPoint(), rangeValueSeries.getColor().brighter());
graphics2D.setPaint(gradientPaint);
graphics2D.fill(arc2D);
graphics2D.setPaint(paint);
}
break;
case GRADIENT_COLOR_RIGHT_TO_LEFT:
{
Paint paint = graphics2D.getPaint();
GradientPaint gradientPaint;
gradientPaint = new GradientPaint(arc2D.getStartPoint(),
rangeValueSeries.getColor().brighter(), arc2D.getEndPoint(), rangeValueSeries.getColor().darker());
graphics2D.setPaint(gradientPaint);
graphics2D.fill(arc2D);
graphics2D.setPaint(paint);
}
break;
default:
graphics2D.setColor(rangeValueSeries.getColor());
graphics2D.fill(arc2D);
break;
}
}
}
}
 
private void drawArrow(double arrowValue, int arrowWidth, Arc2D dialArc, Arc2D arcCenter, Graphics2D graphics2D)
{
Arc2D arc2D = Graphics2DTools.getClone(dialArc);
Arc2D arc2DCenter = Graphics2DTools.getClone(arcCenter);
 
if(_startValue > arrowValue){
return;
}
 
//fleche
int startAngle = 180;
double intervalValue = Graphics2DTools.getIntervalValue(_startValue, _endValue);
double arcAngle = (double)((Graphics2DTools.getValueAsPercentage(
Graphics2DTools.getIntervalValue(_startValue, arrowValue), intervalValue) * 180f)/100);
//System.out.println("drawArrow arcAngle = " + arcAngle);
arcAngle = arcAngle * (-1);
 
arc2D.setAngleStart(startAngle);
arc2D.setAngleExtent(arcAngle);
double xTopArrow = arc2D.getEndPoint().getX();
double yTopArrow = arc2D.getEndPoint().getY();
 
arc2DCenter.setAngleStart(startAngle);
arc2DCenter.setAngleExtent(arcAngle + arrowWidth);
double xBottomRightArrow = arc2DCenter.getEndPoint().getX();
double yBottomRightArrow = arc2DCenter.getEndPoint().getY();
 
arc2DCenter.setAngleStart(startAngle);
arc2DCenter.setAngleExtent(arcAngle - arrowWidth);
double xBottomLeftArrow = arc2DCenter.getEndPoint().getX();
double yBottomLeftArrow = arc2DCenter.getEndPoint().getY();
 
GeneralPath arrow = new GeneralPath();
arrow.moveTo((int)xTopArrow, (int)yTopArrow);
arrow.lineTo((int)xBottomLeftArrow, (int)yBottomLeftArrow);
arrow.lineTo((int)xBottomRightArrow, (int)yBottomRightArrow);
arrow.lineTo((int)xTopArrow, (int)yTopArrow);
graphics2D.setColor(Color.black);
graphics2D.fill(arrow);
//graphics2D.setColor(Color.white);
//graphics2D.draw(arrow);
//graphics2D.drawLine((int)xTopArrow, (int)yTopArrow, (int)arc2D.getCenterX(), (int)arc2D.getCenterY());
}
 
private void drawValue(double arrowValue, Arc2D arc2DCenter, Graphics2D graphics2D)
{
graphics2D.setColor(Color.white);
String value = ""+ (int)arrowValue;
Font font = graphics2D.getFont();
graphics2D.setFont(Graphics2DTools.getFont(graphics2D, 12));
graphics2D.drawString(value,
Graphics2DTools.getXToAlignTxt(graphics2D,
(int)(arc2DCenter.getCenterX()), value),
Graphics2DTools.getYToAlignTxt(graphics2D,
(int)(arc2DCenter.getCenterY() - (arc2DCenter.getHeight()/4)), value));
graphics2D.setFont(font);
}
 
private void drawAnimateArrow(double arrowValue, int arrowWidth, Arc2D dialArc, Arc2D arcCenter, Graphics2D graphics2D,
SVGAnimationContext svgAnimationContext)
{
double intervalValue = Graphics2DTools.getIntervalValue(_startValue, arrowValue);
new SVGGraphics2DAnimateMgr().generateAnimation((SVGGraphics2D)graphics2D, svgAnimationContext,
new DialAnimation(arrowWidth, dialArc, arcCenter,
new ValueCursor(_startValue,
intervalValue/svgAnimationContext.getNbImage(),
arrowValue)));
}
 
private class DialAnimation implements AnimationInterface
{
//
private int _arrowWidth;
private Arc2D _dialArc;
private Arc2D _arcCenter;
 
//
private ValueCursor _valueCursor;
 
public DialAnimation(int arrowWidth, Arc2D dialArc, Arc2D arcCenter, ValueCursor valueCursor)
{
//
_arrowWidth = arrowWidth;
_dialArc = dialArc;
_arcCenter = arcCenter;
 
//
_valueCursor = valueCursor;
}
 
public boolean hasNextImage()
{
return _valueCursor.hasMoreValue();
}
 
public void drawImage(SVGGraphics2D graphics2D)
{
double currentValue = _valueCursor.nextValue();
drawArrow(currentValue, _arrowWidth, _dialArc, _arcCenter, graphics2D);
drawValue((int)currentValue, _arcCenter, graphics2D);
}
 
}
 
/*
public static void main(String[] argv) throws Exception
{
}
*/
 
}
/trunk/project/ofccharts/src/com/oxymel/ofc/charts/CombinedVerticalBarChartXYY.java
New file
0,0 → 1,356
package com.oxymel.ofc.charts;
/*
* Copyright (c) 2006 Oxymel SA.
* All rights reserved.
*
* This software is the confidential and proprietary information of Oxymel SA
* ("Confidential Information"). You shall not disclose such Confidential
* Information and shall use it only in accordance with the terms of the license
* agreement you entered into with Oxymel SA.
*/
 
//java
import java.util.*;
 
import java.awt.*;
 
import com.oxymel.ofc.charts.data.*;
//ofc
import com.oxymel.ofc.charts.exception.*;
import com.oxymel.ofc.charts.series.*;
 
 
/**
* CombinedVerticalBarChartXYY allows to manage combined vertical bar charts
* having the same X axe and two distinct Y axes, each of them having its own graduation.
*/
public class CombinedVerticalBarChartXYY extends ChartWithAxisXYY
{
private HorizontalCategoryAxis _axisX;
private VerticalNumberAxis _axisY;
private VerticalNumberAxisRight _axisYRight;
private Vector _allRenderer = new Vector();
private Vector _allHorizontalLineInfo = new Vector();
 
/**
* Constructor
* @param chartWidth Width of vertical bar chart
* @param chartHeight Height of vertical bar chart
* @param axisX Horizontal axis dedicated to the presentation of bar charts
* @param axisY Vertical graduated axis
* @param axisYRight Second Vertical graduated axis
*/
public CombinedVerticalBarChartXYY(int chartWidth, int chartHeight,
HorizontalCategoryAxis axisX, VerticalNumberAxis axisY, VerticalNumberAxisRight axisYRight)
{
super(chartWidth, chartHeight);
_axisX = axisX;
_axisX.setArrowLength(0);
_axisY = axisY;
_axisYRight = axisYRight;
//setLegendDisplayMode(Legend.LEGEND_DISPLAY_MODE_NONE);
/*
ColorPalette colorPalette = new ColorPalette();
colorPalette.setColor(1, 255, 0, 0);
colorPalette.setColor(2, 255, 100, 100);
colorPalette.setColor(3, 0, 0, 255);
colorPalette.setColor(4, 100, 100, 255);
setColorPalette(colorPalette);
*/
}
 
/**
* Sets the legend display mode. The legend may look like a table.
* @param legendDisplayMode The legend display mode to set.
* @see Legend
*/
public void setLegendDisplayMode(int legendDisplayMode)
{
if((_legend.getLegendDisplayMode() == Legend.LEGEND_DISPLAY_MODE_TABLE) &&
(legendDisplayMode != Legend.LEGEND_DISPLAY_MODE_TABLE)){
_legend = new Legend();
}
 
if(legendDisplayMode == Legend.LEGEND_DISPLAY_MODE_TABLE){
_legend = new LegendTable(getCategoryValueSeriesContainer());
return;
}
super.setLegendDisplayMode(legendDisplayMode);
}
 
 
/**
* Add a vertical bar chart renderer
* @param verticalBarChartRenderer A vertical bar chart renderer
*/
public void addVerticalBarChartRenderer(VerticalBarChartRenderer verticalBarChartRenderer)
{
verticalBarChartRenderer.set3dEffectValue(get3dEffectValue());
int nbSeries = getNbSeries();
_allRenderer.addElement(verticalBarChartRenderer);
//setAllSeriesColorFromPalette(nbSeries+1, verticalBarChartRenderer.getCategoryValueSeriesContainer());
setAllSeriesColorFromPalette(nbSeries, verticalBarChartRenderer.getCategoryValueSeriesContainer());
 
//rapide integration en force (sale) a changer
if(_legend instanceof LegendTable){
_legend = new LegendTable(getCategoryValueSeriesContainer());
}
//fin rapide integration
}
 
/**
* Adds an horizontal line info to the graphic
* @param horizontalLineInfo An horizontal line info
*/
public void addHorizontalLineInfo(HorizontalLineInfo horizontalLineInfo)
{
horizontalLineInfo.setVerticalNumberAxis(_axisY);
_allHorizontalLineInfo.addElement(horizontalLineInfo);
}
 
protected int getNbSeries()
{
int nbSeries = 0;
Vector allRenderer = new Vector();
Enumeration enumAllRenderer = _allRenderer.elements();
while(enumAllRenderer.hasMoreElements()){
VerticalBarChartRenderer renderer =
(VerticalBarChartRenderer)enumAllRenderer.nextElement();
CategoryValueSeriesContainer categoryValueSeriesContainer =
renderer.getCategoryValueSeriesContainer();
nbSeries += categoryValueSeriesContainer.getNbSeries();
}
return nbSeries;
}
 
 
protected SeriesContainer getSeriesContainer()
{
return getCategoryValueSeriesContainer();
}
 
private CategoryValueSeriesContainer getCategoryValueSeriesContainer()
{
/*
Enumeration enumAllRenderer = _allRenderer.elements();
if(enumAllRenderer.hasMoreElements()){
VerticalBarChartRenderer renderer =
(VerticalBarChartRenderer)enumAllRenderer.nextElement();
CategoryValueSeriesContainer categoryValueSeriesContainer = renderer.getCategoryValueSeriesContainer();
//_axisX.setAllCategoriesOrderByDisplayNumber(categoryValueSeriesContainer.getAllCategoriesOrderByDisplayNumber());
return categoryValueSeriesContainer;
}else{
throw new OFCChartsRuntimeException("No renderer add");
}
*/
 
CategoryValueSeriesContainer allSeries = new CategoryValueSeriesContainer();
Enumeration enumAllRenderer = _allRenderer.elements();
while(enumAllRenderer.hasMoreElements()){
VerticalBarChartRenderer renderer =
(VerticalBarChartRenderer)enumAllRenderer.nextElement();
CategoryValueSeriesContainer categoryValueSeriesContainer = renderer.getCategoryValueSeriesContainer();
Enumeration enumAllSeries = categoryValueSeriesContainer.getEnumAllSeriesOrderByDisplayNumber();
while(enumAllSeries.hasMoreElements()){
allSeries.addCategoryValueSeries((CategoryValueSeries)enumAllSeries.nextElement());
}
Enumeration enumAllCategories = categoryValueSeriesContainer.getAllCategoriesOrderByDisplayNumber().elements();
while(enumAllCategories.hasMoreElements()){
allSeries.addCategory((Category)enumAllCategories.nextElement());
}
}
return allSeries;
 
}
 
protected Axis getAxisX(){return _axisX;}
protected Axis getAxisY(){return _axisY;}
protected Axis getAxisYRight(){return _axisYRight;}
 
protected void setAxisParameters() throws OFCChartsException
{
_axisY.setMaxValue(getMaxValue(getEnumAllVerticalBarChartRendererOnAxisYLeft()));
_axisY.setMinValue(getMinValue(getEnumAllVerticalBarChartRendererOnAxisYLeft()));
 
_axisYRight.setMaxValue(getMaxValue(getEnumAllVerticalBarChartRendererOnAxisYRight()));
_axisYRight.setMinValue(getMinValue(getEnumAllVerticalBarChartRendererOnAxisYRight()));
 
Enumeration enumAllRenderer = _allRenderer.elements();
if(enumAllRenderer.hasMoreElements()){
VerticalBarChartRenderer renderer =
(VerticalBarChartRenderer)enumAllRenderer.nextElement();
CategoryValueSeriesContainer categoryValueSeriesContainer = renderer.getCategoryValueSeriesContainer();
_axisX.setAllCategoriesOrderByDisplayNumber(categoryValueSeriesContainer.getAllCategoriesOrderByDisplayNumber());
}else{
throw new OFCChartsException("No renderer add");
}
 
/* fait au moment du draw graphic. a supprimer si ok
enumAllRenderer = _allRenderer.elements();
while(enumAllRenderer.hasMoreElements()){
VerticalBarChartRenderer renderer =
(VerticalBarChartRenderer)enumAllRenderer.nextElement();
renderer.setNbGapOnX(_axisX.getNbGap());
if(renderer.isBasedOnAxisRight()){
renderer.setNbGapOnY(_axisYRight.getNbGap());
renderer.setGapValueOnY(_axisYRight.getGapValue());
}else{
renderer.setNbGapOnY(_axisY.getNbGap());
renderer.setGapValueOnY(_axisY.getGapValue());
}
}
*/
 
//setColorOnAxis(getEnumAllVerticalBarChartRendererOnAxisYRight(), _axisYRight);
//setColorOnAxis(getEnumAllVerticalBarChartRendererOnAxisYLeft(), _axisY);
}
 
/*
private void setColorOnAxis(Enumeration enumRenderOnAxis, Axis axis)
{
if(enumRenderOnAxis.hasMoreElements()){
VerticalBarChartRenderer renderer =
(VerticalBarChartRenderer)enumRenderOnAxis.nextElement();
CategoryValueSeriesContainer categoryValueSeriesContainer = renderer.getCategoryValueSeriesContainer();
Enumeration enumAllSeries = categoryValueSeriesContainer.getEnumAllSeriesOrderByDisplayNumber();
if(enumAllSeries.hasMoreElements()){
Series series = (Series)enumAllSeries.nextElement();
axis.setAxisColor(series.getColor());
axis.setGapIndicatorColor(series.getColor());
axis.setValueWriteColor(series.getColor());
}
}
}
*/
 
protected void drawGraphic(int xTopLeftGraphic, int yTopLeftGraphic, int graphicWidth, int graphicHeight,
int xOrigine, int yOrigine, Graphics2D graphics2D)
{
//rapide integration en force a changer
if(_legend instanceof LegendTable){
((LegendTable)_legend).setNbPixelColumnWidth(_axisX.getSizeOfGap());
((LegendTable)_legend).setXOrigine(xOrigine);
((LegendTable)_legend).setYOrigine(yOrigine);
}
//fin rapide integration
 
int nbGapOnX = _axisX.getNbGap();
int nbGapOnY = _axisY.getNbGap();
int gapValueOnY = _axisY.getGapValue();
 
int nbGapOnYRight = _axisYRight.getNbGap();
int gapValueOnYRight = _axisYRight.getGapValue();
 
Enumeration enumAllRenderer = _allRenderer.elements();
while(enumAllRenderer.hasMoreElements()){
VerticalBarChartRenderer renderer =
(VerticalBarChartRenderer)enumAllRenderer.nextElement();
 
renderer.setNbGapOnX(nbGapOnX);
if(renderer.isBasedOnAxisRight()){
renderer.setNbGapOnY(nbGapOnYRight);
renderer.setGapValueOnY(gapValueOnYRight);
}else{
renderer.setNbGapOnY(nbGapOnY);
renderer.setGapValueOnY(gapValueOnY);
}
 
renderer.drawGraphic(xTopLeftGraphic, yTopLeftGraphic, graphicWidth, graphicHeight,
xOrigine, yOrigine, graphics2D);
}
 
Enumeration enumAllHorizontalLineInfo = _allHorizontalLineInfo.elements();
while(enumAllHorizontalLineInfo.hasMoreElements()){
HorizontalLineInfo horizontalLineInfo = (HorizontalLineInfo)enumAllHorizontalLineInfo.nextElement();
horizontalLineInfo.draw(graphicWidth, graphicHeight, xTopLeftGraphic, yTopLeftGraphic,
xOrigine, yOrigine, graphics2D);
}
}
 
private double getMinValue(Enumeration enumAllVerticalBarChartRenderer) throws OFCChartsException
{
double minValue;
if(enumAllVerticalBarChartRenderer.hasMoreElements()){
VerticalBarChartRenderer verticalBarChartRenderer =
(VerticalBarChartRenderer)enumAllVerticalBarChartRenderer.nextElement();
/*
CategoryValueSeriesContainer categoryValueSeriesContainer =
verticalBarChartRenderer.getCategoryValueSeriesContainer();
minValue = categoryValueSeriesContainer.getMinValueOfAllSeries();
*/
minValue = verticalBarChartRenderer.getMinValueSetOnAxis();
}else{
throw new OFCChartsException("No renderer add");
}
while(enumAllVerticalBarChartRenderer.hasMoreElements()){
VerticalBarChartRenderer verticalBarChartRenderer =
(VerticalBarChartRenderer)enumAllVerticalBarChartRenderer.nextElement();
/*
CategoryValueSeriesContainer categoryValueSeriesContainer =
verticalBarChartRenderer.getCategoryValueSeriesContainer();
double minValueToCompare = categoryValueSeriesContainer.getMinValueOfAllSeries();
*/
minValue = Math.max(minValue, verticalBarChartRenderer.getMinValueSetOnAxis());
}
return minValue;
}
 
private double getMaxValue(Enumeration enumAllVerticalBarChartRenderer) throws OFCChartsException
{
double maxValue;
if(enumAllVerticalBarChartRenderer.hasMoreElements()){
VerticalBarChartRenderer verticalBarChartRenderer =
(VerticalBarChartRenderer)enumAllVerticalBarChartRenderer.nextElement();
/*
CategoryValueSeriesContainer categoryValueSeriesContainer =
verticalBarChartRenderer.getCategoryValueSeriesContainer();
maxValue = categoryValueSeriesContainer.getMaxValueOfAllSeries();
*/
maxValue = verticalBarChartRenderer.getMaxValueSetOnAxis();
}else{
throw new OFCChartsException("No renderer add");
}
while(enumAllVerticalBarChartRenderer.hasMoreElements()){
VerticalBarChartRenderer verticalBarChartRenderer =
(VerticalBarChartRenderer)enumAllVerticalBarChartRenderer.nextElement();
/*
CategoryValueSeriesContainer categoryValueSeriesContainer =
verticalBarChartRenderer.getCategoryValueSeriesContainer();
double maxValueToCompare = categoryValueSeriesContainer.getMaxValueOfAllSeries();
*/
maxValue = Math.max(maxValue, verticalBarChartRenderer.getMaxValueSetOnAxis());
}
return maxValue;
}
 
 
private Enumeration getEnumAllVerticalBarChartRendererOnAxisYLeft()
{
Vector allRenderer = new Vector();
Enumeration enumAllRenderer = _allRenderer.elements();
while(enumAllRenderer.hasMoreElements()){
VerticalBarChartRenderer renderer =
(VerticalBarChartRenderer)enumAllRenderer.nextElement();
if(!renderer.isBasedOnAxisRight()){
allRenderer.addElement(renderer);
}
}
return allRenderer.elements();
}
 
private Enumeration getEnumAllVerticalBarChartRendererOnAxisYRight()
{
Vector allRenderer = new Vector();
Enumeration enumAllRenderer = _allRenderer.elements();
while(enumAllRenderer.hasMoreElements()){
VerticalBarChartRenderer renderer =
(VerticalBarChartRenderer)enumAllRenderer.nextElement();
if(renderer.isBasedOnAxisRight()){
allRenderer.addElement(renderer);
}
}
return allRenderer.elements();
}
 
 
}
/trunk/project/ofccharts/src/com/oxymel/ofc/charts/Legend.java
New file
0,0 → 1,722
package com.oxymel.ofc.charts;
/*
* Copyright (c) 2006 Oxymel SA.
* All rights reserved.
*
* This software is the confidential and proprietary information of Oxymel SA
* ("Confidential Information"). You shall not disclose such Confidential
* Information and shall use it only in accordance with the terms of the license
* agreement you entered into with Oxymel SA.
*/
 
//java
import java.awt.Graphics2D;
import java.awt.Font;
import java.awt.Color;
 
import java.util.Enumeration;
import java.util.Vector;
 
//ofc
import com.oxymel.ofc.charts.series.Series;
import com.oxymel.ofc.charts.util.Graphics2DTools;
import com.oxymel.ofc.charts.exception.OFCChartsRuntimeException;
import java.awt.Stroke;
import java.awt.BasicStroke;
/**
* The legend class contains an enumeration defining the different ways a
* legend can be placed on the graphic.
*/
public class Legend
{
protected int _sizeFontOnX = 9; //if == 0 then current size
 
/**
* The legend is not written
*/
public static final int LEGEND_DISPLAY_MODE_NONE = 0;
 
/**
* The legend is located on the right of the graphic
*/
public static final int LEGEND_DISPLAY_MODE_RIGHT = 1;
/**
* @deprecated replaced by LEGEND_DISPLAY_MODE_RIGHT
*/
public static final int LEGEND_DISPLAY_MODE_LEFT = 1;
/**
* The legend is located on the bottom of the graphic
*/
public static final int LEGEND_DISPLAY_MODE_BOTTOM = 2;
 
/**
* The legend is located on the top of the graphic
*/
public static final int LEGEND_DISPLAY_MODE_TOP = 3;
 
/**
* The legend is organized as a table.
* Usage restricted to bar chart graphics
*/
public static final int LEGEND_DISPLAY_MODE_TABLE = 4;
 
protected int _nbPixelHeightOfLegendIndicator = 9;
protected int _nbPixelWidthOfLegendIndicator = 20;
protected final int _nbPixelBetweenEachLegendLine = 0;
private final int _nbPixelBetweenEachLegend = 15;
protected final int _nbPixelBetweenTxtLegendAndColorAssociate = 3;
protected final int _nbPixelFreeArroundLegendForPresentation = 5;
 
protected Color _legendBackgroundColor = Color.white;
protected Color _legendWriteTxtColor = Color.black;
protected Color _legendCadreColor = Color.black;
 
/**
* No alignement constraint defined for the element belonging to the legend
*/
public static final int LEGEND_ALIGN_MODE_NONE = 0;
 
/**
* The elements composing the legend are organized in columns.
* Column size is not strict to save space.
*/
public static final int LEGEND_ALIGN_MODE_COLUMN = 1;
 
/**
* The elements composing the legend are organized in columns.
* Organization in columns must be strictly respected;
* Such an organization may consume more space
*/
public static final int LEGEND_ALIGN_MODE_COLUMN_STRICT = 2;
 
private int _legendAlignMode = LEGEND_ALIGN_MODE_COLUMN_STRICT;
 
private boolean _isDisplayAsBar = true;
 
protected int _legendDisplayMode = LEGEND_DISPLAY_MODE_RIGHT;
 
private int _legendWidth = 0;
 
private boolean _isLegendInTable = false;
 
 
public void setBackgroundColor(Color color){_legendBackgroundColor = color;}
public void setTextColor(Color color){_legendWriteTxtColor = color;}
public void setCadreColor(Color color){_legendCadreColor = color;}
 
public Legend()
{
setBackgroundColor(Color.white);
setTextColor(Color.black);
setTextColor(Color.black);
setCadreColor(Color.black);
}
 
public void setNbPixelHeightOfLegendIndicator(int nbPixelHeightOfLegendIndicator)
{
_nbPixelHeightOfLegendIndicator = nbPixelHeightOfLegendIndicator;
}
 
public void setIsLegendInTable(boolean isLegendInTable){_isLegendInTable = isLegendInTable;}
 
public void setLegendWidth(int legendWidth){_legendWidth = legendWidth;}
 
public void drawLegend(int xTopLeftLegend, int yTopLeftLegend, Vector allSeries, Graphics2D graphics2D)
{
switch(_legendDisplayMode){
case LEGEND_DISPLAY_MODE_RIGHT:
drawLegendAtLeft(graphics2D, xTopLeftLegend, yTopLeftLegend, allSeries);
break;
case LEGEND_DISPLAY_MODE_BOTTOM:
drawLegendAtBottom(graphics2D, xTopLeftLegend, yTopLeftLegend, allSeries);
break;
case LEGEND_DISPLAY_MODE_TOP:
drawLegendAtBottom(graphics2D, xTopLeftLegend, yTopLeftLegend, allSeries);
break;
}
}
 
public void setFontSize(int size)
{
_sizeFontOnX = size;
}
 
public int getLegendDisplayMode(){return _legendDisplayMode;}
 
public void setDisplayAsBar(boolean isDisplayAsBar){_isDisplayAsBar = isDisplayAsBar;}
 
int getSizeWidthOfLegendAtBottom(Graphics2D graphics2D, Enumeration enumAllSeries)
{
if((_legendDisplayMode != LEGEND_DISPLAY_MODE_BOTTOM) &&(_legendDisplayMode != LEGEND_DISPLAY_MODE_TOP)){
return 0;
}
 
Font font = graphics2D.getFont();
graphics2D.setFont(getFontOnX(graphics2D));
 
int nbSeries = 0;
int nbPixelWithAllLegendLabel = 0;
while(enumAllSeries.hasMoreElements()){
Series series = (Series)enumAllSeries.nextElement();
nbPixelWithAllLegendLabel += Graphics2DTools.getNbPixelWidthOfTxt(graphics2D, series.getLegendLabel()+" ");
nbSeries++;
}
 
graphics2D.setFont(font);
 
if(nbSeries == 0){
return 0;
}
 
int sizeWidthOfLegendAtBottom = nbPixelWithAllLegendLabel +
(2*(_nbPixelWidthOfLegendIndicator + _nbPixelBetweenTxtLegendAndColorAssociate) * nbSeries) +
(_nbPixelBetweenEachLegend * nbSeries)+
(2 * _nbPixelFreeArroundLegendForPresentation);
if(sizeWidthOfLegendAtBottom > _legendWidth){
sizeWidthOfLegendAtBottom = _legendWidth;
}
return sizeWidthOfLegendAtBottom;
}
 
/*
int getSizeHeightOfLegendAtBottom(Graphics2D graphics2D, Enumeration enumAllSeries)
{
if((_legendDisplayMode != LEGEND_DISPLAY_MODE_BOTTOM) && (_legendDisplayMode != LEGEND_DISPLAY_MODE_TOP)){
return 0;
}
 
Font font = graphics2D.getFont();
graphics2D.setFont(getFontOnX(graphics2D));
 
int maxHeightLegendTxt = 0;
 
while(enumAllSeries.hasMoreElements()){
Series series = (Series)enumAllSeries.nextElement();
int currentSize = Graphics2DTools.getNbPixelHeightOfTxt(graphics2D, series.getLegendLabel());
if ( currentSize > maxHeightLegendTxt){
maxHeightLegendTxt = currentSize;
}
}
 
graphics2D.setFont(font);
 
if(maxHeightLegendTxt < _nbPixelHeightOfLegendIndicator){
maxHeightLegendTxt = _nbPixelHeightOfLegendIndicator;
}
 
return maxHeightLegendTxt + (2 * _nbPixelFreeArroundLegendForPresentation);
}
*/
 
int getSizeWidthOfLegendAtLeft(Graphics2D graphics2D, Enumeration enumAllSeries)
{
if(_legendDisplayMode != LEGEND_DISPLAY_MODE_RIGHT){
return 0;
}
 
Font font = graphics2D.getFont();
graphics2D.setFont(getFontOnX(graphics2D));
 
int sizeMaxWithOfLegendTxt = 0;
while(enumAllSeries.hasMoreElements()){
Series series = (Series)enumAllSeries.nextElement();
int currentSize = Graphics2DTools.getNbPixelWidthOfTxt(graphics2D,
series.getLegendLabel()+" ");
if (currentSize > sizeMaxWithOfLegendTxt) {
sizeMaxWithOfLegendTxt = currentSize;
}
}
graphics2D.setFont(font);
 
return sizeMaxWithOfLegendTxt +
_nbPixelWidthOfLegendIndicator +
_nbPixelBetweenTxtLegendAndColorAssociate +
4 * _nbPixelFreeArroundLegendForPresentation;
}
 
void setLegendDisplayMode(int legendDisplayMode) {
_legendDisplayMode = legendDisplayMode;
}
 
void setLegendAlignMode(int legendAlignMode) {
_legendAlignMode = legendAlignMode;
}
 
int getSizeHeightOfLegendAtLeft(Graphics2D graphics2D, Enumeration enumAllSeries)
{
Font font = graphics2D.getFont();
graphics2D.setFont(getFontOnX(graphics2D));
 
int size = 0;
while(enumAllSeries.hasMoreElements()){
Series series = (Series)enumAllSeries.nextElement();
int currentSize = Graphics2DTools.getNbPixelHeightOfTxt(graphics2D, series.getLegendLabel());
if(currentSize > _nbPixelHeightOfLegendIndicator){
size += currentSize;
}
else{
size += _nbPixelHeightOfLegendIndicator;
}
if(enumAllSeries.hasMoreElements()){
size += _nbPixelBetweenEachLegendLine;
}
}
size += 2 * _nbPixelFreeArroundLegendForPresentation;
graphics2D.setFont(font);
return size;
}
 
 
private void drawLegendAtLeft(Graphics2D graphics2D, int xTopLeftLegend, int yTopLeftLegend, Vector allSeries)
{
if(_legendDisplayMode != LEGEND_DISPLAY_MODE_RIGHT){
return;
}
 
Font font = graphics2D.getFont();
Font fontOnX = getFontOnX(graphics2D);
 
graphics2D.setFont(fontOnX);
int sizeWidthOfLegend = getSizeWidthOfLegendAtLeft(graphics2D, allSeries.elements());
int sizeHeightOfLegend = getSizeHeightOfLegendAtLeft(graphics2D, allSeries.elements());
graphics2D.setColor(_legendBackgroundColor);
graphics2D.fillRect(xTopLeftLegend, yTopLeftLegend, sizeWidthOfLegend, sizeHeightOfLegend);
graphics2D.setColor(_legendCadreColor);
graphics2D.drawRect(xTopLeftLegend, yTopLeftLegend, sizeWidthOfLegend, sizeHeightOfLegend);
 
//
int yOfGap = yTopLeftLegend + _nbPixelFreeArroundLegendForPresentation;
int xCurrent = xTopLeftLegend + _nbPixelFreeArroundLegendForPresentation;
Enumeration enumAllSeries = allSeries.elements();
Stroke initialStroke = graphics2D.getStroke();
graphics2D.setStroke(new BasicStroke(2.0f));
while(enumAllSeries.hasMoreElements()){
Series series = (Series)enumAllSeries.nextElement();
graphics2D.setColor(series.getColor());
 
if(_isDisplayAsBar){
graphics2D.drawRect(xCurrent, yOfGap, _nbPixelWidthOfLegendIndicator, _nbPixelHeightOfLegendIndicator);
graphics2D.fillRect(xCurrent, yOfGap, _nbPixelWidthOfLegendIndicator, _nbPixelHeightOfLegendIndicator);
}else{
graphics2D.drawLine(xCurrent, yOfGap + (_nbPixelHeightOfLegendIndicator/2),
xCurrent + _nbPixelWidthOfLegendIndicator, yOfGap + (_nbPixelHeightOfLegendIndicator/2));
series.drawIndicator(xCurrent + (_nbPixelWidthOfLegendIndicator/2),
yOfGap + (_nbPixelHeightOfLegendIndicator/2), graphics2D);
}
 
 
graphics2D.setColor(_legendWriteTxtColor);
graphics2D.drawString(series.getLegendLabel(), xCurrent + _nbPixelWidthOfLegendIndicator +
_nbPixelBetweenTxtLegendAndColorAssociate,
Graphics2DTools.getYToAlignTxt(graphics2D, yOfGap + (_nbPixelHeightOfLegendIndicator/2), series.getLegendLabel()));
 
if(_isLegendInTable){
graphics2D.drawRect(xCurrent - _nbPixelFreeArroundLegendForPresentation, yOfGap, sizeWidthOfLegend, _nbPixelHeightOfLegendIndicator);
}
 
int gap = Graphics2DTools.getNbPixelHeightOfTxt(graphics2D, series.getLegendLabel());
if(gap > _nbPixelHeightOfLegendIndicator){
yOfGap += gap;
}
else{
yOfGap += _nbPixelHeightOfLegendIndicator;
}
if(enumAllSeries.hasMoreElements()){
yOfGap += _nbPixelBetweenEachLegendLine;
}
}
graphics2D.setFont(font);
graphics2D.setStroke(initialStroke);
}
 
 
int getSizeHeightOfLegendAtBottom(Graphics2D graphics2D, Vector allSeries)
{
Enumeration enumAllSeries = allSeries.elements();
if((_legendDisplayMode != LEGEND_DISPLAY_MODE_BOTTOM) && (_legendDisplayMode != LEGEND_DISPLAY_MODE_TOP)){
return 0;
}
 
Font font = graphics2D.getFont();
Font fontOnX = getFontOnX(graphics2D);
 
graphics2D.setFont(fontOnX);
 
int maxHeightLegendTxt = 0;
 
//
int[] allColumnPosition = null;
int nbColumn = 0;
int currentColumn = 0;
switch(_legendAlignMode){
case LEGEND_ALIGN_MODE_NONE :
break;
case LEGEND_ALIGN_MODE_COLUMN :
allColumnPosition = new int[allSeries.size() + 1];
break;
case LEGEND_ALIGN_MODE_COLUMN_STRICT :
allColumnPosition = new int[allSeries.size() + 1];
nbColumn = getAllColumnPositionForLegendAlignColumnStrict(0, 0, allSeries, allColumnPosition,graphics2D );
break;
default:
throw new OFCChartsRuntimeException("Invalid align legend mode");
}
 
//
int yCurrent = 0;
int xCurrent = 0;
int colorNum = 0;
 
switch(_legendAlignMode){
case LEGEND_ALIGN_MODE_NONE :
break;
case LEGEND_ALIGN_MODE_COLUMN :
allColumnPosition[nbColumn] = xCurrent;
nbColumn ++;
break;
case LEGEND_ALIGN_MODE_COLUMN_STRICT :
break;
default:
throw new OFCChartsRuntimeException("Invalid align legend mode");
}
 
 
while(enumAllSeries.hasMoreElements()){
Series series = (Series)enumAllSeries.nextElement();
 
if(_legendWidth < xCurrent + _nbPixelWidthOfLegendIndicator +
_nbPixelBetweenTxtLegendAndColorAssociate + Graphics2DTools.getNbPixelWidthOfTxt(graphics2D, series.getLegendLabel())){
if(xCurrent != 0){ //pour eviter de boucler sans fin
 
switch(_legendAlignMode){
case LEGEND_ALIGN_MODE_NONE:
xCurrent = 0;
break;
case LEGEND_ALIGN_MODE_COLUMN:
case LEGEND_ALIGN_MODE_COLUMN_STRICT:
xCurrent = allColumnPosition[0];
currentColumn = 0;
break;
default:
throw new OFCChartsRuntimeException("Invalid align legend mode");
}
 
 
//yCurrent += maxHeightLegendTxt + _nbPixelBetweenEachLegend;
yCurrent += maxHeightLegendTxt;
maxHeightLegendTxt = 0;
}
}
 
int currentSize = Graphics2DTools.getNbPixelHeightOfTxt(graphics2D, series.getLegendLabel());
if ( currentSize > maxHeightLegendTxt){
maxHeightLegendTxt = currentSize;
}
 
xCurrent += _nbPixelWidthOfLegendIndicator + _nbPixelBetweenTxtLegendAndColorAssociate;
 
xCurrent += Graphics2DTools.getNbPixelWidthOfTxt(graphics2D, series.getLegendLabel()) + _nbPixelBetweenEachLegend;
 
switch(_legendAlignMode){
case LEGEND_ALIGN_MODE_NONE:
break;
case LEGEND_ALIGN_MODE_COLUMN:
if(currentColumn + 1 >= nbColumn){
allColumnPosition[nbColumn] = xCurrent;
nbColumn ++;
}
currentColumn ++;
if(xCurrent <= allColumnPosition[currentColumn]){
xCurrent = allColumnPosition[currentColumn];
}else{
xCurrent = allColumnPosition[0];
currentColumn = 0;
yCurrent += maxHeightLegendTxt;
maxHeightLegendTxt = 0;
}
break;
case LEGEND_ALIGN_MODE_COLUMN_STRICT:
currentColumn ++;
if(currentColumn >= nbColumn){
xCurrent = allColumnPosition[0];
currentColumn = 0;
yCurrent += maxHeightLegendTxt;
maxHeightLegendTxt = 0;
}else{
xCurrent = allColumnPosition[currentColumn];
}
break;
default:
throw new OFCChartsRuntimeException("Invalid align legend mode");
}
}
graphics2D.setFont(font);
return yCurrent + maxHeightLegendTxt + (2 * _nbPixelFreeArroundLegendForPresentation);
}
 
 
private int getAllColumnPositionForLegendAlignColumnStrict(int xTopLeftLegend, int yTopLeftLegend,
Vector allSeries, int [] allColumnPosition, Graphics2D graphics2D)
{
int nbColumn = allSeries.size();
 
int xLeftLegend = xTopLeftLegend + _nbPixelFreeArroundLegendForPresentation;
int xRightLegend = xLeftLegend + _legendWidth;
int xCurrent = xLeftLegend;
 
// int yTopLegend = yTopLeftLegend + _nbPixelFreeArroundLegendForPresentation;
// int yCurrent = yTopLegend;
 
allColumnPosition[0] = xCurrent;
 
for(int i=0; i<allSeries.size(); i++){
boolean isNbColumnFound = true;
boolean isColumnFirstLineFound = false;
xCurrent = xLeftLegend;
int currentColumn = 0;
int nbLine = 0;
 
for(int j=0; j<allSeries.size(); j++){
Series series = (Series)allSeries.elementAt(j);
 
/* old
int xRightCurrentLegend = xCurrent + _nbPixelWidthOfLegendIndicator +
_nbPixelBetweenTxtLegendAndColorAssociate + Graphics2DTools.getNbPixelWidthOfTxt(graphics2D, series.getLegendLabel());
*/
int xRightCurrentLegend = xCurrent + _nbPixelWidthOfLegendIndicator +
4*_nbPixelBetweenTxtLegendAndColorAssociate + Graphics2DTools.getNbPixelWidthOfTxt(graphics2D, series.getLegendLabel()+" ");
 
if(xRightLegend < xRightCurrentLegend){
nbColumn --;
isNbColumnFound = false;
break;
}
 
//current == successor:
currentColumn++;
int xLeftSuccessorLegend = xRightCurrentLegend + _nbPixelBetweenEachLegend;
 
if(!isColumnFirstLineFound){
allColumnPosition[currentColumn] = xLeftSuccessorLegend;
}
 
if(currentColumn >= nbColumn){
currentColumn = 0;
isColumnFirstLineFound = true;
nbLine ++;
}
 
if(isColumnFirstLineFound){
xCurrent = allColumnPosition[currentColumn];
if((xCurrent < xLeftSuccessorLegend) && (currentColumn != 0)){
if(isAllColumnPredecessorLineCanBeMove(xLeftSuccessorLegend, currentColumn,
nbLine, allSeries, nbColumn, xRightLegend, allColumnPosition, graphics2D)){
allColumnPosition[currentColumn] = xLeftSuccessorLegend;
int decalage = xLeftSuccessorLegend - xCurrent;
for(int k=currentColumn+1; k<nbColumn; k++){
allColumnPosition[k] += decalage;
}
xCurrent = xLeftSuccessorLegend;
}else{
nbColumn --;
isNbColumnFound = false;
break;
}
}
}else{
xCurrent = xLeftSuccessorLegend;
}
}
if(isNbColumnFound){
break;
}
}
return nbColumn;
}
 
 
private boolean isAllColumnPredecessorLineCanBeMove(int xColumnToMove, int numberColumnToMove,
int nbLineToControl, Vector allSeries, int nbColumnByLine, int xRightLegend, int[] allColumnPosition,
Graphics2D graphics2D)
{
int numberSeries = -1;
for(int i=0; i<nbLineToControl; i++){
int decalage = 0;
for(int j=0; j<nbColumnByLine; j++){
numberSeries ++;
Series series = (Series)allSeries.elementAt(numberSeries);
int xCurrent = allColumnPosition[j];
if(j == numberColumnToMove){
decalage = xColumnToMove - xCurrent;
xCurrent = xColumnToMove;
}else{
xCurrent += decalage;
}
int xRightCurrentLegend = xCurrent + _nbPixelWidthOfLegendIndicator +
_nbPixelBetweenTxtLegendAndColorAssociate + Graphics2DTools.getNbPixelWidthOfTxt(graphics2D, series.getLegendLabel());
if(xRightLegend < xRightCurrentLegend){
return false;
}
}
}
return true;
}
 
private void drawLegendAtBottom(Graphics2D graphics2D, int xTopLeftLegend, int yTopLeftLegend, Vector allSeries)
{
if((_legendDisplayMode != LEGEND_DISPLAY_MODE_BOTTOM) && (_legendDisplayMode != LEGEND_DISPLAY_MODE_TOP)){
return;
}
 
Font font = graphics2D.getFont();
Font fontOnX = getFontOnX(graphics2D);
 
graphics2D.setFont(fontOnX);
int sizeWidthOfLegend = getSizeWidthOfLegendAtBottom(graphics2D, allSeries.elements());
int sizeHeightOfLegend = getSizeHeightOfLegendAtBottom(graphics2D, allSeries);
graphics2D.setColor(_legendBackgroundColor);
graphics2D.fillRect(xTopLeftLegend, yTopLeftLegend, sizeWidthOfLegend, sizeHeightOfLegend);
graphics2D.setColor(_legendCadreColor);
graphics2D.drawRect(xTopLeftLegend, yTopLeftLegend, sizeWidthOfLegend, sizeHeightOfLegend);
 
//
int[] allColumnPosition = null;
int nbColumn = 0;
int currentColumn = 0;
switch(_legendAlignMode){
case LEGEND_ALIGN_MODE_NONE :
break;
case LEGEND_ALIGN_MODE_COLUMN :
allColumnPosition = new int[allSeries.size() + 1];
break;
case LEGEND_ALIGN_MODE_COLUMN_STRICT :
allColumnPosition = new int[allSeries.size() + 1];
nbColumn = getAllColumnPositionForLegendAlignColumnStrict(
xTopLeftLegend, yTopLeftLegend, allSeries, allColumnPosition, graphics2D);
break;
default:
throw new OFCChartsRuntimeException("Invalid align legend mode");
}
 
 
int yCurrent = yTopLeftLegend + _nbPixelFreeArroundLegendForPresentation;
int xCurrent = xTopLeftLegend + _nbPixelFreeArroundLegendForPresentation;
 
switch(_legendAlignMode){
case LEGEND_ALIGN_MODE_NONE :
break;
case LEGEND_ALIGN_MODE_COLUMN :
allColumnPosition[nbColumn] = xCurrent;
nbColumn ++;
int colorNum = 0;
break;
case LEGEND_ALIGN_MODE_COLUMN_STRICT :
break;
default:
throw new OFCChartsRuntimeException("Invalid align legend mode");
}
 
int maxHeightLegendTxt = 0;
 
Enumeration enumAllSeries = allSeries.elements();
while(enumAllSeries.hasMoreElements()){
Series series = (Series)enumAllSeries.nextElement();
graphics2D.setColor(series.getColor());
 
if(xTopLeftLegend + _nbPixelFreeArroundLegendForPresentation + _legendWidth < xCurrent + _nbPixelWidthOfLegendIndicator +
_nbPixelBetweenTxtLegendAndColorAssociate + Graphics2DTools.getNbPixelWidthOfTxt(graphics2D, series.getLegendLabel())){
if(xCurrent != xTopLeftLegend + _nbPixelFreeArroundLegendForPresentation){ //pour eviter de boucler sans fin
switch(_legendAlignMode){
case LEGEND_ALIGN_MODE_NONE:
xCurrent = xTopLeftLegend + _nbPixelFreeArroundLegendForPresentation;
break;
case LEGEND_ALIGN_MODE_COLUMN:
case LEGEND_ALIGN_MODE_COLUMN_STRICT:
xCurrent = allColumnPosition[0];
currentColumn = 0;
break;
default:
throw new OFCChartsRuntimeException("Invalid align legend mode");
}
 
//yCurrent += _nbPixelBetweenEachLegend + Graphics2DTools.getNbPixelHeightOfTxt(graphics2D, series.getLegendLabel());
yCurrent += maxHeightLegendTxt;
maxHeightLegendTxt = 0;
}
}
 
int currentSize = Graphics2DTools.getNbPixelHeightOfTxt(graphics2D, series.getLegendLabel());
if ( currentSize > maxHeightLegendTxt){
maxHeightLegendTxt = currentSize;
}
 
if(_isDisplayAsBar){
graphics2D.drawRect(xCurrent, yCurrent, _nbPixelWidthOfLegendIndicator, _nbPixelHeightOfLegendIndicator);
graphics2D.fillRect(xCurrent, yCurrent, _nbPixelWidthOfLegendIndicator, _nbPixelHeightOfLegendIndicator);
}else{
graphics2D.drawLine(xCurrent, yCurrent + (_nbPixelHeightOfLegendIndicator/2),
xCurrent + _nbPixelWidthOfLegendIndicator, yCurrent + (_nbPixelHeightOfLegendIndicator/2));
series.drawIndicator(xCurrent + (_nbPixelWidthOfLegendIndicator/2),
yCurrent + (_nbPixelHeightOfLegendIndicator/2), graphics2D);
}
 
graphics2D.setColor(_legendWriteTxtColor);
xCurrent += _nbPixelWidthOfLegendIndicator + _nbPixelBetweenTxtLegendAndColorAssociate;
graphics2D.drawString(series.getLegendLabel(), xCurrent,
Graphics2DTools.getYToAlignTxt(graphics2D, yCurrent + (_nbPixelHeightOfLegendIndicator/2), series.getLegendLabel()));
 
xCurrent += Graphics2DTools.getNbPixelWidthOfTxt(graphics2D, series.getLegendLabel()) + _nbPixelBetweenEachLegend;
switch(_legendAlignMode){
case LEGEND_ALIGN_MODE_NONE:
break;
case LEGEND_ALIGN_MODE_COLUMN:
if(currentColumn + 1 >= nbColumn){
allColumnPosition[nbColumn] = xCurrent;
nbColumn ++;
}
currentColumn ++;
if(xCurrent <= allColumnPosition[currentColumn]){
xCurrent = allColumnPosition[currentColumn];
}else{
xCurrent = allColumnPosition[0];
currentColumn = 0;
yCurrent += maxHeightLegendTxt;
maxHeightLegendTxt = 0;
}
break;
case LEGEND_ALIGN_MODE_COLUMN_STRICT:
currentColumn ++;
if(currentColumn >= nbColumn){
xCurrent = allColumnPosition[0];
currentColumn = 0;
yCurrent += maxHeightLegendTxt;
maxHeightLegendTxt = 0;
}else{
xCurrent = allColumnPosition[currentColumn];
}
break;
default:
throw new OFCChartsRuntimeException("Invalid align legend mode");
}
 
}
graphics2D.setFont(font);
}
 
 
protected Font getFontOnX(Graphics2D graphics2D)
{
Font font = graphics2D.getFont();
if(_sizeFontOnX > 0){
return new Font(font.getName(), font.getStyle(), _sizeFontOnX);
//return new Font("Arial", font.PLAIN, _sizeFontOnX);
//return new Font("Sans-Serif", font.PLAIN, _sizeFontOnX);
// return new Font("Lucida Sans Typewriter", font.PLAIN, _sizeFontOnX);
}
else{
return font;
}
}
 
 
}
/trunk/project/ofccharts/src/com/oxymel/ofc/charts/encoder/PngEncoder.java
New file
0,0 → 1,620
package com.oxymel.ofc.charts.encoder;
/**
* PngEncoder takes a Java Image object and creates a byte string which can be saved as a PNG file.
* The Image is presumed to use the DirectColorModel.
*
* Thanks to Jay Denny at KeyPoint Software
* http://www.keypoint.com/
* who let me develop this code on company time.
*
* You may contact me with (probably very-much-needed) improvements,
* comments, and bug fixes at:
*
* david@catcode.com
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* A copy of the GNU LGPL may be found at
* http://www.gnu.org/copyleft/lesser.html,
*
* @author J. David Eisenberg
* @version 1.4, 31 March 2000
*/
 
import java.awt.*;
import java.awt.image.*;
import java.util.zip.*;
import java.io.*;
 
public class PngEncoder extends Object
{
/** Constant specifying that alpha channel should be encoded. */
public static final boolean ENCODE_ALPHA=true;
/** Constant specifying that alpha channel should not be encoded. */
public static final boolean NO_ALPHA=false;
/** Constants for filters */
public static final int FILTER_NONE = 0;
public static final int FILTER_SUB = 1;
public static final int FILTER_UP = 2;
public static final int FILTER_LAST = 2;
 
protected byte[] pngBytes;
protected byte[] priorRow;
protected byte[] leftBytes;
protected Image image;
protected int width, height;
protected int bytePos, maxPos;
protected int hdrPos, dataPos, endPos;
protected CRC32 crc = new CRC32();
protected long crcValue;
protected boolean encodeAlpha;
protected int filter;
protected int bytesPerPixel;
protected int compressionLevel;
 
/**
* Class constructor
*
*/
public PngEncoder()
{
this( null, false, FILTER_NONE, 0 );
}
 
/**
* Class constructor specifying Image to encode, with no alpha channel encoding.
*
* @param image A Java Image object which uses the DirectColorModel
* @see java.awt.Image
*/
public PngEncoder( Image image )
{
this(image, false, FILTER_NONE, 0);
}
 
/**
* Class constructor specifying Image to encode, and whether to encode alpha.
*
* @param image A Java Image object which uses the DirectColorModel
* @param encodeAlpha Encode the alpha channel? false=no; true=yes
* @see java.awt.Image
*/
public PngEncoder( Image image, boolean encodeAlpha )
{
this(image, encodeAlpha, FILTER_NONE, 0);
}
 
/**
* Class constructor specifying Image to encode, whether to encode alpha, and filter to use.
*
* @param image A Java Image object which uses the DirectColorModel
* @param encodeAlpha Encode the alpha channel? false=no; true=yes
* @param whichFilter 0=none, 1=sub, 2=up
* @see java.awt.Image
*/
public PngEncoder( Image image, boolean encodeAlpha, int whichFilter )
{
this( image, encodeAlpha, whichFilter, 0 );
}
 
 
/**
* Class constructor specifying Image source to encode, whether to encode alpha, filter to use, and compression level.
*
* @param image A Java Image object
* @param encodeAlpha Encode the alpha channel? false=no; true=yes
* @param whichFilter 0=none, 1=sub, 2=up
* @param compLevel 0..9
* @see java.awt.Image
*/
public PngEncoder( Image image, boolean encodeAlpha, int whichFilter,
int compLevel)
{
this.image = image;
this.encodeAlpha = encodeAlpha;
setFilter( whichFilter );
if (compLevel >=0 && compLevel <=9)
{
this.compressionLevel = compLevel;
}
}
 
/**
* Set the image to be encoded
*
* @param image A Java Image object which uses the DirectColorModel
* @see java.awt.Image
* @see java.awt.image.DirectColorModel
*/
public void setImage( Image image )
{
this.image = image;
pngBytes = null;
}
 
/**
* Creates an array of bytes that is the PNG equivalent of the current image, specifying whether to encode alpha or not.
*
* @param encodeAlpha boolean false=no alpha, true=encode alpha
* @return an array of bytes, or null if there was a problem
*/
public byte[] pngEncode( boolean encodeAlpha )
{
byte[] pngIdBytes = { -119, 80, 78, 71, 13, 10, 26, 10 };
int i;
 
if (image == null)
{
return null;
}
width = image.getWidth( null );
height = image.getHeight( null );
this.image = image;
 
/*
* start with an array that is big enough to hold all the pixels
* (plus filter bytes), and an extra 200 bytes for header info
*/
pngBytes = new byte[((width+1) * height * 3) + 200];
 
/*
* keep track of largest byte written to the array
*/
maxPos = 0;
 
bytePos = writeBytes( pngIdBytes, 0 );
hdrPos = bytePos;
writeHeader();
dataPos = bytePos;
if (writeImageData())
{
writeEnd();
pngBytes = resizeByteArray( pngBytes, maxPos );
}
else
{
pngBytes = null;
}
return pngBytes;
}
 
/**
* Creates an array of bytes that is the PNG equivalent of the current image.
* Alpha encoding is determined by its setting in the constructor.
*
* @return an array of bytes, or null if there was a problem
*/
public byte[] pngEncode()
{
return pngEncode( encodeAlpha );
}
 
/**
* Set the alpha encoding on or off.
*
* @param encodeAlpha false=no, true=yes
*/
public void setEncodeAlpha( boolean encodeAlpha )
{
this.encodeAlpha = encodeAlpha;
}
 
/**
* Retrieve alpha encoding status.
*
* @return boolean false=no, true=yes
*/
public boolean getEncodeAlpha()
{
return encodeAlpha;
}
 
/**
* Set the filter to use
*
* @param whichFilter from constant list
*/
public void setFilter( int whichFilter )
{
this.filter = FILTER_NONE;
if ( whichFilter <= FILTER_LAST )
{
this.filter = whichFilter;
}
}
 
/**
* Retrieve filtering scheme
*
* @return int (see constant list)
*/
public int getFilter()
{
return filter;
}
 
/**
* Set the compression level to use
*
* @param level 0 through 9
*/
public void setCompressionLevel( int level )
{
if ( level >= 0 && level <= 9)
{
this.compressionLevel = level;
}
}
 
/**
* Retrieve compression level
*
* @return int in range 0-9
*/
public int getCompressionLevel()
{
return compressionLevel;
}
 
/**
* Increase or decrease the length of a byte array.
*
* @param array The original array.
* @param newLength The length you wish the new array to have.
* @return Array of newly desired length. If shorter than the
* original, the trailing elements are truncated.
*/
protected byte[] resizeByteArray( byte[] array, int newLength )
{
byte[] newArray = new byte[newLength];
int oldLength = array.length;
 
System.arraycopy( array, 0, newArray, 0,
Math.min( oldLength, newLength ) );
return newArray;
}
 
/**
* Write an array of bytes into the pngBytes array.
* Note: This routine has the side effect of updating
* maxPos, the largest element written in the array.
* The array is resized by 1000 bytes or the length
* of the data to be written, whichever is larger.
*
* @param data The data to be written into pngBytes.
* @param offset The starting point to write to.
* @return The next place to be written to in the pngBytes array.
*/
protected int writeBytes( byte[] data, int offset )
{
maxPos = Math.max( maxPos, offset + data.length );
if (data.length + offset > pngBytes.length)
{
pngBytes = resizeByteArray( pngBytes, pngBytes.length +
Math.max( 1000, data.length ) );
}
System.arraycopy( data, 0, pngBytes, offset, data.length );
return offset + data.length;
}
 
/**
* Write an array of bytes into the pngBytes array, specifying number of bytes to write.
* Note: This routine has the side effect of updating
* maxPos, the largest element written in the array.
* The array is resized by 1000 bytes or the length
* of the data to be written, whichever is larger.
*
* @param data The data to be written into pngBytes.
* @param nBytes The number of bytes to be written.
* @param offset The starting point to write to.
* @return The next place to be written to in the pngBytes array.
*/
protected int writeBytes( byte[] data, int nBytes, int offset )
{
maxPos = Math.max( maxPos, offset + nBytes );
if (nBytes + offset > pngBytes.length)
{
pngBytes = resizeByteArray( pngBytes, pngBytes.length +
Math.max( 1000, nBytes ) );
}
System.arraycopy( data, 0, pngBytes, offset, nBytes );
return offset + nBytes;
}
 
/**
* Write a two-byte integer into the pngBytes array at a given position.
*
* @param n The integer to be written into pngBytes.
* @param offset The starting point to write to.
* @return The next place to be written to in the pngBytes array.
*/
protected int writeInt2( int n, int offset )
{
byte[] temp = { (byte)((n >> 8) & 0xff),
(byte) (n & 0xff) };
return writeBytes( temp, offset );
}
 
/**
* Write a four-byte integer into the pngBytes array at a given position.
*
* @param n The integer to be written into pngBytes.
* @param offset The starting point to write to.
* @return The next place to be written to in the pngBytes array.
*/
protected int writeInt4( int n, int offset )
{
byte[] temp = { (byte)((n >> 24) & 0xff),
(byte) ((n >> 16) & 0xff ),
(byte) ((n >> 8) & 0xff ),
(byte) ( n & 0xff ) };
return writeBytes( temp, offset );
}
 
/**
* Write a single byte into the pngBytes array at a given position.
*
* @param n The integer to be written into pngBytes.
* @param offset The starting point to write to.
* @return The next place to be written to in the pngBytes array.
*/
protected int writeByte( int b, int offset )
{
byte[] temp = { (byte) b };
return writeBytes( temp, offset );
}
 
/**
* Write a string into the pngBytes array at a given position.
* This uses the getBytes method, so the encoding used will
* be its default.
*
* @param n The integer to be written into pngBytes.
* @param offset The starting point to write to.
* @return The next place to be written to in the pngBytes array.
* @see java.lang.String#getBytes()
*/
protected int writeString( String s, int offset )
{
return writeBytes( s.getBytes(), offset );
}
 
/**
* Write a PNG "IHDR" chunk into the pngBytes array.
*/
protected void writeHeader()
{
int startPos;
 
startPos = bytePos = writeInt4( 13, bytePos );
bytePos = writeString( "IHDR", bytePos );
width = image.getWidth( null );
height = image.getHeight( null );
bytePos = writeInt4( width, bytePos );
bytePos = writeInt4( height, bytePos );
bytePos = writeByte( 8, bytePos ); // bit depth
bytePos = writeByte( (encodeAlpha) ? 6 : 2, bytePos ); // direct model
bytePos = writeByte( 0, bytePos ); // compression method
bytePos = writeByte( 0, bytePos ); // filter method
bytePos = writeByte( 0, bytePos ); // no interlace
crc.reset();
crc.update( pngBytes, startPos, bytePos-startPos );
crcValue = crc.getValue();
bytePos = writeInt4( (int) crcValue, bytePos );
}
 
/**
* Perform "sub" filtering on the given row.
* Uses temporary array leftBytes to store the original values
* of the previous pixels. The array is 16 bytes long, which
* will easily hold two-byte samples plus two-byte alpha.
*
* @param pixels The array holding the scan lines being built
* @param startPos Starting position within pixels of bytes to be filtered.
* @param width Width of a scanline in pixels.
*/
protected void filterSub( byte[] pixels, int startPos, int width )
{
int i;
int offset = bytesPerPixel;
int actualStart = startPos + offset;
int nBytes = width * bytesPerPixel;
int leftInsert = offset;
int leftExtract = 0;
byte current_byte;
 
for (i=actualStart; i < startPos + nBytes; i++)
{
leftBytes[leftInsert] = pixels[i];
pixels[i] = (byte) ((pixels[i] - leftBytes[leftExtract]) % 256);
leftInsert = (leftInsert+1) % 0x0f;
leftExtract = (leftExtract + 1) % 0x0f;
}
}
 
/**
* Perform "up" filtering on the given row.
* Side effect: refills the prior row with current row
*
* @param pixels The array holding the scan lines being built
* @param startPos Starting position within pixels of bytes to be filtered.
* @param width Width of a scanline in pixels.
*/
protected void filterUp( byte[] pixels, int startPos, int width )
{
int i, nBytes;
byte current_byte;
 
nBytes = width * bytesPerPixel;
 
for (i=0; i < nBytes; i++)
{
current_byte = pixels[startPos + i];
pixels[startPos + i] = (byte) ((pixels[startPos + i] - priorRow[i]) % 256);
priorRow[i] = current_byte;
}
}
 
/**
* Write the image data into the pngBytes array.
* This will write one or more PNG "IDAT" chunks. In order
* to conserve memory, this method grabs as many rows as will
* fit into 32K bytes, or the whole image; whichever is less.
*
*
* @return true if no errors; false if error grabbing pixels
*/
protected boolean writeImageData()
{
int rowsLeft = height; // number of rows remaining to write
int startRow = 0; // starting row to process this time through
int nRows; // how many rows to grab at a time
 
byte[] scanLines; // the scan lines to be compressed
int scanPos; // where we are in the scan lines
int startPos; // where this line's actual pixels start (used for filtering)
 
byte[] compressedLines; // the resultant compressed lines
int nCompressed; // how big is the compressed area?
 
int depth; // color depth ( handle only 8 or 32 )
 
PixelGrabber pg;
 
bytesPerPixel = (encodeAlpha) ? 4 : 3;
 
Deflater scrunch = new Deflater( compressionLevel );
ByteArrayOutputStream outBytes =
new ByteArrayOutputStream(1024);
 
DeflaterOutputStream compBytes =
new DeflaterOutputStream( outBytes, scrunch );
try
{
while (rowsLeft > 0)
{
nRows = Math.min( 32767 / (width*(bytesPerPixel+1)), rowsLeft );
// nRows = rowsLeft;
 
int[] pixels = new int[width * nRows];
 
pg = new PixelGrabber(image, 0, startRow,
width, nRows, pixels, 0, width);
try {
pg.grabPixels();
}
catch (Exception e) {
e.printStackTrace();
System.err.println("interrupted waiting for pixels!");
return false;
}
if ((pg.getStatus() & ImageObserver.ABORT) != 0) {
System.err.println("image fetch aborted or errored");
return false;
}
 
/*
* Create a data chunk. scanLines adds "nRows" for
* the filter bytes.
*/
scanLines = new byte[width * nRows * bytesPerPixel + nRows];
 
if (filter == FILTER_SUB)
{
leftBytes = new byte[16];
}
if (filter == FILTER_UP)
{
priorRow = new byte[width*bytesPerPixel];
}
 
scanPos = 0;
startPos = 1;
for (int i=0; i<width*nRows; i++)
{
if (i % width == 0)
{
scanLines[scanPos++] = (byte) filter;
startPos = scanPos;
}
scanLines[scanPos++] = (byte) ((pixels[i] >> 16) & 0xff);
scanLines[scanPos++] = (byte) ((pixels[i] >> 8) & 0xff);
scanLines[scanPos++] = (byte) ((pixels[i] ) & 0xff);
if (encodeAlpha)
{
scanLines[scanPos++] = (byte) ((pixels[i] >> 24) & 0xff );
}
if ((i % width == width-1) && (filter != FILTER_NONE))
{
if (filter == FILTER_SUB)
{
filterSub( scanLines, startPos, width );
}
if (filter == FILTER_UP)
{
filterUp( scanLines, startPos, width );
}
}
}
 
/*
* Write these lines to the output area
*/
compBytes.write( scanLines, 0, scanPos );
 
 
startRow += nRows;
rowsLeft -= nRows;
}
compBytes.close();
 
/*
* Write the compressed bytes
*/
compressedLines = outBytes.toByteArray();
nCompressed = compressedLines.length;
 
crc.reset();
bytePos = writeInt4( nCompressed, bytePos );
bytePos = writeString("IDAT", bytePos );
crc.update("IDAT".getBytes());
bytePos = writeBytes( compressedLines, nCompressed, bytePos );
crc.update( compressedLines, 0, nCompressed );
 
crcValue = crc.getValue();
bytePos = writeInt4( (int) crcValue, bytePos );
scrunch.finish();
return true;
}
catch (IOException e)
{
System.err.println( e.toString());
return false;
}
}
 
/**
* Write a PNG "IEND" chunk into the pngBytes array.
*/
protected void writeEnd()
{
bytePos = writeInt4( 0, bytePos );
bytePos = writeString( "IEND", bytePos );
crc.reset();
crc.update("IEND".getBytes());
crcValue = crc.getValue();
bytePos = writeInt4( (int) crcValue, bytePos );
}
}
 
/trunk/project/ofccharts/src/com/oxymel/ofc/charts/encoder/PngEncoderB.java
New file
0,0 → 1,442
package com.oxymel.ofc.charts.encoder;
 
/**
* PngEncoderB takes a Java BufferedImage object and creates a byte string which can be saved as a PNG file.
* The encoder will accept BufferedImages with eight-bit samples
* or 4-byte ARGB samples.
*
* There is also code to handle 4-byte samples returned as
* one int per pixel, but that has not been tested.
*
* Thanks to Jay Denny at KeyPoint Software
* http://www.keypoint.com/
* who let me develop this code on company time.
*
* You may contact me with (probably very-much-needed) improvements,
* comments, and bug fixes at:
*
* david@catcode.com
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* A copy of the GNU LGPL may be found at
* http://www.gnu.org/copyleft/lesser.html,
*
* @author J. David Eisenberg
* @version 1.4, 31 March 2000
*/
 
import java.awt.image.*;
import java.util.zip.*;
import java.io.*;
 
public class PngEncoderB extends PngEncoder
{
protected BufferedImage image;
protected WritableRaster wRaster;
protected int tType;
 
/**
* Class constructor
*
*/
public PngEncoderB()
{
this( null, false, FILTER_NONE, 0 );
}
 
/**
* Class constructor specifying BufferedImage to encode, with no alpha channel encoding.
*
* @param image A Java BufferedImage object
*/
public PngEncoderB( BufferedImage image )
{
this(image, false, FILTER_NONE, 0);
}
 
/**
* Class constructor specifying BufferedImage to encode, and whether to encode alpha.
*
* @param image A Java BufferedImage object
* @param encodeAlpha Encode the alpha channel? false=no; true=yes
*/
public PngEncoderB( BufferedImage image, boolean encodeAlpha )
{
this( image, encodeAlpha, FILTER_NONE, 0 );
}
 
/**
* Class constructor specifying BufferedImage to encode, whether to encode alpha, and filter to use.
*
* @param image A Java BufferedImage object
* @param encodeAlpha Encode the alpha channel? false=no; true=yes
* @param whichFilter 0=none, 1=sub, 2=up
*/
public PngEncoderB( BufferedImage image, boolean encodeAlpha,
int whichFilter )
{
this( image, encodeAlpha, whichFilter, 0 );
}
 
/**
* Class constructor specifying BufferedImage source to encode, whether to encode alpha, filter to use, and compression level
*
* @param image A Java BufferedImage object
* @param encodeAlpha Encode the alpha channel? false=no; true=yes
* @param whichFilter 0=none, 1=sub, 2=up
* @param compLevel 0..9
*/
public PngEncoderB( BufferedImage image, boolean encodeAlpha,
int whichFilter, int compLevel )
{
this.image = image;
this.encodeAlpha = encodeAlpha;
setFilter( whichFilter );
if (compLevel >=0 && compLevel <=9)
{
this.compressionLevel = compLevel;
}
}
 
/**
* Set the BufferedImage to be encoded
*
* @param BufferedImage A Java BufferedImage object
*/
public void setImage( BufferedImage image )
{
this.image = image;
pngBytes = null;
}
 
/**
* Creates an array of bytes that is the PNG equivalent of the current image, specifying whether to encode alpha or not.
*
* @param encodeAlpha boolean false=no alpha, true=encode alpha
* @return an array of bytes, or null if there was a problem
*/
public byte[] pngEncode( boolean encodeAlpha )
{
byte[] pngIdBytes = { -119, 80, 78, 71, 13, 10, 26, 10 };
int i;
 
if (image == null)
{
return null;
}
width = image.getWidth( null );
height = image.getHeight( null );
this.image = image;
 
if (!establishStorageInfo())
{
return null;
}
 
/*
* start with an array that is big enough to hold all the pixels
* (plus filter bytes), and an extra 200 bytes for header info
*/
pngBytes = new byte[((width+1) * height * 3) + 200];
 
/*
* keep track of largest byte written to the array
*/
maxPos = 0;
 
bytePos = writeBytes( pngIdBytes, 0 );
hdrPos = bytePos;
writeHeader();
dataPos = bytePos;
if (writeImageData())
{
writeEnd();
pngBytes = resizeByteArray( pngBytes, maxPos );
}
else
{
pngBytes = null;
}
return pngBytes;
}
 
/**
* Creates an array of bytes that is the PNG equivalent of the current image.
* Alpha encoding is determined by its setting in the constructor.
*
* @return an array of bytes, or null if there was a problem
*/
public byte[] pngEncode()
{
return pngEncode( encodeAlpha );
}
 
/**
*
* Get and set variables that determine how picture is stored.
*
* Retrieves the writable raster of the buffered image,
* as well its transfer type.
*
* Sets number of output bytes per pixel, and, if only
* eight-bit bytes, turns off alpha encoding.
* @return true if 1-byte or 4-byte data, false otherwise
*/
protected boolean establishStorageInfo()
{
int dataBytes;
 
wRaster = image.getRaster();
dataBytes = wRaster.getNumDataElements();
tType = wRaster.getTransferType();
 
if (((tType == DataBuffer.TYPE_BYTE) && (dataBytes == 4)) ||
((tType == DataBuffer.TYPE_INT) && (dataBytes == 1)) )
{
bytesPerPixel = (encodeAlpha) ? 4 : 3;
}
else if ((tType == DataBuffer.TYPE_BYTE) && (dataBytes == 1))
{
bytesPerPixel = 1;
encodeAlpha = false; // one-byte samples
}
else
{
return false;
}
return true;
}
 
/**
* Write a PNG "IHDR" chunk into the pngBytes array.
*/
protected void writeHeader()
{
int startPos;
 
startPos = bytePos = writeInt4( 13, bytePos );
bytePos = writeString( "IHDR", bytePos );
width = image.getWidth( null );
height = image.getHeight( null );
bytePos = writeInt4( width, bytePos );
bytePos = writeInt4( height, bytePos );
bytePos = writeByte( 8, bytePos ); // bit depth
if (bytesPerPixel != 1)
{
bytePos = writeByte( (encodeAlpha) ? 6 : 2, bytePos ); // direct model
}
else
{
bytePos = writeByte( 3, bytePos ); // indexed
}
bytePos = writeByte( 0, bytePos ); // compression method
bytePos = writeByte( 0, bytePos ); // filter method
bytePos = writeByte( 0, bytePos ); // no interlace
crc.reset();
crc.update( pngBytes, startPos, bytePos-startPos );
crcValue = crc.getValue();
bytePos = writeInt4( (int) crcValue, bytePos );
}
 
protected void writePalette( IndexColorModel icm )
{
byte[] redPal = new byte[256];
byte[] greenPal = new byte[256];
byte[] bluePal = new byte[256];
byte[] allPal = new byte[768];
int i;
 
icm.getReds( redPal );
icm.getGreens( greenPal );
icm.getBlues( bluePal );
for (i=0; i<256; i++)
{
allPal[i*3 ] = redPal[i];
allPal[i*3+1] = greenPal[i];
allPal[i*3+2] = bluePal[i];
}
bytePos = writeInt4( 768, bytePos );
bytePos = writeString( "PLTE", bytePos );
crc.reset();
crc.update("PLTE".getBytes());
bytePos = writeBytes( allPal, bytePos );
crc.update( allPal );
crcValue = crc.getValue();
bytePos = writeInt4( (int) crcValue, bytePos );
}
 
/**
* Write the image data into the pngBytes array.
* This will write one or more PNG "IDAT" chunks. In order
* to conserve memory, this method grabs as many rows as will
* fit into 32K bytes, or the whole image; whichever is less.
*
*
* @return true if no errors; false if error grabbing pixels
*/
protected boolean writeImageData()
{
int rowsLeft = height; // number of rows remaining to write
int startRow = 0; // starting row to process this time through
int nRows; // how many rows to grab at a time
 
byte[] scanLines; // the scan lines to be compressed
int scanPos; // where we are in the scan lines
int startPos; // where this line's actual pixels start (used for filtering)
int readPos; // position from which source pixels are read
 
byte[] compressedLines; // the resultant compressed lines
int nCompressed; // how big is the compressed area?
 
byte[] pixels; // storage area for byte-sized pixels
int[] iPixels; // storage area for int-sized pixels
 
Deflater scrunch = new Deflater( compressionLevel );
ByteArrayOutputStream outBytes =
new ByteArrayOutputStream(1024);
 
DeflaterOutputStream compBytes =
new DeflaterOutputStream( outBytes, scrunch );
 
if (bytesPerPixel == 1)
{
writePalette( (IndexColorModel) image.getColorModel() );
}
 
try
{
while (rowsLeft > 0)
{
nRows = Math.min( 32767 / (width*(bytesPerPixel+1)), rowsLeft );
// nRows = rowsLeft;
 
/*
* Create a data chunk. scanLines adds "nRows" for
* the filter bytes.
*/
scanLines = new byte[width * nRows * bytesPerPixel + nRows];
 
if (filter == FILTER_SUB)
{
leftBytes = new byte[16];
}
if (filter == FILTER_UP)
{
priorRow = new byte[width*bytesPerPixel];
}
 
if (tType == DataBuffer.TYPE_BYTE)
{
pixels = (byte[]) wRaster.getDataElements(
0, startRow, width, nRows, null );
iPixels = null;
}
else
{
iPixels = (int[]) wRaster.getDataElements(
0, startRow, width, nRows, null );
pixels = null;
}
 
scanPos = 0;
readPos = 0;
startPos = 1;
for (int i=0; i<width*nRows; i++)
{
if (i % width == 0)
{
scanLines[scanPos++] = (byte) filter;
startPos = scanPos;
}
 
if (bytesPerPixel == 1)
{
scanLines[scanPos++] = pixels[readPos++];
}
else if (tType == DataBuffer.TYPE_BYTE)
{
scanLines[scanPos++] = pixels[readPos++];
scanLines[scanPos++] = pixels[readPos++];
scanLines[scanPos++] = pixels[readPos++];
if (encodeAlpha)
{
scanLines[scanPos++] = pixels[readPos++];
}
else
{
readPos++;
}
}
else
{
scanLines[scanPos++] = (byte) ((iPixels[readPos] >> 16) & 0xff);
scanLines[scanPos++] = (byte) ((iPixels[readPos] >> 8) & 0xff);
scanLines[scanPos++] = (byte) ((iPixels[readPos] ) & 0xff);
if (encodeAlpha)
{
scanLines[scanPos++] = (byte) ((iPixels[readPos] >> 24) & 0xff );
}
readPos++;
}
if ((i % width == width-1) && (filter != FILTER_NONE))
{
if (filter == FILTER_SUB)
{
filterSub( scanLines, startPos, width );
}
if (filter == FILTER_UP)
{
filterUp( scanLines, startPos, width );
}
}
}
 
/*
* Write these lines to the output area
*/
compBytes.write( scanLines, 0, scanPos );
 
startRow += nRows;
rowsLeft -= nRows;
}
compBytes.close();
 
/*
* Write the compressed bytes
*/
compressedLines = outBytes.toByteArray();
nCompressed = compressedLines.length;
 
crc.reset();
bytePos = writeInt4( nCompressed, bytePos );
bytePos = writeString("IDAT", bytePos );
crc.update("IDAT".getBytes());
bytePos = writeBytes( compressedLines, nCompressed, bytePos );
crc.update( compressedLines, 0, nCompressed );
 
crcValue = crc.getValue();
bytePos = writeInt4( (int) crcValue, bytePos );
scrunch.finish();
return true;
}
catch (IOException e)
{
System.err.println( e.toString());
return false;
}
}
 
}
 
/trunk/project/ofccharts/src/com/oxymel/ofc/charts/SVGContext.java
New file
0,0 → 1,40
package com.oxymel.ofc.charts;
/*
* Copyright (c) 2006 Oxymel SA.
* All rights reserved.
*
* This software is the confidential and proprietary information of Oxymel SA
* ("Confidential Information"). You shall not disclose such Confidential
* Information and shall use it only in accordance with the terms of the license
* agreement you entered into with Oxymel SA.
*/
 
/**
* This class allows to define a context for an SVG chart
*/
public class SVGContext
{
private String _rootTransformValue;
 
/**
* constructor
*/
public SVGContext(){}
 
 
/**
* Sets the translation values
* @param x
* @param y
*/
public void setRootTranslateValue(int x, int y)
{
_rootTransformValue = "translate(" + x + "," + y + ")";
}
 
/**
* Get the svg "transform" attribute value
* @return the svg "transform" attribute value
*/
public String getRootTransformValue(){return _rootTransformValue;}
}
/trunk/project/ofccharts/src/com/oxymel/ofc/charts/VerticalNumberAxisRight.java
New file
0,0 → 1,122
package com.oxymel.ofc.charts;
/*
* Copyright (c) 2006 Oxymel SA.
* All rights reserved.
*
* This software is the confidential and proprietary information of Oxymel SA
* ("Confidential Information"). You shall not disclose such Confidential
* Information and shall use it only in accordance with the terms of the license
* agreement you entered into with Oxymel SA.
*/
 
//java
import java.awt.Graphics2D;
//ofc
import com.oxymel.ofc.charts.util.Graphics2DTools;
 
/**
* This class provides a vertical number axis right management
*/
public class VerticalNumberAxisRight extends VerticalAxisRight
{
private NumberAxis _numberAxis = new NumberAxis(this);
private boolean _isIntermediaryGapIndicatorVisible = false;
 
/**
* Constructor
* @param label Axis Label
*/
public VerticalNumberAxisRight(String label)
{
super(label);
}
 
/**
* Sets intermediary gap indicator visible
* @param isIntermediaryGapIndicatorVisible If true intermediary gap indicator are visible
*/
public void setIntermediaryGapIndicatorVisible(boolean isIntermediaryGapIndicatorVisible)
{_isIntermediaryGapIndicatorVisible = isIntermediaryGapIndicatorVisible;}
 
//interface NumberAxis
void setMinValue(double minValue){_numberAxis.setMinValue(minValue);}
void setMaxValue(double maxValue){_numberAxis.setMaxValue(maxValue);}
int getGapValue(){return _numberAxis.getGapValue();}
 
//axis drawing interface
int getNbGap(){return _numberAxis.getNbGap();}
int getNbNegativeGapToIncludeMinValue(){return _numberAxis.getNbNegativeGapToIncludeMinValue();}
protected void drawValues(int graphicWidth, int graphicHeight, int xTopLeftGraphic, int yTopLeftGraphic,
int xOrigine, int yOrigine, Graphics2D graphics2D)
{
int xAxisRight = xTopLeftGraphic + graphicWidth;
int nbGapOnY = getNbGap();
int sizeOfGapOnY = graphicHeight / nbGapOnY;
int yOfGap = yTopLeftGraphic + graphicHeight;
graphics2D.setColor(getValueWriteColor());
int gapValueOnY = getGapValue();
int currentGap = 0;
if(isContainsNegativeValue()){
currentGap = getNbNegativeGapToIncludeMinValue() * gapValueOnY * (-1);
}
for(int i=0; i<nbGapOnY + 1; i++){
String szCurrentGap = ""+currentGap;
if(getSuffixAllValues() != null){
szCurrentGap += getSuffixAllValues();
}
graphics2D.drawString(szCurrentGap, xAxisRight + _nbPixelOfGapIndicator +
_nbPixelBetweenValueAndGapIndicator,
Graphics2DTools.getYToAlignTxt(graphics2D, yOfGap, szCurrentGap));
currentGap += gapValueOnY;
yOfGap -= sizeOfGapOnY;
}
}
 
 
protected void drawGapIndicator(int graphicWidth, int graphicHeight, int xTopLeftGraphic,
int yTopLeftGraphic, int xOrigine, int yOrigine, Graphics2D graphics2D)
{
super.drawGapIndicator(graphicWidth, graphicHeight, xTopLeftGraphic,
yTopLeftGraphic, xOrigine, yOrigine, graphics2D);
if(!_isIntermediaryGapIndicatorVisible){
return;
}
 
int xAxisRight = xTopLeftGraphic + graphicWidth;
int nbGapOnY = getNbGap();
int sizeOfGapOnY = graphicHeight / nbGapOnY;
int yOfGap = yTopLeftGraphic + graphicHeight;
int yInterval = yOfGap;
 
int sizeInterval = _numberAxis.getIntervalGapSize(graphicWidth);
if(sizeInterval == 0){
return;
}
int gapValueOnY = getGapValue();
graphics2D.setColor(getGapIndicatorColor());
int nbIntervalCurrent = _numberAxis.getNbIntervalOneGap();
int sizeOfGapCurrent = sizeOfGapOnY;
for(int i=0; i<nbGapOnY; i++){
for(int j=0; j<_numberAxis.getNbIntervalOneGap() - 1; j++){
yInterval -= sizeInterval;
graphics2D.drawLine(xAxisRight - _nbPixelOfGapIndicator + 1, yInterval, xAxisRight + _nbPixelOfGapIndicator - 1, yInterval);
nbIntervalCurrent --;
sizeOfGapCurrent -= sizeInterval;
sizeInterval = sizeOfGapCurrent/nbIntervalCurrent;
}
yOfGap -= sizeOfGapOnY;
yInterval = yOfGap;
nbIntervalCurrent = _numberAxis.getNbIntervalOneGap();
sizeOfGapCurrent = sizeOfGapOnY;
}
}
 
 
//vertical axis interface
protected String getLargerStringValue()
{
return _numberAxis.getLargerStringValue();
}
 
 
}
/trunk/project/ofccharts/src/com/oxymel/ofc/charts/version/ChartsVersion.java
New file
0,0 → 1,25
package com.oxymel.ofc.charts.version;
/*
* Copyright (c) 2006 Oxymel SA.
* All rights reserved.
*
* This software is the confidential and proprietary information of Oxymel SA
* ("Confidential Information"). You shall not disclose such Confidential
* Information and shall use it only in accordance with the terms of the license
* agreement you entered into with Oxymel SA.
*/
 
/**
* This class is used to give the version number of this OFC component.
* */
public class ChartsVersion {
private static final String VERSION = "3.1";
 
public static String getVersionLabel() {
return VERSION;
}
 
public String getVersion() {
return VERSION;
}
}
/trunk/project/ofccharts/src/com/oxymel/ofc/charts/VerticalStackedBarChartRenderer.java
New file
0,0 → 1,178
package com.oxymel.ofc.charts;
/*
* Copyright (c) 2006 Oxymel SA.
* All rights reserved.
*
* This software is the confidential and proprietary information of Oxymel SA
* ("Confidential Information"). You shall not disclose such Confidential
* Information and shall use it only in accordance with the terms of the license
* agreement you entered into with Oxymel SA.
*/
 
//java
import java.util.*;
import java.awt.*;
 
import com.oxymel.ofc.charts.data.*;
import com.oxymel.ofc.charts.exception.*;
import com.oxymel.ofc.charts.series.*;
import com.oxymel.ofc.charts.util.*;
 
/**
* This class provides a vertical stacked bar chart renderer
*/
public class VerticalStackedBarChartRenderer extends VerticalBarChartRenderer
{
 
/**
* Constructor
* @param categoryValueSeriesContainer all category value series
*/
public VerticalStackedBarChartRenderer(CategoryValueSeriesContainer categoryValueSeriesContainer)
{
super(categoryValueSeriesContainer);
}
 
double getMaxValueSetOnAxis() throws OFCChartsException
{
return _categoryValueSeriesContainer.getMaxPositiveSumCategoryValue();
}
 
double getMinValueSetOnAxis() throws OFCChartsException
{
return _categoryValueSeriesContainer.getMinNegativeSumCategoryValue();
}
 
 
void drawGraphic(int xTopLeftGraphic, int yTopLeftGraphic, int graphicWidth, int graphicHeight,
int xOrigine, int yOrigine, Graphics2D graphics2D)
{
 
int sizeOfGapOnY = graphicHeight / _nbGapOnY;
int sizeOfGapOnX = graphicWidth / _nbGapOnX;
 
int nbPixelFreeBeforeSeries = getNbPixelFreeBeforeSeries(sizeOfGapOnX);
int nbPixelFreeAfterSeries = getNbPixelFreeAfterSeries(sizeOfGapOnX);
int maxWidthOfBarHisto = getNbPixelMaxWidthOfBarHisto(sizeOfGapOnX);
int minWidthOfBarHisto = getNbPixelMinWidthOfBarHisto(sizeOfGapOnX);
 
//
int widthOfBarHisto = sizeOfGapOnX - nbPixelFreeBeforeSeries - nbPixelFreeAfterSeries;
if(widthOfBarHisto < minWidthOfBarHisto){
widthOfBarHisto = sizeOfGapOnX;
nbPixelFreeBeforeSeries = 0;
nbPixelFreeAfterSeries = 0;
}else{
if(widthOfBarHisto > maxWidthOfBarHisto){
int nbPixel = (sizeOfGapOnX - maxWidthOfBarHisto)/2;
widthOfBarHisto = maxWidthOfBarHisto;
nbPixelFreeBeforeSeries = nbPixel;
nbPixelFreeAfterSeries = nbPixel;
}
}
 
int nbSeries = _categoryValueSeriesContainer.getNbSeries();
 
Vector allCategories = _categoryValueSeriesContainer.getAllCategoriesOrderByDisplayNumber();
Vector allSeriesOrderByDisplayNumber = _categoryValueSeriesContainer.getAllSeriesOrderByDisplayNumber();
Vector allSeriesOrderByReverseDisplayNumber = _categoryValueSeriesContainer.getAllSeriesOrderByReverseDisplayNumber();
 
for(int i= 0; i<allCategories.size(); i++){
Category category = (Category)allCategories.elementAt(i);
int xBarTopLeft = xOrigine + (sizeOfGapOnX * i) + nbPixelFreeBeforeSeries;
 
 
int yOrigineNegativeBar = yOrigine;
for(int j= 0; j<_categoryValueSeriesContainer.getNbSeries(); j++){
CategoryValueSeries categoryValueSeries = (CategoryValueSeries)allSeriesOrderByReverseDisplayNumber.elementAt(j);
if(categoryValueSeries.isVisible()){
double value = categoryValueSeries.getCategoryValueAsDouble(category.getId());
if(value != 0){
int relativeSizeOfValue = Graphics2DTools.getRelativeSizeOfValue(value, _gapValueOnY, sizeOfGapOnY);
if(value < 0){
yOrigineNegativeBar -= relativeSizeOfValue;
}
}
}
}
 
if(yOrigineNegativeBar != yOrigine){
//value negative
for(int j= 0; j<_categoryValueSeriesContainer.getNbSeries(); j++){
CategoryValueSeries categoryValueSeries = (CategoryValueSeries)allSeriesOrderByReverseDisplayNumber.elementAt(j);
if(categoryValueSeries.isVisible()){
double value = categoryValueSeries.getCategoryValueAsDouble(category.getId());
if(value != 0){
int relativeSizeOfValue = Graphics2DTools.getRelativeSizeOfValue(value, _gapValueOnY, sizeOfGapOnY);
if(value < 0){
yOrigineNegativeBar += relativeSizeOfValue;
drawBar(xBarTopLeft, yOrigineNegativeBar, widthOfBarHisto, relativeSizeOfValue,
categoryValueSeries, graphics2D);
}
}
String info = categoryValueSeries.getCategoryValue(category.getId()).getValueInformation();
int displayInfo = categoryValueSeries.getCategoryValue(category.getId()).getValueInformationDisplayMode();
if(displayInfo != CategoryValue.VALUE_INFORMATION_DISPLAY_NONE && info != null)
{
drawInfoTag(xBarTopLeft, yOrigineNegativeBar, widthOfBarHisto,
Graphics2DTools.getRelativeSizeOfValue(value, _gapValueOnY, sizeOfGapOnY),
info, displayInfo, graphics2D);
}
}
}
}
 
int yOriginePositiveBar = yOrigine;
for(int j= 0; j<_categoryValueSeriesContainer.getNbSeries(); j++){
CategoryValueSeries categoryValueSeries = (CategoryValueSeries)allSeriesOrderByDisplayNumber.elementAt(j);
if(categoryValueSeries.isVisible()){
double value = categoryValueSeries.getCategoryValueAsDouble(category.getId());
if(value != 0){
int relativeSizeOfValue = Graphics2DTools.getRelativeSizeOfValue(value, _gapValueOnY, sizeOfGapOnY);
if(value > 0){
drawBar(xBarTopLeft, yOriginePositiveBar, widthOfBarHisto, relativeSizeOfValue,
categoryValueSeries, graphics2D);
String info = categoryValueSeries.getCategoryValue(category.getId()).getValueInformation();
int displayInfo = categoryValueSeries.getCategoryValue(category.getId()).getValueInformationDisplayMode();
if(displayInfo != CategoryValue.VALUE_INFORMATION_DISPLAY_NONE && info != null)
{
drawInfoTag(xBarTopLeft, yOriginePositiveBar, widthOfBarHisto,
Graphics2DTools.getRelativeSizeOfValue(value, _gapValueOnY, sizeOfGapOnY),
info, displayInfo, graphics2D);
}
yOriginePositiveBar -= relativeSizeOfValue;
}
}
}
}
 
/*
//algorithm valid for 2d only:
int yOrigineNegativeBar = yOrigine;
int yOriginePositiveBar = yOrigine;
for(int j= 0; j<_categoryValueSeriesContainer.getNbSeries(); j++){
CategoryValueSeries categoryValueSeries = (CategoryValueSeries)allSeriesOrderByDisplayNumber.elementAt(j);
if(categoryValueSeries.isVisible()){
double value = categoryValueSeries.getCategoryValueAsDouble(category.getId());
if(value != 0){
int relativeSizeOfValue = Graphics2DTools.getRelativeSizeOfValue(value, _axisY.getGapValue(), sizeOfGapOnY);
if(value > 0){
drawBar(xBarTopLeft, yOriginePositiveBar, widthOfBarHisto, relativeSizeOfValue,
categoryValueSeries, graphics2D);
yOriginePositiveBar -= relativeSizeOfValue;
}else{
drawBar(xBarTopLeft, yOrigineNegativeBar, widthOfBarHisto, relativeSizeOfValue,
categoryValueSeries, graphics2D);
yOrigineNegativeBar -= relativeSizeOfValue;
}
}
}
}
*/
}
}
 
 
 
 
}
/trunk/project/ofccharts/src/com/oxymel/ofc/charts/VerticalAxisCommon.java
New file
0,0 → 1,52
package com.oxymel.ofc.charts;
/*
* Copyright (c) 2006 Oxymel SA.
* All rights reserved.
*
* This software is the confidential and proprietary information of Oxymel SA
* ("Confidential Information"). You shall not disclose such Confidential
* Information and shall use it only in accordance with the terms of the license
* agreement you entered into with Oxymel SA.
*/
 
//java
import java.awt.Graphics2D;
import java.awt.Font;
 
//ofc
import com.oxymel.ofc.charts.util.Graphics2DTools;
 
/**
* This class provides the common vertical axis management
*/
abstract class VerticalAxisCommon extends Axis
{
protected VerticalAxisCommon(String label)
{
super(label);
}
 
abstract protected String getLargerStringValue();
 
protected int getNbPixelUsedForWriteYValues(Graphics2D graphics2D)
{
String szMaxValueOfGapIndicator = getLargerStringValue();
if(getSuffixAllValues() != null){
szMaxValueOfGapIndicator += getSuffixAllValues();
}
 
Font font = graphics2D.getFont();
graphics2D.setFont(getFont(graphics2D));
int nbPixelFreeForWriteYValues = Graphics2DTools.getNbPixelWidthOfTxt(graphics2D, szMaxValueOfGapIndicator);
graphics2D.setFont(font);
return nbPixelFreeForWriteYValues;
}
 
 
protected int getNbPixelUsedByLabel(Graphics2D graphics2D)
{
return Graphics2DTools.getNbPixelHeightOfTxt(graphics2D, getLabel());
}
 
 
}
/trunk/project/ofccharts/src/com/oxymel/ofc/charts/GaugeChart.java
New file
0,0 → 1,482
package com.oxymel.ofc.charts;
/*
* Copyright (c) 2006 Oxymel SA.
* All rights reserved.
*
* This software is the confidential and proprietary information of Oxymel SA
* ("Confidential Information"). You shall not disclose such Confidential
* Information and shall use it only in accordance with the terms of the license
* agreement you entered into with Oxymel SA.
*/
 
//batik
import java.awt.*;
import java.awt.geom.*;
 
import org.apache.batik.svggen.*;
import com.oxymel.ofc.charts.animation.*;
import com.oxymel.ofc.charts.exception.*;
import com.oxymel.ofc.charts.series.*;
import com.oxymel.ofc.charts.util.*;
 
/**
* This class provides a gauge chart management
* It is an indicator which looks like a gauge.
* It indicates a value and all colored zone (ie: all range value)
*/
public class GaugeChart extends Chart
{
private int _nbPixelToDecalGraduation = 2;
private double _radialGradientValue = 1;
private double _radialGradientValueForAnimation = 4;
 
 
private RangeValueSeriesContainer _rangeValueSeriesContainer;
private double _gaugeValue;
 
//
ColoredVerticalNumberAxis _coloredAxis = new ColoredVerticalNumberAxis("");
 
/**
* Constructor
* @param chartWidth image width
* @param chartHeight image height
* @param rangeValueSeriesContainer colored range indicator
* @param gaugeValue value to display
* @throws OFCChartsException
*/
public GaugeChart(int chartWidth, int chartHeight,
RangeValueSeriesContainer rangeValueSeriesContainer,
double gaugeValue) throws OFCChartsException
{
super(chartWidth, chartHeight);
setRangeValueSeriesContainer(rangeValueSeriesContainer);
_gaugeValue = gaugeValue;
set3dEffectValue(10);
 
//
_coloredAxis.setAxisColor(Color.black);
_coloredAxis.setValueWriteColor(Color.black);
_coloredAxis.setArrowLength(0);
_coloredAxis.setMaxValue(Math.max(_rangeValueSeriesContainer.getMaxValue(), gaugeValue));
_coloredAxis.setMinValue(Math.min(_rangeValueSeriesContainer.getMinValue(), gaugeValue));
 
_coloredAxis.setNbColoredPixelArroundAxis(15);
_coloredAxis.setRangeValueSeriesContainer(_rangeValueSeriesContainer);
}
 
/**
* Change data used to draw chart
* @param rangeValueSeriesContainer All range value series
*/
public void setRangeValueSeriesContainer(RangeValueSeriesContainer rangeValueSeriesContainer)
{
_rangeValueSeriesContainer = rangeValueSeriesContainer;
setAllSeriesColorFromPalette(rangeValueSeriesContainer);
}
 
protected SeriesContainer getSeriesContainer(){return _rangeValueSeriesContainer;}
 
protected void doDrawChart(Graphics2D graphics2D) throws OFCChartsException
{
int xTopLeftGraphic = getXTopLeftGraphic(graphics2D);
int yTopLeftGraphic = getYTopLeftGraphic(graphics2D);
int graphicWidth = getGraphicWidth(graphics2D);
int graphicHeight = getGraphicHeight(graphics2D);
 
//drawGraphicBackground(xTopLeftGraphic, yTopLeftGraphic,
// graphicWidth, graphicHeight, graphics2D);
 
//_legend.drawLegend(getXTopLeftLegend(graphics2D), getYTopLeftLegend(graphics2D),
// getSeriesContainer().getAllSeriesOrderByDisplayNumber(), graphics2D);
 
//bug à voir plus tard
if (_legend.getLegendDisplayMode() > 0){
_legend.drawLegend(
getXTopLeftLegend(xTopLeftGraphic, yTopLeftGraphic, graphicWidth,
graphicHeight, graphics2D),
getYTopLeftLegend(xTopLeftGraphic, yTopLeftGraphic, graphicWidth,
graphicHeight, graphics2D),
getSeriesContainer().getAllSeriesOrderByDisplayNumber(), graphics2D);
}
 
drawGraphic(xTopLeftGraphic, yTopLeftGraphic, graphicWidth, graphicHeight, graphics2D, false, null);
}
 
/**
* Value 0 : no legend
* Value 1 : align right
* @param legendDisplayMode int
*/
public void setLegendDisplayMode(int legendDisplayMode) {
if (legendDisplayMode == 0) _legend.setLegendDisplayMode(Legend.LEGEND_ALIGN_MODE_NONE);
else _legend.setLegendDisplayMode(Legend.LEGEND_DISPLAY_MODE_RIGHT);
}
 
/**
* Value 0 : no legend
* Value 1 : align right
* @param legendAlignMode The legend align mode to set.
* @see Legend
*/
public void setLegendAlignMode(int legendAlignMode) {
if (legendAlignMode == 0) _legend.setLegendDisplayMode(Legend.LEGEND_ALIGN_MODE_NONE);
else _legend.setLegendDisplayMode(Legend.LEGEND_DISPLAY_MODE_RIGHT);
}
 
protected void doDrawAnimateSVGChart(SVGGraphics2D graphics2D, SVGAnimationContext svgAnimationContext) throws OFCChartsException
{
int xTopLeftGraphic = getXTopLeftGraphic(graphics2D);
int yTopLeftGraphic = getYTopLeftGraphic(graphics2D);
int graphicWidth = getGraphicWidth(graphics2D);
int graphicHeight = getGraphicHeight(graphics2D);
 
drawGraphic(xTopLeftGraphic, yTopLeftGraphic, graphicWidth, graphicHeight, graphics2D, true, svgAnimationContext);
}
 
 
private void drawGraphic(int xTopLeftGraphic, int yTopLeftGraphic, int graphicWidth, int graphicHeight,
Graphics2D graphics2D, boolean isAnimateGauge, SVGAnimationContext svgAnimationContext) throws OFCChartsException
{
int xTopLeft = xTopLeftGraphic;
int yTopLeft = yTopLeftGraphic;
int width = graphicWidth;
int height = graphicHeight;
 
//draw Thermometer base
int withThermometerBase = width/4;
int heightThermometerBase = height/4;
int xTopLeftThermometerBase = xTopLeft + width/2 - withThermometerBase/2;
int yTopLeftThermometerBase = yTopLeft + height - heightThermometerBase;
Arc2D arc = new Arc2D.Double((double)xTopLeftThermometerBase,
(double)yTopLeftThermometerBase,
(double)withThermometerBase, (double)heightThermometerBase, 120, 300 , Arc2D.OPEN);
drawArcWithRadialGradientEffect3D(arc, Color.lightGray, _radialGradientValue, graphics2D);
 
//draw tube
int withThermometerTube = (int)(arc.getEndPoint().getX() - arc.getStartPoint().getX());
int heightThermometerTube = (int)(height - heightThermometerBase + (arc.getEndPoint().getY() - yTopLeftThermometerBase));
int xTopLeftThermometerTube = xTopLeftThermometerBase + withThermometerTube/2;
int yTopLeftThermometerTube = yTopLeft;
drawTubeWithHorizontalLinearGradientEffect3D(xTopLeftThermometerTube,
yTopLeftThermometerTube, withThermometerTube, heightThermometerTube,
Color.lightGray, graphics2D);
 
//drawArcAtTopOfTube
/*
Arc2D arcTopTube = getArcTopOfTube(xTopLeftThermometerTube, yTopLeftThermometerTube,
withThermometerTube, heightThermometerTube);
graphics2D.setColor(Color.gray);
graphics2D.fill(arcTopTube);
*/
 
//draw graduation
drawGraduation(xTopLeftThermometerTube - _nbPixelToDecalGraduation, yTopLeftThermometerTube, graphicWidth,
heightThermometerTube, xTopLeftThermometerTube - _nbPixelToDecalGraduation,
yTopLeftThermometerTube + heightThermometerTube, graphics2D);
 
//
if(!isAnimateGauge){
drawThermometerValue(_gaugeValue, arc, xTopLeftThermometerTube, yTopLeftThermometerTube,
withThermometerTube, heightThermometerTube, _radialGradientValue, graphics2D);
}
else{
drawArcWithRadialGradientEffect3D(arc, Color.blue, _radialGradientValue, graphics2D);
drawAnimateThermometerValue(_gaugeValue, arc, xTopLeftThermometerTube, yTopLeftThermometerTube,
withThermometerTube, heightThermometerTube, (SVGGraphics2D)graphics2D, svgAnimationContext);
}
 
}
 
private void drawThermometerValue(double value, Arc2D arc,
int xTopLeftThermometerTube, int yTopLeftThermometerTube,
int withThermometerTube, int heightThermometerTube, double radialGradientValue,
Graphics2D graphics2D)
{
drawArcWithRadialGradientEffect3D(arc, Color.blue, radialGradientValue, graphics2D);
drawTubeAndValue(value, arc,
xTopLeftThermometerTube, yTopLeftThermometerTube,
withThermometerTube, heightThermometerTube, radialGradientValue,
graphics2D);
}
 
private void drawTubeAndValue(double value, Arc2D arc,
int xTopLeftThermometerTube, int yTopLeftThermometerTube,
int withThermometerTube, int heightThermometerTube, double radialGradientValue,
Graphics2D graphics2D)
{
double relativeSizeOfValue = Graphics2DTools.getRelativeSizeOfValue(value,
_coloredAxis.getGapValue(), _coloredAxis.getSizeOfGap());
drawValue(value, arc, Color.black, graphics2D);
double yTopLetfOfLiquideInTube = getYTopLetfOfLiquideInTube(yTopLeftThermometerTube,
heightThermometerTube, relativeSizeOfValue);
drawTubeWithHorizontalLinearGradientEffect3D(xTopLeftThermometerTube, yTopLetfOfLiquideInTube,
withThermometerTube,
getHeightOfLiquideInTube(relativeSizeOfValue, yTopLetfOfLiquideInTube, yTopLeftThermometerTube, heightThermometerTube),
Color.blue, graphics2D);
}
 
private double getYTopLetfOfLiquideInTube(int yTopLeftThermometerTube,
int heightThermometerTube, double relativeSizeOfValue)
{
if(relativeSizeOfValue >= 0){
return yTopLeftThermometerTube + heightThermometerTube - (relativeSizeOfValue +
(_coloredAxis.getSizeOfGap() * _coloredAxis.getNbNegativeGapToIncludeMinValue()));
}else{
relativeSizeOfValue = (-1) * relativeSizeOfValue;
return yTopLeftThermometerTube + heightThermometerTube -
(_coloredAxis.getSizeOfGap() * _coloredAxis.getNbNegativeGapToIncludeMinValue()) +
relativeSizeOfValue;
}
}
 
private double getHeightOfLiquideInTube(double relativeSizeOfValue, double yTopLetfOfLiquideInTube,
double yTopLeftThermometerTube, double heightThermometerTube)
{
if(relativeSizeOfValue >= 0){
return relativeSizeOfValue +
(_coloredAxis.getSizeOfGap() * _coloredAxis.getNbNegativeGapToIncludeMinValue());
}else{
double yBottomTube = yTopLeftThermometerTube + heightThermometerTube;
return yBottomTube - (yTopLetfOfLiquideInTube ) ;
}
}
 
private void drawValue(double valueToDraw, Arc2D arc, Color color, Graphics2D graphics2D)
{
graphics2D.setColor(color);
String value = ""+ (int)valueToDraw;
Font font = graphics2D.getFont();
graphics2D.setFont(getFont(graphics2D, 12));
graphics2D.drawString(value,
Graphics2DTools.getXToAlignTxt(graphics2D,
(int)(arc.getCenterX()), value),
Graphics2DTools.getYToAlignTxt(graphics2D,
(int)arc.getCenterY(), value));
graphics2D.setFont(font);
}
 
private void drawAnimateThermometerValue(double arrowValue, Arc2D arc,
int xTopLeftThermometerTube, int yTopLeftThermometerTube,
int withThermometerTube, int heightThermometerTube,
SVGGraphics2D graphics2D, SVGAnimationContext svgAnimationContext)
{
/*
SVGGraphics2DAnimateMgr.generateAnimation(graphics2D, svgAnimationContext,
new GaugeAnimation(arrowValue, arc,
xTopLeftThermometerTube, yTopLeftThermometerTube,
withThermometerTube, heightThermometerTube,
svgAnimationContext.getNbImage()));
*/
double firstValueOnAxis = _coloredAxis.getFirstValueOnAxis();
double intervalValue = Graphics2DTools.getIntervalValue(firstValueOnAxis, arrowValue);
new SVGGraphics2DAnimateMgr().generateAnimation(graphics2D, svgAnimationContext,
new GaugeAnimation(arc,
xTopLeftThermometerTube, yTopLeftThermometerTube,
withThermometerTube, heightThermometerTube,
new ValueCursor(firstValueOnAxis,
intervalValue/svgAnimationContext.getNbImage(),
arrowValue)));
 
}
 
private void drawGraduation(int xTop, int yTop, int width, int height,
int xOrigine, int yOrigine, Graphics2D graphics2D) throws OFCChartsException
{
_coloredAxis.setNbPixelSize(height);
_coloredAxis.setNbGapMax(graphics2D);
_coloredAxis.draw(width, height, xTop, yTop,
xOrigine,
yOrigine - (_coloredAxis.getSizeOfGap() * _coloredAxis.getNbNegativeGapToIncludeMinValue()),
graphics2D);
 
}
 
private void drawArcWithRadialGradientEffect3D(Arc2D arc, Color color, double angleExtent, Graphics2D graphics2D)
{
graphics2D.setColor(color);
graphics2D.fill(arc);
 
double initialAngleStart = arc.getAngleStart();
double initialAngleExtent = arc.getAngleExtent();
 
double angleStart = 0;
arc.setAngleStart(0);
arc.setAngleExtent(0);
Paint paint = graphics2D.getPaint();
while(angleStart< 360){
arc.setAngleStart(angleStart);
arc.setAngleExtent(angleExtent);
GradientPaint gradientPaint;
gradientPaint = new GradientPaint(new Point2D.Double(arc.getCenterX(), arc.getCenterY()),
Color.white, new Point2D.Double(arc.getEndPoint().getX(), arc.getEndPoint().getY()), color);
graphics2D.setPaint(gradientPaint);
graphics2D.drawLine((int)arc.getCenterX(), (int)arc.getCenterY(), (int)arc.getEndPoint().getX(), (int)arc.getEndPoint().getY());
angleStart += angleExtent;
}
graphics2D.setPaint(paint);
arc.setAngleStart(initialAngleStart);
arc.setAngleExtent(initialAngleExtent);
}
 
private void drawTubeWithHorizontalLinearGradientEffect3D(double xTopLeftThermometerTube,
double yTopLeftThermometerTube, double withThermometerTube, double heightThermometerTube,
Color color, Graphics2D graphics2D)
{
Arc2D arcTopOfTube = getArcTopOfTube(xTopLeftThermometerTube, yTopLeftThermometerTube,
withThermometerTube, heightThermometerTube);
Arc2D arcBottomOfTube = getArcBottomOfTube(xTopLeftThermometerTube, yTopLeftThermometerTube,
withThermometerTube, heightThermometerTube);
 
//tube left part
arcTopOfTube.setAngleStart(180);
arcTopOfTube.setAngleExtent(90);
arcBottomOfTube.setAngleStart(180);
arcBottomOfTube.setAngleExtent(90);
GeneralPath tubeLeftPart = getGeneralPathOfTube(arcTopOfTube, arcBottomOfTube);
 
//tube right part
arcTopOfTube.setAngleStart(270);
arcTopOfTube.setAngleExtent(90);
arcBottomOfTube.setAngleStart(270);
arcBottomOfTube.setAngleExtent(90);
GeneralPath tubeRightPart = getGeneralPathOfTube(arcTopOfTube, arcBottomOfTube);
 
//color
Paint paint = graphics2D.getPaint();
GradientPaint gradientPaint = new GradientPaint(
(float)xTopLeftThermometerTube, (float)yTopLeftThermometerTube, color,
(float)(xTopLeftThermometerTube + withThermometerTube), (float)yTopLeftThermometerTube, Color.white);
graphics2D.setPaint(gradientPaint);
graphics2D.fill(tubeLeftPart);
graphics2D.setPaint(paint);
 
gradientPaint = new GradientPaint(
(float)xTopLeftThermometerTube, (float)yTopLeftThermometerTube, Color.white,
(float)(xTopLeftThermometerTube + withThermometerTube), (float)yTopLeftThermometerTube, color);
graphics2D.setPaint(gradientPaint);
graphics2D.fill(tubeRightPart);
graphics2D.setPaint(paint);
 
//drawArcAtTopOfTube
arcTopOfTube.setAngleStart(0);
arcTopOfTube.setAngleExtent(360);
graphics2D.setColor(color.darker());
graphics2D.fill(arcTopOfTube);
}
 
private GeneralPath getGeneralPathOfTube(Arc2D arcTopOfTube, Arc2D arcBottomOfTube)
{
GeneralPath tubePart = new GeneralPath();
tubePart.moveTo((int)arcTopOfTube.getStartPoint().getX(), (int)arcTopOfTube.getStartPoint().getY());
tubePart.append(arcTopOfTube.getPathIterator(null), true);
tubePart.lineTo((int)arcTopOfTube.getEndPoint().getX(), (int)arcTopOfTube.getEndPoint().getY());
 
tubePart.lineTo((int)arcBottomOfTube.getEndPoint().getX(), (int)arcBottomOfTube.getEndPoint().getY());
tubePart.append(arcBottomOfTube.getPathIterator(null), true);
tubePart.lineTo((int)arcBottomOfTube.getStartPoint().getX(), (int)arcBottomOfTube.getStartPoint().getY());
tubePart.lineTo((int)arcTopOfTube.getStartPoint().getX(), (int)arcTopOfTube.getStartPoint().getY());
 
return tubePart;
}
 
private Arc2D getArcTopOfTube(double xTopLeftThermometerTube, double yTopLeftThermometerTube,
double withThermometerTube, double heightThermometerTube)
{
double heightTopTube = get3dEffectValue();
return new Arc2D.Double((double)xTopLeftThermometerTube,
(double)yTopLeftThermometerTube - heightTopTube/2,
(double)withThermometerTube, heightTopTube, 0, 360 , Arc2D.OPEN);
}
 
private Arc2D getArcBottomOfTube(double xTopLeftThermometerTube, double yTopLeftThermometerTube,
double withThermometerTube, double heightThermometerTube)
{
double heightBottomTube = get3dEffectValue();
double xTopLeftBottomTube = xTopLeftThermometerTube;
double yTopLeftBottomTube = yTopLeftThermometerTube + heightThermometerTube - heightBottomTube/2;
return new Arc2D.Double(xTopLeftBottomTube,
yTopLeftBottomTube,
(double)withThermometerTube, heightBottomTube, 0, 360 , Arc2D.OPEN);
}
 
 
private Font getFont(Graphics2D graphics2D, int sizeFont)
{
Font font = graphics2D.getFont();
if(sizeFont > 0){
return new Font(font.getName(), font.getStyle(), sizeFont);
}
else{
return font;
}
}
 
 
private class GaugeAnimation implements AnimationInterface
{
//
private Arc2D _arc;
private int _xTopLeftThermometerTube;
private int _yTopLeftThermometerTube;
private int _withThermometerTube;
private int _heightThermometerTube;
private ValueCursor _valueCursor;
 
 
//ValueCursor(double value, double step, double valueStart)
 
public GaugeAnimation(Arc2D arc,
int xTopLeftThermometerTube, int yTopLeftThermometerTube,
int withThermometerTube, int heightThermometerTube,
ValueCursor valueCursor)
{
//
_arc = arc;
_xTopLeftThermometerTube = xTopLeftThermometerTube;
_yTopLeftThermometerTube = yTopLeftThermometerTube;
_withThermometerTube = withThermometerTube;
_heightThermometerTube = heightThermometerTube;
 
//
_valueCursor = valueCursor;
 
//
//_valueCursor = new ValueCursor(_value, Math.abs(value)/nbImage, valueStart);
//Math.abs()
 
//_value = value;
//_step = value/nbImage;
}
 
public boolean hasNextImage()
{
return _valueCursor.hasMoreValue();
}
 
public void drawImage(SVGGraphics2D graphics2D)
{
drawTubeAndValue(_valueCursor.nextValue(), _arc, _xTopLeftThermometerTube, _yTopLeftThermometerTube,
_withThermometerTube, _heightThermometerTube, _radialGradientValue, graphics2D);
/*
if(_currentValue == _value){
_currentValue ++;
return;
}
if(_currentValue < _value){
_currentValue += _step;
if(_currentValue > _value){
_currentValue = _value;
}
}
*/
}
 
}
 
/*
public static void main(String[] argv) throws Exception
{
}
*/
}
/trunk/project/ofccharts/src/com/oxymel/ofc/charts/RadarChart.java
New file
0,0 → 1,397
package com.oxymel.ofc.charts;
/*
* Copyright (c) 2006 Oxymel SA.
* All rights reserved.
*
* This software is the confidential and proprietary information of Oxymel SA
* ("Confidential Information"). You shall not disclose such Confidential
* Information and shall use it only in accordance with the terms of the license
* agreement you entered into with Oxymel SA.
*/
 
//java
import java.util.*;
import java.awt.*;
//ofc
import com.oxymel.ofc.charts.data.*;
import com.oxymel.ofc.charts.exception.*;
import com.oxymel.ofc.charts.series.*;
 
 
public class RadarChart extends Chart
{
private RadarSeriesContainer _radarSeriesContainer;
private Vector _nameOfCategories;
private int _margin=0;
private int _nbMaxGap = 5;
private int _gapSize = 0;
private double _gapValue = 0;
private boolean _drawNet = true;
private boolean _showValues = false;
private boolean _fillArea = false;
 
public RadarChart(int chartWidth,int chartHeight,RadarSeriesContainer radarSeriesContainer,Vector nameOfCategories)
{
super(chartWidth, chartHeight);
setCategoryValueSeriesContainer(radarSeriesContainer);
_nameOfCategories = nameOfCategories;
}
 
public void setDrawNet(boolean b)
{
_drawNet = b;
}
 
public void setShowValues(boolean b)
{
_showValues = b;
}
 
public void setFillArea(boolean b)
{
_fillArea = b;
}
 
public int getLegendWidthMax(Graphics2D graphics2D)
{
int max = 0;
for(int i=0; i<_nameOfCategories.size(); i++)
{
Dimension d = getLegendDimension((String)_nameOfCategories.elementAt(i),graphics2D);
int legendWidth = (int)d.getWidth();
if(legendWidth > max)
max = legendWidth;
}
return max;
}
 
public void setCategoryValueSeriesContainer(RadarSeriesContainer radarSeriesContainer)
{
_radarSeriesContainer = radarSeriesContainer;
setAllSeriesColorFromPalette(radarSeriesContainer);
}
 
 
protected SeriesContainer getSeriesContainer(){return _radarSeriesContainer;}
 
 
protected void doDrawChart(Graphics2D graphics2D) throws OFCChartsException
{
int xTopLeftGraphic = getXTopLeftGraphic(graphics2D);
int yTopLeftGraphic = getYTopLeftGraphic(graphics2D);
int graphicWidth = getGraphicWidth(graphics2D);
int graphicHeight = getGraphicHeight(graphics2D);
 
drawGraphicBackground(xTopLeftGraphic, yTopLeftGraphic, graphicWidth, graphicHeight, graphics2D);
 
_legend.drawLegend(getXTopLeftLegend(graphics2D), getYTopLeftLegend(graphics2D),
getSeriesContainer().getAllSeriesOrderByDisplayNumber(), graphics2D);
 
/*bug à voir plus tard
_legend.drawLegend(
getXTopLeftLegend(xTopLeftGraphic, yTopLeftGraphic, graphicWidth, graphicHeight, graphics2D),
getYTopLeftLegend(xTopLeftGraphic, yTopLeftGraphic, graphicWidth, graphicHeight, graphics2D),
getSeriesContainer().getAllSeriesOrderByDisplayNumber(), graphics2D);
*/
_margin = getLegendWidthMax(graphics2D);
int valMin = Math.min(graphicWidth, graphicHeight);
valMin -=(_margin*2);
 
double max = _radarSeriesContainer.getMaxValueSeries();
_gapValue = (double)(max/_nbMaxGap);
_gapSize = valMin/_nbMaxGap;
 
xTopLeftGraphic+=_margin;
yTopLeftGraphic+=_margin;
 
for(int i=0; i<_nbMaxGap; i++)
{
if(i==0)
drawAxis(xTopLeftGraphic+(i*(_gapSize/2)), yTopLeftGraphic+(i*(_gapSize/2)), valMin-(i*_gapSize), valMin -(i*_gapSize),graphics2D, true, max-(i*_gapValue));
else
drawAxis(xTopLeftGraphic+(i*(_gapSize/2)), yTopLeftGraphic+(i*(_gapSize/2)), valMin-(i*_gapSize), valMin -(i*_gapSize),graphics2D, false, max-(i*_gapValue));
}
// drawAxis(xTopLeftGraphic+_margin, yTopLeftGraphic+_margin, valMin, valMin ,graphics2D,true);
_gapSize = (_gapSize/2);
if(_fillArea)
sortSeries();
drawGraphic(xTopLeftGraphic, yTopLeftGraphic, valMin, valMin, graphics2D);
if(_fillArea)
{
graphics2D.setColor(Color.black.brighter());
boolean drawNetSave = _drawNet;
_drawNet = false;
for(int i=0; i<_nbMaxGap; i++)
{
if(i==0)
drawAxis(xTopLeftGraphic+(i*(_gapSize)), yTopLeftGraphic+(i*(_gapSize)), valMin-(i*_gapSize*2), valMin -(i*_gapSize*2),graphics2D, true, max-(i*_gapValue));
else
drawAxis(xTopLeftGraphic+(i*(_gapSize)), yTopLeftGraphic+(i*(_gapSize)), valMin-(i*_gapSize*2), valMin -(i*_gapSize*2),graphics2D, false, max-(i*_gapValue));
}
_drawNet = drawNetSave;
}
}
 
 
private void sortSeries()
{
//la plus petite devant
int nbSeries = _radarSeriesContainer.getNbSeries();
int [] seriesWeigth = new int[nbSeries];
RadarSeries [] mySeries = new RadarSeries[nbSeries];
for(int j=0; j<nbSeries;j++)
seriesWeigth[j]=0;
Enumeration enum0 = _radarSeriesContainer.getEnumAllSeriesOrderByDisplayNumber();
int i = 0;
int maxValues = 0;
while(enum0.hasMoreElements())
{
mySeries[i] = (RadarSeries)enum0.nextElement();
if(mySeries[i].getNbValues()>maxValues)
maxValues = mySeries[i].getNbValues();
i++;
}
 
for(i=0; i<maxValues;i++)
{
// int idxMax = 0;
for(int k=0;k<mySeries.length;k++)
{
double maxValue = mySeries[k].getValueAt(i);
int poids = mySeries.length;
for(int j=0;j<mySeries.length;j++)
{
if(maxValue < mySeries[j].getValueAt(i))
{
poids--;
}
}
seriesWeigth[k]+=poids;
}
}
for(i=0;i<mySeries.length;i++)System.out.println("Serie "+mySeries[i].getId()+" poids: "+seriesWeigth[i]);
_radarSeriesContainer = new RadarSeriesContainer();
for(i=0; i<mySeries.length;i++)
{
double maxValue = -1;
int idxMax = 0;
for(int j=0;j<mySeries.length;j++)
{
if(maxValue < seriesWeigth[j])
{
maxValue = seriesWeigth[j];
idxMax = j;
}
}
seriesWeigth[idxMax] = -1;
_radarSeriesContainer.addRadarSeries(mySeries[idxMax]);
}
}
 
 
private void drawAxis(int xTopLeftGraphic, int yTopLeftGraphic, int graphicWidth, int graphicHeight,
Graphics2D graphics2D, boolean drawLegend, double maxValOnAxis)
{
int xCenter = xTopLeftGraphic + graphicHeight/2;
int yCenter = yTopLeftGraphic + graphicWidth/2;
int xDest = 0;
int yDest = 0;
 
int nbCategories = _nameOfCategories.size();
int angle = (int)(360/nbCategories);
int startAngle = 90;
int lastX = 0;
int lastY = 0;
int firstX = 0;
int firstY = 0;
 
for(int i=0; i<nbCategories ; i++)
{
Point2D p = getNewPointOfCircle(xCenter,yCenter,graphicWidth,graphicHeight,startAngle,angle,graphics2D);
xDest = (int)p.getX();
yDest = (int)p.getY();
 
int legendHeight = 0;
int legendWidth = 0;
Dimension d = null;
Stroke stroke = graphics2D.getStroke();
// if(startAngle == 90 || startAngle == 180 || startAngle == 270 || startAngle == 360 || startAngle == 0)
if(startAngle != 90 || startAngle != 180 || startAngle != 270 || startAngle != 360 || startAngle != 0)
graphics2D.setStroke(new BasicStroke(0.4f));
graphics2D.drawLine(xCenter,yCenter,xDest,yDest);
graphics2D.setStroke(stroke);
if(lastX!=0 && lastY!=0)
{
if(_drawNet)
graphics2D.drawLine(lastX,lastY,xDest,yDest);
}
else
{
String s = Double.toString(maxValOnAxis);
s=s.substring(0,s.indexOf(".")+2);
d = getLegendDimension(s,graphics2D);
legendHeight = (int)d.getHeight();
legendWidth = (int)d.getWidth();
graphics2D.drawString(s,xDest-legendWidth,yDest-1);
}
lastX = xDest;
lastY = yDest;
if(firstX==0 && firstY==0)
{
firstX = xDest;
firstY = yDest;
}
d = getLegendDimension((String)_nameOfCategories.elementAt(i),graphics2D);
legendHeight = (int)d.getHeight();
legendWidth = (int)d.getWidth();
 
int decalLegendX = 1;
int decalLegendY = 1;
 
if(startAngle > 90 && startAngle<270)
decalLegendX = -1;
else
decalLegendX = 0;
if(startAngle<=180 || startAngle==360)
decalLegendY = 0;
 
if(drawLegend)
{
if(startAngle == 90)
graphics2D.drawString((String)_nameOfCategories.elementAt(i),xDest+(legendWidth*decalLegendX),yDest+(legendHeight*decalLegendY)-10);
else
graphics2D.drawString((String)_nameOfCategories.elementAt(i),xDest+(legendWidth*decalLegendX),yDest+(legendHeight*decalLegendY));
}
 
if((startAngle + angle)>360)
startAngle = angle - (360-startAngle);
else
startAngle += angle;
}
if(_drawNet)
graphics2D.drawLine(firstX,firstY,xDest,yDest);
}
 
 
private Dimension getLegendDimension(String s, Graphics2D graphics2D)
{
FontMetrics fm = graphics2D.getFontMetrics();
int wTmp = fm.stringWidth(s);
int hTmp = fm.getHeight();
Dimension d = new Dimension(wTmp,hTmp);
return d;
}
 
 
private Point2D getNewPointOfCircle(int centreX,int centreY,int graphicWidth,int graphicHeight,int startAngle,int arcAngle,Graphics2D graphics2D)
{
Point2D point = null;
int angleBisec = startAngle;
int rayonX = graphicWidth;
int rayonY = graphicHeight;
int decalX = 1;
int decalY = 1;
System.out.println(">>>"+angleBisec);
 
if(angleBisec < 180)
decalY = -1;
 
if(angleBisec > 90 && angleBisec < 270)
{
decalX = -1;
}
 
int angleBisecTmp = angleBisec; //sauvegarde de l'angle de la bisectrice de la part courante
 
while(angleBisec > 90)
angleBisec -= 90;
 
 
if(angleBisecTmp>270 || (angleBisecTmp>90 && angleBisecTmp<=180))
{
int x = (int)(Math.sin(Math.toRadians((double)angleBisec))*((double)((rayonX)/2))); //il faudra certainement retirer la marge.
int y = (int)(Math.cos(Math.toRadians((double)angleBisec))*((double)((rayonY)/2))); //il faudra certainement retirer la marge.
x = x*decalX;
y = y*decalY;
point = new Point2D(centreX+x, centreY+y);
}
else
{
int x = (int)(Math.sin(Math.toRadians((double)angleBisec))*((double)((rayonY)/2))); //il faudra certainement retirer la marge.
int y = (int)(Math.cos(Math.toRadians((double)angleBisec))*((double)((rayonX)/2)));
x = x*decalY;
y = y*decalX;
point = new Point2D(centreX+y,centreY+x);
}
return point;
}
 
 
private void drawGraphic(int xTopLeftGraphic, int yTopLeftGraphic, int graphicWidth, int graphicHeight,Graphics2D graphics2D)
{
System.out.println("entre dans drawGraphic");
int yCenter = xTopLeftGraphic + (graphicWidth/2);
int xCenter = yTopLeftGraphic + (graphicHeight/2);
int angle = (int)(360/_nameOfCategories.size());
Enumeration enum0 = _radarSeriesContainer.getEnumAllSeriesOrderByDisplayNumber();
while(enum0.hasMoreElements())
{
RadarSeries serie = (RadarSeries)enum0.nextElement();
int angleDepart = 90;
int lastX = 0;
int lastY = 0;
int firstX = 0;
int firstY = 0;
Polygon forme = new Polygon();
Color c = serie.getColor();
for(int i = 0; i<serie.getNbValues();i++)
{
int x=0;
int y=0;
graphics2D.setColor(c);
int angleCourant = angleDepart+(i*angle);
int deplacement = (int)((double)(_gapSize*serie.getValueAt(i))/(_gapValue));
x = xCenter+(int)(Math.cos(Math.toRadians(angleCourant))*(double)deplacement);
y = yCenter-(int)(Math.sin(Math.toRadians(angleCourant))*(double)deplacement);
forme.addPoint(x,y);
if(i==0)
{
graphics2D.drawLine(x,y,x,y);
firstX = x;
firstY = y;
lastX = x;
lastY = y;
}
else
{
//on trace une ligne
graphics2D.drawLine(x,y,lastX,lastY);
lastX = x;
lastY = y;
}
if(_showValues)
{
// graphics2D.setColor(Color.black);
graphics2D.drawString(Double.toString(serie.getValueAt(i)),x,y);
// graphics2D.setColor(c);
}
//System.out.println("serie "+ serie.getNameAt(i) +" valeur:"+serie.getValueAt(i) );
}
graphics2D.drawLine(firstX,firstY,lastX,lastY);
if(_fillArea)
{
graphics2D.setColor(c);
graphics2D.fill(forme);
graphics2D.setColor(Color.black);
graphics2D.drawPolygon(forme);
graphics2D.setColor(c);
}
}
}
 
/*
public static void main(String[] args)
{
}
*/
}
/trunk/project/ofccharts/src/com/oxymel/ofc/charts/VerticalTimeAxisRight.java
New file
0,0 → 1,99
package com.oxymel.ofc.charts;
/*
* Copyright (c) 2006 Oxymel SA.
* All rights reserved.
*
* This software is the confidential and proprietary information of Oxymel SA
* ("Confidential Information"). You shall not disclose such Confidential
* Information and shall use it only in accordance with the terms of the license
* agreement you entered into with Oxymel SA.
*/
//java
import java.awt.*;
//ofc
import com.oxymel.ofc.charts.util.*;
 
class VerticalTimeAxisRight extends VerticalNumberAxisRight
{
public static final int UNIT_IS_MILLISECONDS = 1;
public static final int UNIT_IS_SECONDS = 1000;
public static final int UNIT_IS_MINUTES = 60000;
public static final int UNIT_IS_HOURS = 3600000;
 
private String _format = "HHhMMminSSs";
private int _typeUnits =UNIT_IS_MILLISECONDS;
 
public VerticalTimeAxisRight(String label)
{
super(label);
}
 
public String getTimeFormat()
{
return _format;
}
 
public int getTimeUnits()
{
return _typeUnits;
}
 
public void setTypeUnits(int unit)
{
_typeUnits = unit;
}
 
public void setFormat(String format)
{
_format = format;
}
 
protected void drawValues(int graphicWidth, int graphicHeight, int xTopLeftGraphic, int yTopLeftGraphic,
int xOrigine, int yOrigine, Graphics2D graphics2D)
{
int xAxisRight = xTopLeftGraphic + graphicWidth;
int nbGapOnY = getNbGap();
int sizeOfGapOnY = graphicHeight / nbGapOnY;
int yOfGap = yTopLeftGraphic + graphicHeight;
graphics2D.setColor(getValueWriteColor());
int gapValueOnY = getGapValue();
int currentGap = 0;
if(isContainsNegativeValue()){
currentGap = getNbNegativeGapToIncludeMinValue() * gapValueOnY * (-1);
}
for(int i=0; i<nbGapOnY + 1; i++){
String szCurrentGap = ""+currentGap;
if(getSuffixAllValues() != null){
szCurrentGap += getSuffixAllValues();
}
//>>>>
szCurrentGap = getFormattedString(szCurrentGap);
//<<<<
graphics2D.drawString(szCurrentGap, xAxisRight + _nbPixelOfGapIndicator +
_nbPixelBetweenValueAndGapIndicator,
Graphics2DTools.getYToAlignTxt(graphics2D, yOfGap, szCurrentGap));
currentGap += gapValueOnY;
yOfGap -= sizeOfGapOnY;
}
}
 
public String getFormattedString(String date)
{
return DateUtilities.getFormattedDate(_format, _typeUnits, date);
}
 
//vertical axis interface
protected String getLargerStringValue()
{
double negativeValue = 0;
if(getNbNegativeGapToIncludeMinValue() > 0){
negativeValue = getNbNegativeGapToIncludeMinValue() * getGapValue() * (-1);
}
double positiveValue = getNbGap() * getGapValue();
 
String strNegativeValue = getFormattedString("" + (int)negativeValue);
String strPositiveValue = getFormattedString("" + (int)positiveValue);
return (strPositiveValue.length() > strNegativeValue.length())? strPositiveValue : strNegativeValue;
}
 
}
/trunk/project/ofccharts/src/com/oxymel/ofc/charts/ColoredVerticalNumberAxis.java
New file
0,0 → 1,141
package com.oxymel.ofc.charts;
/*
* Copyright (c) 2006 Oxymel SA.
* All rights reserved.
*
* This software is the confidential and proprietary information of Oxymel SA
* ("Confidential Information"). You shall not disclose such Confidential
* Information and shall use it only in accordance with the terms of the license
* agreement you entered into with Oxymel SA.
*/
 
//java
import java.awt.Graphics2D;
import java.awt.Font;
import java.awt.Color;
import java.awt.Stroke;
import java.awt.BasicStroke;
import java.util.Enumeration;
 
//ofc
import com.oxymel.ofc.charts.util.Graphics2DTools;
import com.oxymel.ofc.charts.series.RangeValueSeriesContainer;
import com.oxymel.ofc.charts.series.Series;
import com.oxymel.ofc.charts.series.RangeValueSeries;
 
 
/**
* This class provides a vertical number axis which could be colored by range value
*/
class ColoredVerticalNumberAxis extends VerticalNumberAxis
{
private int _nbColoredPixelArroundAxis = 0;
private RangeValueSeriesContainer _rangeValueSeriesContainer;
 
/**
* Constructor
* @param label Axis Label
* @param rangeValueSeriesContainer
*/
public ColoredVerticalNumberAxis(String label, RangeValueSeriesContainer rangeValueSeriesContainer)
{
super(label);
_rangeValueSeriesContainer = rangeValueSeriesContainer;
}
 
ColoredVerticalNumberAxis(String label)
{
super(label);
}
 
void setNbColoredPixelArroundAxis(int nbColoredPixelArroundAxis){_nbColoredPixelArroundAxis = nbColoredPixelArroundAxis;}
void setRangeValueSeriesContainer(RangeValueSeriesContainer rangeValueSeriesContainer){_rangeValueSeriesContainer = rangeValueSeriesContainer;}
 
void draw(int graphicWidth, int graphicHeight, int xTopLeftGraphic, int yTopLeftGraphic,
int xOrigine, int yOrigine, Graphics2D graphics2D)
{
/*
double predecessorValue = 0;
int yCurrent = yOrigine;
int xTopLeft = xTopLeftGraphic - getNbPixelUsedAtLeft(graphics2D) - getNbPixelUsedAtRight(graphics2D);
int width = getNbPixelUsedAtLeft(graphics2D) + getNbPixelUsedAtRight(graphics2D);
Enumeration enumAllSeries = _rangeValueSeriesContainer.getEnumAllSeriesOrderByDisplayNumber();
while(enumAllSeries.hasMoreElements()){
RangeValueSeries valueSeries = (RangeValueSeries)enumAllSeries.nextElement();
double currentValue = valueSeries.getMax();
if(currentValue > predecessorValue){
int relativeSizeOfValue = Graphics2DTools.getRelativeSizeOfValue(currentValue - predecessorValue, getGapValue(), getSizeOfGap());
drawBar(xTopLeft, yCurrent, width, relativeSizeOfValue, valueSeries, graphics2D);
yCurrent -= relativeSizeOfValue;
predecessorValue = currentValue;
}
}
*/
 
double lastValueOnAxis = getLastValueOnAxis();
double firstValueOnAxis = getFirstValueOnAxis();
double predecessorValue = 0;
int yCurrent = yOrigine;
int xTopLeft = xTopLeftGraphic - getNbPixelUsedAtLeft(graphics2D) - getNbPixelUsedAtRight(graphics2D);
int width = getNbPixelUsedAtLeft(graphics2D) + getNbPixelUsedAtRight(graphics2D);
Enumeration enumAllSeries = _rangeValueSeriesContainer.getEnumAllSeriesOrderByDisplayNumber();
while(enumAllSeries.hasMoreElements()){
RangeValueSeries rangeValueSeries = (RangeValueSeries)enumAllSeries.nextElement();
double minInterval = rangeValueSeries.getMin();
if(minInterval < firstValueOnAxis){
minInterval = firstValueOnAxis;
}
 
double maxInterval = rangeValueSeries.getMax();
if(maxInterval > lastValueOnAxis){
maxInterval = lastValueOnAxis;
}
 
if((minInterval <0) && (maxInterval <0)){
yCurrent = yOrigine + ((-1)*Graphics2DTools.getRelativeSizeOfValue(maxInterval, getGapValue(), getSizeOfGap()));
int relativeSizeOfValue = Graphics2DTools.getRelativeSizeOfValue(minInterval - maxInterval, getGapValue(), getSizeOfGap());
drawBar(xTopLeft, yCurrent, width, relativeSizeOfValue, rangeValueSeries, graphics2D);
}
else{
if((minInterval >=0) && (maxInterval >=0)){
yCurrent = yOrigine - Graphics2DTools.getRelativeSizeOfValue(minInterval, getGapValue(), getSizeOfGap());
int relativeSizeOfValue = Graphics2DTools.getRelativeSizeOfValue(maxInterval - minInterval, getGapValue(), getSizeOfGap());
drawBar(xTopLeft, yCurrent, width, relativeSizeOfValue, rangeValueSeries, graphics2D);
}
else{
yCurrent = yOrigine;
int relativeSizeOfValue = Graphics2DTools.getRelativeSizeOfValue(minInterval, getGapValue(), getSizeOfGap());
drawBar(xTopLeft, yCurrent, width, relativeSizeOfValue, rangeValueSeries, graphics2D);
relativeSizeOfValue = Graphics2DTools.getRelativeSizeOfValue(maxInterval, getGapValue(), getSizeOfGap());
drawBar(xTopLeft, yCurrent, width, relativeSizeOfValue, rangeValueSeries, graphics2D);
}
}
}
 
super.draw(graphicWidth, graphicHeight, xTopLeftGraphic - getNbPixelUsedAtRight(graphics2D), yTopLeftGraphic,
xOrigine - getNbPixelUsedAtRight(graphics2D), yOrigine, graphics2D);
}
 
private void drawBar(int xBarTopLeft, int yOrigine, int widthOfBarHisto, int relativeSizeOfValue, Series series,
Graphics2D graphics2D)
{
int yBarTopLeft = (relativeSizeOfValue < 0)? yOrigine : yOrigine - relativeSizeOfValue;
int heightOfBarHisto = (relativeSizeOfValue < 0)? (relativeSizeOfValue*(-1)) : relativeSizeOfValue;
 
graphics2D.setColor(series.getColor());
graphics2D.fillRect(xBarTopLeft, yBarTopLeft, widthOfBarHisto, heightOfBarHisto);
//graphics2D.setColor(Color.black);
//graphics2D.drawRect(xBarTopLeft, yBarTopLeft, widthOfBarHisto, heightOfBarHisto);
}
 
int getNbPixelUsedAtLeft(Graphics2D graphics2D)
{
return super.getNbPixelUsedAtLeft(graphics2D) + 5;
}
 
int getNbPixelUsedAtRight(Graphics2D graphics2D)
{
return super.getNbPixelUsedAtRight(graphics2D) + _nbPixelOfGapIndicator + 5;
}
 
}
/trunk/project/ofccharts/src/com/oxymel/ofc/charts/Contour2D.java
New file
0,0 → 1,383
package com.oxymel.ofc.charts;
/*
* Copyright (c) 2006 Oxymel SA.
* All rights reserved.
*
* This software is the confidential and proprietary information of Oxymel SA
* ("Confidential Information"). You shall not disclose such Confidential
* Information and shall use it only in accordance with the terms of the license
* agreement you entered into with Oxymel SA.
*/
 
//java
import java.util.Vector;
import java.util.Enumeration;
 
import java.awt.geom.GeneralPath;
import java.awt.Graphics2D;
import java.awt.Color;
 
//ofc
import com.oxymel.ofc.charts.series.CategoryValueSeries;
import com.oxymel.ofc.charts.exception.OFCChartsException;
import com.oxymel.ofc.charts.util.Graphics2DTools;
import com.oxymel.ofc.charts.series.CategoryValueSeriesContainer;
import com.oxymel.ofc.charts.series.SeriesContainer;
 
import com.oxymel.ofc.charts.data.grid.Grid;
import com.oxymel.ofc.charts.data.Point2D;
import com.oxymel.ofc.charts.geographic.Isoline;
import com.oxymel.ofc.charts.geographic.Graph;
import com.oxymel.ofc.charts.geographic.Arc;
import com.oxymel.ofc.charts.geographic.Vertex;
import com.oxymel.ofc.charts.geographic.Face;
 
 
/**
* This class allows to manage 2D Contour graphics.
* It generates isolines from a grid and fill the areas delimited by these isolines with colors according to the defined ColorPalette.
*
*/
public class Contour2D extends ChartWithAxisXY
{
private VerticalNumberAxis _axisY;
private HorizontalNumberAxis _axisX;
private Grid _grid;
 
private Graph _isolineGraph;
private Isoline _isoline;
 
private Vector _allHorizontalLineInfo = new Vector();
/**
* Constructor
* @param chartWidth Chart width
* @param chartHeight Chart height
* @param axisX horizontal graduated axis
* @param axisY vertical graduated axis
* @param grid input data used to compute the isolines
* @param zStart isoline start value
* @param zEnd isoline end value
* @param zStep isoline step value
*/
public Contour2D(int chartWidth, int chartHeight,
HorizontalNumberAxis axisX, VerticalNumberAxis axisY,
Grid grid, double zStart, double zEnd, double zStep)
{
super(chartWidth, chartHeight);
_axisX = axisX;
_axisY = axisY;
_grid = grid;
_isoline = new Isoline(_grid, zStart, zEnd, zStep);
 
//default parameters
ColorPalette colorPalette = new ColorPalette();
colorPalette.initPaletteHotToColdFromData(getNumberOfData(zStart, zEnd, zStep));
this.setColorPalette(colorPalette);
setInternalGridVisible(false);
 
_legend = new LegendInterval(zStart, zEnd, zStep, colorPalette, chartHeight);
 
//_isolineGraph = _isoline.getGraph();
_isolineGraph = _isoline.getClosedGraph();
}
 
/**
* Sets color Palette.
* This Palette replaces the default one.
* @param colorPalette Palette of colors to be set
*/
public void setColorPalette(ColorPalette colorPalette)
{
super.setColorPalette(colorPalette);
if(_legend instanceof LegendInterval){
((LegendInterval)_legend).setColorPalette(colorPalette);
}
}
 
/**
* Calcul du nb de données
* @param min double
* @param max double
* @param step double
* @return int
*/
private int getNumberOfData(double min,
double max,
double step)
{
double minIntervalValue = Math.min(min, max);
double maxIntervalValue = Math.max(min, max);
step = Math.abs(step);
 
Vector _allInterval = new Vector();
int nb = 1;
 
_allInterval.addElement(nb+"");
 
double currentMinIntervalValue = minIntervalValue;
while(currentMinIntervalValue < maxIntervalValue){
nb++;
double currentMaxIntervalValue = currentMinIntervalValue + step;
if(currentMaxIntervalValue > maxIntervalValue){
currentMaxIntervalValue = maxIntervalValue;
}
 
_allInterval.addElement(nb+"");
currentMinIntervalValue = currentMaxIntervalValue;
 
}
nb++;
_allInterval.addElement(nb+"");
 
return _allInterval.size();
 
}
protected Axis getAxisX(){return _axisX;}
protected Axis getAxisY(){return _axisY;}
 
protected void setAxisParameters() throws OFCChartsException
{
_axisX.setMaxValue(_grid.getXMax());
_axisX.setMinValue(_grid.getXMin());
_axisY.setMaxValue(_grid.getYMax());
_axisY.setMinValue(_grid.getYMin());
}
 
//tmp:
protected SeriesContainer getSeriesContainer()
{
CategoryValueSeriesContainer tmp = new CategoryValueSeriesContainer();
tmp.addCategoryValueSeries(new CategoryValueSeries("s1", "toto"));
return tmp;
}
 
protected void drawGraphic(int xTopLeftGraphic, int yTopLeftGraphic, int graphicWidth, int graphicHeight,
int xOrigine, int yOrigine, Graphics2D graphics2D)
{
int sizeOfGapOnY = graphicHeight / _axisY.getNbGap();
int sizeOfGapOnX = graphicWidth / _axisX.getNbGap();
int gapValueOnX = _axisX.getGapValue();
int gapValueOnY = _axisY.getGapValue();
 
//graphics2D.setColor(_colorPalette.getColor(0));
//graphics2D.fillRect(xTopLeftGraphic, yTopLeftGraphic, graphicWidth, graphicHeight);
 
 
//Enumeration enumAllFace = _isoline.getEnumAllFace();
//* correct
Enumeration enumAllFace = _isoline.getEnumAllFaceOrderByDisplayPosition();
int nbFace = 0;
while(enumAllFace.hasMoreElements()){
nbFace ++;
Face face = (Face)enumAllFace.nextElement();
if(face.isIntervalValueDefined()){
GeneralPath facePath = new GeneralPath();
Enumeration enumAllArc = face.getEnumAllArc();
Vertex lastVertex = null;
if(enumAllArc.hasMoreElements()){
Arc arc = (Arc)enumAllArc.nextElement();
if(face.isArcFirstInGoodDirection()){
getArcGeneralPath(arc, sizeOfGapOnY, sizeOfGapOnX,
gapValueOnX, gapValueOnY, xOrigine, yOrigine, facePath, true);
lastVertex = arc.getFinalVertex();
}else{
getArcReverseGeneralPath(arc, sizeOfGapOnY, sizeOfGapOnX,
gapValueOnX, gapValueOnY, xOrigine, yOrigine, facePath, true);
lastVertex = arc.getInitialVertex();
}
}
while(enumAllArc.hasMoreElements()){
Arc arc = (Arc)enumAllArc.nextElement();
if(arc.getInitialVertex().equals(lastVertex)){
getArcGeneralPath(arc, sizeOfGapOnY, sizeOfGapOnX,
gapValueOnX, gapValueOnY, xOrigine, yOrigine, facePath, false);
lastVertex = arc.getFinalVertex();
}else{
getArcReverseGeneralPath(arc, sizeOfGapOnY, sizeOfGapOnX,
gapValueOnX, gapValueOnY, xOrigine, yOrigine, facePath, false);
lastVertex = arc.getInitialVertex();
}
}
 
facePath.closePath();
//graphics2D.setColor(Color.black);
//graphics2D.draw(facePath);
LegendInterval legend = (LegendInterval)_legend;
graphics2D.setColor(legend.getColor(face.getMinValue(), face.getMaxValue()));
graphics2D.fill(facePath);
 
Enumeration enumAllHorizontalLineInfo = _allHorizontalLineInfo.elements();
while(enumAllHorizontalLineInfo.hasMoreElements()){
HorizontalLineInfo horizontalLineInfo = (HorizontalLineInfo)enumAllHorizontalLineInfo.nextElement();
horizontalLineInfo.draw(graphicWidth, graphicHeight, xTopLeftGraphic, yTopLeftGraphic,
xOrigine, yOrigine, graphics2D);
}
 
}
}
 
//end coirrect*/
 
/*
enumAllFace = _isoline.getEnumAllFaceOrderByDisplayPosition();
nbFace = 0;
while(enumAllFace.hasMoreElements()){
nbFace ++;
Face face = (Face)enumAllFace.nextElement();
Enumeration enumAllArc = face.getEnumAllArc();
Arc arcPred = null;
if(enumAllArc.hasMoreElements()){
arcPred = (Arc)enumAllArc.nextElement();
drawArc(arcPred, sizeOfGapOnY, sizeOfGapOnX,
gapValueOnX, gapValueOnY, xOrigine, yOrigine, graphics2D);
}
while(enumAllArc.hasMoreElements()){
Arc arc = (Arc)enumAllArc.nextElement();
if(arc.isSameDirectionAsArcPredecessor(arcPred)){
drawArc(arc, sizeOfGapOnY, sizeOfGapOnX,
gapValueOnX, gapValueOnY, xOrigine, yOrigine, graphics2D);
}else{
drawArcReverse(arc, sizeOfGapOnY, sizeOfGapOnX,
gapValueOnX, gapValueOnY, xOrigine, yOrigine, graphics2D);
}
arcPred = arc;
}
 
}
System.out.println("Nb face = " + nbFace);
*/
 
/*
int nbArc = 0;
Enumeration enumAllArc = _isolineGraph.getEnumAllArc();
while(enumAllArc.hasMoreElements()){
nbArc ++;
Arc arc = (Arc)enumAllArc.nextElement();
System.out.println("arc" + nbArc + " = " + arc.toString());
drawArc(arc, sizeOfGapOnY, sizeOfGapOnX,
gapValueOnX, gapValueOnY, xOrigine, yOrigine, graphics2D);
}
System.out.println("nbArc = " + nbArc);
*/
}
 
private void drawArc(Arc arc, int sizeOfGapOnY, int sizeOfGapOnX,
int gapValueOnX, int gapValueOnY, int xOrigine, int yOrigine,
Graphics2D graphics2D)
{
GeneralPath generalPath = getArcGeneralPath(arc, sizeOfGapOnY, sizeOfGapOnX,
gapValueOnX, gapValueOnY, xOrigine, yOrigine);
graphics2D.setColor(Color.black);
graphics2D.draw(generalPath);
}
 
private GeneralPath getArcGeneralPath(Arc arc, int sizeOfGapOnY, int sizeOfGapOnX,
int gapValueOnX, int gapValueOnY, int xOrigine, int yOrigine)
{
GeneralPath generalPath = new GeneralPath();
getArcGeneralPath(arc, sizeOfGapOnY, sizeOfGapOnX,
gapValueOnX, gapValueOnY, xOrigine, yOrigine, generalPath, true);
return generalPath;
}
 
private void getArcGeneralPath(Arc arc, int sizeOfGapOnY, int sizeOfGapOnX,
int gapValueOnX, int gapValueOnY, int xOrigine, int yOrigine,
GeneralPath generalPath, boolean isFirstArcInPath)
{
//System.out.println("***** getArcGeneralPath = " + arc.toString());
 
Vertex initialVertex = arc.getInitialVertex();
//System.out.println("** Arc initialVertex = " + initialVertex.toString());
if(isFirstArcInPath){
generalPath.moveTo(
getXRelative(initialVertex.getX(), gapValueOnX, sizeOfGapOnX, xOrigine),
getYRelative(initialVertex.getY(), gapValueOnY, sizeOfGapOnY, yOrigine));
}
Enumeration enumAllIntermediaryPoint = arc.getEnumAllIntermediaryPoint();
while(enumAllIntermediaryPoint.hasMoreElements()){
Point2D intermediaryPoint = (Point2D)enumAllIntermediaryPoint.nextElement();
//System.out.println("Arc intermediaryPoint = " + intermediaryPoint.toString());
generalPath.lineTo(
getXRelative(intermediaryPoint.getX(), gapValueOnX, sizeOfGapOnX, xOrigine),
getYRelative(intermediaryPoint.getY(), gapValueOnY, sizeOfGapOnY, yOrigine));
}
Vertex finalVertex = arc.getFinalVertex();
//System.out.println("** Arc finalVertex = " + finalVertex.toString());
generalPath.lineTo(
getXRelative(finalVertex.getX(), gapValueOnX, sizeOfGapOnX, xOrigine),
getYRelative(finalVertex.getY(), gapValueOnY, sizeOfGapOnY, yOrigine));
}
 
private void drawArcReverse(Arc arc, int sizeOfGapOnY, int sizeOfGapOnX,
int gapValueOnX, int gapValueOnY, int xOrigine, int yOrigine,
Graphics2D graphics2D)
{
GeneralPath generalPath = getArcReverseGeneralPath(arc, sizeOfGapOnY, sizeOfGapOnX,
gapValueOnX, gapValueOnY, xOrigine, yOrigine);
graphics2D.setColor(Color.black);
graphics2D.draw(generalPath);
}
 
private GeneralPath getArcReverseGeneralPath(Arc arc, int sizeOfGapOnY, int sizeOfGapOnX,
int gapValueOnX, int gapValueOnY, int xOrigine, int yOrigine)
{
GeneralPath generalPath = new GeneralPath();
getArcReverseGeneralPath(arc, sizeOfGapOnY, sizeOfGapOnX,
gapValueOnX, gapValueOnY, xOrigine, yOrigine, generalPath, true);
return generalPath;
}
 
private void getArcReverseGeneralPath(Arc arc, int sizeOfGapOnY, int sizeOfGapOnX,
int gapValueOnX, int gapValueOnY, int xOrigine, int yOrigine, GeneralPath generalPath, boolean isFirstArcInPath)
{
//System.out.println("***** getArcReverseGeneralPath = " + arc.toString());
 
Vertex initialVertex = arc.getFinalVertex();
//System.out.println("** Reverse Arc initialVertex = " + initialVertex.toString());
if(isFirstArcInPath){
generalPath.moveTo(
getXRelative(initialVertex.getX(), gapValueOnX, sizeOfGapOnX, xOrigine),
getYRelative(initialVertex.getY(), gapValueOnY, sizeOfGapOnY, yOrigine));
}
Vector allIntermediaryPoint = arc.getAllIntermediaryPoint();
for(int i=allIntermediaryPoint.size() - 1; i>=0; i--){
Point2D intermediaryPoint = (Point2D)allIntermediaryPoint.elementAt(i);
//System.out.println("Reverse Arc intermediaryPoint = " + intermediaryPoint.toString());
generalPath.lineTo(
getXRelative(intermediaryPoint.getX(), gapValueOnX, sizeOfGapOnX, xOrigine),
getYRelative(intermediaryPoint.getY(), gapValueOnY, sizeOfGapOnY, yOrigine));
}
Vertex finalVertex = arc.getInitialVertex();
//System.out.println("** Reverse Arc finalVertex = " + finalVertex.toString());
generalPath.lineTo(
getXRelative(finalVertex.getX(), gapValueOnX, sizeOfGapOnX, xOrigine),
getYRelative(finalVertex.getY(), gapValueOnY, sizeOfGapOnY, yOrigine));
}
 
 
private int getXRelative(double x, int gapValueOnX, int sizeOfGapOnX, int xOrigine)
{
return xOrigine + Graphics2DTools.getRelativeSizeOfValue(x, gapValueOnX, sizeOfGapOnX);
}
 
private int getYRelative(double y, int gapValueOnY, int sizeOfGapOnY, int yOrigine)
{
return yOrigine - Graphics2DTools.getRelativeSizeOfValue(y, gapValueOnY, sizeOfGapOnY);
}
 
/**
* Adds an horizontal line info to the graphic
* @param horizontalLineInfo An horizontal line info
*/
public void addHorizontalLineInfo(HorizontalLineInfo horizontalLineInfo)
{
horizontalLineInfo.setVerticalNumberAxis(_axisY);
_allHorizontalLineInfo.addElement(horizontalLineInfo);
}
 
/*
public static void main(String[] argv) throws Exception
{
}
*/
}
/trunk/project/ofccharts/src/com/oxymel/ofc/charts/VerticalBarChart.java
New file
0,0 → 1,393
package com.oxymel.ofc.charts;
/*
* Copyright (c) 2006 Oxymel SA.
* All rights reserved.
*
* This software is the confidential and proprietary information of Oxymel SA
* ("Confidential Information"). You shall not disclose such Confidential
* Information and shall use it only in accordance with the terms of the license
* agreement you entered into with Oxymel SA.
*/
 
//java
import java.awt.*;
//batik
import org.apache.batik.svggen.*;
//ofc
import com.oxymel.ofc.charts.animation.*;
import com.oxymel.ofc.charts.exception.*;
import com.oxymel.ofc.charts.series.*;
 
 
/**
* This class manages vertical bar charts, it has subclasses allowing to customize the representation of the bar charts.
*/
public class VerticalBarChart extends BarChart
{
protected VerticalNumberAxis _axisY;
protected HorizontalCategoryAxis _axisX;
 
private VerticalBarChartRenderer _renderer;
 
/**
* Constructor
* @param chartWidth Width of vertical bar chart
* @param chartHeight Height of vertical bar chart
* @param axisX Horizontal axis to display categories
* @param axisY Vertical number axis
* @param categoryValueSeriesContainer All series of couple category-value
*/
public VerticalBarChart(int chartWidth, int chartHeight,
HorizontalCategoryAxis axisX, VerticalNumberAxis axisY,
CategoryValueSeriesContainer categoryValueSeriesContainer)
{
super(chartWidth, chartHeight, categoryValueSeriesContainer);
_axisX = axisX;
_axisY = axisY;
_renderer = new VerticalBarChartRenderer(categoryValueSeriesContainer);
_renderer.setPercentageBetweenEachBarHisto(0);
_renderer.setPercentageFreeBeforeSeries(5);
_renderer.setPercentageFreeAfterSeries(5);
}
 
//tmp à mettre sur la classe de base
/*
public void setCategoryValueSeriesContainer(CategoryValueSeriesContainer categoryValueSeriesContainer)
{
_categoryValueSeriesContainer = categoryValueSeriesContainer;
setAllSeriesColorFromPalette(categoryValueSeriesContainer);
_renderer.setCategoryValueSeriesContainer(categoryValueSeriesContainer);
}
*/
 
/**
* Provides a backward circular translation of data.
* After the operation the first data series becomes the last one, and the
* second one becomes the first and so on. This feature may be used when
* managing animated graphics for instance.
*/
public void moveDataBackCircular()
{
_categoryValueSeriesContainer.moveDataBackCircular();
}
 
/**
* Replaces the first data series by the one given as argument and then
* provides a backward circular translation of data series.
* After the operation the first data series does not exist anymore and
* the other series are translated from their original position to the previous
* one. The new last series is the one given as parameter.
* @param newValueAddAtEnd the new last data series in the container.
*/
public void moveDataBack(double newValueAddAtEnd)
{
_categoryValueSeriesContainer.moveDataBack(newValueAddAtEnd);
}
 
 
/**
* Provides a forward circular translation of data.
* After the operation the first data series becomes the second one,.., and the
* last one becomes the first and so on. This feature may be used when
* managing animated graphics for instance.
*/
 
public void moveDataForwardCircular()
{
_categoryValueSeriesContainer.moveDataForwardCircular();
}
 
/**
* Move data forward. All data are moved. The end is removed. The first value became the second value etc..
* The new data is the new first value
*/
/**
* Replaces the last data series by the one given as argument and then
* provides a forward circular translation of data series.
* After the operation the last data series does not exist anymore and
* the other series are translated from their original position to the next
* one. The new first series is the one given as parameter.
* @param newValueAddAtStart the new first data series in the container.
*/
public void moveDataForward(double newValueAddAtStart)
{
_categoryValueSeriesContainer.moveDataForward(newValueAddAtStart);
}
 
/**
* Sets the legend display mode. The legend may look like a table.
* @param legendDisplayMode The legend display mode to be set.
* @see Legend
*/
public void setLegendDisplayMode(int legendDisplayMode)
{
if((_legend.getLegendDisplayMode() == Legend.LEGEND_DISPLAY_MODE_TABLE) &&
(legendDisplayMode != Legend.LEGEND_DISPLAY_MODE_TABLE)){
_legend = new Legend();
}
 
if(legendDisplayMode == Legend.LEGEND_DISPLAY_MODE_TABLE){
_legend = new LegendTable(_renderer.getCategoryValueSeriesContainer());
return;
}
super.setLegendDisplayMode(legendDisplayMode);
}
 
protected VerticalBarChartRenderer getChartRenderer(){return _renderer;};
 
protected void setAxisXDrawingInfo()
{
_axisX.setNbPixelDecalYToStartWriteValues(
_axisY.getNbNegativeGapToIncludeMinValue() * _axisY.getSizeOfGap());
}
 
protected BarChartRenderer getBarChartRenderer(){return _renderer;}
 
protected Axis getAxisX(){return _axisX;}
protected Axis getAxisY(){return _axisY;}
 
protected void setAxisParameters() throws OFCChartsException
{
_axisX.setAllCategoriesOrderByDisplayNumber(_categoryValueSeriesContainer.getAllCategoriesOrderByDisplayNumber());
_axisY.setMaxValue(_categoryValueSeriesContainer.getMaxValueOfAllSeries());
_axisY.setMinValue(_categoryValueSeriesContainer.getMinValueOfAllSeries());
 
}
 
protected void drawGraphic(int xTopLeftGraphic, int yTopLeftGraphic, int graphicWidth, int graphicHeight,
int xOrigine, int yOrigine, Graphics2D graphics2D)
{
//rapide integration en force a changer
if(_legend instanceof LegendTable){
((LegendTable)_legend).setNbPixelColumnWidth(_axisX.getSizeOfGap());
((LegendTable)_legend).setXOrigine(xOrigine);
((LegendTable)_legend).setYOrigine(yOrigine);
}
//fin rapide integration
 
//VerticalBarChartRenderer renderer = new VerticalBarChartRenderer(getCategoryValueSeriesContainer());
VerticalBarChartRenderer renderer = _renderer;
renderer.setNbGapOnX(_axisX.getNbGap());
renderer.setNbGapOnY(_axisY.getNbGap());
renderer.setGapValueOnY(_axisY.getGapValue());
//BEGIN_BLOCKER_CHART_3D
renderer.set3dEffectValue(get3dEffectValue());
//END_BLOCKER_CHART_3D
renderer.drawGraphic(xTopLeftGraphic, yTopLeftGraphic, graphicWidth, graphicHeight,
xOrigine, yOrigine, graphics2D);
}
 
 
protected void drawAnimateGraphic(int xTopLeftGraphic, int yTopLeftGraphic, int graphicWidth, int graphicHeight,
int xOrigine, int yOrigine, SVGGraphics2D graphics2D, SVGAnimationContext svgAnimationContext)
{
if(svgAnimationContext.isExternalAnimation()){
drawGraphic(xTopLeftGraphic, yTopLeftGraphic, graphicWidth, graphicHeight,
xOrigine, yOrigine, graphics2D);
return;
}
 
//rapide integration en force (sale) a changer
if(_legend instanceof LegendTable){
((LegendTable)_legend).setNbPixelColumnWidth(_axisX.getSizeOfGap());
((LegendTable)_legend).setXOrigine(xOrigine);
((LegendTable)_legend).setYOrigine(yOrigine);
}
//fin rapide integration
 
//VerticalBarChartRenderer renderer = new VerticalBarChartRenderer(getCategoryValueSeriesContainer());
VerticalBarChartRenderer renderer = getChartRenderer();
renderer.setNbGapOnX(_axisX.getNbGap());
renderer.setNbGapOnY(_axisY.getNbGap());
renderer.setGapValueOnY(_axisY.getGapValue());
//BEGIN_BLOCKER_CHART_3D
renderer.set3dEffectValue(get3dEffectValue());
//END_BLOCKER_CHART_3D
//renderer.drawGraphic(xTopLeftGraphic, yTopLeftGraphic, graphicWidth, graphicHeight,
// xOrigine, yOrigine, graphics2D);
 
 
drawAnimateCircularGraphic(renderer,
xTopLeftGraphic, yTopLeftGraphic, graphicWidth, graphicHeight,
xOrigine, yOrigine, graphics2D, svgAnimationContext);
 
}
 
private void drawAnimateCircularGraphic(VerticalBarChartRenderer renderer,
int xTopLeftGraphic, int yTopLeftGraphic, int graphicWidth, int graphicHeight,
int xOrigine, int yOrigine, SVGGraphics2D graphics2D, SVGAnimationContext svgAnimationContext)
{
new SVGGraphics2DAnimateMgr().generateAnimation((SVGGraphics2D)graphics2D, svgAnimationContext,
new CircularAnimation( renderer,
xTopLeftGraphic, yTopLeftGraphic, graphicWidth, graphicHeight,
xOrigine, yOrigine));
}
 
private class CircularAnimation implements AnimationInterface
{
private VerticalBarChartRenderer _renderer;
private int _xTopLeftGraphic;
private int _yTopLeftGraphic;
private int _graphicWidth;
private int _graphicHeight;
private int _xOrigine;
private int _yOrigine;
 
//
int _currentImage = 0;
int _nbImage;
 
public CircularAnimation(VerticalBarChartRenderer renderer,
int xTopLeftGraphic, int yTopLeftGraphic, int graphicWidth, int graphicHeight,
int xOrigine, int yOrigine)
{
//
_renderer = renderer;
_xTopLeftGraphic = xTopLeftGraphic;
_yTopLeftGraphic = yTopLeftGraphic;
_graphicWidth = graphicWidth;
_graphicHeight = graphicHeight;
_xOrigine = xOrigine;
_yOrigine = yOrigine;
 
//
_nbImage = _renderer.getCategoryValueSeriesContainer().getNbCategories() + 1;
}
 
public boolean hasNextImage()
{
return (_currentImage < _nbImage);
}
 
public void drawImage(SVGGraphics2D graphics2D)
{
_renderer.drawGraphic(_xTopLeftGraphic, _yTopLeftGraphic, _graphicWidth, _graphicHeight,
_xOrigine, _yOrigine, graphics2D);
_currentImage++;
if(hasNextImage()){
_categoryValueSeriesContainer.moveDataBackCircular();
/*
Vector allCategories = _categoryValueSeriesContainer.getAllCategoriesOrderByDisplayNumber();
Enumeration enumAllSeries = _categoryValueSeriesContainer.getEnumAllSeriesOrderByDisplayNumber();
while(enumAllSeries.hasMoreElements()){
CategoryValueSeries categoryValueSeries = (CategoryValueSeries)enumAllSeries.nextElement();
Category category = (Category)allCategories.elementAt(0);
CategoryValue categoryValue = categoryValueSeries.getCategoryValue(category.getId());
double firstValue = categoryValue.getValue();
 
for(int i= 1; i<allCategories.size(); i++){
category = (Category)allCategories.elementAt(i);
CategoryValue categoryValueToMove = categoryValueSeries.getCategoryValue(category.getId());
categoryValue.setValue(categoryValueToMove.getValue());
categoryValue = categoryValueToMove;
}
categoryValue.setValue(firstValue);
}
*/
}
}
}
 
 
 
 
/*
protected void drawGraphic(int xTopLeftGraphic, int yTopLeftGraphic, int graphicWidth, int graphicHeight,
int xOrigine, int yOrigine, Graphics2D graphics2D)
{
int sizeOfGapOnY = graphicHeight / _axisY.getNbGap();
int sizeOfGapOnX = graphicWidth / _axisX.getNbGap();
 
//draw bar histo
int widthOfBarHisto = sizeOfGapOnX - _nbPixelFreeBeforeSeries - _nbPixelFreeAfterSeries;
int nbSeries = _categoryValueSeriesContainer.getNbSeries();
if(nbSeries > 0){
widthOfBarHisto -= ((_categoryValueSeriesContainer.getNbSeries() - 1) * _nbPixelBetweenEachBarHisto);
widthOfBarHisto = widthOfBarHisto / nbSeries;
}
 
Vector allCategories = _categoryValueSeriesContainer.getAllCategoriesOrderByDisplayNumber();
 
for(int i= 0; i<allCategories.size(); i++){
Category category = (Category)allCategories.elementAt(i);
int xBarTopLeft = xOrigine + (sizeOfGapOnX * i) + _nbPixelFreeBeforeSeries;
 
Enumeration enumAllSeries = _categoryValueSeriesContainer.getEnumAllSeriesOrderByDisplayNumber();
while(enumAllSeries.hasMoreElements()){
CategoryValueSeries categoryValueSeries = (CategoryValueSeries)enumAllSeries.nextElement();
if(categoryValueSeries.isVisible()){
double value = categoryValueSeries.getCategoryValueAsDouble(category.getId());
if(value != 0){
 
drawBar(xBarTopLeft, yOrigine, widthOfBarHisto,
Graphics2DTools.getRelativeSizeOfValue(value, _axisY.getGapValue(), sizeOfGapOnY),
categoryValueSeries, graphics2D);
}
}
xBarTopLeft += widthOfBarHisto + _nbPixelBetweenEachBarHisto;
}
//xOfGap += _nbPixelFreeAfterSeries;
}
}
*/
 
/*
protected void drawBar(int xBarTopLeft, int yOrigine, int widthOfBarHisto, int relativeSizeOfValue, CategoryValueSeries series,
Graphics2D graphics2D)
{
int yBarTopLeft = (relativeSizeOfValue < 0)? yOrigine : yOrigine - relativeSizeOfValue;
int heightOfBarHisto = (relativeSizeOfValue < 0)? (relativeSizeOfValue*(-1)) : relativeSizeOfValue;
 
graphics2D.setColor(series.getColor());
graphics2D.fillRect(xBarTopLeft, yBarTopLeft, widthOfBarHisto, heightOfBarHisto);
graphics2D.setColor(Color.black);
graphics2D.drawRect(xBarTopLeft, yBarTopLeft, widthOfBarHisto, heightOfBarHisto);
//graphics2D.draw3DRect(xBarTopLeft, yBarTopLeft, widthOfBarHisto, heightOfBarHisto, false);
 
//BEGIN_BLOCKER_CHART_3D
if(get3dEffectValue() != 0){
set3DEffect(xBarTopLeft, yBarTopLeft, widthOfBarHisto, heightOfBarHisto, get3dEffectValue(), series, graphics2D);
}
//END_BLOCKER_CHART_3D
}
*/
 
/*
//BEGIN_BLOCKER_CHART_3D
private void set3DEffect(int xBarTopLeft, int yBarTopLeft, int widthOfBarHisto, int heightOfBarHisto, int effect3dValue,
CategoryValueSeries series, Graphics2D graphics2D)
{
GeneralPath bar3dRight = new GeneralPath();
bar3dRight.moveTo((float)(xBarTopLeft + widthOfBarHisto), (float)yBarTopLeft);
bar3dRight.lineTo((float)(xBarTopLeft + widthOfBarHisto), (float)(yBarTopLeft+heightOfBarHisto));
bar3dRight.lineTo((float)(xBarTopLeft + widthOfBarHisto + effect3dValue),
(float)(yBarTopLeft + heightOfBarHisto - effect3dValue));
bar3dRight.lineTo((float)(xBarTopLeft + widthOfBarHisto+effect3dValue), (float)(yBarTopLeft - effect3dValue));
//graphics2D.setColor(series.getColor().darker());
graphics2D.setColor(series.getColor().darker().darker());
graphics2D.fill(bar3dRight);
 
GeneralPath bar3dTop = new GeneralPath();
bar3dTop.moveTo( (float) xBarTopLeft, (float) yBarTopLeft);
bar3dTop.lineTo((float) (xBarTopLeft + effect3dValue), (float) (yBarTopLeft - effect3dValue));
bar3dTop.lineTo((float) (xBarTopLeft + widthOfBarHisto+effect3dValue), (float) (yBarTopLeft - effect3dValue));
bar3dTop.lineTo((float) (xBarTopLeft + widthOfBarHisto), (float) (yBarTopLeft) );
//graphics2D.setColor(series.getColor().brighter());
graphics2D.setColor(series.getColor().darker());
graphics2D.fill(bar3dTop);
 
graphics2D.setColor(Color.black);
graphics2D.draw(bar3dRight);
graphics2D.draw(bar3dTop);
 
}
//END_BLOCKER_CHART_3D
*/
 
/*
public static void main(String[] argv) throws Exception
{
}
*/
 
}
/trunk/project/ofccharts/src/com/oxymel/ofc/charts/VerticalLinePlot.java
New file
0,0 → 1,147
package com.oxymel.ofc.charts;
/*
* Copyright (c) 2006 Oxymel SA.
* All rights reserved.
*
* This software is the confidential and proprietary information of Oxymel SA
* ("Confidential Information"). You shall not disclose such Confidential
* Information and shall use it only in accordance with the terms of the license
* agreement you entered into with Oxymel SA.
*/
 
//java
import java.util.*;
import java.awt.*;
import com.oxymel.ofc.charts.data.*;
import com.oxymel.ofc.charts.exception.*;
import com.oxymel.ofc.charts.series.*;
import com.oxymel.ofc.charts.util.*;
 
/**
* This class provides a vertical line plot
*/
public class VerticalLinePlot
extends ChartWithAxisXY {
 
private int _nbPixelFreeBeforeUnit = 5;
 
private VerticalNumberAxis _axisY;
private HorizontalNumberAxis _axisX;
 
private Point2DSeriesContainer _point2DSeriesContainer;
 
/**
* Constructor
* @param chartWidth Width of vertical bar chart
* @param chartHeight Height of vertical bar chart
* @param axisX Horizontal axis to display categories
* @param axisY Vertical number axis
* @param point2DSeriesContainer All series of couple category-value
*/
public VerticalLinePlot(int chartWidth, int chartHeight,
HorizontalNumberAxis axisX, VerticalNumberAxis axisY,
Point2DSeriesContainer point2DSeriesContainer) {
super(chartWidth, chartHeight);
_legend.setDisplayAsBar(false);
_axisX = axisX;
_axisY = axisY;
setPoint2DSeriesContainer(point2DSeriesContainer);
}
 
/**
* Change data used to draw chart
* @param point2DSeriesContainer All series of couple category-value
*/
public void setPoint2DSeriesContainer(Point2DSeriesContainer
point2DSeriesContainer) {
_point2DSeriesContainer = point2DSeriesContainer;
setAllSeriesColorFromPalette(point2DSeriesContainer);
}
 
protected SeriesContainer getSeriesContainer() {
return _point2DSeriesContainer;
}
 
protected Axis getAxisX() {
return _axisX;
}
 
protected Axis getAxisY() {
return _axisY;
}
 
protected void setAxisParameters() throws OFCChartsException {
_axisX.setMinValue(_point2DSeriesContainer.getXMinOfAllSeries());
_axisX.setMaxValue(_point2DSeriesContainer.getXMaxOfAllSeries());
//_axisX.setFontSize(9);
 
_axisY.setMinValue(_point2DSeriesContainer.getYMinOfAllSeries());
_axisY.setMaxValue(_point2DSeriesContainer.getYMaxOfAllSeries());
_axisY.setNbGapMax(10);
}
 
protected void drawGraphic(int xTopLeftGraphic, int yTopLeftGraphic,
int graphicWidth, int graphicHeight,
int xOrigine, int yOrigine, Graphics2D graphics2D) {
int sizeOfGapOnY = graphicHeight / _axisY.getNbGap();
int sizeOfGapOnX = graphicWidth / _axisX.getNbGap();
int gapValueOnX = _axisX.getGapValue();
int gapValueOnY = _axisY.getGapValue();
Enumeration enumAllSeries = _point2DSeriesContainer.
getEnumAllSeriesOrderByDisplayNumber();
while (enumAllSeries.hasMoreElements()) {
Point2DSeries point2DSeries = (Point2DSeries) enumAllSeries.nextElement();
if (point2DSeries.isVisible()) {
drawLine(xOrigine, yOrigine, point2DSeries, gapValueOnX, sizeOfGapOnX,
gapValueOnY, sizeOfGapOnY, graphics2D);
}
}
 
}
 
private void drawLine(int xOrigine, int yOrigine, Point2DSeries point2DSeries,
int gapValueOnX, int sizeOfGapOnX,
int gapValueOnY, int sizeOfGapOnY,
Graphics2D graphics2D) {
graphics2D.setColor(point2DSeries.getColor());
 
Enumeration enumAllPoint2D = point2DSeries.getEnumAllPoint2D();
if (!enumAllPoint2D.hasMoreElements()) {
return;
}
Point2D initialPoint = (Point2D) enumAllPoint2D.nextElement();
while (enumAllPoint2D.hasMoreElements()) {
Point2D finalPoint = (Point2D) enumAllPoint2D.nextElement();
 
int x1 = xOrigine +
Graphics2DTools.getRelativeSizeOfValue(initialPoint.getX(),
gapValueOnX, sizeOfGapOnX);
int y1 = yOrigine -
Graphics2DTools.getRelativeSizeOfValue(initialPoint.getY(),
gapValueOnY, sizeOfGapOnY);
int x2 = xOrigine +
Graphics2DTools.getRelativeSizeOfValue(finalPoint.getX(), gapValueOnX,
sizeOfGapOnX);
int y2 = yOrigine -
Graphics2DTools.getRelativeSizeOfValue(finalPoint.getY(), gapValueOnY,
sizeOfGapOnY);
 
point2DSeries.drawIndicator(x1, y1, graphics2D);
point2DSeries.drawIndicator(x2, y2, graphics2D);
 
Stroke initialStroke = graphics2D.getStroke();
graphics2D.setStroke(new BasicStroke(2.0f));
graphics2D.drawLine(x1, y1, x2, y2);
graphics2D.setStroke(initialStroke);
initialPoint = finalPoint;
}
}
 
/*
public static void main(String[] argv) throws Exception
{
 
}
*/
 
}
/trunk/project/ofccharts/src/com/oxymel/ofc/charts/ExplodedPieChart.java
New file
0,0 → 1,755
package com.oxymel.ofc.charts;
/*
* Copyright (c) 2006 Oxymel SA.
* All rights reserved.
*
* This software is the confidential and proprietary information of Oxymel SA
* ("Confidential Information"). You shall not disclose such Confidential
* Information and shall use it only in accordance with the terms of the license
* agreement you entered into with Oxymel SA.
*/
 
//java
import java.util.*;
 
import java.awt.*;
 
import com.oxymel.ofc.charts.exception.*;
import com.oxymel.ofc.charts.series.*;
 
public class ExplodedPieChart
extends Chart {
/**
* The value to set if the tags to write are labels.
* Example : <br>
* <li>pieChart.setTypeOfTag( ExplodedPieChart.TAG_LABEL );
*/
public static final int TAG_LABEL = 1;
 
/**
* The value to set if the tags to write are values (default).
* Example : <br>
* <li>pieChart.setTypeOfTag( ExplodedPieChart.TAG_VALUE );
*/
public static final int TAG_VALUE = 2;
 
private int _typeOfTag = TAG_VALUE;
private ValueSeriesContainer _valueSeriesContainer;
 
//these attributes can be setting by user
private boolean _isCircular = true;
private boolean _verticalEllipse = false;
private boolean _is3D = false;
private boolean _isPieWithTags = false;
 
private double _marginPercent = 0.2; //default value equals 20 per cent of image size, translation width is (_margin/2)
private int maxDegree = 360;
private boolean _isTagLabelToCut = false;
private int _minPercentToDisplayTag = 2;
 
//these attributes are used by API to define display appearence
private int _profondeur = 16;
private int _margin = 0;
private double _rationElipseX = 1.0;
private double _rationElipseY = 1.0;
private int _externalGraphicLegendMargin = 0;
/**
* Constructor of the exploded pie chart.
* @param chartWidth Width of pie chart
* @param chartHeight Height of pie chart
* @param valueSeriesContainer ValueSeriesContainer - All series of couple category-value
*/
public ExplodedPieChart(int chartWidth, int chartHeight,
ValueSeriesContainer valueSeriesContainer) {
super(chartWidth, chartHeight);
setCategoryValueSeriesContainer(valueSeriesContainer);
}
 
/**
* Constructor of the exploded pie chart.
* @param chartWidth int
* @param chartHeight int
* @param valueSeriesContainer ValueSeriesContainer - All series of couple category-value
* @param margin double (default value = 0.02 corresponding to 20% of the image size)
*/
public ExplodedPieChart(int chartWidth, int chartHeight,
ValueSeriesContainer valueSeriesContainer,
double margin) {
super(chartWidth, chartHeight);
setCategoryValueSeriesContainer(valueSeriesContainer);
_marginPercent = margin;
}
 
/**
* Change margin value.
* @param margin new margin value
*/
public void setMargin(int margin) {
_margin = margin;
}
 
/**
* To set the external graphic legend margin (default value = 0).<br>
* Allows to extend the line between the graphic and the legend.
* @param longTag int
*/
public void setTagOnPieWidth(int longTag) {
_externalGraphicLegendMargin = longTag;
}
 
/**
* If is3D is true, the pie chart is displayed on 3D.
* @param is3D boolean
*/
public void set3D(boolean is3D) {
_is3D = is3D;
if (!_is3D)
_profondeur = 0;
}
 
/**
* Sets the value of the 3D effect.
* @param profondeur int
*/
public void set3Dprofondeur(int prof) {
_profondeur = prof;
if (_profondeur > 0) _is3D = true;
}
 
/**
* If isCircular is true, the pie chart is displayed as circular Pie.
* @param isCircular boolean
*/
public void setCircular(boolean isCircular) {
_isCircular = isCircular;
}
 
/**
* If verticalEllipse is true, the pie chart is displayed as a vertical Ellipse.
* @param verticalEllipse boolean
*/
public void setVerticalEllipse(boolean verticalEllipse) {
_verticalEllipse = verticalEllipse;
}
 
/**
* If isPieWithTags is true, each arc of the pie chart has a legend tag.
* @param isPieWithTags boolean
*/
public void setPieWithTags(boolean isPieWithTags) {
_isPieWithTags = isPieWithTags;
}
 
/**
* Sets the type of legend on the tags.<br>
* Possibles value are :
* <ul>
* <li>ExplodedPieChart.TAG_VALUE (default)
* <li>ExplodedPieChart.TAG_LABEL
* </ul>
* @param type int
*/
public void setTypeOfTag(int type) {
if (type == TAG_VALUE) {
_externalGraphicLegendMargin = 1;
_marginPercent = 0.05;
}
_typeOfTag = type;
}
 
/**
* If isHalfPie is true, the pie chart is displayed as an half pie (0-180°).
* @param isHalfPie boolean
*/
public void setIsHalfPie(boolean isHalfPie) {
if (isHalfPie)
maxDegree = 180;
else
maxDegree = 360;
}
 
/**
* Allows to cut the long labels on the graphic's sections if toCut is true.
* If toCut is false, the long labels will be replaced by the value.
* @param toCut boolean
*/
public void setTagLabelToCut(boolean toCut) {
_isTagLabelToCut = toCut;
}
 
private boolean getTagLabelToCut(){
if (_typeOfTag == TAG_LABEL)
return _isTagLabelToCut;
else return false;
 
}
/**
* Allows to fix the minimum percent value to display tag (by default minPercentToDisplayTag = 2).
* @param minPercentToDisplayTag int
*/
public void setMinPercentToDisplayTag(int minPercentToDisplayTag) {
_minPercentToDisplayTag = minPercentToDisplayTag;
}
 
 
/**
* Changes the data used to draw chart.
* @param categoryValueSeriesContainer ValueSeriesContainer - All series of couple category-value
*/
public void setCategoryValueSeriesContainer(ValueSeriesContainer
valueSeriesContainer) {
_valueSeriesContainer = valueSeriesContainer;
setAllSeriesColorFromPalette(valueSeriesContainer);
}
 
int maxLabelSize = 0;
protected SeriesContainer getSeriesContainer() {
return _valueSeriesContainer;
}
 
protected void doDrawChart(Graphics2D graphics2D) throws OFCChartsException {
int xTopLeftGraphic = getXTopLeftGraphic(graphics2D);
int yTopLeftGraphic = getYTopLeftGraphic(graphics2D);
int graphicWidth = getGraphicWidth(graphics2D);
int graphicHeight = getGraphicHeight(graphics2D);
 
drawGraphicBackground(xTopLeftGraphic, yTopLeftGraphic,
graphicWidth, graphicHeight, graphics2D);
 
_legend.drawLegend(getXTopLeftLegend(graphics2D),
getYTopLeftLegend(graphics2D),
getSeriesContainer().getAllSeriesOrderByDisplayNumber(),
graphics2D);
 
/*bug à voir plus tard
_legend.drawLegend(
getXTopLeftLegend(xTopLeftGraphic, yTopLeftGraphic, graphicWidth, graphicHeight, graphics2D),
getYTopLeftLegend(xTopLeftGraphic, yTopLeftGraphic, graphicWidth, graphicHeight, graphics2D),
getSeriesContainer().getAllSeriesOrderByDisplayNumber(), graphics2D);
*/
int graphWidth = getGraphicWidth(graphics2D);
int graphHeight = getGraphicHeight(graphics2D);
 
int decalY = 0;
int maxLengthLegend = 0;
updateRatio(graphWidth, graphHeight); //update _ratioEllipseX and _ratioEllipseY attributes
 
//if only half Pie is displayed, final graph have to be centered on Image
if (maxDegree == 180)
decalY = graphHeight / 4;
 
// if tags are displayed on graph, free space is allowed on GraphWith
// this free space size is defined with Font and the longer Word to display
if (_isPieWithTags) {
maxLengthLegend = getMaxLengthForLegend(graphics2D) + _externalGraphicLegendMargin;
if (_typeOfTag == TAG_LABEL) {
//permet de couper les labels trops longs
if (getTagLabelToCut()) {
int nbToCut = 0;
while (maxLengthLegend > graphWidth / 4) {
nbToCut++;
maxLengthLegend = getMaxLengthForLegend(graphics2D, nbToCut) +
_externalGraphicLegendMargin;
}
}
else {
if (maxLengthLegend > graphWidth / 4) {
_typeOfTag = TAG_VALUE;
maxLengthLegend = getMaxLengthForLegend(graphics2D) +
_externalGraphicLegendMargin;
}
}
}
graphWidth -= (maxLengthLegend * 2);
}
 
if (_isCircular) {
int valMin = Math.min(graphWidth, graphHeight);
_margin = (int) (valMin * _marginPercent); //initialization of _margin value
 
int x = xTopLeftGraphic + ( (graphWidth - valMin) / 2) + maxLengthLegend;
int y = yTopLeftGraphic + ( (graphHeight - valMin) / 2) + decalY;
if (_is3D) {
for (int i = _profondeur; i > 0; i--)
drawGraphic3D(x, y + i, valMin, valMin, graphics2D);
}
drawGraphic(x, y, valMin, valMin, graphics2D);
}
else {
int decalHeight = 0;
int decalWidth = 0;
//if graph is displayed as vertical Ellipse, Dimensions of drawing area are transformed to obtain Heigth longer than width
if (_verticalEllipse) {
if (graphWidth >= graphHeight) { //transforme en rectangle une zone de dessin carré pour obtenir une ellipse
decalWidth = graphWidth - graphHeight;
graphWidth = graphHeight;
graphWidth = (int) ( (double) graphWidth * 0.80);
decalWidth += (int) ( (double) graphWidth * 0.20);
}
}
else {
if (graphWidth <= graphHeight) { //transforme en rectangle une zone de dessin carré pour obtenir une ellipse
decalHeight = graphHeight - graphWidth;
graphHeight = graphWidth;
graphHeight = (int) ( (double) graphHeight * 0.80);
decalHeight += (int) ( (double) graphHeight * 0.20);
}
}
 
int valMin = Math.min(graphWidth, graphHeight);
_margin = (int) (valMin * _marginPercent); //initialization of _margin value
 
int x = xTopLeftGraphic + maxLengthLegend + (decalWidth / 2);
int y = yTopLeftGraphic + (decalHeight / 2) + decalY;
if (_is3D) {
for (int i = _profondeur; i > 0; i--)
drawGraphic3D(x, y + i, graphWidth, graphHeight - (_profondeur * 2),
graphics2D);
}
drawGraphic(x, y, graphWidth, graphHeight - (_profondeur * 2), graphics2D);
}
}
 
/**
* This method get max StringWidth to display as tag legend
*/
private int getMaxLengthForLegend(Graphics2D graphics2D) {
Vector allPieSeries = _valueSeriesContainer.getAllSeriesOrderByDisplayNumber();
int max = 0;
for (int i = 0; i < allPieSeries.size(); i++) {
PieSeries pieSeries = (PieSeries) allPieSeries.elementAt(i);
FontMetrics fm = graphics2D.getFontMetrics();
int tmp = 0;
if (_typeOfTag == TAG_VALUE)
tmp = fm.stringWidth(Integer.toString( (int) pieSeries.getValue()));
else {
tmp = fm.stringWidth(pieSeries.getLegendLabel());
if (maxLabelSize == 0 ||
maxLabelSize < pieSeries.getLegendLabel().length())
maxLabelSize = pieSeries.getLegendLabel().length();
}
if (max < tmp)
max = tmp;
}
return max;
}
 
/**
* This method get max StringWidth to display as tag legend
* adaptate to the graphic width
* @param graphics2D Graphics2D
* @param nbToCut int
* @return int
*/
private int getMaxLengthForLegend(Graphics2D graphics2D, int nbToCut) {
Vector allPieSeries = _valueSeriesContainer.getAllSeriesOrderByDisplayNumber();
int max = 0;
maxLabelSize = maxLabelSize - nbToCut;
 
for (int i = 0; i < allPieSeries.size(); i++) {
PieSeries pieSeries = (PieSeries) allPieSeries.elementAt(i);
FontMetrics fm = graphics2D.getFontMetrics();
int tmp = 0;
if (_typeOfTag == TAG_VALUE)
tmp = fm.stringWidth(Integer.toString( (int) pieSeries.getValue()));
else {
String label = pieSeries.getLegendLabel();
if (label.length() > maxLabelSize)
label = label.substring(0, maxLabelSize);
tmp = fm.stringWidth(label);
}
if (max < tmp)
max = tmp;
}
 
return max;
}
 
/**
* This method update ration values to display graph as Ellipse
*/
private void updateRatio(int width, int height) {
if (width > height) {
_rationElipseY = (double) ( ( (double) height) / ( (double) width));
}
if (width < height) {
_rationElipseX = (double) ( ( (double) width) / ( (double) height));
}
}
 
private void drawGraphic(int xTopLeftGraphic, int yTopLeftGraphic,
int graphicWidth, int graphicHeight,
Graphics2D graphics2D) {
updateExplodedPercentValues();
 
Vector allPieSeries = _valueSeriesContainer.
getAllSeriesOrderByDisplayNumber();
 
double sumAllValues = _valueSeriesContainer.getSumAllValues();
 
int startAngle = 0;
int arcAngle = 0;
for (int i = 0; i < allPieSeries.size(); i++) {
PieSeries pieSeries = (PieSeries) allPieSeries.elementAt(i);
if (pieSeries.isVisible()) {
double value = pieSeries.getValue();
if (i + 1 < allPieSeries.size()) {
arcAngle = (int) ( (getValueAsPercentage(value, sumAllValues) *
( (double) maxDegree)) / 100);
}
else {
arcAngle = maxDegree - startAngle;
}
 
graphics2D.setColor(pieSeries.getColor());
if (pieSeries.isExploded()) { //verification si la tranche doit être décalée
int angleBisec = startAngle + (arcAngle / 2);
int valTranslate = (int) ( (_margin * pieSeries.getExplodedPercent()) /
2);
int decalX = getVarX(startAngle, arcAngle, angleBisec, valTranslate);
int decalY = getVarY(startAngle, arcAngle, angleBisec, valTranslate);
 
if (angleBisec > 270 || (angleBisec > 90 && angleBisec < 180)) {
graphics2D.fillArc(xTopLeftGraphic + (_margin / 2) +
( (int) ( (decalY) * _rationElipseX)),
yTopLeftGraphic + (_margin / 2) +
( (int) ( (decalX) * _rationElipseY)),
graphicWidth - _margin, graphicHeight - _margin,
startAngle, arcAngle);
if (_isPieWithTags &&
( (int) getValueAsPercentage(value, sumAllValues)) >=
_minPercentToDisplayTag){
drawTagOnArc(xTopLeftGraphic + (_margin / 2) +
( (int) ( (decalY) * _rationElipseX)),
yTopLeftGraphic + (_margin / 2) +
( (int) ( (decalX) * _rationElipseY)),
graphicWidth - _margin, graphicHeight - _margin,
startAngle, arcAngle, graphics2D, pieSeries);
}
}
else {
graphics2D.fillArc(xTopLeftGraphic + (_margin / 2) +
( (int) ( (decalX) * _rationElipseX)),
yTopLeftGraphic + (_margin / 2) +
( (int) ( (decalY) * _rationElipseY)),
graphicWidth - _margin, graphicHeight - _margin,
startAngle, arcAngle);
if (_isPieWithTags &&
( (int) getValueAsPercentage(value, sumAllValues)) >= _minPercentToDisplayTag){
drawTagOnArc(xTopLeftGraphic + (_margin / 2) +
( (int) ( (decalX) * _rationElipseX)),
yTopLeftGraphic + (_margin / 2) +
( (int) ( (decalY) * _rationElipseY)),
graphicWidth - _margin, graphicHeight - _margin,
startAngle, arcAngle, graphics2D, pieSeries);
}
}
}
else {
graphics2D.fillArc(xTopLeftGraphic + (_margin / 2),
yTopLeftGraphic + (_margin / 2),
graphicWidth - _margin, graphicHeight - _margin,
startAngle, arcAngle);
if (_isPieWithTags &&
( (int) getValueAsPercentage(value, sumAllValues)) >=
_minPercentToDisplayTag)
drawTagOnArc(xTopLeftGraphic + (_margin / 2),
yTopLeftGraphic + (_margin / 2),
graphicWidth - _margin, graphicHeight - _margin,
startAngle, arcAngle, graphics2D, pieSeries);
}
startAngle += arcAngle;
}
}
}
 
private void drawTagOnArc(int xTopLeftGraphic, int yTopLeftGraphic,
int graphicWidth, int graphicHeight, int startAngle,
int arcAngle, Graphics2D graphics2D,
PieSeries pieSeries) {
int angleBisec = startAngle + (arcAngle / 2);
int centreX = xTopLeftGraphic + ( (graphicWidth) / 2);
int centreY = yTopLeftGraphic + ( (graphicHeight) / 2);
int rayonX = graphicWidth;
int rayonY = graphicHeight;
int legendX = _externalGraphicLegendMargin;
int decalX = 1;
int decalY = 1;
int decalLegend = 0;
 
if (angleBisec < 180)
decalY = -1;
 
if (angleBisec > 90 && angleBisec < 270) {
decalX = -1;
FontMetrics fm = graphics2D.getFontMetrics();
String label = Integer.toString( (int) pieSeries.getValue());
if (_typeOfTag == TAG_LABEL){
label = pieSeries.getLegendLabel();
if (getTagLabelToCut()) {
if (label.length() > maxLabelSize)
if (label.length() > maxLabelSize - 3)
label = label.substring(0, maxLabelSize - 3) + "...";
}
}
 
decalLegend = -1 * (fm.stringWidth(label));
decalLegend -= 5;
}
else
decalLegend = 5;
 
int angleBisecTmp = angleBisec; //sauvegarde de l'angle de la bisectrice de la part courante
 
while (angleBisec > 90)
angleBisec -= 90;
 
legendX = legendX * decalX;
graphics2D.setColor(Color.black);
 
if (angleBisecTmp > 270 || (angleBisecTmp > 90 && angleBisecTmp < 180)) {
int x = (int) (Math.sin(Math.toRadians( (double) angleBisec)) *
( (double) ( (rayonX) / 2))); //il faudra certainement retirer la marge.
int y = (int) (Math.cos(Math.toRadians( (double) angleBisec)) *
( (double) ( (rayonY) / 2))); //il faudra certainement retirer la marge.
x = x * decalX;
y = y * decalY;
/*if (_typeOfTag == TAG_VALUE) {
if (angleBisecTmp > 270){
graphics2D.drawString(Integer.toString( (int) pieSeries.getValue()),
centreX + x + 1,
centreY + y + _profondeur +(graphics2D.getFontMetrics().getHeight() / 2) +1
);
}else{
graphics2D.drawString(Integer.toString( (int) pieSeries.getValue()),
centreX+x-graphics2D.getFontMetrics().stringWidth(Integer.toString((int)pieSeries.getValue()))-1,
centreY + y - 1);
}
}
else {*/
String label;
if (_typeOfTag == TAG_LABEL){
label = pieSeries.getLegendLabel();
if (getTagLabelToCut()) {
if (label.length() > maxLabelSize)
if (label.length() > maxLabelSize - 3)
label = label.substring(0, maxLabelSize - 3) + "...";
}
}else {
label = Integer.toString( (int) pieSeries.getValue());
}
graphics2D.drawLine(centreX + x, centreY + y,
centreX + ( (rayonX / 2) * decalX) + legendX,
centreY + y);
 
graphics2D.drawString(label,
centreX + ( (rayonX / 2) * decalX) + legendX +
decalLegend, centreY + y);
//}
}
else {
int x = (int) (Math.sin(Math.toRadians( (double) angleBisec)) *
( (double) ( (rayonY) / 2))); //il faudra certainement retirer la marge.
int y = (int) (Math.cos(Math.toRadians( (double) angleBisec)) *
( (double) ( (rayonX) / 2)));
x = x * decalY;
y = y * decalX;
/*if (_typeOfTag == TAG_VALUE) {
if (angleBisecTmp > 180){
graphics2D.drawString(Integer.toString( (int) pieSeries.getValue()),
centreX + y - graphics2D.getFontMetrics().stringWidth(Integer.toString( (int) pieSeries.getValue())) - 1,
centreY + x + _profondeur +
(graphics2D.getFontMetrics().getHeight() / 2) +
1);
} else {
graphics2D.drawString(Integer.toString( (int) pieSeries.getValue()),
centreX + y + 1, centreY + x - 1);
}
}
else {*/
String label;
if (_typeOfTag == TAG_LABEL) {
label = pieSeries.getLegendLabel();
if (getTagLabelToCut()) {
if (label.length() > maxLabelSize)
if (label.length() > maxLabelSize - 3)
label = label.substring(0, maxLabelSize - 3) + "...";
}
}else {
label = Integer.toString( (int) pieSeries.getValue());
}
graphics2D.drawLine(centreX + y, centreY + x,
centreX + ( (rayonX / 2) * decalX) + legendX,
centreY + x);
graphics2D.drawString(label,
centreX + ( (rayonX / 2) * decalX) + legendX +
decalLegend, centreY + x);
//}
}
}
 
private int getVarX(int startAngle, int arcAngle, int angleBisec,
int longTranslate) {
int varSigne = 0;
 
if (angleBisec > 90 && angleBisec < 270)
varSigne = -1;
if (angleBisec < 90)
varSigne = 1;
if (angleBisec > 270)
varSigne = 1;
if (angleBisec == 90 || angleBisec == 270)
varSigne = 0;
 
while (angleBisec > 90)
angleBisec -= 90;
 
angleBisec = 90 - angleBisec;
 
float varX = longTranslate * ( (float) (angleBisec / 90.0));
 
return varSigne * ( (int) varX);
}
 
private int getVarY(int startAngle, int arcAngle, int angleBisec,
int longTranslate) {
int varSigne = 0;
 
if (angleBisec < 180)
varSigne = -1;
if (angleBisec > 180)
varSigne = 1;
if (angleBisec == 0 || angleBisec == 180)
varSigne = 0;
 
while (angleBisec > 90)
angleBisec -= 90;
 
float varY = ( (float) (longTranslate * angleBisec)) / 90;
 
return varSigne * ( (int) varY);
}
 
private void updateExplodedPercentValues() {
Vector allPieSeries = _valueSeriesContainer.
getAllSeriesOrderByDisplayNumber();
int totalWeight = 0;
 
for (int i = 0; i < allPieSeries.size(); i++) {
PieSeries pieSeries = (PieSeries) allPieSeries.elementAt(i);
totalWeight += pieSeries.getExplodedWeight();
}
 
if (totalWeight == 0)
return;
 
for (int i = 0; i < allPieSeries.size(); i++) {
PieSeries pieSeries = (PieSeries) allPieSeries.elementAt(i);
pieSeries.setExplodedPercent( (double) ( ( (double) pieSeries.
getExplodedWeight()) /
( (double) totalWeight)));
}
}
 
private double getValueAsPercentage(double value, double sumAllValues) {
return ( (value * 100) / sumAllValues);
}
 
private void drawGraphic3D(int xTopLeftGraphic, int yTopLeftGraphic,
int graphicWidth, int graphicHeight,
Graphics2D graphics2D) {
updateExplodedPercentValues();
 
Vector allPieSeries = _valueSeriesContainer.
getAllSeriesOrderByDisplayNumber();
 
double sumAllValues = _valueSeriesContainer.getSumAllValues();
 
int startAngle = 0;
int arcAngle = 0;
for (int i = 0; i < allPieSeries.size(); i++) {
PieSeries pieSeries = (PieSeries) allPieSeries.elementAt(i);
if (pieSeries.isVisible()) {
double value = pieSeries.getValue();
if (i + 1 < allPieSeries.size()) {
arcAngle = (int) ( (getValueAsPercentage(value, sumAllValues) *
( (double) maxDegree)) / 100);
}
else {
arcAngle = maxDegree - startAngle;
}
 
graphics2D.setColor(pieSeries.getColor().darker());
 
if (pieSeries.isExploded()) { //verification si la tranche doit être décalée
int angleBisec = startAngle + (arcAngle / 2);
int valTranslate = (int) ( (_margin * pieSeries.getExplodedPercent()) /
2);
int decalX = getVarX(startAngle, arcAngle, angleBisec, valTranslate);
int decalY = getVarY(startAngle, arcAngle, angleBisec, valTranslate);
 
if (angleBisec > 270 || (angleBisec > 90 && angleBisec < 180)) {
graphics2D.fillArc(xTopLeftGraphic + (_margin / 2) +
( (int) ( (decalY) * _rationElipseX)),
yTopLeftGraphic + (_margin / 2) +
( (int) ( (decalX) * _rationElipseY)),
graphicWidth - _margin, graphicHeight - _margin,
startAngle, arcAngle);
}
else {
graphics2D.fillArc(xTopLeftGraphic + (_margin / 2) +
( (int) ( (decalX) * _rationElipseX)),
yTopLeftGraphic + (_margin / 2) +
( (int) ( (decalY) * _rationElipseY)),
graphicWidth - _margin, graphicHeight - _margin,
startAngle, arcAngle);
}
}
else {
graphics2D.fillArc(xTopLeftGraphic + (_margin / 2),
yTopLeftGraphic + (_margin / 2),
graphicWidth - _margin, graphicHeight - _margin,
startAngle, arcAngle);
}
startAngle += arcAngle;
}
}
}
 
/*
static private void bug() throws Exception
{
ValueSeriesContainer valueSeriesContainer = new ValueSeriesContainer();
valueSeriesContainer.addValueSeries(new PieSeries("102", "D.S.I", 50));
valueSeriesContainer.addValueSeries(new PieSeries("202", "D.P.E", 20));
valueSeriesContainer.addValueSeries(new PieSeries("302", "D. Medical", 15));
valueSeriesContainer.addValueSeries(new PieSeries("602", "Entreprise", 15));
valueSeriesContainer.addValueSeries(new PieSeries("402", "D. Mktg", 12));
valueSeriesContainer.addValueSeries(new PieSeries("403", "G.M.S", 12));
valueSeriesContainer.addValueSeries(new PieSeries("404", "D.R.H", 12));
valueSeriesContainer.addValueSeries(new PieSeries("405", "D.A.E.P", 12));
 
 
ExplodedPieChart pieChart = new ExplodedPieChart(300, 200, valueSeriesContainer,0);
pieChart.setCircular(false);
pieChart.setVerticalEllipse(false);
pieChart.set3D(true);
pieChart.setPieWithTags(false);
pieChart.setIsHalfPie(false);
pieChart.setLegendDisplayMode(Legend.LEGEND_DISPLAY_MODE_BOTTOM);
pieChart.setLegendFontSize(9);
pieChart.drawJPEG("bug.jpg");
pieChart.setImageBagroundColor(new Color(244,244,236));
pieChart.setGraphicBagroundColor(new Color(244,244,236));
pieChart.drawSVG("bug.svg");
 
}
*/
 
/*
public static void main(String[] argv) throws Exception
{
}
*/
 
}
/trunk/project/ofccharts/src/com/oxymel/ofc/charts/VerticalAreaChart.java
New file
0,0 → 1,109
package com.oxymel.ofc.charts;
/*
* Copyright (c) 2006 Oxymel SA.
* All rights reserved.
*
* This software is the confidential and proprietary information of Oxymel SA
* ("Confidential Information"). You shall not disclose such Confidential
* Information and shall use it only in accordance with the terms of the license
* agreement you entered into with Oxymel SA.
*/
 
//java
import java.awt.*;
//ofc
import com.oxymel.ofc.charts.series.*;
 
 
/**
* This class allows to draw bar charts as areas. In such a presentation
* the tops of the bars within a given series are joined together to provide
* a line. The different areas delimited by the lines corresponding to the
* series are colored according to the color palette.
*/
public class VerticalAreaChart extends VerticalBarChart
{
private VerticalAreaChartRenderer _renderer;
 
/**
* Constructor
* @param chartWidth Width of vertical bar chart
* @param chartHeight Height of vertical bar chart
* @param axisX Horizontal axis to display categories
* @param axisY Vertical number axis
* @param categoryValueSeriesContainer All series of couple category-value
*/
public VerticalAreaChart(int chartWidth, int chartHeight,
HorizontalCategoryAxis axisX, VerticalNumberAxis axisY,
CategoryValueSeriesContainer categoryValueSeriesContainer)
{
super(chartWidth, chartHeight, axisX, axisY, categoryValueSeriesContainer);
_renderer = new VerticalAreaChartRenderer(categoryValueSeriesContainer);
}
 
 
protected VerticalBarChartRenderer getChartRenderer(){return _renderer;};
 
protected void drawGraphic(int xTopLeftGraphic, int yTopLeftGraphic, int graphicWidth, int graphicHeight,
int xOrigine, int yOrigine, Graphics2D graphics2D)
{
_renderer.setNbGapOnX(_axisX.getNbGap());
_renderer.setNbGapOnY(_axisY.getNbGap());
_renderer.setGapValueOnY(_axisY.getGapValue());
_renderer.drawGraphic( xTopLeftGraphic, yTopLeftGraphic, graphicWidth, graphicHeight,
xOrigine, yOrigine, graphics2D);
 
/*
int sizeOfGapOnY = graphicHeight / _axisY.getNbGap();
int sizeOfGapOnX = graphicWidth / _axisX.getNbGap();
 
Vector allCategories = _categoryValueSeriesContainer.getAllCategoriesOrderByDisplayNumber();
 
Enumeration enumAllSeries = _categoryValueSeriesContainer.getEnumAllSeriesOrderByDisplayNumber();
while(enumAllSeries.hasMoreElements()){
int xCurrent = xOrigine + (sizeOfGapOnX/2);
GeneralPath generalPath = new GeneralPath();
generalPath.moveTo(xCurrent, yOrigine);
CategoryValueSeries categoryValueSeries = (CategoryValueSeries)enumAllSeries.nextElement();
if(categoryValueSeries.isVisible()){
for(int i= 0; i<allCategories.size(); i++){
Category category = (Category)allCategories.elementAt(i);
xCurrent = xOrigine + (sizeOfGapOnX * i) + (sizeOfGapOnX/2);
double value = categoryValueSeries.getCategoryValueAsDouble(category.getId());
addLineArea(xCurrent, yOrigine, sizeOfGapOnX,
Graphics2DTools.getRelativeSizeOfValue(value, _axisY.getGapValue(), sizeOfGapOnY),
categoryValueSeries, generalPath, graphics2D);
}
generalPath.lineTo(xCurrent, yOrigine);
 
xCurrent = xOrigine + (sizeOfGapOnX/2);
generalPath.lineTo(xCurrent, yOrigine);
graphics2D.setColor(categoryValueSeries.getColor());
graphics2D.fill(generalPath);
graphics2D.draw(generalPath);
}
}
*/
}
 
/*
private void addLineArea(int xCurrent, int yOrigine, int sizeOfGapOnX, int relativeSizeOfValue,
CategoryValueSeries series, GeneralPath generalPath, Graphics2D graphics2D)
{
int x1 = xCurrent;
 
int y1 = yOrigine - relativeSizeOfValue;
 
generalPath.lineTo(x1, y1);
 
 
}
*/
 
/*
public static void main(String[] argv) throws Exception
{
}
*/
 
}
/trunk/project/ofccharts/src/com/oxymel/ofc/charts/BarChart.java
New file
0,0 → 1,129
package com.oxymel.ofc.charts;
/*
* Copyright (c) 2006 Oxymel SA.
* All rights reserved.
*
* This software is the confidential and proprietary information of Oxymel SA
* ("Confidential Information"). You shall not disclose such Confidential
* Information and shall use it only in accordance with the terms of the license
* agreement you entered into with Oxymel SA.
*/
 
//ofc
import com.oxymel.ofc.charts.series.CategoryValueSeriesContainer;
import com.oxymel.ofc.charts.series.SeriesContainer;
 
/**
* BarChart is the abstract superclass for all Bar chart
*/
abstract class BarChart extends ChartWithAxisXY
{
/*
protected final int _nbPixelBetweenEachBarHisto = 0;
protected int _nbPixelFreeBeforeSeries = 5;
protected int _nbPixelFreeAfterSeries = 5;
*/
 
protected CategoryValueSeriesContainer _categoryValueSeriesContainer;
 
protected BarChart(int chartWidth, int chartHeight,
CategoryValueSeriesContainer categoryValueSeriesContainer)
{
super(chartWidth, chartHeight);
setCategoryValueSeriesContainer(categoryValueSeriesContainer);
}
 
/**
* Replaces the data series used to draw the chart.
* It can be used to draw several graphics with the same characteristics
* but different input data.
* @param categoryValueSeriesContainer All series defining the couples category-value, they are grouped within a series container.
*/
public void setCategoryValueSeriesContainer(CategoryValueSeriesContainer categoryValueSeriesContainer)
{
_categoryValueSeriesContainer = categoryValueSeriesContainer;
setAllSeriesColorFromPalette(categoryValueSeriesContainer);
}
 
/**
* Gets the series container defining the input data.
* @return CategoryValueSeriesContainer currently used to draw chart
*/
public CategoryValueSeriesContainer getCategoryValueSeriesContainer(){return _categoryValueSeriesContainer;}
 
 
 
/**
* Sets the free space beetween two bars.
* The space is given on a percentage basis, assuming that 100% corresponds
* to the whole space required to display one information category.
* Setting this information is not mandatory and furthermore the OFC-Chart
* kernel used it only if it provides a consistent resulting graphic.
* @param percentageBetweenEachBarHisto the free space percentage
* beetween two bars
*/
public void setPercentageBetweenEachBarHisto(int percentageBetweenEachBarHisto)
{
getBarChartRenderer().setPercentageBetweenEachBarHisto(percentageBetweenEachBarHisto);
}
 
/**
* Sets the free space before the first bar within a category.
* The space is given on a percentage basis, assuming that 100% corresponds
* to the whole space required to display one information category.
* The acceptance of this percentage by the OFC-Chart kernel depends on the
* resulting graphic consistency.
* @param percentageFreeBeforeSeries the free space percentage before the
* first bar
*/
public void setPercentageFreeBeforeSeries(int percentageFreeBeforeSeries)
{
getBarChartRenderer().setPercentageFreeBeforeSeries(percentageFreeBeforeSeries);
}
 
/**
* Sets the free space after the last bar within a category.
* The space is given on a percentage basis, assuming that 100% corresponds
* to the whole space required to display one information category.
* The acceptance of this percentage by the OFC-Chart kernel depends on the
* resulting graphic consistency.
* @param percentageFreeAfterSeries the free space percentage after the
* last bar
*/
public void setPercentageFreeAfterSeries(int percentageFreeAfterSeries)
{
getBarChartRenderer().setPercentageFreeAfterSeries(percentageFreeAfterSeries);
}
 
/**
* Customizes the bar width by giving a maximum size.
* The maximum width is given on a percentage basis, assuming that 100%
* corresponds
* to the whole space required to display one information category.
* This information is taken into account only if it provides a consistent
* resulting graphic.
* @param percentageBarWidthMax the percentage of bar width max
*/
public void setPercentageBarWidthMax(int percentageBarWidthMax)
{
getBarChartRenderer().setPercentageBarWidthMax(percentageBarWidthMax);
}
 
/**
* Customizes the bar width by giving a minimum size.
* The maximum width is given on a percentage basis, assuming that 100%
* corresponds
* to the whole space required to display one information category.
* This information is taken into account only if it provides a consistent
* resulting graphic.
* @param percentageBarWidthMin the percentage of bar width min
*/
public void setPercentageBarWidthMin(int percentageBarWidthMin)
{
getBarChartRenderer().setPercentageBarWidthMax(percentageBarWidthMin);
}
 
abstract protected BarChartRenderer getBarChartRenderer();
protected SeriesContainer getSeriesContainer(){return _categoryValueSeriesContainer;}
 
}
/trunk/project/ofccharts/src/com/oxymel/ofc/charts/geographic/IsolineGC.java
New file
0,0 → 1,188
package com.oxymel.ofc.charts.geographic;
/*
* Copyright (c) 2006 Oxymel SA.
* All rights reserved.
*
* This software is the confidential and proprietary information of Oxymel SA
* ("Confidential Information"). You shall not disclose such Confidential
* Information and shall use it only in accordance with the terms of the license
* agreement you entered into with Oxymel SA.
*/
 
//java
import java.io.*;
import java.util.Vector;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.StringTokenizer;
 
//ofc
import com.oxymel.ofc.charts.data.grid.Grid;
import com.oxymel.ofc.charts.exception.OFCChartsException;
import com.oxymel.ofc.charts.geographic.Graph;
import com.oxymel.ofc.charts.data.grid.Ridge;
import com.oxymel.ofc.charts.data.Point2D;
import com.oxymel.ofc.charts.exception.OFCChartsRuntimeException;
import com.oxymel.ofc.charts.util.OFCMath;
import com.oxymel.ofc.charts.util.ContainerTools;
 
import com.oxymel.ofc.charts.data.grid.RegularGrid;
import com.oxymel.ofc.charts.interpolation.PointContainer;
import com.oxymel.ofc.charts.interpolation.InvertDistanceSquareInterpolation;
import com.oxymel.ofc.charts.interpolation.LaporteInterpolation;
import com.oxymel.ofc.charts.interpolation.InterpolationMethod;
 
/**
*
* <p>Title: Isoline</p>
* <p>Description: Generate isolines. </p>
*/
public class IsolineGC
{
private static final String GC_HEADER = "//$VERSION 5.0\n//$DELIMITER \"tab\"\n//$QUOTED-TEXT \"no\"\n//$CHARSET ANSI\n//$UNIT Distance:m\n//$FORMAT 2\n//$SYSCOORD {Type:1}\n";
 
private Isoline _isoline;
private String _typeName = "isoType";
private String _subTypeName = "isoSubType";
 
public IsolineGC(PointContainer pointContainer, InterpolationMethod interpolationMethode, int nbLine, int nbColumn,
double zStep)
{
RegularGrid grid = new RegularGrid(nbLine, nbColumn,
pointContainer.getStepXOfGridContainsAllPoint(nbColumn), pointContainer.getStepYOfGridContainsAllPoint(nbLine),
pointContainer.getXMin(), pointContainer.getYMin());
long startTimeMillis = System.currentTimeMillis();
System.out.println("start interpolateAllZ");
grid.interpolateAllZ(pointContainer.getAllPoint(), interpolationMethode);
System.out.println("end interpolateAllZ" + "- Nb ms = " + (System.currentTimeMillis() - startTimeMillis));
 
/*
double zMin = grid.getZMin();
double zStart = (((int)(zMin / zStep)) * zStep);
if(zMin < 0){
zStart -= zStep;
}
*/
 
_isoline = new Isoline(grid, zStep);
}
 
 
public void writeIsoline(String fileName) throws Exception
{
long startTimeMillis = System.currentTimeMillis();
System.out.println("start compute isoline graph");
Graph graph = _isoline.getGraph();
System.out.println("end compute isoline graph" + "- Nb ms = " + (System.currentTimeMillis() - startTimeMillis));
 
FileWriter writer = new FileWriter(fileName);
writer.write(GC_HEADER);
 
startTimeMillis = System.currentTimeMillis();
System.out.println("start write GC format");
int nbIsoline = 0;
Enumeration enumAllArc = graph.getEnumAllArc();
while(enumAllArc.hasMoreElements()){
nbIsoline++;
Arc arc = (Arc)enumAllArc.nextElement();
//System.out.println("arc" + nbArc + " = " + arc.toString());
StringBuffer strBuffer = getArcAsGCFormat(arc, nbIsoline);
writer.write(strBuffer.toString());
 
}
System.out.println("nbIsoline = " + nbIsoline);
System.out.println("end write GC format" + "- Nb ms = " + (System.currentTimeMillis() - startTimeMillis));
}
 
private StringBuffer getArcAsGCFormat(Arc arc, int arcId)
{
StringBuffer stringBuffer = new StringBuffer();
 
Vertex initialVertex = arc.getInitialVertex();
Vertex finalVertex = arc.getFinalVertex();
 
//identificateur
stringBuffer.append(arcId);
stringBuffer.append("\t");
 
//type
stringBuffer.append(_typeName);
stringBuffer.append("\t");
 
//sous type
stringBuffer.append(_subTypeName);
stringBuffer.append("\t");
 
//nom de objet
stringBuffer.append("\t");
 
//nombre de champs
stringBuffer.append("1\t");
 
//Z
stringBuffer.append(arc.getValue());
stringBuffer.append("\t");
 
 
// X Sommet init
stringBuffer.append(initialVertex.getX());
stringBuffer.append("\t");
 
 
// Y Sommet init
stringBuffer.append(initialVertex.getY());
stringBuffer.append("\t");
 
// X Sommet fin
stringBuffer.append(finalVertex.getX());
stringBuffer.append("\t");
 
// Y Sommet fin
stringBuffer.append(finalVertex.getY());
stringBuffer.append("\t");
 
Vector allIntermediaryPoint = arc.getAllIntermediaryPoint();
 
//Nombre de point de l'objet
stringBuffer.append(allIntermediaryPoint.size() + 1);
stringBuffer.append("\t");
 
//double xPred = initialVertex.getX();
//double yPred = initialVertex.getY();
for(int i=0; i< allIntermediaryPoint.size(); i++){
Point2D intermediaryPoint = (Point2D)allIntermediaryPoint.elementAt(i);
 
//X relatif Pt Inter par rapport point precedent
//double xCurrent = intermediaryPoint.getX();
//stringBuffer.append(xCurrent - xPred);
stringBuffer.append(intermediaryPoint.getX());
stringBuffer.append("\t");
 
//Y relatif Pt Inter par rapport point precedent
//double yCurrent = intermediaryPoint.getY();
//stringBuffer.append(yCurrent - yPred);
stringBuffer.append(intermediaryPoint.getY());
stringBuffer.append("\t");
 
//xPred = xCurrent;
//yPred = yCurrent;
 
}
 
stringBuffer.append(finalVertex.getX());
stringBuffer.append("\t");
stringBuffer.append(finalVertex.getY());
stringBuffer.append("\t");
 
 
stringBuffer.append("\n");
return stringBuffer;
}
 
/*
public static void main(String[] argv) throws Exception
{
}
*/
 
}
/trunk/project/ofccharts/src/com/oxymel/ofc/charts/geographic/Vertex.java
New file
0,0 → 1,100
package com.oxymel.ofc.charts.geographic;
/*
* Copyright (c) 2006 Oxymel SA.
* All rights reserved.
*
* This software is the confidential and proprietary information of Oxymel SA
* ("Confidential Information"). You shall not disclose such Confidential
* Information and shall use it only in accordance with the terms of the license
* agreement you entered into with Oxymel SA.
*/
 
import java.util.Vector;
import java.util.Enumeration;
 
//ofc
import com.oxymel.ofc.charts.data.Point2D;
import com.oxymel.ofc.charts.util.Segment;
 
/**
*
* <p>Title: Point2D </p>
* <p>Description: Manage Point2D</p>
*/
public class Vertex extends Point2D
{
private Vector _allArcGoIn = new Vector();
private Vector _allArcGoOut = new Vector();
 
/**
* Constructor
* @param x X of point
* @param y Y of Point
*/
public Vertex(double x, double y)
{
super(x, y);
}
 
static public String getKey(double x, double y)
{
StringBuffer key = new StringBuffer();
key.append("X");
key.append(x);
key.append("Y");
key.append(y);
return key.toString();
}
 
public boolean isOnSegment(double xInitial, double yInitial, double xFinal, double yFinal)
{
return Segment.isPointOnSegment(getX(), getY(),
xInitial, yInitial, xFinal, yFinal);
}
 
public int getNbArcGoIn(){return _allArcGoIn.size();}
public int getNbArcGoOut(){return _allArcGoOut.size();}
 
public Enumeration getEnumAllArcGoInOut(Arc arcToExclude)
{
return getArcGoInOut(arcToExclude).elements();
}
 
Vector getArcGoInOut(Arc arcToExclude)
{
Vector allArcGoInOut = new Vector();
 
for(int i=0;i<_allArcGoIn.size();i++){
Arc arc = (Arc)_allArcGoIn.elementAt(i);
if(!arc.equals(arcToExclude)){
allArcGoInOut.addElement(arc);
}
}
 
for(int i=0;i<_allArcGoOut.size();i++){
Arc arc = (Arc)_allArcGoOut.elementAt(i);
if(!arc.equals(arcToExclude)){
allArcGoInOut.addElement(arc);
}
}
 
return allArcGoInOut;
}
 
public void clearAllArcGoInOut()
{
_allArcGoIn.clear();
_allArcGoOut.clear();
}
 
public void addArcGoIn(Arc arc)
{
_allArcGoIn.addElement(arc);
}
 
public void addArcGoOut(Arc arc)
{
_allArcGoOut.addElement(arc);
}
 
}
/trunk/project/ofccharts/src/com/oxymel/ofc/charts/geographic/Face.java
New file
0,0 → 1,146
package com.oxymel.ofc.charts.geographic;
/*
* Copyright (c) 2006 Oxymel SA.
* All rights reserved.
*
* This software is the confidential and proprietary information of Oxymel SA
* ("Confidential Information"). You shall not disclose such Confidential
* Information and shall use it only in accordance with the terms of the license
* agreement you entered into with Oxymel SA.
*/
 
import java.util.Vector;
import java.util.Enumeration;
 
//ofc
import com.oxymel.ofc.charts.data.Point2D;
 
/**
*
*/
public class Face
{
 
private Vector _allArc = new Vector();
private Rectangle _boundingRectangle = null;
private double _minValue;
private double _maxValue;
private boolean _isIntervalValueDefined = false;
 
boolean _isArcFirstInGoodDirection = true;
 
/**
* Constructor
*/
public Face()
{
}
 
public boolean isArcFirstInGoodDirection(){return _isArcFirstInGoodDirection;}
public void setIsArcFirstInGoodDirection(boolean isArcFirstInGoodDirection){_isArcFirstInGoodDirection = isArcFirstInGoodDirection;}
 
public void addArc(Arc arc)
{
_allArc.addElement(arc);
}
 
public Enumeration getEnumAllArc()
{
return _allArc.elements();
}
 
public boolean isIntervalValueDefined(){return _isIntervalValueDefined;}
public double getMinValue(){return _minValue;}
public double getMaxValue(){return _maxValue;}
public void setIntervalValue()
{
if(_allArc.size() == 0){
return;
}
 
int firstArcPosition = 0;
for(firstArcPosition=0; firstArcPosition<_allArc.size(); firstArcPosition++){
Arc arcCurrent = (Arc)_allArc.elementAt(firstArcPosition);
if(arcCurrent.isValueDefined()){
_isIntervalValueDefined = true;
_minValue = arcCurrent.getValue();
_maxValue = arcCurrent.getValue();
break;
}
}
 
for(int i=firstArcPosition+1; i<_allArc.size(); i++){
Arc arcCurrent = (Arc)_allArc.elementAt(i);
if(arcCurrent.isValueDefined()){
_minValue = Math.min(arcCurrent.getValue(), _minValue);
_maxValue = Math.max(arcCurrent.getValue(), _maxValue);
}
}
}
 
public void setIntervalValue(double value)
{
_minValue = Math.min(value, _minValue);
_maxValue = Math.max(value, _maxValue);
_isIntervalValueDefined = true;
}
 
public void setIntervalValue(double minValue, double maxValue)
{
_minValue = minValue;
_maxValue = maxValue;
_isIntervalValueDefined = true;
}
 
public Rectangle getBoundingRectangle()
{
if(_boundingRectangle != null){
return _boundingRectangle;
}
 
double xMin = 0;
double yMin = 0;
double xMax = 0;
double yMax = 0;
 
if(_allArc.size() == 0){
_boundingRectangle = new Rectangle(xMin, yMin, xMax, yMax);
return _boundingRectangle;
}else{
Arc arc = (Arc)_allArc.elementAt(0);
Rectangle rectangle = arc.getBoundingRectangle();
xMin = rectangle.getXMin();
yMin = rectangle.getYMin();
xMax = rectangle.getXMax();
yMax = rectangle.getYMax();
}
 
for(int i=0;i<_allArc.size();i++){
Arc arc = (Arc)_allArc.elementAt(i);
Rectangle rectangle = arc.getBoundingRectangle();
xMin = Math.min(rectangle.getXMin(), xMin);
yMin = Math.min(rectangle.getYMin(), yMin);
xMax = Math.max(rectangle.getXMax(), xMax);
yMax = Math.max(rectangle.getYMax(), yMax);
}
 
_boundingRectangle = new Rectangle(xMin, yMin, xMax, yMax);
return _boundingRectangle;
}
 
public boolean isPointOnLimit(double x, double y)
{
for(int i=0;i<_allArc.size();i++){
Arc arc = (Arc)_allArc.elementAt(i);
if(arc.isPointOnArc(x, y)){
return true;
}
}
return false;
}
 
public String toString()
{
return "minValue = " + _minValue + " - maxValue = " + _maxValue;
}
}
/trunk/project/ofccharts/src/com/oxymel/ofc/charts/geographic/Point3D.java
New file
0,0 → 1,43
package com.oxymel.ofc.charts.geographic;
/*
* Copyright (c) 2006 Oxymel SA.
* All rights reserved.
*
* This software is the confidential and proprietary information of Oxymel SA
* ("Confidential Information"). You shall not disclose such Confidential
* Information and shall use it only in accordance with the terms of the license
* agreement you entered into with Oxymel SA.
*/
 
import java.util.Vector;
 
import com.oxymel.ofc.charts.data.Point2D;
 
public class Point3D extends Point2D
{
private double _z;
 
/**
* Constructor
* @param x X of point
* @param y Y of Point
*/
public Point3D(double x, double y, double z)
{
super(x, y);
_z = z;
}
 
public double getZ()
{
return _z;
}
 
 
public String toString()
{
return super.toString() + " - z = " + getZ();
}
 
 
}
/trunk/project/ofccharts/src/com/oxymel/ofc/charts/geographic/Graph.java
New file
0,0 → 1,414
package com.oxymel.ofc.charts.geographic;
/*
* Copyright (c) 2006 Oxymel SA.
* All rights reserved.
*
* This software is the confidential and proprietary information of Oxymel SA
* ("Confidential Information"). You shall not disclose such Confidential
* Information and shall use it only in accordance with the terms of the license
* agreement you entered into with Oxymel SA.
*/
 
import java.util.Vector;
import java.util.Enumeration;
import java.util.Hashtable;
 
//ofc
import com.oxymel.ofc.charts.data.Point2D;
import com.oxymel.ofc.charts.data.grid.Grid;
import com.oxymel.ofc.charts.exception.OFCChartsRuntimeException;
 
/**
*
*/
public class Graph
{
Hashtable _allVertex = new Hashtable();
Vector _allArc = new Vector();
 
/**
* Constructor
*/
public Graph()
{
 
}
 
/*
public Graph clone(Enumeration allArcToClone)
{
Graph graphClone = new Graph();
while(allArcToClone.hasMoreElements()){
Arc arc = (Arc)allArcToClone.nextElement();
graphClone.addElement();
}
return graphClone;
}
 
private void addArcToClone(Arc)
{
_allArc.
}
*/
 
public boolean isArcExist(double xInitialVertex, double yInitialVertex, Vector allIntermediaryPoint,
double xFinalVertex, double yFinalVertex)
{
Enumeration enumAllArc = getEnumAllArc();
while(enumAllArc.hasMoreElements()){
Arc arc = (Arc)enumAllArc.nextElement();
Vertex initialVertex = arc.getInitialVertex();
if(initialVertex.isSameXY(xInitialVertex, yInitialVertex)){
Vertex finalVertex = arc.getFinalVertex();
if(finalVertex.isSameXY(xFinalVertex, yFinalVertex)){
if(arc.isIntermediaryPointEquals(allIntermediaryPoint)){
return true;
}
}
}
}
return false;
}
 
public Arc addArc(double xInitialVertex, double yInitialVertex, Vector allIntermediaryPoint,
double xFinalVertex, double yFinalVertex, double value)
{
Arc arc = new Arc(getVertex(xInitialVertex, yInitialVertex), allIntermediaryPoint,
getVertex(xFinalVertex, yFinalVertex), value);
_allArc.addElement(arc);
return arc;
}
 
public Arc addArc(Arc arcToAdd)
{
Arc arc = new Arc(getVertex(arcToAdd.getInitialVertex().getX(), arcToAdd.getInitialVertex().getY()), arcToAdd.getAllIntermediaryPoint(),
getVertex(arcToAdd.getFinalVertex().getX(), arcToAdd.getFinalVertex().getY()));
_allArc.addElement(arc);
return arc;
}
 
public void addAllArc(Enumeration enumAllArc)
{
while(enumAllArc.hasMoreElements()){
Arc arc = (Arc)enumAllArc.nextElement();
if(!isArcExist(arc)){
arc.reverse();
if(!isArcExist(arc)){
arc.reverse();
addArc(arc);
}else{
arc.reverse();
}
}
}
}
 
public void setArcIntersection(Vertex vertex)
{
Enumeration enumAllArc = getEnumAllArc();
while(enumAllArc.hasMoreElements()){
Arc arc = (Arc)enumAllArc.nextElement();
if(setArcIntersection(arc, vertex)){
return;
}
}
}
 
public Face getFace(Arc arcStart, boolean isFindInArcDirection)
{
//System.out.println("******* Start FACE");
//System.out.println("arcStart = " + arcStart.toString());
Face face = new Face();
face.setIsArcFirstInGoodDirection(isFindInArcDirection);
face.addArc(arcStart);
Arc arcCurrent = arcStart;
boolean isArcCurrentInGoodDirection = isFindInArcDirection;
 
Vertex currentVertexFinal;
if(isArcCurrentInGoodDirection){
currentVertexFinal = arcCurrent.getFinalVertex();
}else{
currentVertexFinal = arcCurrent.getInitialVertex();
}
Arc arcSuccessor = arcCurrent.getArcMoreAtLeftSuccessor(isArcCurrentInGoodDirection);
while(arcSuccessor != null){
boolean isArcSuccessorInGoodDirection = (arcSuccessor.getInitialVertex().equals(currentVertexFinal));
//System.out.println("arcSuccessor = " + arcSuccessor.toString());
 
face.addArc(arcSuccessor);
arcCurrent = arcSuccessor;
isArcCurrentInGoodDirection = isArcSuccessorInGoodDirection;
if(isArcCurrentInGoodDirection){
currentVertexFinal = arcCurrent.getFinalVertex();
arcCurrent.setIsTraveledInThisDirection();
}else{
currentVertexFinal = arcCurrent.getInitialVertex();
arcCurrent.setIsTraveledInOppositeDirection();
}
arcSuccessor = arcCurrent.getArcMoreAtLeftSuccessor(isArcCurrentInGoodDirection);
if(arcSuccessor != null){
if(arcSuccessor.equals(arcStart)){
arcSuccessor = null;
}
}
}
//System.out.println("******* End FACE");
return face;
}
 
private boolean isArcExist(Arc arc)
{
Vertex initialVertex = arc.getInitialVertex();
Vertex finalVertex = arc.getFinalVertex();
return isArcExist(initialVertex.getX(), initialVertex.getY(), arc.getAllIntermediaryPoint(),
finalVertex.getX(), finalVertex.getY());
}
 
private boolean setArcIntersection(Arc arcToIntersect, Vertex vertexIntersection)
{
if(vertexIntersection.isSameXY(arcToIntersect.getInitialVertex())){
return true;
}
if(vertexIntersection.isSameXY(arcToIntersect.getFinalVertex())){
return true;
}
 
double xInitial = arcToIntersect.getInitialVertex().getX();
double yInitial = arcToIntersect.getInitialVertex().getY();
Vector allIntermediaryPoint = arcToIntersect.getAllIntermediaryPoint();
double xIntersection = vertexIntersection.getX();
double yIntersection = vertexIntersection.getY();
 
if(allIntermediaryPoint.size() == 0){
double xFinal = arcToIntersect.getFinalVertex().getX();
double yFinal = arcToIntersect.getFinalVertex().getY();
if(vertexIntersection.isOnSegment(xInitial, yInitial, xFinal, yFinal)){
_allArc.remove(arcToIntersect);
Arc arcFirst = new Arc(getVertex(xInitial, yInitial), getVertex(xIntersection, yIntersection));
_allArc.addElement(arcFirst);
Arc arcSecond = new Arc(getVertex(xIntersection, yIntersection), getVertex(xFinal, yFinal));
_allArc.addElement(arcSecond);
return true;
}
return false;
}
 
double xPred = xInitial;
double yPred = yInitial;
Point2D pointPred = null;
boolean isPredInitialVertex = true;
Vector allIntermediaryPointFirstArc = new Vector();
Vector allIntermediaryPointSecondArc = new Vector();
boolean isArcIntersected = false;
for(int i=0; i< allIntermediaryPoint.size(); i++){
Point2D pointCurrent = (Point2D)allIntermediaryPoint.elementAt(i);
double xCurrent = pointCurrent.getX();
double yCurrent = pointCurrent.getY();
if(!isArcIntersected){
if(vertexIntersection.isOnSegment(xPred, yPred, xCurrent, yCurrent)){
isArcIntersected = true;
}
if(!isPredInitialVertex){
if(!pointPred.isSameXY(xIntersection, yIntersection)){
allIntermediaryPointFirstArc.addElement(pointPred);
}
}
}else{
if(!isPredInitialVertex){
if(!pointPred.isSameXY(xIntersection, yIntersection)){
allIntermediaryPointSecondArc.addElement(pointPred);
}
}
}
xPred = xCurrent;
yPred = yCurrent;
pointPred = pointCurrent;
isPredInitialVertex = false;
}
 
double xFinal = arcToIntersect.getFinalVertex().getX();
double yFinal = arcToIntersect.getFinalVertex().getY();
if(!isArcIntersected){
if(vertexIntersection.isOnSegment(xPred, yPred, xFinal, yFinal)){
isArcIntersected = true;
}
if(!isPredInitialVertex){
if(!pointPred.isSameXY(xIntersection, yIntersection)){
allIntermediaryPointFirstArc.addElement(pointPred);
}
}
}else{
if(!isPredInitialVertex){
if(!pointPred.isSameXY(xIntersection, yIntersection)){
allIntermediaryPointSecondArc.addElement(pointPred);
}
}
}
 
if(isArcIntersected){
_allArc.remove(arcToIntersect);
Arc arcFirst = new Arc(getVertex(xInitial, yInitial), allIntermediaryPointFirstArc, getVertex(xIntersection, yIntersection));
_allArc.addElement(arcFirst);
Arc arcSecond = new Arc(getVertex(xIntersection, yIntersection), allIntermediaryPointSecondArc, getVertex(xFinal, yFinal));
_allArc.addElement(arcSecond);
}
return isArcIntersected;
}
 
public Enumeration getEnumAllArc(){return _allArc.elements();}
 
public Vector getAllArcOpen()
{
Vector allArcToFind = new Vector();
for(int i=0;i<_allArc.size();i++){
Arc arc = (Arc)_allArc.elementAt(i);
if(!arc.getInitialVertex().equals(arc.getFinalVertex())){
allArcToFind.addElement(arc);
}
}
return allArcToFind;
}
 
public Vector getAllArcClose()
{
Vector allArcToFind = new Vector();
for(int i=0;i<_allArc.size();i++){
Arc arc = (Arc)_allArc.elementAt(i);
if(arc.getInitialVertex().equals(arc.getFinalVertex())){
allArcToFind.addElement(arc);
}
}
return allArcToFind;
}
 
static public Arc getBoundingArc(Grid grid)
{
Enumeration enumAllPointBorderGrid = grid.getEnumAllBorderPointInHorlogeDirection();
if(!enumAllPointBorderGrid.hasMoreElements()){
throw new OFCChartsRuntimeException("Grid data error");
}
 
Point2D pointTopLeftGrid = (Point2D)enumAllPointBorderGrid.nextElement();
Vertex vertex = new Vertex(pointTopLeftGrid.getX(), pointTopLeftGrid.getY()) ;
 
Vector allIntermediaryPoint = new Vector();
while(enumAllPointBorderGrid.hasMoreElements()){
Point2D point = (Point2D)enumAllPointBorderGrid.nextElement();
allIntermediaryPoint.addElement(point);
}
return new Arc(vertex, allIntermediaryPoint, vertex);
 
/*
double xInitial = grid.getX(0,0);
double yInitial = grid.getY(0,0);
Vertex vertex = new Vertex(xInitial, yInitial) ;
Vector allIntermediaryPoint = new Vector();
allIntermediaryPoint.addElement(new Point2D(
grid.getX(0, grid.getNbColumn() - 1),
grid.getY(0, grid.getNbColumn() - 1)));
allIntermediaryPoint.addElement(new Point2D(
grid.getX(grid.getNbLine() - 1, grid.getNbColumn() - 1),
grid.getY(grid.getNbLine() - 1, grid.getNbColumn() - 1)));
allIntermediaryPoint.addElement(new Point2D(
grid.getX(grid.getNbLine() - 1, 0),
grid.getY(grid.getNbLine() - 1, 0)));
 
return new Arc(vertex, allIntermediaryPoint, vertex);
*/
/*
double xInitial = grid.getX(0,0);
double yInitial = grid.getY(0,0);
Vector allIntermediaryPoint = new Vector();
int nbColumn = grid.getNbColumn();
int nbLine = grid.getNbLine();
for(int i=1; i< nbColumn; i++){
double xCurrent = grid.getX(0,i);
double yCurrent = grid.getY(0,i);
allIntermediaryPoint.addElement(new Point2D(xCurrent, yCurrent));
}
int numColumnLast = nbColumn - 1;
for(int i=0; i< nbLine; i++){
double xCurrent = grid.getX(i, numColumnLast);
double yCurrent = grid.getY(i, numColumnLast);
allIntermediaryPoint.addElement(new Point2D(xCurrent, yCurrent));
}
int numLineLast = nbLine - 1;
for(int i=numColumnLast; i >= 0; i--){
double xCurrent = grid.getX(numLineLast,i);
double yCurrent = grid.getY(numLineLast,i);
allIntermediaryPoint.addElement(new Point2D(xCurrent, yCurrent));
}
for(int i=numLineLast; i > 0; i--){
double xCurrent = grid.getX(i, 0);
double yCurrent = grid.getY(i, 0);
allIntermediaryPoint.addElement(new Point2D(xCurrent, yCurrent));
}
 
Vertex vertex = new Vertex(xInitial, yInitial) ;
return new Arc(vertex, allIntermediaryPoint, vertex);
*/
}
 
public void setArcGoInOutForAllVertex()
{
Enumeration enumAllVertex = _allVertex.elements();
while(enumAllVertex.hasMoreElements()){
Vertex vertex = (Vertex)enumAllVertex.nextElement();
vertex.clearAllArcGoInOut();
}
 
for(int i=0; i<_allArc.size();i++){
Arc arc = (Arc)_allArc.elementAt(i);
Vertex initialVertex = arc.getInitialVertex();
initialVertex.addArcGoOut(arc);
Vertex finalVertex = arc.getFinalVertex();
finalVertex.addArcGoIn(arc);
}
 
}
 
public void displayAllVertexInfo()
{
Enumeration enumAllVertex = _allVertex.elements();
while(enumAllVertex.hasMoreElements()){
Vertex vertex = (Vertex)enumAllVertex.nextElement();
System.out.println("X = " + vertex.getX() + " - Y = " + vertex.getY() +
" - Nb Arc Go IN = " + vertex.getNbArcGoIn() + " - Nb Arc Go OUT = " + vertex.getNbArcGoOut());
}
}
 
 
public void displayAllArcInfo()
{
Enumeration enumAllArc = _allArc.elements();
System.out.println("**START All Arc Info");
int i = 0;
while(enumAllArc.hasMoreElements()){
i++;
Arc arc = (Arc)enumAllArc.nextElement();
System.out.println("Arc" + i+ " = " + arc.toString());
}
System.out.println("**End All Arc Info");
}
 
 
 
private Vertex getVertex(double x, double y)
{
String vertexKey = Vertex.getKey(x, y);
Vertex vertex = (Vertex)_allVertex.get(vertexKey);
/*
if(vertex == null){
System.out.println("New Vertex");
}else{
System.out.println("Old Vertex");
}
*/
if(vertex == null){
vertex = new Vertex(x, y);
_allVertex.put(vertexKey, vertex);
}
return vertex;
}
 
}
/trunk/project/ofccharts/src/com/oxymel/ofc/charts/geographic/Isoline.java
New file
0,0 → 1,838
package com.oxymel.ofc.charts.geographic;
/*
* Copyright (c) 2006 Oxymel SA.
* All rights reserved.
*
* This software is the confidential and proprietary information of Oxymel SA
* ("Confidential Information"). You shall not disclose such Confidential
* Information and shall use it only in accordance with the terms of the license
* agreement you entered into with Oxymel SA.
*/
 
//java
import java.io.*;
import java.util.Vector;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.StringTokenizer;
 
//ofc
import com.oxymel.ofc.charts.data.grid.Grid;
import com.oxymel.ofc.charts.exception.OFCChartsException;
import com.oxymel.ofc.charts.geographic.Graph;
import com.oxymel.ofc.charts.data.grid.Ridge;
import com.oxymel.ofc.charts.data.Point2D;
import com.oxymel.ofc.charts.exception.OFCChartsRuntimeException;
import com.oxymel.ofc.charts.util.OFCMath;
import com.oxymel.ofc.charts.util.ContainerTools;
 
/**
*
* <p>Title: Isoline</p>
* <p>Description: Generate isolines. </p>
*/
public class Isoline
{
private Grid _grid;
private double _zStart;
private double _zEnd;
private double _zStep;
 
//
private Graph _graph = null;
private Vector _allFace = null;
private Vector _allFaceOrdered = null;
 
public Isoline(Grid grid, double zStart, double zEnd, double zStep)
{
_zStart = zStart;
_zEnd = zEnd;
setParameters(grid, zStep);
}
 
public Isoline(Grid grid, double zStep)
{
setParameters(grid, zStep);
double zMin = grid.getZMin();
_zStart = (((int)(zMin / _zStep)) * _zStep);
if(zMin < 0){
_zStart -= _zStep;
}
_zEnd = _grid.getZMax();
}
 
private void setParameters(Grid grid, double isolineStep)
{
_grid = grid;
if(isolineStep == 0){
throw new OFCChartsRuntimeException("Invalid isoline step");
}
_zStep = Math.abs(isolineStep);
//_zStep = isolineStep;
_graph = null;
_allFace = null;
_allFaceOrdered = null;
}
 
 
public Graph getGraph()
{
if(_graph != null){
return _graph;
}
_graph = new Graph();
//double zCurrent = _grid.getZMin();
double zCurrent = _zStart;
//double zMax = _grid.getZMax();
double zMax = _zEnd;
//long startTimeMillis = System.currentTimeMillis();
while(zCurrent <= zMax){
//long currentTimeMillis = System.currentTimeMillis();
getIsolineGraph(zCurrent, _graph);
//System.out.println("** End Compute Isoline = " + zCurrent + " Nb ms = " + (System.currentTimeMillis() - currentTimeMillis));
zCurrent += _zStep;
//System.out.println("zCurrent = " + zCurrent + " _zStep = " + _zStep);
}
//System.out.println("***** End Compute All Isoline - Nb ms = " + (System.currentTimeMillis() - startTimeMillis));
return _graph;
}
 
public Enumeration getEnumAllFace()
{
return getAllFace().elements();
}
 
private Vector getAllFace()
{
if(_allFace != null){
return _allFace;
}
 
_allFace = new Vector();
 
Graph isolineGraph = getGraph();
Vector allArcIsolineOpen = isolineGraph.getAllArcOpen();
Graph graphClose = getGraphOpenIsolineClosedByGrid(allArcIsolineOpen);
 
//System.out.println("***** graphClose Start displayAllVertexInfo");
//graphClose.displayAllVertexInfo();
//System.out.println("***** graphClose End displayAllVertexInfo");
 
isolineGraph.addAllArc(graphClose.getEnumAllArc());
isolineGraph.setArcGoInOutForAllVertex();
 
//System.out.println("***** Start displayAllVertexInfo");
//isolineGraph.displayAllVertexInfo();
//System.out.println("***** End displayAllVertexInfo");
 
for(int i=0; i<allArcIsolineOpen.size();i++){
Arc arc = (Arc)allArcIsolineOpen.elementAt(i);
if(!arc.isTraveledInThisDirection()){
Face face = isolineGraph.getFace(arc, true);
setIntervalValueOfFaceOnGridBorder(face, arc);
_allFace.addElement(face);
}
}
 
for(int i=0; i<allArcIsolineOpen.size();i++){
Arc arc = (Arc)allArcIsolineOpen.elementAt(i);
if(!arc.isTraveledInOppositeDirection()){
Face face = isolineGraph.getFace(arc, false);
setIntervalValueOfFaceOnGridBorder(face, arc);
_allFace.addElement(face);
}
}
 
Vector allArcIsolineClose = isolineGraph.getAllArcClose();
for(int i=0; i<allArcIsolineClose.size();i++){
Arc arc = (Arc)allArcIsolineClose.elementAt(i);
Face face = new Face();
face.addArc(arc);
face.setIntervalValue();
_allFace.addElement(face);
}
 
return _allFace;
}
 
public Enumeration getEnumAllFaceOrderByDisplayPosition()
{
return getAllFaceOrderByDisplayPosition().elements();
}
 
private void setIntervalValueOfFaceOnGridBorder(Face face, Arc arcOpenIsoline)
{
//case : face with different isoline
face.setIntervalValue();
if(face.getMinValue() != face.getMaxValue()){
return;
}
 
//case : open isoline = close isoline
int nbIsoline = 0;
Enumeration enumAllArc = face.getEnumAllArc();
while(enumAllArc.hasMoreElements()){
Arc arc = (Arc)enumAllArc.nextElement();
if(arc.isValueDefined()){
nbIsoline ++;
if(nbIsoline > 1){
return;
}
}
}
 
//other case = face with only one isoline
Hashtable allRidge = getAllRidgeIntersecteByOpenIsoline(arcOpenIsoline.getValue());
 
double value = getValueOfFaceOnGridBorder(allRidge.elements(), arcOpenIsoline.getInitialVertex(), face, arcOpenIsoline);
if(value != arcOpenIsoline.getValue()){
face.setIntervalValue(value);
return;
}
 
face.setIntervalValue(getValueOfFaceOnGridBorder(allRidge.elements(), arcOpenIsoline.getFinalVertex(), face, arcOpenIsoline));
}
 
private double getValueOfFaceOnGridBorder(Enumeration enumAllRidge, Vertex vertexToCompare, Face face, Arc arcOpenIsoline)
{
while(enumAllRidge.hasMoreElements()){
Ridge ridge = (Ridge)enumAllRidge.nextElement();
if(vertexToCompare.isOnSegment(ridge.getXInitialNode(_grid), ridge.getYInitialNode(_grid),
ridge.getXFinalNode(_grid), ridge.getYFinalNode(_grid))){
int lineNumber = ridge.getLineNumberInitialNode();
int columnNumber = ridge.getColumnNumberInitialNode();
double x = _grid.getX(lineNumber, columnNumber);
double y = _grid.getY(lineNumber, columnNumber);
if((!vertexToCompare.isSameXY(x, y)) && (face.isPointOnLimit(x, y))) {
return _grid.getZ(lineNumber, columnNumber);
}
 
lineNumber = ridge.getLineNumberFinalNode();
columnNumber = ridge.getColumnNumberFinalNode();
x = _grid.getX(lineNumber, columnNumber);
y = _grid.getY(lineNumber, columnNumber);
if((!vertexToCompare.isSameXY(x, y)) && (face.isPointOnLimit(x, y))) {
return _grid.getZ(lineNumber, columnNumber);
}
}
}
return arcOpenIsoline.getValue();
}
 
 
private Vector getAllFaceOrderByDisplayPosition()
{
if(_allFaceOrdered != null){
return _allFaceOrdered;
}
 
_allFaceOrdered = new Vector();
Vector allFace = getAllFace();
if(allFace.size() == 0){
return _allFaceOrdered;
}else{
_allFaceOrdered.addElement(allFace.elementAt(0));
}
for(int i=1; i< allFace.size(); i++){
Face face = (Face)allFace.elementAt(i);
boolean isFaceAdd = false;
Rectangle rectangle = face.getBoundingRectangle();
for(int j=0; j < _allFaceOrdered.size(); j++){
Face faceOrdered = (Face)_allFaceOrdered.elementAt(j);
Rectangle rectangleOrdered = faceOrdered.getBoundingRectangle();
if(rectangleOrdered.isIncludeIn(rectangle)){
_allFaceOrdered.insertElementAt(face, j);
isFaceAdd = true;
break;
}
}
if(!isFaceAdd){
_allFaceOrdered.addElement(face);
}
}
 
if(_allFaceOrdered.size() > 1){
Face firstFace = (Face)_allFaceOrdered.elementAt(0);
if(!firstFace.isIntervalValueDefined()){
//case : univers not defined = no isoline open
Face includeFace = (Face)_allFaceOrdered.elementAt(1);
double includeFaceValue = includeFace.getMinValue();
firstFace.setIntervalValue(includeFaceValue - _zStep, includeFaceValue);
}
}
if(_allFaceOrdered.size() == 1){
//only univers = grid limit. No isoline found
double zMin = _grid.getZMin();
double zMax = _grid.getZMax();
//if(zMin == zMax){
//cas = zoom on isoline closed. limite of isoline are not visible in grid scope
Face firstFace = (Face)_allFaceOrdered.elementAt(0);
firstFace.setIntervalValue(zMin, zMax);
//}
}
return _allFaceOrdered;
}
 
public Graph getClosedGraph()
{
Graph isolineGraph = getGraph();
Vector allArcIsolineOpen = isolineGraph.getAllArcOpen();
Graph graphClose = getGraphOpenIsolineClosedByGrid(allArcIsolineOpen);
graphClose.addAllArc(isolineGraph.getAllArcClose().elements());
graphClose.addAllArc(allArcIsolineOpen.elements());
return graphClose;
}
 
private Graph getGraphOpenIsolineClosedByGrid(Vector allOpenIsolineArc)
{
Graph graph = new Graph();
graph.addArc(Graph.getBoundingArc(_grid));
 
//tmp:
//Arc toto = Graph.getBoundingArc(_grid);
//System.out.println("getBoundingArc = " + toto.toString());
 
for(int i=0; i<allOpenIsolineArc.size(); i++){
Arc arc = (Arc)allOpenIsolineArc.elementAt(i);
 
//System.out.println("getInitialVertex = " + arc.getInitialVertex().toString() );
graph.setArcIntersection(arc.getInitialVertex());
// graph.displayAllArcInfo();
 
//System.out.println("getFinalVertex = " + arc.getFinalVertex().toString());
graph.setArcIntersection(arc.getFinalVertex());
//graph.displayAllArcInfo();
}
 
return graph;
}
 
 
private Graph getIsolineGraph(double zIsoline, Graph graph)
{
//long currentTimeMillis = System.currentTimeMillis();
Hashtable allRidgeIntersectByOpenIsoline = getAllRidgeIntersecteByOpenIsoline(zIsoline);
//System.out.println("getAllRidgeIntersecteByOpenIsoline Nb ms = " + (System.currentTimeMillis() - currentTimeMillis));
 
//currentTimeMillis = System.currentTimeMillis();
Hashtable allRidgeIntersectByIsoline = getAllRidgeIntersecteByClosedIsoline(zIsoline);
//System.out.println("getAllRidgeIntersecteByClosedIsoline Nb ms = " + (System.currentTimeMillis() - currentTimeMillis));
 
//currentTimeMillis = System.currentTimeMillis();
allRidgeIntersectByIsoline.putAll(allRidgeIntersectByOpenIsoline);
//System.out.println("putAll in Hashtable Nb ms = " + (System.currentTimeMillis() - currentTimeMillis));
 
//currentTimeMillis = System.currentTimeMillis();
getGraphAllOpenIsoline(allRidgeIntersectByOpenIsoline, allRidgeIntersectByIsoline, zIsoline, graph);
//System.out.println("getGraphAllOpenIsoline Nb ms = " + (System.currentTimeMillis() - currentTimeMillis));
 
//currentTimeMillis = System.currentTimeMillis();
getGraphAllCloseIsoline(allRidgeIntersectByIsoline, zIsoline, graph);
//System.out.println("getGraphAllCloseIsoline Nb ms = " + (System.currentTimeMillis() - currentTimeMillis));
return graph;
}
 
private Hashtable getAllRidgeIntersecteByOpenIsoline(double zIsoline)
{
Hashtable allRidge = new Hashtable();
 
//first line
getHorizontalGridRidgeIntersectByIsoline(0, 0,
0, _grid.getNbColumn() - 2, zIsoline, allRidge);
//last line
getHorizontalGridRidgeIntersectByIsoline(_grid.getNbLine() - 1, _grid.getNbLine() - 1,
0, _grid.getNbColumn() - 2, zIsoline, allRidge);
 
//first column
getVerticalGridRidgeIntersectByIsoline(0, _grid.getNbLine() - 2,
0, 0, zIsoline, allRidge);
//last column
getVerticalGridRidgeIntersectByIsoline(0, _grid.getNbLine() - 2,
_grid.getNbColumn() - 1, _grid.getNbColumn() - 1, zIsoline, allRidge);
 
return allRidge;
}
 
private Hashtable getAllRidgeIntersecteByClosedIsoline(double zIsoline)
{
Hashtable allRidge = new Hashtable();
 
//all line whithout first and last line
getHorizontalGridRidgeIntersectByIsoline(1, _grid.getNbLine() - 2,
0, _grid.getNbColumn() - 2, zIsoline, allRidge);
 
//all column whithout first and last column
getVerticalGridRidgeIntersectByIsoline(0, _grid.getNbLine() - 2,
1, _grid.getNbColumn() - 2, zIsoline, allRidge);
 
return allRidge;
}
 
private void getGraphAllOpenIsoline(Hashtable allRidgeIntersectByOpenIsoline,
Hashtable allRidgeIntersectByIsoline, double zIsoline, Graph graph)
{
Enumeration enumAllRidgeIntersectByOpenIsoline = allRidgeIntersectByOpenIsoline.elements();
while(enumAllRidgeIntersectByOpenIsoline.hasMoreElements()){
Ridge ridge = (Ridge)enumAllRidgeIntersectByOpenIsoline.nextElement();
getGraphOpenIsoline(ridge, allRidgeIntersectByOpenIsoline, allRidgeIntersectByIsoline, zIsoline, graph);
enumAllRidgeIntersectByOpenIsoline = allRidgeIntersectByOpenIsoline.elements();
}
}
 
private void getGraphOpenIsoline(Ridge ridgeStart, Hashtable allRidgeIntersectByOpenIsoline,
Hashtable allRidgeIntersectByIsoline, double zIsoline, Graph graph)
{
//System.out.println("Start getGraphOpenIsoline");
boolean isOneRidgeNodeEqualsToZ = ridgeStart.isRidgeNodeEqualsToZ(zIsoline, _grid);
double xInitialVertex = getXIsolineIntersection(ridgeStart, zIsoline);
double yInitialVertex = getYIsolineIntersection(ridgeStart, zIsoline);
 
double xPredecessorPoint = xInitialVertex;
double yPredecessorPoint = yInitialVertex;
 
//System.out.println("xInitialVertex = " + xInitialVertex + " - yInitialVertex = " + yInitialVertex);
 
allRidgeIntersectByIsoline.remove(ridgeStart.getKey());
allRidgeIntersectByOpenIsoline.remove(ridgeStart.getKey());
Vector allIntermediaryPoint = new Vector();
Ridge lastRidge = ridgeStart;
Ridge currentRidge = getRidgeSuccessor(ridgeStart, allRidgeIntersectByIsoline);
while(currentRidge != null){
if(!isOneRidgeNodeEqualsToZ){
isOneRidgeNodeEqualsToZ = currentRidge.isRidgeNodeEqualsToZ(zIsoline, _grid);
}
double xCurrent = getXIsolineIntersection(currentRidge, zIsoline);
double yCurrent = getYIsolineIntersection(currentRidge, zIsoline);
if(!((xCurrent == xPredecessorPoint) && (yCurrent == yPredecessorPoint))){
allIntermediaryPoint.addElement(new Point2D(xCurrent,yCurrent));
xPredecessorPoint = xCurrent;
yPredecessorPoint = yCurrent;
}
allRidgeIntersectByIsoline.remove(currentRidge.getKey());
allRidgeIntersectByOpenIsoline.remove(currentRidge.getKey());
lastRidge = currentRidge;
currentRidge = getRidgeSuccessor(currentRidge, allRidgeIntersectByIsoline);
}
if(allIntermediaryPoint.size() == 0){
//System.out.println("end return getGraphOpenIsoline");
return;
}
Point2D finalPoint2D = (Point2D)allIntermediaryPoint.lastElement();
allIntermediaryPoint.removeElementAt(allIntermediaryPoint.size()-1);
 
if(isOneRidgeNodeEqualsToZ){
//on essaye d'eliminer le cas suivant visible sur l'exemple ci-apres. soit le maillage suivant:
//3 3 3 3
//4 4 4 4
//5 5 5 5
//4 4 4 4
// on obtient 2 isolines horizontal passant par les noeud 5
//avec une recherche d'isoline=5 on passe 2 fois sur la line des 5
//on a 2 isolines superposées (de direction opposée) car on passe par les memes nodes
if(graph.isArcExist(xInitialVertex, yInitialVertex, allIntermediaryPoint,
finalPoint2D.getX(), finalPoint2D.getY())){
return;
}
ContainerTools.reverseAllElement(allIntermediaryPoint);
if(graph.isArcExist(finalPoint2D.getX(), finalPoint2D.getY(), allIntermediaryPoint,
xInitialVertex, yInitialVertex)){
return;
}
ContainerTools.reverseAllElement(allIntermediaryPoint);
}
 
Arc arc = graph.addArc(xInitialVertex, yInitialVertex, allIntermediaryPoint,
finalPoint2D.getX(), finalPoint2D.getY(), zIsoline);
setIsolineWithUpperZAtLeft(arc, lastRidge);
//System.out.println("return getGraphOpenIsoline");
}
 
private void getGraphAllCloseIsoline(Hashtable allRidgeIntersectByIsoline, double zIsoline, Graph graph)
{
Enumeration enumAllRidgeIntersectByIsoline = allRidgeIntersectByIsoline.elements();
while(enumAllRidgeIntersectByIsoline.hasMoreElements()){
Ridge ridge = (Ridge)enumAllRidgeIntersectByIsoline.nextElement();
getGraphCloseIsoline(ridge, allRidgeIntersectByIsoline, zIsoline, graph);
enumAllRidgeIntersectByIsoline = allRidgeIntersectByIsoline.elements();
}
}
 
private void getGraphCloseIsoline(Ridge ridgeStart, Hashtable allRidgeIntersectByIsoline, double zIsoline, Graph graph)
{
double xInitialVertex = getXIsolineIntersection(ridgeStart, zIsoline);
double yInitialVertex = getYIsolineIntersection(ridgeStart, zIsoline);
allRidgeIntersectByIsoline.remove(ridgeStart.getKey());
Vector allIntermediaryPoint = new Vector();
Ridge currentRidge = getRidgeSuccessor(ridgeStart, allRidgeIntersectByIsoline);
while(currentRidge != null){
allIntermediaryPoint.addElement(new Point2D(
getXIsolineIntersection(currentRidge, zIsoline),
getYIsolineIntersection(currentRidge, zIsoline)));
allRidgeIntersectByIsoline.remove(currentRidge.getKey());
currentRidge = getRidgeSuccessor(currentRidge, allRidgeIntersectByIsoline);
}
//isoline closed have same initial and final vertex
graph.addArc(xInitialVertex, yInitialVertex, allIntermediaryPoint,
xInitialVertex, yInitialVertex, zIsoline);
}
 
private Ridge getRidgeSuccessor(Ridge ridge, Hashtable allRidgeIntersectByIsoline)
{
Ridge successorRidge = null;
switch(ridge.getPositionType()){
case Ridge.RIDGE_HORIZONTAL:
successorRidge = getHorizontalRidgeSuccessorInMeshBottom(ridge, allRidgeIntersectByIsoline);
if(successorRidge == null){
successorRidge = getHorizontalRidgeSuccessorInMeshTop(ridge, allRidgeIntersectByIsoline);
}
break;
case Ridge.RIDGE_VERTICAL:
successorRidge = getVerticalRidgeSuccessorInMeshRight(ridge, allRidgeIntersectByIsoline);
if(successorRidge == null){
successorRidge = getVerticalRidgeSuccessorInMeshLeft(ridge, allRidgeIntersectByIsoline);
}
break;
default:
throw new OFCChartsRuntimeException("Invalid ridge type");
}
return successorRidge;
}
 
private Ridge getHorizontalRidgeSuccessorInMeshBottom(Ridge ridge, Hashtable allRidgeIntersectByIsoline)
{
//Sample horizontal ridge :
//First node of Ridge = (line = 0, column = 0)
 
//successor is on ridge vertical right of mesh right:
//First node of Ridge sucessor = (line = 0, column = 0)
Ridge forcedSuccessor = getRidgeFromKey(
Ridge.getKey(ridge.getLineNumberInitialNode(), ridge.getColumnNumberInitialNode() + 1, Ridge.RIDGE_VERTICAL),
allRidgeIntersectByIsoline);
if(forcedSuccessor != null){
return forcedSuccessor;
}
 
//successor is on ridge horizontal bottom of mesh right:
Ridge horizontalSuccessor = getRidgeFromKey(
Ridge.getKey(ridge.getLineNumberInitialNode() + 1, ridge.getColumnNumberInitialNode(), Ridge.RIDGE_HORIZONTAL),
allRidgeIntersectByIsoline);
 
//successor is on ridge vertical left of mesh right:
Ridge verticalSuccessor = getRidgeFromKey(
Ridge.getKey(ridge.getLineNumberInitialNode(), ridge.getColumnNumberInitialNode(), Ridge.RIDGE_VERTICAL),
allRidgeIntersectByIsoline);
 
//if only one ridge find, return this one
if((verticalSuccessor == null) && (horizontalSuccessor != null)){
return horizontalSuccessor;
}
if((horizontalSuccessor == null) && (verticalSuccessor != null)){
return verticalSuccessor;
}
 
return null;
}
 
private Ridge getHorizontalRidgeSuccessorInMeshTop(Ridge ridge, Hashtable allRidgeIntersectByIsoline)
{
//successor is on ridge vertical left of mesh left:
Ridge forcedSuccessor = getRidgeFromKey(
Ridge.getKey(ridge.getLineNumberInitialNode() - 1, ridge.getColumnNumberInitialNode() + 1, Ridge.RIDGE_VERTICAL),
allRidgeIntersectByIsoline);
if(forcedSuccessor != null){
return forcedSuccessor;
}
 
//successor is on ridge horizontal top of mesh left:
Ridge horizontalSuccessor = getRidgeFromKey(
Ridge.getKey(ridge.getLineNumberInitialNode() - 1, ridge.getColumnNumberInitialNode(), Ridge.RIDGE_HORIZONTAL),
allRidgeIntersectByIsoline);
 
//successor is on ridge vertical right of mesh left:
Ridge verticalSuccessor = getRidgeFromKey(
Ridge.getKey(ridge.getLineNumberInitialNode() - 1, ridge.getColumnNumberInitialNode(), Ridge.RIDGE_VERTICAL),
allRidgeIntersectByIsoline);
 
//if only one ridge find, return this one
if((verticalSuccessor == null) && (horizontalSuccessor != null)){
return horizontalSuccessor;
}
if((horizontalSuccessor == null) && (verticalSuccessor != null)){
return verticalSuccessor;
}
 
return null;
}
 
 
private Ridge getVerticalRidgeSuccessorInMeshRight(Ridge ridge, Hashtable allRidgeIntersectByIsoline)
{
//successor is on ridge vertical right of mesh right:
Ridge forcedSuccessor = getRidgeFromKey(
Ridge.getKey(ridge.getLineNumberInitialNode() + 1, ridge.getColumnNumberInitialNode(), Ridge.RIDGE_HORIZONTAL),
allRidgeIntersectByIsoline);
if(forcedSuccessor != null){
return forcedSuccessor;
}
 
//successor is on ridge horizontal bottom of mesh right:
Ridge horizontalSuccessor = getRidgeFromKey(
Ridge.getKey(ridge.getLineNumberInitialNode(), ridge.getColumnNumberInitialNode(), Ridge.RIDGE_HORIZONTAL),
allRidgeIntersectByIsoline);
 
//successor is on ridge vertical left of mesh right:
Ridge verticalSuccessor = getRidgeFromKey(
Ridge.getKey(ridge.getLineNumberInitialNode(), ridge.getColumnNumberInitialNode() + 1, Ridge.RIDGE_VERTICAL),
allRidgeIntersectByIsoline);
 
//if only one ridge find, return this one
if((verticalSuccessor == null) && (horizontalSuccessor != null)){
return horizontalSuccessor;
}
if((horizontalSuccessor == null) && (verticalSuccessor != null)){
return verticalSuccessor;
}
 
return null;
}
 
private Ridge getVerticalRidgeSuccessorInMeshLeft(Ridge ridge, Hashtable allRidgeIntersectByIsoline)
{
//successor is on ridge vertical left of mesh left:
Ridge forcedSuccessor = getRidgeFromKey(
Ridge.getKey(ridge.getLineNumberInitialNode(), ridge.getColumnNumberInitialNode() - 1, Ridge.RIDGE_HORIZONTAL),
allRidgeIntersectByIsoline);
if(forcedSuccessor != null){
return forcedSuccessor;
}
 
//successor is on ridge horizontal top of mesh left:
Ridge horizontalSuccessor = getRidgeFromKey(
Ridge.getKey(ridge.getLineNumberInitialNode() + 1, ridge.getColumnNumberInitialNode() - 1, Ridge.RIDGE_HORIZONTAL),
allRidgeIntersectByIsoline);
 
//successor is on ridge vertical right of mesh left:
Ridge verticalSuccessor = getRidgeFromKey(
Ridge.getKey(ridge.getLineNumberInitialNode(), ridge.getColumnNumberInitialNode() - 1, Ridge.RIDGE_VERTICAL),
allRidgeIntersectByIsoline);
 
//if only one ridge find, return this one
if((verticalSuccessor == null) && (horizontalSuccessor != null)){
return horizontalSuccessor;
}
if((horizontalSuccessor == null) && (verticalSuccessor != null)){
return verticalSuccessor;
}
 
return null;
}
 
 
private Ridge getRidgeFromKey(String ridgeKey, Hashtable allRidgeIntersectByIsoline)
{
return (Ridge)allRidgeIntersectByIsoline.get(ridgeKey);
}
 
private void getHorizontalGridRidgeIntersectByIsoline(int lineNumberStart, int lineNumberEnd,
int columnNumberStart, int columnNumberEnd, double zIsoline, Hashtable allRidgeIntersected)
{
for(int lineNumber = lineNumberStart; lineNumber <= lineNumberEnd; lineNumber ++){
for(int columnNumber = columnNumberStart; columnNumber <= columnNumberEnd; columnNumber ++){
if(isRidgeIntersectByIsoline(_grid.getZ(lineNumber, columnNumber), _grid.getZ(lineNumber, columnNumber + 1), zIsoline)){
allRidgeIntersected.put(Ridge.getKey(lineNumber, columnNumber, Ridge.RIDGE_HORIZONTAL),
new Ridge(lineNumber, columnNumber, Ridge.RIDGE_HORIZONTAL));
}
}
}
}
 
private void getVerticalGridRidgeIntersectByIsoline(int lineNumberStart, int lineNumberEnd,
int columnNumberStart, int columnNumberEnd, double zIsoline, Hashtable allRidgeIntersected)
{
for(int columnNumber = columnNumberStart; columnNumber <= columnNumberEnd; columnNumber ++){
for(int lineNumber = lineNumberStart; lineNumber <= lineNumberEnd; lineNumber ++){
if(isRidgeIntersectByIsoline(_grid.getZ(lineNumber, columnNumber), _grid.getZ(lineNumber +1, columnNumber), zIsoline)){
allRidgeIntersected.put(Ridge.getKey(lineNumber, columnNumber, Ridge.RIDGE_VERTICAL),
new Ridge(lineNumber, columnNumber, Ridge.RIDGE_VERTICAL));
}
}
}
}
 
 
private boolean isRidgeIntersectByIsoline(double zNodeFirst, double zNodeSecond, double zIsoline)
{
//*initial:
return ( (((zNodeFirst < zIsoline)&&(zNodeSecond >= zIsoline))||
((zNodeFirst >= zIsoline)&&(zNodeSecond < zIsoline))) );
//*/
 
/* essai
return ( (((zNodeFirst <= zIsoline)&&(zNodeSecond >= zIsoline))||
((zNodeFirst >= zIsoline)&&(zNodeSecond <= zIsoline))) );
*/
 
//correction:
/*
return ( (((zNodeFirst < zIsoline)&&(zNodeSecond >= zIsoline)) || (((zNodeFirst <= zIsoline)&&(zNodeSecond > zIsoline)) ||
((zNodeFirst >= zIsoline)&&(zNodeSecond < zIsoline))) || ((zNodeFirst > zIsoline)&&(zNodeSecond <= zIsoline))));
*/
}
 
private double getXIsolineIntersection(Ridge ridge, double zIsoline)
{
if(ridge.getPositionType() == Ridge.RIDGE_VERTICAL){
return ridge.getXInitialNode(_grid);
}
 
return getXYIsolineIntersection(ridge, zIsoline,
ridge.getXInitialNode(_grid), ridge.getXFinalNode(_grid));
}
 
private double getYIsolineIntersection(Ridge ridge, double zIsoline)
{
if(ridge.getPositionType() == Ridge.RIDGE_HORIZONTAL){
return ridge.getYInitialNode(_grid);
}
 
return getXYIsolineIntersection(ridge, zIsoline,
ridge.getYInitialNode(_grid), ridge.getYFinalNode(_grid));
}
 
 
private double getXYIsolineIntersection(Ridge ridge, double zIsoline,
double xyInitialNode, double xyFinalNode)
{
double zInitialNode = ridge.getZInitialNode(_grid);
double zFinalNode = ridge.getZFinalNode(_grid);
double zNodeTop = Math.max(zInitialNode, zFinalNode);
double zNodeBottom = Math.min(zInitialNode, zFinalNode);
 
double xyNodeTop;
double xyNodeBottom;
if(zNodeTop == zInitialNode){
xyNodeTop = xyInitialNode;
xyNodeBottom = xyFinalNode;
}else{
xyNodeTop = xyFinalNode;
xyNodeBottom = xyInitialNode;
}
 
 
//double xyNodeTop = Math.max(xyInitialNode, xyFinalNode);
//double xyNodeBottom = Math.min(xyInitialNode, xyFinalNode);
 
if(zNodeTop == zIsoline){
return xyNodeTop;
}
 
if(zNodeBottom == zIsoline){
return xyNodeBottom;
}
 
double coeffLinearInterpol;
if(zIsoline - zNodeBottom != 0){
coeffLinearInterpol = (zNodeTop - zIsoline)/(zIsoline - zNodeBottom);
}
else{
coeffLinearInterpol = 0;
}
 
if((1 + coeffLinearInterpol) !=0){
return (xyNodeTop + coeffLinearInterpol * xyNodeBottom)/(1 + coeffLinearInterpol);
}
 
return 0;
}
 
 
private void setIsolineWithUpperZAtLeft(Arc arcIsoline, Ridge lastRidgeIntersectByIsoline)
{
if(!isIsolineWithUpperZAtLeft(arcIsoline, lastRidgeIntersectByIsoline)){
//System.out.println("************ reverse arc");
arcIsoline.reverse();
}
}
 
/**
* isIsolineWithUpperZAtLeft
* Role : Par convention une isoline doit etre oriente de telle sorte qu'elle ait
* l'isoligne d'altitude superieur à gauche. Pour determiner si on doit
* retourner ou non l'isoligne, on effectue un produit vectoriel avec
* 2 points d'intersections concecutifs des aretes du maillage par
* l'isoligne Z0, et les noeuds de l'aretes sur laquel on a obtenu le
* 2ème points d'intersection. Alors le signe du produit vectoriel obtenu
* avec le noeud le plus bas ou le noued le plus haut, permet de
* determiner l'orientation des isolignes.
* Return : Renvoie TRUE si l'isoline a l'altitude superieur à gauche
*/
boolean isIsolineWithUpperZAtLeft(Arc isolineArc, Ridge lastRidgeIntersectByIsoline)
{
//find point before last point
Point2D point2D = isolineArc.getLastIntermediaryPoint();
double xPointBeforeLast;
double yPointBeforeLast;
if(point2D != null){
xPointBeforeLast = point2D.getX();
yPointBeforeLast = point2D.getY();
}else{
Vertex initialVertex = isolineArc.getInitialVertex();
xPointBeforeLast = initialVertex.getX();
yPointBeforeLast = initialVertex.getY();
}
 
//find last point
Vertex finalVertex = isolineArc.getFinalVertex();
double xLastPoint = finalVertex.getX();
double yLastPoint = finalVertex.getY();
 
//get xy node bottom of last ridge intersect by isoline
double zInitialNode = lastRidgeIntersectByIsoline.getZInitialNode(_grid);
double zFinalNode = lastRidgeIntersectByIsoline.getZFinalNode(_grid);
double zNodeBottom = Math.min(zInitialNode, zFinalNode);
double xNodeBottom;
double yNodeBottom;
if(zNodeBottom == zInitialNode){
xNodeBottom = lastRidgeIntersectByIsoline.getXInitialNode(_grid);
yNodeBottom = lastRidgeIntersectByIsoline.getYInitialNode(_grid);
}else{
xNodeBottom = lastRidgeIntersectByIsoline.getXFinalNode(_grid);
yNodeBottom = lastRidgeIntersectByIsoline.getYFinalNode(_grid);
}
 
//Produit vectoriel :
double prodVectWithNodeBottom = OFCMath.getVectorialProduct(xPointBeforeLast, yPointBeforeLast,
xLastPoint, yLastPoint, xNodeBottom, yNodeBottom);
if(prodVectWithNodeBottom > 0)
return false;
if(prodVectWithNodeBottom < 0)
return true;
 
//get xy node top of last ridge intersect by isoline
double zNodeTop = Math.max(zInitialNode, zFinalNode);
double xNodeTop;
double yNodeTop;
if(zNodeTop == zInitialNode){
xNodeTop = lastRidgeIntersectByIsoline.getXInitialNode(_grid);
yNodeTop = lastRidgeIntersectByIsoline.getYInitialNode(_grid);
}else{
xNodeBottom = lastRidgeIntersectByIsoline.getXInitialNode(_grid);
yNodeBottom = lastRidgeIntersectByIsoline.getYInitialNode(_grid);
xNodeTop = lastRidgeIntersectByIsoline.getXFinalNode(_grid);
yNodeTop = lastRidgeIntersectByIsoline.getYFinalNode(_grid);
}
 
//Produit vectoriel :
double prodVectWithNodeTop = OFCMath.getVectorialProduct(xPointBeforeLast, yPointBeforeLast,
xLastPoint, yLastPoint, xNodeTop, yNodeTop);
if(prodVectWithNodeTop < 0)
return false;
if(prodVectWithNodeTop > 0)
return true;
 
return false;
}
 
 
 
}
/trunk/project/ofccharts/src/com/oxymel/ofc/charts/geographic/Rectangle.java
New file
0,0 → 1,120
package com.oxymel.ofc.charts.geographic;
/*
* Copyright (c) 2006 Oxymel SA.
* All rights reserved.
*
* This software is the confidential and proprietary information of Oxymel SA
* ("Confidential Information"). You shall not disclose such Confidential
* Information and shall use it only in accordance with the terms of the license
* agreement you entered into with Oxymel SA.
*/
 
import com.oxymel.ofc.charts.data.Point2D;
 
/**
*
* <p>Title: Rectangle </p>
* <p>Description: Manage Rectangle</p>
*/
public class Rectangle
{
private double _xMin;
private double _yMin;
private double _xMax;
private double _yMax;
 
 
/**
* Constructor
* @param x X of point
* @param y Y of Point
*/
public Rectangle(double xMin, double yMin, double xMax, double yMax)
{
_xMin = xMin;
_yMin = yMin;
_xMax = xMax;
_yMax = yMax;
}
 
public Rectangle()
{
}
 
/**
* Get X of point
* @return X of point
*/
public double getXMax()
{
return _xMax;
}
 
/**
* Get Y of point
* @return Y of point
*/
public double getYMax()
{
return _yMax;
}
 
 
/**
* Get X of point
* @return X of point
*/
public double getXMin()
{
return _xMin;
}
 
/**
* Get Y of point
* @return Y of point
*/
public double getYMin()
{
return _yMin;
}
 
public void setXMax(double xMax)
{
_xMax = xMax;
}
 
public void setYMax(double yMax)
{
_yMax = yMax;
}
 
public void setXMin(double xMin)
{
_xMin = xMin;
}
 
public void setYMin(double yMin)
{
_yMin = yMin;
}
 
 
public boolean isIncludeIn(Rectangle boundingRectangle)
{
return ( (_xMin >= boundingRectangle.getXMin()) && (_xMin <= boundingRectangle.getXMax()) &&
(_xMax >= boundingRectangle.getXMin()) && (_xMax <= boundingRectangle.getXMax()) &&
(_yMin >= boundingRectangle.getYMin()) && (_yMin <= boundingRectangle.getYMax()) &&
(_yMax >= boundingRectangle.getYMin()) && (_yMax <= boundingRectangle.getYMax()) );
}
 
public boolean isContains(Point2D point)
{
return isContains(point.getX(), point.getY());
}
 
public boolean isContains(double x, double y)
{
return ( (_xMin <= x) && (_xMax >= x) && (_yMin <= y) && (_yMax >= y) );
}
 
}
/trunk/project/ofccharts/src/com/oxymel/ofc/charts/geographic/Arc.java
New file
0,0 → 1,332
package com.oxymel.ofc.charts.geographic;
/*
* Copyright (c) 2006 Oxymel SA.
* All rights reserved.
*
* This software is the confidential and proprietary information of Oxymel SA
* ("Confidential Information"). You shall not disclose such Confidential
* Information and shall use it only in accordance with the terms of the license
* agreement you entered into with Oxymel SA.
*/
 
import java.util.Vector;
import java.util.Enumeration;
 
//ofc
import com.oxymel.ofc.charts.data.Point2D;
import com.oxymel.ofc.charts.geographic.Rectangle;
import com.oxymel.ofc.charts.util.ContainerTools;
import com.oxymel.ofc.charts.util.OFCMath;
import com.oxymel.ofc.charts.util.Segment;
 
 
public class Arc
{
private Vertex _initialVertex;
private Vertex _finalVertex;
private Vector _allIntermediaryPoint;
private Rectangle _boundingRectangle = null;
 
private double _value;
private boolean _isValueDefined = false;
 
private boolean _isTraveledInThisDirection = false;
private boolean _isTraveledInOppositeDirection = false;
 
public Arc(Vertex initialVertex, Vertex finalVertex)
{
_initialVertex = initialVertex;
_finalVertex = finalVertex;
_allIntermediaryPoint = new Vector();
}
 
public Arc(Vertex initialVertex, Vector allIntermediaryPoint, Vertex finalVertex)
{
_initialVertex = initialVertex;
_finalVertex = finalVertex;
_allIntermediaryPoint = allIntermediaryPoint;
}
 
public void setIsTraveledInThisDirection(){_isTraveledInThisDirection = true;}
public boolean isTraveledInThisDirection(){return _isTraveledInThisDirection;}
 
public void setIsTraveledInOppositeDirection(){_isTraveledInOppositeDirection = true;}
public boolean isTraveledInOppositeDirection(){return _isTraveledInOppositeDirection;}
 
 
 
public Arc(Vertex initialVertex, Vector allIntermediaryPoint, Vertex finalVertex, double value)
{
this(initialVertex, allIntermediaryPoint, finalVertex);
_value = value;
_isValueDefined = true;
}
 
public double getValue(){return _value;}
public boolean isValueDefined(){return _isValueDefined;}
 
public Vertex getInitialVertex(){return _initialVertex;}
public Vertex getFinalVertex(){return _finalVertex;}
 
public Enumeration getEnumAllIntermediaryPoint(){return _allIntermediaryPoint.elements();}
public Vector getAllIntermediaryPoint(){return _allIntermediaryPoint;}
 
public Point2D getLastIntermediaryPoint()
{
if(_allIntermediaryPoint.size() == 0){
return null;
}
return (Point2D)_allIntermediaryPoint.elementAt(_allIntermediaryPoint.size() - 1);
}
 
public boolean isIntermediaryPointEquals(Vector allIntermediaryPointToCompare)
{
if(allIntermediaryPointToCompare.size() != _allIntermediaryPoint.size()){
return false;
}
for(int i=0;i< _allIntermediaryPoint.size(); i++){
Point2D point2D = (Point2D)_allIntermediaryPoint.elementAt(i);
Point2D point2DToCompare = (Point2D)allIntermediaryPointToCompare.elementAt(i);
if(!point2D.isSameXY(point2DToCompare)){
return false;
}
}
return true;
}
 
synchronized public void reverse()
{
Vertex oldFinalVertex = _finalVertex;
_finalVertex = _initialVertex;
_initialVertex = oldFinalVertex;
 
ContainerTools.reverseAllElement(_allIntermediaryPoint);
}
 
 
public Rectangle getBoundingRectangle()
{
if(_boundingRectangle != null){
return _boundingRectangle;
}
Vertex initialVertex = getInitialVertex();
Vertex finalVertex = getFinalVertex();
 
double xMin = Math.min(initialVertex.getX(), finalVertex.getX());
double yMin = Math.min(initialVertex.getY(), finalVertex.getY());
double xMax = Math.max(initialVertex.getX(), finalVertex.getX());
double yMax = Math.max(initialVertex.getY(), finalVertex.getY());
 
for(int i=0;i<_allIntermediaryPoint.size();i++){
Point2D point2D = (Point2D)_allIntermediaryPoint.elementAt(i);
xMin = Math.min(xMin, point2D.getX());
yMin = Math.min(yMin, point2D.getY());
xMax = Math.max(xMax, point2D.getX());
yMax = Math.max(yMax, point2D.getY());
}
_boundingRectangle = new Rectangle(xMin, yMin, xMax, yMax);
return _boundingRectangle;
}
 
public Arc getArcMoreAtLeftSuccessor(boolean isFindInArcDirection)
{
Segment lastSegmentOfArc;
Vertex lastVertex;
if(isFindInArcDirection){
lastSegmentOfArc = getFinalSegment();
lastVertex = getFinalVertex();
}
else{
lastSegmentOfArc = getInitialSegment();
lastSegmentOfArc.reverse();
lastVertex = getInitialVertex();
}
 
return getArcMoreAtLeftSuccessor(lastSegmentOfArc, lastVertex, lastVertex.getEnumAllArcGoInOut(this));
}
 
public Segment getInitialSegment()
{
Segment segment = new Segment();
 
Vertex initialVertex = getInitialVertex();
segment.setXInitial(initialVertex.getX());
segment.setYInitial(initialVertex.getY());
 
if(_allIntermediaryPoint.size() != 0){
Point2D point2D = (Point2D)_allIntermediaryPoint.elementAt(0);
segment.setXFinal(point2D.getX());
segment.setYFinal(point2D.getY());
}else{
Vertex finalVertex = getFinalVertex();
segment.setXFinal(finalVertex.getX());
segment.setYFinal(finalVertex.getY());
}
return segment;
}
 
public Segment getFinalSegment()
{
Segment segment = new Segment();
 
Vertex finalVertex = getFinalVertex();
segment.setXFinal(finalVertex.getX());
segment.setYFinal(finalVertex.getY());
 
if(_allIntermediaryPoint.size() != 0){
Point2D point2D = (Point2D)_allIntermediaryPoint.lastElement();
segment.setXInitial(point2D.getX());
segment.setYInitial(point2D.getY());
}else{
Vertex initialVertex = getInitialVertex();
segment.setXInitial(initialVertex.getX());
segment.setYInitial(initialVertex.getY());
}
return segment;
}
 
public boolean isSameDirectionAsArcPredecessor(Arc arcPredecessor)
{
/*
double xFinalPred = arcPredecessor.getFinalVertex().getX();
double yFinalPred = arcPredecessor.getFinalVertex().getY();
double xInitial = getInitialVertex().getX();
double yInitial = getInitialVertex().getY();
 
return ((xFinalPred == xInitial) && (yFinalPred == yInitial)) ;
*/
return (arcPredecessor.getFinalVertex().equals(this.getInitialVertex()));
}
 
public boolean isPointOnArc(double x, double y)
{
Vertex initialVertex = getInitialVertex();
double xInitialSegment = initialVertex.getX();
double yInitialSegment = initialVertex.getY();
 
Enumeration enumAllIntermediaryPoint = getEnumAllIntermediaryPoint();
while(enumAllIntermediaryPoint.hasMoreElements()){
Point2D intermediaryPoint = (Point2D)enumAllIntermediaryPoint.nextElement();
double xFinalSegment = intermediaryPoint.getX();
double yFinalSegment = intermediaryPoint.getY();
if(Segment.isPointOnSegment(x, y, xInitialSegment, yInitialSegment,
xFinalSegment, yFinalSegment)){
return true;
}
xInitialSegment = xFinalSegment;
yInitialSegment = yFinalSegment;
}
 
Vertex finalVertex = getFinalVertex();
double xFinalSegment = finalVertex.getX();
double yFinalSegment = finalVertex.getY();
if(Segment.isPointOnSegment(x, y, xInitialSegment, yInitialSegment,
xFinalSegment, yFinalSegment)){
return true;
}
 
return false;
}
 
private Arc getArcMoreAtLeftSuccessor(Segment lastSegmentOfArc, Vertex lastVertex, Enumeration enumAllArc)
{
if(!enumAllArc.hasMoreElements()){
return null;
}
Arc arcSuccessor = (Arc)enumAllArc.nextElement();
while(enumAllArc.hasMoreElements()){
Arc arc = (Arc)enumAllArc.nextElement();
arcSuccessor = getArcMoreAtLeftSuccessor(lastSegmentOfArc, lastVertex, arcSuccessor, arc);
}
return arcSuccessor;
}
 
/**
* le signe du produit vectoriel est trouver en plaçant le pouce dans la direction
* du premier segment, l'index dans la direction du second, le majeur donne alors
* le signe qui est positif s'il pointe vers soi, negatif dans le cas contraire
*/
private Arc getArcMoreAtLeftSuccessor(Segment lastSegmentOfArc, Vertex lastVertex,
Arc arcSuccessor1, Arc arcSuccessor2)
 
{
//System.out.println("arcSuccessor1 = " + arcSuccessor1.toString());
//System.out.println("arcSuccessor2 = " + arcSuccessor2.toString());
 
//il faut dans tous les cas prendre le segment oriente allant vers
//la gauche.
 
//
Segment segmentArcSuccessor1;
if(arcSuccessor1.getInitialVertex().equals(lastVertex)){
//parcour de l'arc dans son sens
segmentArcSuccessor1 = arcSuccessor1.getInitialSegment();
}
else{
//parcour de l'arc en sens inverse
//On recupere le segment final que l'on retourne
segmentArcSuccessor1 = arcSuccessor1.getFinalSegment();
segmentArcSuccessor1.reverse();
}
boolean isSuccessor1AtLeft = false;
if(OFCMath.getVectorialProduct(lastSegmentOfArc, segmentArcSuccessor1)>0){
// Point Final of segment Successor is At Left Of last Segment Of Arc
isSuccessor1AtLeft = true;
}
 
//
Segment segmentArcSuccessor2;
if(arcSuccessor2.getInitialVertex().equals(lastVertex)){
//parcour de l'arc dans sons sens
segmentArcSuccessor2 = arcSuccessor2.getInitialSegment();
}
else{
//parcour de l'arc en sens inverse
//On recupere le segment final que l'on retourne
segmentArcSuccessor2 = arcSuccessor2.getFinalSegment();
segmentArcSuccessor2.reverse();
}
boolean isSuccessor2AtLeft = false;
if(OFCMath.getVectorialProduct(lastSegmentOfArc, segmentArcSuccessor2)>0){
// Point Final of segment Successor is At Left Of last Segment Of Arc
isSuccessor2AtLeft = true;
}
 
//
if( ((isSuccessor1AtLeft)&&(isSuccessor2AtLeft)) || ((!isSuccessor1AtLeft)&&(!isSuccessor2AtLeft)) ){
//il faut savoir lequel est le plus a gauche
if(OFCMath.getVectorialProduct(segmentArcSuccessor1, segmentArcSuccessor2)<0){
return arcSuccessor1;
}
else{
return arcSuccessor2;
}
}
else{
if(isSuccessor2AtLeft){
return arcSuccessor2;
}
else{
return arcSuccessor1;
}
}
}
 
 
public String toString()
{
 
String ptIntermedaireInfo = "";
for(int i=0; i< _allIntermediaryPoint.size(); i++){
Point2D point = (Point2D)_allIntermediaryPoint.elementAt(i);
ptIntermedaireInfo += " - PT" + i + ": X = " + point.getX() + " Y = " + point.getY();
}
 
 
return "xInitialVertex = " + getInitialVertex().getX() + " - yInitialVertex = " + getInitialVertex().getY() +
" | xFinalVertex = " + getFinalVertex().getX() + " - yFinalVertex = " + getFinalVertex().getY() +
" - Nb Point = " + _allIntermediaryPoint.size() + " - value = " + _value +
" - isValueDefined = " + _isValueDefined + ptIntermedaireInfo;
}
 
}
/trunk/project/ofccharts/src/com/oxymel/ofc/charts/ChartWithAxisXYY.java
New file
0,0 → 1,176
package com.oxymel.ofc.charts;
/*
* Copyright (c) 2006 Oxymel SA.
* All rights reserved.
*
* This software is the confidential and proprietary information of Oxymel SA
* ("Confidential Information"). You shall not disclose such Confidential
* Information and shall use it only in accordance with the terms of the license
* agreement you entered into with Oxymel SA.
*/
 
//java
import java.awt.Graphics2D;
import java.util.Vector;
import java.util.Enumeration;
 
//ofc
import com.oxymel.ofc.charts.series.Point2DSeries;
import com.oxymel.ofc.charts.exception.OFCChartsException;
import com.oxymel.ofc.charts.series.SeriesContainer;
 
 
/**
* This class is the abstract superclass for all char with one axis X and two axis Y.
*/
abstract class ChartWithAxisXYY extends ChartWithAxisXY
{
protected ChartWithAxisXYY(int chartWidth, int chartHeight)
{
super(chartWidth, chartHeight);
}
 
//tmp on ne gere pas le 3d sur les graphics complex avec 2 axes des Y
public void set3dEffectValue(int coeff3dEffect)
{
}
 
 
protected void doDrawChart(Graphics2D graphics2D) throws OFCChartsException
{
setAxisParameters();
 
Axis axisX = getAxisX();
Axis axisY = getAxisY();
Axis axisYRight = getAxisYRight();
 
int xTopLeftGraphic = getXTopLeftGraphic(graphics2D);
int yTopLeftGraphic = getYTopLeftGraphic(graphics2D);
int graphicWidth = getGraphicWidth(graphics2D);
axisX.setNbPixelSize(graphicWidth);
int graphicHeight = getGraphicHeight(graphics2D);
axisY.setNbPixelSize(graphicHeight);
axisYRight.setNbPixelSize(graphicHeight);
 
int sizeOfGapOnY = graphicHeight / axisY.getNbGap();
int sizeOfGapOnYRight = graphicHeight / axisYRight.getNbGap();
int sizeOfGapOnX = graphicWidth / axisX.getNbGap();
 
int decalageOrigineToIncludeNegativeValueOnY = sizeOfGapOnY * axisY.getNbNegativeGapToIncludeMinValue();
int decalageOrigineToIncludeNegativeValueOnYRight = sizeOfGapOnYRight * axisYRight.getNbNegativeGapToIncludeMinValue();
 
int yOrigine;
if(decalageOrigineToIncludeNegativeValueOnY > decalageOrigineToIncludeNegativeValueOnYRight){
yOrigine = (yTopLeftGraphic + graphicHeight) - decalageOrigineToIncludeNegativeValueOnY;
}else{
yOrigine = (yTopLeftGraphic + graphicHeight) - decalageOrigineToIncludeNegativeValueOnYRight;
}
 
int xOrigine = xTopLeftGraphic +
(sizeOfGapOnX * axisX.getNbNegativeGapToIncludeMinValue());
 
drawGraphicBackground(xTopLeftGraphic, yTopLeftGraphic,
graphicWidth, graphicHeight, graphics2D);
 
 
 
//axisY.drawInternalGrid(graphicWidth, graphicHeight, xTopLeftGraphic, yTopLeftGraphic,
// xOrigine, yOrigine, graphics2D);
//axisX.drawInternalGrid(graphicWidth, graphicHeight, xTopLeftGraphic, yTopLeftGraphic,
// xOrigine, yOrigine, graphics2D);
 
//drawInternalGrid(graphicWidth, graphicHeight, xTopLeftGraphic, yTopLeftGraphic,
// xOrigine, yOrigine, graphics2D);
 
axisY.draw(graphicWidth, graphicHeight, xTopLeftGraphic, yTopLeftGraphic,
xOrigine, yOrigine, graphics2D);
axisYRight.draw(graphicWidth, graphicHeight, xTopLeftGraphic, yTopLeftGraphic,
xOrigine, yOrigine, graphics2D);
 
drawGraphic(xTopLeftGraphic, yTopLeftGraphic, graphicWidth, graphicHeight,
xOrigine, yOrigine, graphics2D);
 
axisX.draw(graphicWidth, graphicHeight, xTopLeftGraphic, yTopLeftGraphic,
xOrigine, yOrigine, graphics2D);
 
//pas de legend affichée
_legend.drawLegend(getXTopLeftLegend(graphics2D), getYTopLeftLegend(graphics2D),
getSeriesContainer().getAllSeriesOrderByDisplayNumber(), graphics2D);
 
/* bug à voir plus tard
_legend.drawLegend(
getXTopLeftLegend(xTopLeftGraphic, yTopLeftGraphic, graphicWidth, graphicHeight, graphics2D),
getYTopLeftLegend(xTopLeftGraphic, yTopLeftGraphic, graphicWidth, graphicHeight, graphics2D),
getSeriesContainer().getAllSeriesOrderByDisplayNumber(), graphics2D);
*/
}
 
 
//template pattern used by doDrawChart :
abstract protected Axis getAxisYRight();
 
protected int getYTopLeftGraphic(Graphics2D graphics2D)
{
Axis axisY = getAxisY();
Axis axisYRight = getAxisYRight();
 
int yTopLeftGraphic = super.getYTopLeftGraphic(graphics2D);
int nbPixelUsedAtTopByAxisYRight = axisYRight.getNbPixelUsedAtTop(graphics2D);
int nbPixelUsedAtTopByAxisYLeft = axisY.getNbPixelUsedAtTop(graphics2D);
if( nbPixelUsedAtTopByAxisYRight > nbPixelUsedAtTopByAxisYLeft)
yTopLeftGraphic += nbPixelUsedAtTopByAxisYRight - nbPixelUsedAtTopByAxisYLeft;
return yTopLeftGraphic;
}
 
protected int getGraphicWidth(Graphics2D graphics2D)
{
Axis axisYRight = getAxisYRight();
int graphicWidth = super.getGraphicWidth(graphics2D);
graphicWidth -= (axisYRight.getNbPixelUsedAtLeft(graphics2D) +
axisYRight.getNbPixelUsedAtRight(graphics2D));
return graphicWidth;
}
 
protected int getGraphicHeight(Graphics2D graphics2D) throws OFCChartsException
{
Axis axisYRight = getAxisYRight();
Axis axisY = getAxisY();
 
int graphicHeight = super.getGraphicHeight(graphics2D);
 
int nbPixelUsedAtTopByAxisYRight = axisYRight.getNbPixelUsedAtTop(graphics2D);
int nbPixelUsedAtTopByAxisYLeft = axisY.getNbPixelUsedAtTop(graphics2D);
if(nbPixelUsedAtTopByAxisYRight > nbPixelUsedAtTopByAxisYLeft){
graphicHeight -= nbPixelUsedAtTopByAxisYRight - nbPixelUsedAtTopByAxisYLeft;
}
 
int nbPixelUsedAtBottomByAxisYRight = axisYRight.getNbPixelUsedAtBottom(graphics2D);
int nbPixelUsedAtBottomByAxisYLeft = axisY.getNbPixelUsedAtBottom(graphics2D);
if(nbPixelUsedAtBottomByAxisYRight > nbPixelUsedAtBottomByAxisYLeft){
graphicHeight -= nbPixelUsedAtBottomByAxisYRight - nbPixelUsedAtBottomByAxisYLeft;
}
 
return graphicHeight;
}
 
protected int getXTopLeftLegend(Graphics2D graphics2D) throws OFCChartsException
{
int xTopLeftLegend = super.getXTopLeftLegend(graphics2D);
switch(_legend.getLegendDisplayMode()){
case Legend.LEGEND_DISPLAY_MODE_RIGHT:
Axis axisX = getAxisX();
Axis axisYRight = getAxisYRight();
 
int nbPixelUsedAtRightByAxisX = axisX.getNbPixelUsedAtRight(graphics2D);
int nbPixelUsedByAxisYRight = axisYRight.getNbPixelUsedAtRight(graphics2D) +
axisYRight.getNbPixelUsedAtLeft(graphics2D);
if(nbPixelUsedByAxisYRight > nbPixelUsedAtRightByAxisX){
xTopLeftLegend += (nbPixelUsedByAxisYRight - nbPixelUsedAtRightByAxisX);
}
break;
}
return xTopLeftLegend;
}
 
 
}
/trunk/project/ofccharts/src/com/oxymel/ofc/charts/VerticalAxisRight.java
New file
0,0 → 1,130
package com.oxymel.ofc.charts;
/*
* Copyright (c) 2006 Oxymel SA.
* All rights reserved.
*
* This software is the confidential and proprietary information of Oxymel SA
* ("Confidential Information"). You shall not disclose such Confidential
* Information and shall use it only in accordance with the terms of the license
* agreement you entered into with Oxymel SA.
*/
 
//java
import java.awt.Graphics2D;
import java.awt.Font;
import java.awt.geom.AffineTransform;
import java.awt.RenderingHints;
//ofc
import com.oxymel.ofc.charts.util.Graphics2DTools;
import com.oxymel.ofc.charts.exception.OFCChartsRuntimeException;
 
abstract class VerticalAxisRight extends VerticalAxisCommon
{
protected VerticalAxisRight(String label)
{
super(label);
}
 
 
int getNbPixelUsedAtLeft(Graphics2D graphics2D){return 0;}
int getNbPixelUsedAtRight(Graphics2D graphics2D)
{
int nbPixelUsedForWriteYValues = getNbPixelUsedForWriteYValues(graphics2D) +
_nbPixelBetweenValueAndGapIndicator +_nbPixelOfGapIndicator;
 
switch(_labelPosition){
case LABEL_POSITION_HORIZONTAL_TOP :
int nbPixelUsedForLabel = (getNbPixelWidthOfLabel(graphics2D)/2);
return (nbPixelUsedForWriteYValues > nbPixelUsedForLabel)? nbPixelUsedForWriteYValues : nbPixelUsedForLabel;
case LABEL_POSITION_VERTICAL_RIGHT_CENTER :
return nbPixelUsedForWriteYValues + _nbPixelFreeBeforeLabel +
Graphics2DTools.getNbPixelHeightOfTxt(graphics2D, getLabel());
default:
throw new OFCChartsRuntimeException("Invalid label position = " + _labelPosition);
}
 
}
 
int getNbPixelUsedAtTop(Graphics2D graphics2D)
{
Font font = graphics2D.getFont();
graphics2D.setFont(getFont(graphics2D));
int nbPixelUsedToWriteLabel = getNbPixelUsedToDrawLabel(graphics2D);
graphics2D.setFont(font);
return getArrowLength() + nbPixelUsedToWriteLabel;
}
int getNbPixelUsedAtBottom(Graphics2D graphics2D){return 0;}
 
 
protected void drawAxisLine(int graphicWidth, int graphicHeight, int xTopLeftGraphic,
int yTopLeftGraphic, int xOrigine, int yOrigine, Graphics2D graphics2D)
{
int xAxisRight = xTopLeftGraphic + graphicWidth;
graphics2D.drawLine(xAxisRight, yTopLeftGraphic, xAxisRight, yTopLeftGraphic + graphicHeight);
}
 
protected void drawArrow(int graphicWidth, int graphicHeight, int xTopLeftGraphic,
int yTopLeftGraphic, int xOrigine, int yOrigine, Graphics2D graphics2D)
{
Graphics2DTools.drawSouthNorthArrow(getArrowLength(), xTopLeftGraphic + graphicWidth,
yTopLeftGraphic, graphics2D);
}
 
protected void drawGapIndicator(int graphicWidth, int graphicHeight, int xTopLeftGraphic,
int yTopLeftGraphic, int xOrigine, int yOrigine, Graphics2D graphics2D)
{
int xAxisRight = xTopLeftGraphic + graphicWidth;
int nbGapOnY = getNbGap();
int sizeOfGapOnY = graphicHeight / nbGapOnY;
int yOfGap = yTopLeftGraphic + graphicHeight;
graphics2D.setColor(getGapIndicatorColor());
for(int i=0; i<nbGapOnY + 1; i++){
graphics2D.drawLine(xAxisRight - _nbPixelOfGapIndicator, yOfGap, xAxisRight + _nbPixelOfGapIndicator, yOfGap);
yOfGap -= sizeOfGapOnY;
}
}
 
protected void drawLabel(int graphicWidth, int graphicHeight, int xTopLeftGraphic,
int yTopLeftGraphic, int xOrigine, int yOrigine, Graphics2D graphics2D)
{
int xAxisRight = xTopLeftGraphic + graphicWidth;
 
switch(_labelPosition){
case LABEL_POSITION_HORIZONTAL_TOP :
graphics2D.drawString(getLabel(), Graphics2DTools.getXToAlignTxt(graphics2D, xAxisRight, getLabel()),
yTopLeftGraphic - getArrowLength() - _nbPixelFreeBeforeLabel);
break;
case LABEL_POSITION_VERTICAL_RIGHT_CENTER:
RenderingHints render = graphics2D.getRenderingHints();
render.put(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF);
render.put(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_OFF);
 
AffineTransform saveXform = graphics2D.getTransform();
AffineTransform at = new AffineTransform();
 
int nbPixelUsedForWriteYValues = getNbPixelUsedForWriteYValues(graphics2D) +
_nbPixelBetweenValueAndGapIndicator +_nbPixelOfGapIndicator;
 
int xToAlignTxt = xAxisRight + nbPixelUsedForWriteYValues + _nbPixelFreeBeforeLabel +
(Graphics2DTools.getNbPixelHeightOfTxt(graphics2D, getLabel())/2);
int yToWriteLine = yTopLeftGraphic + (graphicHeight/2);
at.rotate(Math.toRadians(-90), xToAlignTxt, yToWriteLine);
graphics2D.transform(at);
 
graphics2D.drawString(getLabel(), xToAlignTxt - Graphics2DTools.getNbPixelHeightOfTxt(graphics2D, getLabel()) , yToWriteLine);
 
 
graphics2D.setTransform(saveXform);
 
render.put(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
render.put(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
 
break;
default:
throw new OFCChartsRuntimeException("Invalid label position = " + _labelPosition);
}
 
}
 
 
}
/trunk/project/ofccharts/src/com/oxymel/ofc/charts/ColorPalette.java
New file
0,0 → 1,298
package com.oxymel.ofc.charts;
/*
* Copyright (c) 2006 Oxymel SA.
* All rights reserved.
*
* This software is the confidential and proprietary information of Oxymel SA
* ("Confidential Information"). You shall not disclose such Confidential
* Information and shall use it only in accordance with the terms of the license
* agreement you entered into with Oxymel SA.
*/
 
//java
import java.awt.Color;
import java.util.Vector;
 
/**
* ColorPalette class allows to customize the colors used in a given graphic.
* It contains a set of colors, and it provides methods to manage the colors.
* The colors belonging to the Palette are ordered, and the first one is at the position 0.
*/
public class ColorPalette {
private Vector _allColor = new Vector();
 
/**
* Constructor
* The Color palette is initialized with default colors
*/
public ColorPalette() {
initPalette();
}
 
/**
* Gets the number of colors contained in palette.
* @return number The color's count
*/
public int size() {
return _allColor.size();
}
 
/**
* Reset the color palette so that it becomes empty.
*/
public void clear() {
_allColor.clear();
}
 
/**
* Adds a new color to the palette.
* The color is given as an instance of the Color class. It is stored at the last position in the palette.
* @param color new color to add
*/
public void addColor(Color color) {
_allColor.addElement(color);
}
 
/**
* Gets the color located at the given position;
* @param colorPosition The color position in the palette
* @return Color asked, if position is greater than the number of existing colors the last color is returned.
*/
public Color getColorAt(int colorPosition) {
//int numColor = numColorInPalette - 1;
int numColor = colorPosition;
if (numColor < 0) {
return (Color) _allColor.firstElement();
}
if (numColor >= _allColor.size()) {
return (Color) _allColor.lastElement();
}
return (Color) _allColor.elementAt(numColor);
}
 
/**
* Sets or replaces the color at the given position by the one passed as argument (color).
* If the given position does not exists in the palette, nothing is done.
* @param color New color to set at the colorPosition in the palette
* @param colorPosition color position in palette, it must corresponds to an existing position
*/
public void setColorAt(Color color, int colorPosition) {
//int numColor = numColorInPalette - 1;
int numColor = colorPosition;
if ( (numColor < 0) || (numColor >= _allColor.size())) {
return;
}
_allColor.setElementAt(color, numColor);
}
 
/**
* Sets or replaces the color at the given position by the one passed as argument as a RGB color.
* If the given position does not exists in the palette, nothing is done.
* @param R Red part of color
* @param G Green part of color
* @param B Blue part of color
* @param colorPosition The color position in the palette, it must corresponds to an existing position
*/
public void setColorAt(int R, int G, int B, int colorPosition) {
//int numColor = numColorInPalette - 1;
int numColor = colorPosition;
if ( (numColor < 0) || (numColor >= _allColor.size())) {
return;
}
_allColor.setElementAt(getColor(R, G, B), numColor);
}
 
/**
* Builds a Color instance from its RGB representation
* @param R Red part of color
* @param G Green part of color
* @param B Blue part of color
* @return Color The Color instance corresponding to the RGB color definition
*/
static public Color getColor(int R, int G, int B) {
return new Color( (float) R / 256, (float) G / 256, (float) B / 256);
}
 
/**
* Initializes the ColorPalette with the defaults values, it contains 12 different colors
*/
public void initPalette() {
_allColor.clear();
 
//classic color
_allColor.addElement(Color.blue);// #0000FE
_allColor.addElement(getColor(0, 192, 192));// #00C0C0
_allColor.addElement(Color.cyan);// #00FFFF
_allColor.addElement(Color.green);
_allColor.addElement(Color.red);
_allColor.addElement(Color.magenta);
_allColor.addElement(Color.pink);
_allColor.addElement(Color.orange);
_allColor.addElement(Color.yellow);
_allColor.addElement(Color.lightGray);
_allColor.addElement(Color.gray);
_allColor.addElement(Color.darkGray);
}
 
/**
* Initializes the ColorPalette as blue gradient, it contains 5 colors
*/
public void initPaletteAsBlueGradient() {
_allColor.clear();
_allColor.addElement(getColor(0, 4, 182));
_allColor.addElement(getColor(0, 0, 255));
_allColor.addElement(getColor(68, 72, 255));
_allColor.addElement(getColor(122, 125, 255));
_allColor.addElement(getColor(193, 194, 255));
}
 
/**
* Initializes the ColorPalette as cold to hot effect with the given number of data
* @param nbOfData int
*/
private void initPaletteAsHotToColdEffect(int nbOfData) {
_allColor.clear();
int pas = 50;
if (20 < nbOfData && nbOfData <= 30) {
pas = 35;
}
if (30 < nbOfData && nbOfData <= 40) {
pas = 25;
}
if (40 < nbOfData && nbOfData <= 50) {
pas = 15;
}
if (50 < nbOfData && nbOfData <= 100) {
pas = 10;
}
if (100 < nbOfData && nbOfData <= 150) {
pas = 8;
}
if (150 < nbOfData) {
pas = 5;
}
int factor = 8;
 
for (int i = 150; i <= 255; i += pas * factor) { //dégradé de bleu
_allColor.addElement(getColor(0, 0, i));
}
for (int i = pas; i <= 255; i += pas) { //bleu -> cyan
_allColor.addElement(getColor(0, i, 255));
}
for (int i = pas; i <= 255; i += pas) { //cyan -> vert
_allColor.addElement(getColor(0, 255, 255 - i));
}
for (int i = pas; i <= 255; i += pas) { //vert -> jaune
_allColor.addElement(getColor(i, 255, 0));
}
for (int i = pas; i <= 255; i += pas) { //jaune -> rouge
_allColor.addElement(getColor(255, 255 - i, 0));
}
for (int i = pas; i < 155; i += pas * factor) { //dégradé de rouge
_allColor.addElement(getColor(255 - i, 0, 0));
}
}
 
/**
* Initializes the ColorPalette as cold to hot effect, it contains 22 colors
*/
public void initPaletteAsHotToColdEffect() {
_allColor.clear();
 
_allColor.addElement(getColor(0, 0, 120)); //bleu
_allColor.addElement(getColor(0, 0, 175));
_allColor.addElement(getColor(0, 19, 255));
_allColor.addElement(getColor(0, 115, 255));
_allColor.addElement(getColor(0, 156, 255));
_allColor.addElement(getColor(0, 198, 255));
_allColor.addElement(getColor(0, 255, 255));
_allColor.addElement(getColor(0, 255, 198));
_allColor.addElement(getColor(0, 255, 140));
_allColor.addElement(getColor(0, 255, 82));
_allColor.addElement(getColor(0, 255, 33));
_allColor.addElement(getColor(33, 255, 0));
_allColor.addElement(getColor(90, 255, 0));
_allColor.addElement(getColor(140, 255, 0));
_allColor.addElement(getColor(198, 255, 0));
_allColor.addElement(getColor(255, 255, 0));
_allColor.addElement(getColor(255, 206, 0));
_allColor.addElement(getColor(255, 148, 0));
_allColor.addElement(getColor(255, 90, 0));
_allColor.addElement(getColor(255, 33, 0));
_allColor.addElement(getColor(220, 0, 0));
_allColor.addElement(getColor(160, 0, 0)); //rouge
 
}
 
/**
* Initializes the ColorPaletteSets as an excel color palette, it contains 8 colors
*/
public void initPaletteAsExcelColor() {
_allColor.clear();
_allColor.addElement(getColor(153, 153, 255));
_allColor.addElement(getColor(153, 153, 255));
_allColor.addElement(getColor(153, 51, 102));
_allColor.addElement(getColor(255, 255, 204));
_allColor.addElement(getColor(204, 255, 255));
_allColor.addElement(getColor(102, 0, 102));
_allColor.addElement(getColor(255, 128, 128));
_allColor.addElement(getColor(0, 102, 204));
}
 
/**
* Initializes the ColorPalette as cold to hot effect with the given number of data
* @param nbOfData int
*/
public void initPaletteHotToColdFromData(int nbOfData) {
initPaletteAsHotToColdEffect(nbOfData);
 
if (nbOfData < _allColor.size()) {
Vector tmp_allColor = new Vector();
java.util.List elementsToRemove = new java.util.ArrayList();
int nbToRemove = 0;
 
//calcul du nombre d'elements à enlever à la palette
nbToRemove = (_allColor.size() - nbOfData);
//recherche de l'intervalle à utiliser pour oter des elements
//pour une répartition homogene sur l'ensemble de la palette
double interval = new Double(_allColor.size()).doubleValue() /
new Double( (nbToRemove + 1)).doubleValue();
//enregistrement des numeros des elements à enlever de la palette
for (int j = 1; j <= nbToRemove; j++) {
int t = new Long(Math.round(interval * j)).intValue();
elementsToRemove.add(t + "");
}
for (int i = 0; i < _allColor.size(); i++) {
boolean toRemove = false;
for (int n = 0; n < elementsToRemove.size() && !toRemove; n++) {
toRemove = (i == Integer.parseInt( (String) elementsToRemove.get(n)));
}
//si l'element n'est pas à enlever, écriture dans la palette
if (!toRemove) {
tmp_allColor.add(_allColor.get(i));
}
}
_allColor = tmp_allColor;
}
}
 
/**
* Initializes the ColorPalette with 42 differents colors
*/
public void initPaletteWith42Colors() {
// _allColor.clear();
initPalette();
String[] colors = {
"9090E0", "D07C7C", "15E015", "8A2BE2", "008B8B", "8B0000",
"FFAA28", "A0D0D0", "DC143C", "B8860B", "228B22", "00008B", "BDB76B",
"8B008B", "6495ED", "FF7F50", "A9A9A9",
"DAA520", "00BFFF", "FF1493", "00FA9A", "800000", "66CDAA", "0000CD",
"FF4500", "BA55D3", "3CB371", "7B68EE", "C71585", "FF0000", "DEB887",
"D2691E", "006400", "E9967A", "8FBC8F", "483D8B", "FF8C00", "9400D3",
"556B2F", "696969", "1E90FF", "000000"};
for (int i = 0; i < colors.length; i++) {
_allColor.add(new Color(Integer.parseInt(colors[i].trim(), 16)));
}
}
 
}
/trunk/project/ofccharts/src/com/oxymel/ofc/charts/util/Interval.java
New file
0,0 → 1,78
package com.oxymel.ofc.charts.util;
/*
* Copyright (c) 2006 Oxymel SA.
* All rights reserved.
*
* This software is the confidential and proprietary information of Oxymel SA
* ("Confidential Information"). You shall not disclose such Confidential
* Information and shall use it only in accordance with the terms of the license
* agreement you entered into with Oxymel SA.
*/
 
//ofc
import com.oxymel.ofc.charts.exception.OFCChartsRuntimeException;
 
 
public class Interval
{
public static final int COMPARISON_TYPE_LOWER_STRICT = 0;
public static final int COMPARISON_TYPE_LOWER_OR_EGAL = 1;
public static final int COMPARISON_TYPE_GREATER_STRICT = 2;
public static final int COMPARISON_TYPE_GREATER_OR_EGAL = 3;
 
 
private double _startInterval;
private int _startIntervalComparisonType;
private double _endInterval;
private int _endIntervalComparisonType;
 
public Interval(double startInterval, int startIntervalComparisonType, double endInterval, int endIntervalComparisonType)
{
_startInterval = startInterval;
_startIntervalComparisonType = startIntervalComparisonType;
_endInterval = endInterval;
_endIntervalComparisonType = endIntervalComparisonType;
}
 
public double getStartValue(){return _startInterval;}
public double getEndValue(){return _endInterval;}
 
public boolean isContains(double startInterval, double endInterval)
{
if(!isContains(startInterval)){
return false;
}
if(!isContains(endInterval)){
return false;
}
return true;
}
 
public boolean isContains(double value)
{
if(!isValueRespectIntervalComparison(value, _startInterval, _startIntervalComparisonType)){
return false;
}
if(!isValueRespectIntervalComparison(value, _endInterval, _endIntervalComparisonType)){
return false;
}
return true;
}
 
private boolean isValueRespectIntervalComparison(double value, double interval, int intervalComparisonType)
{
switch(intervalComparisonType){
case COMPARISON_TYPE_LOWER_STRICT:
return (value < interval);
case COMPARISON_TYPE_LOWER_OR_EGAL:
return (value <= interval);
case COMPARISON_TYPE_GREATER_STRICT:
return (value > interval);
case COMPARISON_TYPE_GREATER_OR_EGAL:
return (value >= interval);
default:
throw new OFCChartsRuntimeException("Invalid interval comparaison type");
}
}
 
}
/trunk/project/ofccharts/src/com/oxymel/ofc/charts/util/Graphics2DTools.java
New file
0,0 → 1,276
package com.oxymel.ofc.charts.util;
/*
* Copyright (c) 2006 Oxymel SA.
* All rights reserved.
*
* This software is the confidential and proprietary information of Oxymel SA
* ("Confidential Information"). You shall not disclose such Confidential
* Information and shall use it only in accordance with the terms of the license
* agreement you entered into with Oxymel SA.
*/
 
//java
import java.awt.Graphics2D;
import java.awt.Font;
import java.awt.geom.Rectangle2D;
import java.awt.geom.Arc2D;
import java.util.StringTokenizer;
 
 
public class Graphics2DTools
{
private Graphics2DTools()
{
}
 
//Text
public static int getXToAlignTxt(Graphics2D graphics2D, int xCenter, String txt)
{
return xCenter - (getNbPixelWidthOfTxt(graphics2D, txt)/2);
}
public static int getYToAlignTxt(Graphics2D graphics2D, int yCenter, String txt)
{
return yCenter + (getNbPixelHeightOfTxt(graphics2D, txt)/2) - 1;
}
public static int getNbPixelWidthOfTxt(Graphics2D graphics2D, String txt)
{
Rectangle2D rectangle = graphics2D.getFont().getStringBounds(txt, graphics2D.getFontRenderContext());
return (int)rectangle.getWidth();
}
public static int getNbPixelHeightOfTxt(Graphics2D graphics2D, String txt)
{
Rectangle2D rectangle = graphics2D.getFont().getStringBounds(txt, graphics2D.getFontRenderContext());
return (int)rectangle.getHeight();
}
 
//Arrow
public static void drawSouthNorthArrow(int arrowLength, int xBottom, int yBottom, Graphics2D graphics2D)
{
int yTop = yBottom - arrowLength;
graphics2D.drawLine(xBottom, yBottom, xBottom, yTop);
graphics2D.drawLine(xBottom, yTop, xBottom - 5, yTop + 5);
graphics2D.drawLine(xBottom, yTop, xBottom + 5, yTop + 5);
}
public static void drawEastWestArrow(int arrowLength, int xRight, int yRight, Graphics2D graphics2D)
{
int xLeft = xRight + arrowLength;
graphics2D.drawLine(xRight, yRight, xLeft, yRight);
graphics2D.drawLine(xLeft, yRight, xLeft - 5, yRight - 5);
graphics2D.drawLine(xLeft, yRight, xLeft - 5, yRight + 5);
}
 
//value
static public int getRelativeSizeOfValue(double value, int templateValue, int sizeTemplateValue)
{
return( (int)(sizeTemplateValue*value)/templateValue);
}
static public double getValueAsPercentage(double value, double sumAllValues)
{
return ((value * 100) / sumAllValues);
}
static public double getIntervalValue(double firstValue, double secondValue)
{
if(((firstValue < 0) && (secondValue > 0)) ||
((firstValue > 0) && (secondValue < 0))){
return Math.abs(firstValue) + Math.abs(secondValue);
}
return Math.abs(Math.abs(firstValue) - Math.abs(secondValue));
}
 
 
//Arc
static public Arc2D getArcPercentageToAnother(Arc2D arc2d, int percentageNewArc)
{
double newWith = (arc2d.getWidth() * percentageNewArc)/100;
double newHeight = (arc2d.getHeight() * percentageNewArc)/100;
 
return new Arc2D.Double(arc2d.getX() + ((arc2d.getWidth() - newWith)/2),
arc2d.getY() + ((arc2d.getHeight() - newHeight)/2),
newWith, newHeight, arc2d.getAngleStart(), arc2d.getAngleExtent(), Arc2D.PIE);
}
static public Arc2D getClone(Arc2D arcToClone)
{
return getArcPercentageToAnother(arcToClone, 100);
}
 
//Font
static public Font getFont(Graphics2D graphics2D, int sizeFont)
{
Font font = graphics2D.getFont();
if(sizeFont > 0){
return new Font(font.getName(), font.getStyle(), sizeFont);
}
else{
return font;
}
}
 
// Start get Lines To Write
static public String[] getLinesToWrite(Graphics2D graphics2D, int sizeWidthToWrite, String valuesOnX, int nbLi