/*******************************************************************************
* Copyright (c) 2008-2009 SWTChart project. All rights reserved.
*
* This code is distributed under the terms of the Eclipse Public License v1.0
* which is available at http://www.eclipse.org/legal/epl-v10.html
*******************************************************************************/
package org.swtchart;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.ImageData;
import org.eclipse.swt.graphics.ImageLoader;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.swtchart.internal.ChartLayout;
import org.swtchart.internal.ChartLayoutData;
import org.swtchart.internal.ChartTitle;
import org.swtchart.internal.Legend;
import org.swtchart.internal.PlotArea;
import org.swtchart.internal.Title;
import org.swtchart.internal.axis.AxisSet;
/**
* A chart which are composed of title, legend, axes and plot area.
*/
public class Chart extends Composite implements Listener
{
/** the title */
private final Title title;
/** the legend */
private final Legend legend;
/** the set of axes */
private final AxisSet axisSet;
/** the plot area */
private final PlotArea plotArea;
/** the orientation of chart which can be horizontal or vertical */
private int orientation;
/** the state indicating if compressing series is enabled */
private boolean compressEnabled;
/**
* Constructor.
*
* @param parent
* the parent composite on which chart is placed
* @param style
* the style of widget to construct
*/
public Chart ( final Composite parent, final int style )
{
super ( parent, style );
orientation = SWT.HORIZONTAL;
compressEnabled = true;
parent.layout ();
setLayout ( new ChartLayout () );
title = new ChartTitle ( this, SWT.NONE );
title.setLayoutData ( new ChartLayoutData ( SWT.DEFAULT, 100 ) );
legend = new Legend ( this, SWT.NONE );
legend.setLayoutData ( new ChartLayoutData ( 200, SWT.DEFAULT ) );
plotArea = new PlotArea ( this, SWT.NONE );
axisSet = new AxisSet ( this );
updateLayout ();
addListener ( SWT.Resize, this );
}
/**
* Gets the chart title.
*
* @return the chart title
*/
public ITitle getTitle ()
{
return title;
}
/**
* Gets the legend.
*
* @return the legend
*/
public ILegend getLegend ()
{
return legend;
}
/**
* Gets the set of axes.
*
* @return the set of axes
*/
public IAxisSet getAxisSet ()
{
return axisSet;
}
/**
* Gets the plot area.
*
* @return the plot area
*/
public Composite getPlotArea ()
{
return plotArea;
}
/**
* Gets the set of series.
*
* @return the set of series
*/
public ISeriesSet getSeriesSet ()
{
return plotArea.getSeriesSet ();
}
/*
* @see Control#setBackground(Color)
*/
@Override
public void setBackground ( final Color color )
{
super.setBackground ( color );
for ( Control child : getChildren () )
{
if ( ! ( child instanceof PlotArea ) && ! ( child instanceof Legend ) )
{
child.setBackground ( color );
}
}
}
/**
* Gets the background color in plot area. This method is identical with
* <tt>getPlotArea().getBackground()</tt>.
*
* @return the background color in plot area
*/
public Color getBackgroundInPlotArea ()
{
return plotArea.getBackground ();
}
/**
* Sets the background color in plot area.
*
* @param color
* the background color in plot area. If <tt>null</tt> is given,
* default background color will be set.
* @exception IllegalArgumentException
* if given color is disposed
*/
public void setBackgroundInPlotArea ( final Color color )
{
if ( ( color != null ) && color.isDisposed () )
{
SWT.error ( SWT.ERROR_INVALID_ARGUMENT );
}
plotArea.setBackground ( color );
}
/**
* Sets the state of chart orientation. The horizontal orientation means
* that X axis is horizontal as usual, while the vertical orientation means
* that Y axis is horizontal.
*
* @param orientation
* the orientation which can be SWT.HORIZONTAL or SWT.VERTICAL
*/
public void setOrientation ( final int orientation )
{
if ( ( orientation == SWT.HORIZONTAL ) || ( orientation == SWT.VERTICAL ) )
{
this.orientation = orientation;
}
updateLayout ();
}
/**
* Gets the state of chart orientation. The horizontal orientation means
* that X axis is horizontal as usual, while the vertical orientation means
* that Y axis is horizontal.
*
* @return the orientation which can be SWT.HORIZONTAL or SWT.VERTICAL
*/
public int getOrientation ()
{
return orientation;
}
/**
* Enables compressing series. By default, compressing series is enabled,
* and normally there should be no usecase to disable it. However, if you
* suspect that something is wrong in compressing series, you can disable it
* to isolate the issue.
*
* @param enabled
* true if enabling compressing series
*/
public void enableCompress ( final boolean enabled )
{
compressEnabled = enabled;
}
/**
* Gets the state indicating if compressing series is enabled.
*
* @return true if compressing series is enabled
*/
public boolean isCompressEnabled ()
{
return compressEnabled;
}
/*
* @see Listener#handleEvent(Event)
*/
public void handleEvent ( final Event event )
{
switch ( event.type )
{
case SWT.Resize:
updateLayout ();
redraw ();
break;
default:
break;
}
}
/**
* Updates the layout of chart elements.
*/
public void updateLayout ()
{
if ( legend != null )
{
legend.updateLayoutData ();
}
if ( title != null )
{
title.updateLayoutData ();
}
if ( axisSet != null )
{
axisSet.updateLayoutData ();
}
layout ();
if ( axisSet != null )
{
axisSet.refresh ();
}
}
/*
* @see Control#update()
*/
@Override
public void update ()
{
super.update ();
for ( Control child : getChildren () )
{
child.update ();
}
}
/*
* @see Widget#dispose()
*/
@Override
public void dispose ()
{
title.dispose ();
legend.dispose ();
axisSet.dispose ();
plotArea.dispose ();
super.dispose ();
}
/*
* @see Control#redraw()
*/
@Override
public void redraw ()
{
super.redraw ();
for ( Control child : getChildren () )
{
child.redraw ();
}
}
/**
* Saves to file with given format.
*
* @param filename
* the file name
* @param format
* the format (SWT.IMAGE_*). The supported formats depend on OS.
*/
public void save ( final String filename, final int format )
{
Point size = getSize ();
GC gc = new GC ( this );
Image image = new Image ( Display.getDefault (), size.x, size.y );
gc.copyArea ( image, 0, 0 );
gc.dispose ();
ImageData data = image.getImageData ();
ImageLoader loader = new ImageLoader ();
loader.data = new ImageData[] { data };
loader.save ( filename, format );
image.dispose ();
}
public void setBackgroundOverlay ( final BackgroundOverlay backgroundOverlay )
{
this.plotArea.setBackgroundOverlay ( backgroundOverlay );
}
public BackgroundOverlay getBackgroundOverlay ()
{
return this.plotArea.getBackgroundOverlay ();
}
}