/* ========================
* JSynoptic : a free Synoptic editor
* ========================
*
* Project Info: http://jsynoptic.sourceforge.net/index.html
*
* This program 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 program 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
* program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
* Boston, MA 02111-1307, USA.
*
* (C) Copyright 2001-2003, by :
* Corporate:
* Astrium SAS
* EADS CRC
* Individual:
* Nicolas Brodu
*
* $Id: JSynopticXYItemRendererHelper.java,v 1.4 2004/02/23 11:22:14 brodu Exp $
*
* Changes
* -------
* 25-Sep-2003 : Initial public release (NB);
* 10-Oct-2003 : Dynamic color changes, revert to older version, new color handling (NB)
*
*/
package jsynoptic.plugins.jfreechart;
import java.awt.Color;
import java.awt.Paint;
import java.io.Serializable;
import java.util.Vector;
import org.jfree.chart.LegendItem;
import org.jfree.chart.plot.DefaultDrawingSupplier;
import org.jfree.chart.plot.DrawingSupplier;
import org.jfree.util.ObjectUtils;
import simtools.data.DataSource;
import simtools.data.DataSourcePool;
import simtools.data.UnsupportedOperation;
import simtools.ui.ColorMapper;
import simtools.ui.MenuResourceBundle;
import simtools.ui.ResourceFinder;
/**
* Extended XY Item Renderer that makes distiction between primary, secondary, etc... sources
* of information. Color and legend items change according to the x_ary parameter.
*
*/
public class JSynopticXYItemRendererHelper implements Serializable, Cloneable {
static final long serialVersionUID = 3439594416374185740L;
public static MenuResourceBundle resources = ResourceFinder.getMenu(JSynopticXYItemRendererHelper.class);
protected int x_ary;
/** only used to avoid creating the same object multiple times */
protected transient DrawingSupplier supplier;
/** the color mappers for the series */
protected Vector colorMappers;
/** the data sources used together with the color mappers for the series */
protected transient Vector sources;
/**
* Default is to build a renderer for the primary source of information
*/
public JSynopticXYItemRendererHelper() {
this(1);
}
/**
* @param x_ary Set to 1,2,3... if the renderer is destinated to primary, secondary, tertiary... information
*/
public JSynopticXYItemRendererHelper(int x_ary) {
super();
this.x_ary=x_ary;
colorMappers = new Vector();
sources = new Vector();
}
/**
* @return
*/
public ColorMapper getColorMapper(int i) {
if (i>=colorMappers.size()) return null;
return (ColorMapper)colorMappers.get(i);
}
/**
* @param colorMapper
*/
public void setColorMapper(int i, ColorMapper colorMapper) {
if (i>=colorMappers.size()) {
int s = colorMappers.size();
for (int j=s; j<i; ++j) colorMappers.add(null);
colorMappers.add(colorMapper);
}
else colorMappers.set(i,colorMapper);
}
/**
* @return
*/
public DataSource getDataSource(int i) {
if (i>=sources.size()) return null;
return (DataSource)sources.get(i);
}
/**
* @param
*/
public void setDataSource(int i, DataSource ds) {
if (i>=sources.size()) {
int s = sources.size();
for (int j=s; j<i; ++j) sources.add(null);
sources.add(ds);
}
else sources.set(i,ds);
}
/**
* @return
*/
public ColorMapper removeColorMapper(int i) {
if (i>=colorMappers.size()) return null;
return (ColorMapper)colorMappers.remove(i);
}
/**
* @return
*/
public DataSource removeDataSource(int i) {
if (i>=sources.size()) return null;
return (DataSource)sources.remove(i);
}
public DrawingSupplier getDrawingSupplier() {
if (supplier==null) supplier = new DefaultDrawingSupplier() {
public Paint getNextPaint() {
Paint p = super.getNextPaint();
if ((x_ary>1) && (p instanceof Color)) {
Color c = ((Color)p);
float[] hsb = Color.RGBtoHSB(c.getRed(),c.getGreen(),c.getBlue(),new float[3]);
hsb[0] += 0.1 * (x_ary-1);
if (hsb[0]>1) hsb[0] -=1;
return Color.getHSBColor(hsb[0], hsb[1], hsb[2]);
}
return p;
}
};
return supplier;
}
public LegendItem getLegendItem(JSynopticXYItemRenderer renderer, int datasetIndex, int series) {
LegendItem ret = renderer.getDefaultLegendItem(datasetIndex,series);
if (x_ary>1) ret = new XAryLegendItem(ret);
return ret;
}
protected class XAryLegendItem extends LegendItem {
public XAryLegendItem(LegendItem item) {
super(item.getLabel() + " (" +
((x_ary<=resources.getIntValue("legendXAryNum"))
? resources.getString("legendXAryText"+x_ary)
: resources.getString("legendXAryTextMore")+x_ary)
+ ")",
"", item.getShape(), item.getPaint(), item.getPaint(), null);
}
}
/* (non-Javadoc)
* @see org.jfree.chart.renderer.AbstractRenderer#getItemPaint(int, int)
*/
public Paint getItemPaint(JSynopticXYItemRenderer renderer, int row, int column) {
ColorMapper colorMapper = getColorMapper(row);
if (colorMapper!=null) {
DataSource ds = getDataSource(row);
Paint ret;
try {
ret = colorMapper.getPaint(ds,ds.getStartIndex()+column);
} catch (UnsupportedOperation e) {
ret = null;
}
if (ret!=null) return ret;
}
return renderer.getDefaultItemPaint(row, column);
}
/* (non-Javadoc)
* @see org.jfree.chart.renderer.AbstractRenderer#getSeriesPaint(int)
*/
public Paint getSeriesPaint(JSynopticXYItemRenderer renderer, int series) {
// Make sure we return a Color
Paint ret = renderer.getDefaultSeriesPaint(series);
if (ret instanceof Color) return ret;
return Color.black;
}
public JSynopticXYItemRendererHelper cloneHelper() {
try {
JSynopticXYItemRendererHelper h = (JSynopticXYItemRendererHelper)super.clone();
h.supplier = (DrawingSupplier)ObjectUtils.clone(supplier);
// Mappers and sources are shared objects, cloning vector is enough
h.colorMappers = (Vector)colorMappers.clone();
h.sources = (Vector)sources.clone();
return h;
} catch (CloneNotSupportedException e) {
return this; // JFreeChart default behaviour
}
}
// Take care of serialisation. Special handling for datasources
private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
out.defaultWriteObject();
int n = sources.size();
out.writeInt(n);
for (int i=0; i<n; ++i) {
DataSourcePool.global.writeDataSource(out, (DataSource)sources.get(i));
}
}
private void readObject(java.io.ObjectInputStream in) throws java.lang.ClassNotFoundException, java.io.IOException {
in.defaultReadObject();
int n =in.readInt();
sources = new Vector();
for (int i=0; i<n; ++i) {
sources.add(DataSourcePool.global.readDataSource(in));
}
}
}