dHeight, dWidth
dWidth, dHeight
	private double[] computeHorizalByCategory( IDisplayServer xs, Chart cm,			RunTimeContext rtc, ITextMetrics itm, Label la,			LegendData legendData ) throws ChartException	{		double dWidth = 0, dHeight = 0;		double dRowHeight;		double dRealWidth = 0, dExtraHeight = 0;		ArrayList columnList = new ArrayList( );		SeriesDefinition sdBase = null;		if ( cm instanceof ChartWithAxes )		{			// ONLY SUPPORT 1 BASE AXIS FOR NOW			final Axis axPrimaryBase = ( (ChartWithAxes) cm ).getBaseAxes( )[0];			if ( axPrimaryBase.getSeriesDefinitions( ).isEmpty( ) )			{				throw new ChartException( ChartEnginePlugin.ID,						ChartException.GENERATION,						"exception.base.axis.no.series.definitions", //$NON-NLS-1$ 						Messages.getResourceBundle( xs.getULocale( ) ) );			}			// OK TO ASSUME THAT 1 BASE SERIES DEFINITION EXISTS			sdBase = (SeriesDefinition) axPrimaryBase.getSeriesDefinitions( )					.get( 0 );		}		else if ( cm instanceof ChartWithoutAxes )		{			if ( ( (ChartWithoutAxes) cm ).getSeriesDefinitions( ).isEmpty( ) )			{				throw new ChartException( ChartEnginePlugin.ID,						ChartException.GENERATION,						"exception.base.axis.no.series.definitions", //$NON-NLS-1$						Messages.getResourceBundle( xs.getULocale( ) ) );			}			// OK TO ASSUME THAT 1 BASE SERIES DEFINITION EXISTS			sdBase = (SeriesDefinition) ( (ChartWithoutAxes) cm ).getSeriesDefinitions( )					.get( 0 );		}		// OK TO ASSUME THAT 1 BASE RUNTIME SERIES EXISTS		Series seBase = (Series) sdBase.getRunTimeSeries( ).get( 0 );		DataSetIterator dsiBase = null;		try		{			dsiBase = new DataSetIterator( seBase.getDataSet( ) );		}		catch ( Exception ex )		{			throw new ChartException( ChartEnginePlugin.ID,					ChartException.GENERATION,					ex );		}		FormatSpecifier fs = null;		if ( sdBase != null )		{			fs = sdBase.getFormatSpecifier( );		}		int pos = -1;		while ( dsiBase.hasNext( ) )		{			Object obj = dsiBase.next( );			// Skip invalid data			while ( obj == null && dsiBase.hasNext( ) )			{				obj = dsiBase.next( );			}			pos++;			// filter the not-used legend.			if ( legendData.bMinSliceApplied					&& Arrays.binarySearch( legendData.filteredMinSliceEntry,							pos ) >= 0 )			{				continue;			}			String lgtext = String.valueOf( obj );			if ( fs != null )			{				try				{					lgtext = ValueFormatter.format( obj,							fs,							rtc.getULocale( ),							null );				}				catch ( ChartException e )				{					// ignore, use original text.				}			}			la.getCaption( ).setValue( lgtext );			itm.reuse( la, legendData.maxWrappingSize );			BoundingBox bb = null;			try			{				bb = Methods.computeBox( xs, IConstants.ABOVE, la, 0, 0 );			}			catch ( IllegalArgumentException uiex )			{				throw new ChartException( ChartEnginePlugin.ID,						ChartException.RENDERING,						uiex );			}			double dFWidth = bb.getWidth( );			double dFHeight = bb.getHeight( );			double dDeltaWidth = legendData.insCa.getLeft( )					+ dFWidth					+ ( 3 * legendData.dItemHeight )					/ 2					+ legendData.insCa.getRight( );			if ( dWidth + dDeltaWidth > legendData.dAvailableWidth )			{				// check available bounds				dRowHeight = dHeight + legendData.dVerticalReservedSpace;				if ( dExtraHeight + dRowHeight > legendData.dAvailableHeight						+ legendData.dSafeSpacing )				{					dHeight = -legendData.dVerticalReservedSpace;					columnList.clear( );					break;				}				else				{					legendData.legendItems.addAll( columnList );					columnList.clear( );					dExtraHeight += dRowHeight;					dHeight = dFHeight;					dRealWidth = Math.max( dRealWidth, dWidth );					dWidth = dDeltaWidth;				}			}			else			{				dHeight = Math.max( dFHeight, dHeight );				dWidth += dDeltaWidth;			}			columnList.add( new LegendItemHints( LEGEND_ENTRY,					new Point( dWidth - dDeltaWidth, dExtraHeight ),					dFWidth,					dFHeight,					la.getCaption( ).getValue( ),					pos ) );		}		// compute the extra MinSlice legend item if applicable.		if ( legendData.bMinSliceApplied )		{			la.getCaption( ).setValue( legendData.sMinSliceLabel );			itm.reuse( la, legendData.maxWrappingSize );			BoundingBox bb = null;			try			{				bb = Methods.computeBox( xs, IConstants.ABOVE, la, 0, 0 );			}			catch ( IllegalArgumentException uiex )			{				throw new ChartException( ChartEnginePlugin.ID,						ChartException.RENDERING,						uiex );			}			double dFWidth = bb.getWidth( );			double dFHeight = bb.getHeight( );			double dDeltaWidth = legendData.insCa.getLeft( )					+ dFWidth					+ ( 3 * legendData.dItemHeight )					/ 2					+ legendData.insCa.getRight( );			if ( dWidth + dDeltaWidth > legendData.dAvailableWidth )			{				// check available bounds				dRowHeight = dHeight + legendData.dVerticalReservedSpace;				if ( dExtraHeight + dRowHeight > legendData.dAvailableHeight						+ legendData.dSafeSpacing )				{					dHeight = -legendData.dVerticalReservedSpace;					columnList.clear( );					// !not add the entry if it exceeds the available					// bounds.				}				else				{					legendData.legendItems.addAll( columnList );					columnList.clear( );					dExtraHeight += dRowHeight;					dHeight = dFHeight;					dRealWidth = Math.max( dRealWidth, dWidth );					dWidth = dDeltaWidth;					columnList.add( new LegendItemHints( LEGEND_MINSLICE_ENTRY,							new Point( dWidth - dDeltaWidth, dExtraHeight ),							dFWidth,							dFHeight,							la.getCaption( ).getValue( ),							dsiBase.size( ) ) );				}			}			else			{				dHeight = Math.max( dFHeight, dHeight );				dWidth += dDeltaWidth;				columnList.add( new LegendItemHints( LEGEND_MINSLICE_ENTRY,						new Point( dWidth - dDeltaWidth, dExtraHeight ),						dFWidth,						dFHeight,						la.getCaption( ).getValue( ),						dsiBase.size( ) ) );			}		}		// check available bounds		dRowHeight = dHeight + legendData.dVerticalReservedSpace;		if ( dExtraHeight + dRowHeight > legendData.dAvailableHeight				+ legendData.dSafeSpacing )		{			dHeight = -legendData.dVerticalReservedSpace;		}		else		{			legendData.legendItems.addAll( columnList );		}		columnList.clear( );		dHeight += dExtraHeight + legendData.dVerticalReservedSpace;		dWidth = Math.max( dWidth, dRealWidth );		return new double[]{				dHeight, dWidth		};	}