double dWZ = zoomScale * dPointToPixel; double dW = dXDZ * zoomScale * dPointToPixel;
double dWZ = zoomScale; double dW = dXDZ * zoomScale;
	public void compute( Bounds bo ) throws ChartException,			IllegalArgumentException	{		bo = bo.scaledInstance( dPointToPixel ); // CONVERSION		boPlotBackground = BoundsImpl.copyInstance( bo );		// 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;		final Axis[] axa = cwa.getPrimaryBaseAxes( );		final Axis axPrimaryBase = axa[0];		final Axis axPrimaryOrthogonal = cwa.getPrimaryOrthogonalAxis( axPrimaryBase );		final Axis axAncillaryBase = cwa.getAncillaryBaseAxis( axPrimaryBase );		// INITIALIZE AXES DATASETS		Object oaData = null;		// COMPUTE PRIMARY BASE DATA		OneAxis oaxPrimaryBase = aax.getPrimaryBase( );		int iPrimaryAxisType = getAxisType( axPrimaryBase );		if ( iPrimaryAxisType == TEXT || oaxPrimaryBase.isCategoryScale( ) )		{			oaData = getTypedDataSet( axPrimaryBase, iPrimaryAxisType, 0 );		}		else if ( ( iPrimaryAxisType & NUMERICAL ) == NUMERICAL )		{			oaData = getMinMax( axPrimaryBase, iPrimaryAxisType );		}		else if ( ( iPrimaryAxisType & DATE_TIME ) == DATE_TIME )		{			oaData = getMinMax( axPrimaryBase, iPrimaryAxisType );		}		DataSetIterator dsiPrimaryBase = ( oaData instanceof DataSetIterator ) ? (DataSetIterator) oaData				: new DataSetIterator( oaData, iPrimaryAxisType );		oaData = null;		// COMPUTE ANCILLARY BASE DATA		OneAxis oaxAncillaryBase = aax.getAncillaryBase( );		int iAncillaryAxisType = getAxisType( axAncillaryBase );		if ( iAncillaryAxisType == TEXT || oaxAncillaryBase.isCategoryScale( ) )		{			oaData = getAncillaryDataSet( axAncillaryBase,					axPrimaryOrthogonal,					iAncillaryAxisType );		}		else if ( ( iAncillaryAxisType & NUMERICAL ) == NUMERICAL )		{			oaData = getMinMax( axAncillaryBase, iAncillaryAxisType );		}		else if ( ( iAncillaryAxisType & DATE_TIME ) == DATE_TIME )		{			oaData = getMinMax( axAncillaryBase, iAncillaryAxisType );		}		DataSetIterator dsiAncillary = ( oaData instanceof DataSetIterator ) ? (DataSetIterator) oaData				: new DataSetIterator( oaData, iAncillaryAxisType );		oaData = null;		// COMPUTE ORTHOGONAL DATA		OneAxis oaxPrimaryOrthogonal = aax.getPrimaryOrthogonal( );		int iOrthogonalAxisType = getAxisType( axPrimaryOrthogonal );		DataSetIterator dsiOrthogonal = null;		if ( ( iOrthogonalAxisType & NUMERICAL ) == NUMERICAL				|| ( iOrthogonalAxisType & DATE_TIME ) == DATE_TIME )		{			dsiOrthogonal = new DataSetIterator( getMinMax( axPrimaryOrthogonal,					iOrthogonalAxisType ),					iOrthogonalAxisType );		}		else		{			throw new ChartException( ChartEnginePlugin.ID,					ChartException.DATA_FORMAT,					"exception.orthogonal.axis.numerical.datetime", //$NON-NLS-1$					Messages.getResourceBundle( rtc.getULocale( ) ) );		}		// COMPUTE AUTOMATIC ZOOM SCALE AND FACTOR		double dXDZ = dsiPrimaryBase.size( ) * 1d / dsiAncillary.size( );		final Bounds adjustedBounds = getAdjustedPlotBounds( );		double xOffset = adjustedBounds.getLeft( );		double yOffset = adjustedBounds.getTop( );		double zoomScale = detectZoomScale( get3DEngine( ),				dXDZ,				xOffset,				yOffset,				adjustedBounds.getWidth( ),				adjustedBounds.getHeight( ) );		double dWZ = zoomScale * dPointToPixel;		double dW = dXDZ * zoomScale * dPointToPixel;		double dH = ( dW + dWZ ) / 2;		double dX = -dW / 2;		double dY = -dH / 2;		double dZ = -dWZ / 2;		Location panningOffset = getPanningOffset( );		double xZoom = computeAxisZoomFactor( get3DEngine( ),				dX,				dX + dW,				Location3DImpl.create( dX, dY, dZ ),				Location3DImpl.create( dX + dW, dY, dZ ),				panningOffset.getX( ),				panningOffset.getY( ) );		double yZoom = computeAxisZoomFactor( get3DEngine( ),				dY,				dY + dH,				Location3DImpl.create( dX, dY, dZ ),				Location3DImpl.create( dX, dY + dH, dZ ),				panningOffset.getX( ),				panningOffset.getY( ) );		double zZoom = computeAxisZoomFactor( get3DEngine( ),				dZ,				dZ + dWZ,				Location3DImpl.create( dX, dY, dZ ),				Location3DImpl.create( dX, dY, dZ + dWZ ),				panningOffset.getX( ),				panningOffset.getY( ) );		double dStart, dEnd;		// COMPUTE PRIMARY-BASE-AXIS PROPERTIES AND ITS SCALE		AutoScale scPrimaryBase = null;		dStart = dX;		dEnd = dX + dW;		Scale sc = axPrimaryBase.getScale( );		scPrimaryBase = AutoScale.computeScale( ids,				oaxPrimaryBase,				dsiPrimaryBase,				iPrimaryAxisType,				dStart,				dEnd,				sc.getMin( ),				sc.getMax( ),				sc.isSetStep( ) ? new Double( sc.getStep( ) ) : null,				axPrimaryBase.getFormatSpecifier( ),				rtc,				FORWARD,				xZoom );		oaxPrimaryBase.set( scPrimaryBase ); // UPDATE SCALE ON PRIMARY-BASE		// AXIS		// COMPUTE ANCILLARY-BASE-AXIS PROPERTIES AND ITS SCALE		AutoScale scAncillaryBase = null;		dStart = dZ;		dEnd = dZ + dWZ;		sc = axAncillaryBase.getScale( );		scAncillaryBase = AutoScale.computeScale( ids,				oaxAncillaryBase,				dsiAncillary,				iAncillaryAxisType,				dStart,				dEnd,				sc.getMin( ),				sc.getMax( ),				sc.isSetStep( ) ? new Double( sc.getStep( ) ) : null,				axAncillaryBase.getFormatSpecifier( ),				rtc,				FORWARD,				zZoom );		oaxAncillaryBase.set( scAncillaryBase ); // UPDATE SCALE ON		// ANCILLARY-BASE AXIS		// COMPUTE PRIMARY-ORTHOGONAL-AXIS PROPERTIES AND ITS SCALE		AutoScale scPrimaryOrthogonal = null;		dStart = dY;		dEnd = dH;		sc = axPrimaryOrthogonal.getScale( );		scPrimaryOrthogonal = AutoScale.computeScale( ids,				oaxPrimaryOrthogonal,				dsiOrthogonal,				iOrthogonalAxisType,				dStart,				dEnd,				sc.getMin( ),				sc.getMax( ),				sc.isSetStep( ) ? new Double( sc.getStep( ) ) : null,				axPrimaryOrthogonal.getFormatSpecifier( ),				rtc,				FORWARD,				yZoom );		oaxPrimaryOrthogonal.set( scPrimaryOrthogonal ); // UPDATE SCALE ON		// PRIMARY-ORTHOGONAL AXIS		// Here we ignore the intersection Value/Max setting, always		// use the Intersection.Min for 3D chart.		double dYAxisLocationOnX = dX;		double dYAxisLocationOnZ = dZ;		double dXAxisLocation = dY;		double dZAxisLocation = dY;		// SETUP THE FULL DATASET FOR THE PRIMARY ORTHOGONAL AXIS		iOrthogonalAxisType = getAxisType( axPrimaryOrthogonal );		oaData = getTypedDataSet( axPrimaryOrthogonal, iOrthogonalAxisType, 0 );		scPrimaryOrthogonal.setData( dsiOrthogonal );		// Setup the full dataset for the ancillary base axis.		iAncillaryAxisType = getAxisType( axAncillaryBase );		if ( iAncillaryAxisType != IConstants.TEXT )		{			scAncillaryBase.setData( getTypedDataSet( axAncillaryBase,					iAncillaryAxisType,					0 ) );		}		// SETUP THE FULL DATASET FOR THE PRIMARY ORTHOGONAL AXIS		iPrimaryAxisType = getAxisType( axPrimaryBase );		if ( iPrimaryAxisType != IConstants.TEXT )		{			scPrimaryBase.setData( getTypedDataSet( axPrimaryBase,					iPrimaryAxisType,					0 ) );		}		scPrimaryBase.resetShifts( );		scAncillaryBase.resetShifts( );		scPrimaryOrthogonal.resetShifts( );		// UPDATE FOR OVERLAYS		final OneAxis axPH = aax.getPrimaryBase( );		final OneAxis axPV = 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 ) );	}