/******************************************************************************* * 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.internal; import org.eclipse.swt.SWT; import org.eclipse.swt.events.PaintEvent; import org.eclipse.swt.events.PaintListener; import org.eclipse.swt.graphics.Color; import org.eclipse.swt.graphics.GC; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Display; import org.swtchart.BackgroundOverlay; import org.swtchart.Chart; import org.swtchart.IAxis; import org.swtchart.IBarSeries; import org.swtchart.ILineSeries; import org.swtchart.ISeries; import org.swtchart.ISeriesSet; import org.swtchart.internal.series.Series; import org.swtchart.internal.series.SeriesSet; /** * Plot area to draw series and grids. */ public class PlotArea extends Composite implements PaintListener { /** the chart */ protected Chart chart; /** the set of plots */ protected SeriesSet seriesSet; /** the image cache */ private Image imageCache; /** the state indicating if image cache has to be updated */ private boolean updateImageCache; protected BackgroundOverlay backgroundOverlay; /** the default background color */ private static final int DEFAULT_BACKGROUND = SWT.COLOR_WHITE; /** * Constructor. * * @param chart * the chart * @param style * the style */ public PlotArea ( final Chart chart, final int style ) { super ( chart, style | SWT.NO_BACKGROUND ); this.chart = chart; seriesSet = new SeriesSet ( chart ); updateImageCache = true; setBackground ( Display.getDefault ().getSystemColor ( DEFAULT_BACKGROUND ) ); addPaintListener ( this ); } /** * Gets the set of series. * * @return the set of series */ public ISeriesSet getSeriesSet () { return seriesSet; } /* * @see Control#setBounds(int, int, int, int) */ @Override public void setBounds ( final int x, final int y, final int width, final int height ) { super.setBounds ( x, y, width, height ); ( (SeriesSet)getSeriesSet () ).compressAllSeries (); } /* * @see Control#setBackground(Color) */ @Override public void setBackground ( final Color color ) { if ( color == null ) { super.setBackground ( Display.getDefault ().getSystemColor ( DEFAULT_BACKGROUND ) ); } else { super.setBackground ( color ); } } /* * @see PaintListener#paintControl(PaintEvent) */ public void paintControl ( final PaintEvent e ) { if ( updateImageCache ) { Point p = getSize (); if ( ( imageCache != null ) && !imageCache.isDisposed () ) { imageCache.dispose (); } imageCache = new Image ( Display.getCurrent (), p.x, p.y ); GC gc = new GC ( imageCache ); // draw the plot area background gc.setBackground ( getBackground () ); gc.fillRectangle ( 0, 0, p.x, p.y ); // draw grid for ( IAxis axis : chart.getAxisSet ().getAxes () ) { ( (Grid)axis.getGrid () ).draw ( gc, p.x, p.y ); } // draw additional background overlay if ( chart.getBackgroundOverlay () != null ) { chart.getBackgroundOverlay ().draw ( gc, p.x, p.y ); } // draw series. The line series should be drawn on bar series. for ( ISeries series : chart.getSeriesSet ().getSeries () ) { if ( series instanceof IBarSeries ) { ( (Series)series ).draw ( gc, p.x, p.y ); } } for ( ISeries series : chart.getSeriesSet ().getSeries () ) { if ( series instanceof ILineSeries ) { ( (Series)series ).draw ( gc, p.x, p.y ); } } gc.dispose (); updateImageCache = false; } e.gc.drawImage ( imageCache, 0, 0 ); } /* * @see Control#update() */ @Override public void update () { super.update (); updateImageCache = true; } /* * @see Control#redraw() */ @Override public void redraw () { super.redraw (); updateImageCache = true; } /* * @see Widget#dispose() */ @Override public void dispose () { super.dispose (); seriesSet.dispose (); if ( ( imageCache != null ) && !imageCache.isDisposed () ) { imageCache.dispose (); } } public BackgroundOverlay getBackgroundOverlay () { return backgroundOverlay; } public void setBackgroundOverlay ( final BackgroundOverlay backgroundOverlay ) { this.backgroundOverlay = backgroundOverlay; } }