/******************************************************************************* * 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.axis; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.HashMap; import java.util.Set; import org.eclipse.swt.SWT; import org.swtchart.Chart; import org.swtchart.IAxis; import org.swtchart.IAxisSet; import org.swtchart.ISeries; import org.swtchart.IAxis.Direction; import org.swtchart.internal.ChartLayout; import org.swtchart.internal.ChartLayoutData; import org.swtchart.internal.Legend; import org.swtchart.internal.Title; import org.swtchart.internal.series.SeriesSet; /** * An axis container. By default, axis set has X Axis and Y axis with axis id 0. */ public class AxisSet implements IAxisSet { /** the set of X axes */ private HashMap<Integer, Axis> xAxisMap; /** the set of Y axes */ private HashMap<Integer, Axis> yAxisMap; /** the chart */ private Chart chart; /** * Constructor. * * @param chart * the chart */ public AxisSet ( Chart chart ) { this.chart = chart; xAxisMap = new HashMap<Integer, Axis> (); yAxisMap = new HashMap<Integer, Axis> (); // add default axes Axis xAxis = new Axis ( 0, Direction.X, chart ); Axis yAxis = new Axis ( 0, Direction.Y, chart ); xAxisMap.put ( 0, xAxis ); yAxisMap.put ( 0, yAxis ); } /** * Gets the axis map for given direction. * * @param direction * the direction * @return the axis map */ private HashMap<Integer, Axis> getAxisMap ( Direction direction ) { if ( direction == Direction.X ) { return xAxisMap; } return yAxisMap; } /* * @see IAxisSet#createXAxis() */ public int createXAxis () { return createAxis ( Direction.X ); } /* * @see IAxisSet#createYAxis() */ public int createYAxis () { return createAxis ( Direction.Y ); } /** * Creates the axis for given direction. * * @param direction * the direction of axis * @return the created axis id */ private int createAxis ( Direction direction ) { int id = getUniqueId ( direction ); Axis axis = new Axis ( id, direction, chart ); getAxisMap ( direction ).put ( id, axis ); chart.updateLayout (); SeriesSet series = (SeriesSet)chart.getSeriesSet (); if ( series != null ) { series.compressAllSeries (); } return id; } /** * Gets a unique axis id. * * @param direction * the axis direction * @return a unique axis id */ private int getUniqueId ( Direction direction ) { Set<Integer> keySet = getAxisMap ( direction ).keySet (); int i = 0; while ( keySet.contains ( i ) ) { i++; } return i; } /* * @see IAxisSet#getXAxis(int) */ public IAxis getXAxis ( int id ) { return getAxis ( id, Direction.X ); } /* * @see IAxisSet#getYAxis(int) */ public IAxis getYAxis ( int id ) { return getAxis ( id, Direction.Y ); } /** * Gets the axis with axis id for given direction. * * @param id * the axis id * @param direction * the direction * @return the axis */ private IAxis getAxis ( int id, Direction direction ) { return getAxisMap ( direction ).get ( id ); } /* * @see IAxisSet#getXAxes() */ public IAxis[] getXAxes () { return xAxisMap.values ().toArray ( new IAxis[0] ); } /* * @see IAxisSet#getYAxes() */ public IAxis[] getYAxes () { return yAxisMap.values ().toArray ( new IAxis[0] ); } /* * @see IAxisSet#getAxes() */ public IAxis[] getAxes () { Collection<Axis> axes = new ArrayList<Axis> (); axes.addAll ( xAxisMap.values () ); axes.addAll ( yAxisMap.values () ); return axes.toArray ( new Axis[0] ); } /* * @see IAxisSet#getXAxisIds() */ public int[] getXAxisIds () { return getAxisIds ( Direction.X ); } /* * @see IAxisSet#getYAxisIds() */ public int[] getYAxisIds () { return getAxisIds ( Direction.Y ); } /** * Gets the axis ids for given direction. * * @param direction * the direction * @return the axis ids */ private int[] getAxisIds ( Direction direction ) { Integer[] array = getAxisMap ( direction ).keySet ().toArray ( new Integer[0] ); int[] ids = new int[array.length]; for ( int i = 0; i < ids.length; i++ ) { ids[i] = array[i]; } Arrays.sort ( ids ); return ids; } /* * @see IAxisSet#deleteXAxis(int) */ public void deleteXAxis ( int id ) { deleteAxis ( id, Direction.X ); } /* * @see IAxisSet#deleteYAxis(int) */ public void deleteYAxis ( int id ) { deleteAxis ( id, Direction.Y ); } /** * Deletes the axis with the axis id for given direction. * * @param id * the axis id * @param direction * the direction */ private void deleteAxis ( int id, Direction direction ) { if ( id == 0 ) { SWT.error ( SWT.ERROR_CANNOT_BE_ZERO ); } if ( getAxisMap ( direction ).get ( id ) == null ) { throw new IllegalArgumentException ( "Given axis id doesn't exist" ); } ( (Axis)getAxis ( id, direction ) ).dispose (); getAxisMap ( direction ).remove ( id ); for ( ISeries series : chart.getSeriesSet ().getSeries () ) { if ( direction == Direction.X ) { if ( series.getXAxisId () == id ) { series.setXAxisId ( 0 ); } } else { if ( series.getYAxisId () == id ) { series.setYAxisId ( 0 ); } } } chart.updateLayout (); } /* * @see IAxisSet#adjustRange() */ public void adjustRange () { for ( IAxis axis : getAxes () ) { ( (Axis)axis ).adjustRange ( false ); } chart.updateLayout (); } /* * @see IAxisSet#zoomIn() */ public void zoomIn () { for ( IAxis axis : getAxes () ) { axis.zoomIn (); } } /* * @see IAxisSet#zoomOut() */ public void zoomOut () { for ( IAxis axis : getAxes () ) { axis.zoomOut (); } } /** * Updates the layout data. */ public void updateLayoutData () { IAxis[] horizontalAxes; IAxis[] verticalAxes; if ( chart.getOrientation () == SWT.HORIZONTAL ) { horizontalAxes = getXAxes (); verticalAxes = getYAxes (); } else { horizontalAxes = getYAxes (); verticalAxes = getXAxes (); } updateAxesLayoutData ( horizontalAxes ); updateVerticalTick ( horizontalAxes, verticalAxes ); updateAxesLayoutData ( verticalAxes ); updateHorizontalTick ( horizontalAxes, verticalAxes ); } /** * Updates the layout data * * @param axes */ private void updateAxesLayoutData ( IAxis[] axes ) { for ( IAxis axis : axes ) { ( (Axis)axis ).updateLayoutData (); } } /** * Updates the horizontal tick. * * @param horizontalAxes * the horizontal axes * @param verticalAxes * the vertical axes */ private void updateHorizontalTick ( IAxis[] horizontalAxes, IAxis[] verticalAxes ) { int legendPosition = ( (Legend)chart.getLegend () ).getPosition (); int legendWidth = ( (ChartLayoutData) ( (Legend)chart.getLegend () ).getLayoutData () ).widthHint; int axesWidth = 0; for ( IAxis axis : verticalAxes ) { axesWidth += ( (ChartLayoutData) ( (Title) ( (Axis)axis ).getTitle () ).getLayoutData () ).widthHint + ( (Axis)axis ) .getTick () .getAxisTickLabels () .getLayoutData ().widthHint + ( (Axis)axis ).getTick ().getAxisTickMarks ().getLayoutData ().widthHint; } int axisWidth = chart.getSize ().x - axesWidth - ChartLayout.MARGIN * 2 - ( legendPosition == SWT.LEFT || legendPosition == SWT.RIGHT ? legendWidth + ( legendWidth == 0 ? 0 : ChartLayout.PADDING ) : 0 ); for ( IAxis axis : horizontalAxes ) { ( (Axis)axis ).getTick ().updateTick ( axisWidth ); } } /** * Updates the vertical tick. * * @param horizontalAxes * the horizontal axes * @param verticalAxes * the vertical axes */ private void updateVerticalTick ( IAxis[] horizontalAxes, IAxis[] verticalAxes ) { int legendPosition = ( (Legend)chart.getLegend () ).getPosition (); int legendHeight = ( (ChartLayoutData) ( (Legend)chart.getLegend () ).getLayoutData () ).heightHint; int titleHeight = ( (ChartLayoutData) ( (Title)chart.getTitle () ).getLayoutData () ).heightHint; int axesHeight = 0; for ( IAxis axis : horizontalAxes ) { axesHeight += ( (ChartLayoutData) ( (Title) ( (Axis)axis ).getTitle () ).getLayoutData () ).heightHint + ( (Axis)axis ) .getTick () .getAxisTickLabels () .getLayoutData ().heightHint + ( (Axis)axis ).getTick ().getAxisTickMarks ().getLayoutData ().heightHint; } int axisHeight = chart.getSize ().y - titleHeight - axesHeight - ChartLayout.MARGIN * 2 - ( titleHeight == 0 ? 0 : ChartLayout.PADDING ) - ( ( legendPosition == SWT.TOP || legendPosition == SWT.BOTTOM ) ? legendHeight + ( legendHeight == 0 ? 0 : ChartLayout.PADDING ) : 0 ); for ( IAxis axis : verticalAxes ) { ( (Axis)axis ).getTick ().updateTick ( axisHeight ); } } /** * Refreshes the cache. */ public void refresh () { for ( IAxis axis : getAxes () ) { ( (Axis)axis ).refresh (); } } /** * Disposes the resources. */ public void dispose () { for ( IAxis axis : getAxes () ) { ( (Axis)axis ).dispose (); } } }