double dYAxisLocationOnX = adjustHorizontal( dX, dW, aax );     double dYAxisLocationOnZ = adjustAncillary( dX, dW, aax );    double dXAxisLocation = adjustVerticalDueToHorizontalPlane( dY, dH, aax );   double dZAxisLocation = dXAxisLocation;
double dYAxisLocationOnX = dX; double dYAxisLocationOnZ = dZ; double dXAxisLocation = dY; double dZAxisLocation = dY;
	public void compute( Bounds bo ) throws ChartException,			IllegalArgumentException	{		bo = bo.scaledInstance( dPointToPixel ); // CONVERSION		// TODO compute seriesThickness as per rotation.		// dSeriesThickness =		// MAINTAIN IN LOCAL VARIABLES FOR PERFORMANCE/CONVENIENCE		// TODO initial bounding box constraint, may compute as per the rotation		// angle.		// Always use zero as start point.		double dX = 0;// bo.getLeft( ) + insCA.getLeft( );		double dY = 0;// bo.getTop( ) + insCA.getTop( );		double dW = bo.getWidth( ) - insCA.getLeft( ) - insCA.getRight( );		double dH = bo.getHeight( ) - insCA.getTop( ) - insCA.getBottom( );		// MUST BE 3-D DIMENSION ONLY HERE.		iDimension = getDimension( cwa.getDimension( ) );		assert iDimension == IConstants.THREE_D;		dXAxisPlotSpacing = cwa.getPlot( ).getHorizontalSpacing( )				* dPointToPixel; // CONVERSION		dYAxisPlotSpacing = cwa.getPlot( ).getVerticalSpacing( )				* dPointToPixel; // CONVERSION		dZAxisPlotSpacing = dXAxisPlotSpacing;		double dStart, dEnd;		final Axis[] axa = cwa.getPrimaryBaseAxes( );		final Axis axPrimaryBase = axa[0];		final Axis axPrimaryOrthogonal = cwa.getPrimaryOrthogonalAxis( axPrimaryBase );		final Axis axAncillaryBase = cwa.getAncillaryBaseAxis( axPrimaryBase );		// COMPUTE PRIMARY-BASE-AXIS PROPERTIES AND ITS SCALE		AutoScale scPrimaryBase = null;		OneAxis oaxPrimaryBase = aax.getPrimaryBase( );		int iAxisType = getAxisType( axPrimaryBase );		Object oaData = null;		if ( iAxisType == TEXT || oaxPrimaryBase.isCategoryScale( ) )		{			oaData = getTypedDataSet( axPrimaryBase, iAxisType, 0 );		}		else if ( ( iAxisType & NUMERICAL ) == NUMERICAL )		{			oaData = getMinMax( axPrimaryBase, iAxisType );		}		else if ( ( iAxisType & DATE_TIME ) == DATE_TIME )		{			oaData = getMinMax( axPrimaryBase, iAxisType );		}		DataSetIterator dsi = ( oaData instanceof DataSetIterator ) ? (DataSetIterator) oaData				: new DataSetIterator( oaData, iAxisType );		oaData = null;		// TODO compute 3d start end point.		dStart = ( aax.areAxesSwapped( ) ) ? dY : dX;		dEnd = ( aax.areAxesSwapped( ) ) ? dY + dH : dX + dW;		Scale sc = axPrimaryBase.getScale( );		scPrimaryBase = AutoScale.computeScale( ids,				oaxPrimaryBase,				dsi,				iAxisType,				dStart,				dEnd,				sc.getMin( ),				sc.getMax( ),				sc.isSetStep( ) ? new Double( sc.getStep( ) ) : null,				axPrimaryBase.getFormatSpecifier( ),				rtc,				FORWARD );		oaxPrimaryBase.set( scPrimaryBase ); // UPDATE SCALE ON PRIMARY-BASE		// AXIS		// COMPUTE ANCILLARY-BASE-AXIS PROPERTIES AND ITS SCALE		AutoScale scAncillaryBase = null;		OneAxis oaxAncillaryBase = aax.getAncillaryBase( );		iAxisType = getAxisType( axAncillaryBase );		oaData = null;		if ( iAxisType == TEXT || oaxAncillaryBase.isCategoryScale( ) )		{			oaData = getAncillaryDataSet( axAncillaryBase,					axPrimaryOrthogonal,					iAxisType );		}		else if ( ( iAxisType & NUMERICAL ) == NUMERICAL )		{			oaData = getMinMax( axAncillaryBase, iAxisType );		}		else if ( ( iAxisType & DATE_TIME ) == DATE_TIME )		{			oaData = getMinMax( axAncillaryBase, iAxisType );		}		dsi = ( oaData instanceof DataSetIterator ) ? (DataSetIterator) oaData				: new DataSetIterator( oaData, iAxisType );		oaData = null;		// TODO compute 3d start end point, use the same setting as primary base		// axis here.		dStart = ( aax.areAxesSwapped( ) ) ? dY : dX;		dEnd = ( aax.areAxesSwapped( ) ) ? dY + dH : dX + dW;		sc = axAncillaryBase.getScale( );		scAncillaryBase = AutoScale.computeScale( ids,				oaxAncillaryBase,				dsi,				iAxisType,				dStart,				dEnd,				sc.getMin( ),				sc.getMax( ),				sc.isSetStep( ) ? new Double( sc.getStep( ) ) : null,				axAncillaryBase.getFormatSpecifier( ),				rtc,				FORWARD );		oaxAncillaryBase.set( scAncillaryBase ); // UPDATE SCALE ON		// ANCILLARY-BASE AXIS		// COMPUTE PRIMARY-ORTHOGONAL-AXIS PROPERTIES AND ITS SCALE		AutoScale scPrimaryOrthogonal = null;		OneAxis oaxPrimaryOrthogonal = aax.getPrimaryOrthogonal( );		iAxisType = getAxisType( axPrimaryOrthogonal );		oaData = null;		if ( ( iAxisType & NUMERICAL ) == NUMERICAL				|| ( iAxisType & DATE_TIME ) == DATE_TIME )		{			dsi = new DataSetIterator( getMinMax( axPrimaryOrthogonal,					iAxisType ), iAxisType );		}		else		{			throw new ChartException( ChartEnginePlugin.ID,					ChartException.DATA_FORMAT,					"exception.orthogonal.axis.numerical.datetime", //$NON-NLS-1$					Messages.getResourceBundle( rtc.getULocale( ) ) );		}		// TODO compute 3d start end point.		dStart = ( aax.areAxesSwapped( ) ) ? dX : dY;		dEnd = ( aax.areAxesSwapped( ) ) ? dX + dW : dY + dH;		sc = axPrimaryOrthogonal.getScale( );		scPrimaryOrthogonal = AutoScale.computeScale( ids,				oaxPrimaryOrthogonal,				dsi,				iAxisType,				dStart,				dEnd,				sc.getMin( ),				sc.getMax( ),				sc.isSetStep( ) ? new Double( sc.getStep( ) ) : null,				axPrimaryOrthogonal.getFormatSpecifier( ),				rtc,				FORWARD );		oaxPrimaryOrthogonal.set( scPrimaryOrthogonal ); // UPDATE SCALE ON		// PRIMARY-ORTHOGONAL AXIS		// TODO here we should ignore the intersection Value/Max setting, always		// use the Intersection.Min for 3D chart. the adjustVerticalXXX() should		// return a double[] to		// indicate a coordinate value.		// ITERATIVELY ADJUST THE PRIMARY ORTHOGONAL AXIS POSITION DUE TO THE		// SCALE, START/END LABELS		double dYAxisLocationOnX = adjustHorizontal( dX, dW, aax );		// Iteratively adjust the ancillary base axis position due to the scale,		// start/end		// labels.		double dYAxisLocationOnZ = adjustAncillary( dX, dW, aax );		// ITERATIVELY ADJUST THE PRIMARY BASE AXIS POSITION DUE TO THE SCALE,		// START/END LABELS		double dXAxisLocation = adjustVerticalDueToHorizontalPlane( dY, dH, aax );		// TODO Just use XAxisLocation as the ZAxisLocation now.		double dZAxisLocation = dXAxisLocation;		// SETUP THE FULL DATASET FOR THE PRIMARY ORTHOGONAL AXIS		iAxisType = getAxisType( axPrimaryOrthogonal );		oaData = getTypedDataSet( axPrimaryOrthogonal, iAxisType, 0 );		scPrimaryOrthogonal.setData( dsi );		// Setup the full dataset for the ancillary base axis.		iAxisType = getAxisType( axAncillaryBase );		if ( iAxisType != IConstants.TEXT )		{			scAncillaryBase.setData( getTypedDataSet( axAncillaryBase,					iAxisType,					0 ) );		}		// SETUP THE FULL DATASET FOR THE PRIMARY ORTHOGONAL AXIS		iAxisType = getAxisType( axPrimaryBase );		if ( iAxisType != IConstants.TEXT )		{			scPrimaryBase.setData( getTypedDataSet( axPrimaryBase, iAxisType, 0 ) );		}		scPrimaryBase.resetShifts( );		scAncillaryBase.resetShifts( );		scPrimaryOrthogonal.resetShifts( );		// UPDATE FOR OVERLAYS		final OneAxis axPH = aax.areAxesSwapped( ) ? aax.getPrimaryOrthogonal( )				: aax.getPrimaryBase( );		final OneAxis axPV = aax.areAxesSwapped( ) ? aax.getPrimaryBase( )				: aax.getPrimaryOrthogonal( );		final OneAxis axAB = aax.getAncillaryBase( );		// keep old invocation to ensure compatibility.		axPH.setAxisCoordinate( dXAxisLocation );		axPV.setAxisCoordinate( dYAxisLocationOnX );		axAB.setAxisCoordinate( dZAxisLocation );		// set new 3D axis coordinate. this coordinate has been normalized to		// Zero-coordinates.		axPH.setAxisCoordinate3D( Location3DImpl.create( 0,				dXAxisLocation,				dYAxisLocationOnZ ) );		axPV.setAxisCoordinate3D( Location3DImpl.create( dYAxisLocationOnX,				0,				dYAxisLocationOnZ ) );		axAB.setAxisCoordinate3D( Location3DImpl.create( dYAxisLocationOnX,				dZAxisLocation,				0 ) );		boPlotBackground = BoundsImpl.copyInstance( bo );	}