if ( fsOrthogonal == null ) { fsOrthogonal = sdOrthogonal.getFormatSpecifier( );
if ( fsOrthogonal == null && seOrthogonal.eContainer( ) instanceof SeriesDefinition ) { fsOrthogonal = ( (SeriesDefinition) seOrthogonal.eContainer( ) ).getFormatSpecifier( );
	public final ISeriesRenderingHints getSeriesRenderingHints(			SeriesDefinition sdOrthogonal, Series seOrthogonal )			throws ChartException, IllegalArgumentException	{		if ( seOrthogonal == null				|| seOrthogonal.getClass( ) == SeriesImpl.class ) // EMPTY		// PLOT		// RENDERING		// TECHNIQUE		{			return null;		}		OneAxis oaxOrthogonal = findOrthogonalAxis( seOrthogonal );		if ( oaxOrthogonal == null )		{			throw new ChartException( ChartEnginePlugin.ID,					ChartException.NOT_FOUND,					"exception.axis.series.link.broken", //$NON-NLS-1$					new Object[]{						seOrthogonal					},					ResourceBundle.getBundle( Messages.ENGINE, rtc.getLocale( ) ) );		}		final OneAxis oaxBase = aax.getPrimaryBase( );		final SeriesDefinition sdBase = (SeriesDefinition) oaxBase.getModelAxis( )				.getSeriesDefinitions( )				.get( 0 );		final AutoScale scBase = oaxBase.getScale( );		final AutoScale scOrthogonal = oaxOrthogonal.getScale( );		final int iTickCount = scBase.getTickCount( );		int iUnitCount = iTickCount;		final double dUnitSize = scBase.getUnitSize( );		if ( scBase.getType( ) == IConstants.DATE_TIME )		{			// TBD: HANDLE DATETIME VALUE VS TEXT AXIS		}		double[] daTickCoordinates = scBase.getTickCordinates( );		Object oDataBase = null;		DataSetIterator dsiDataBase = scBase.getData( );		Object oDataOrthogonal;		DataSetIterator dsiDataOrthogonal = getTypedDataSet( seOrthogonal,				oaxOrthogonal.getScale( ).getType( ) );		double dOrthogonalZero = 0;		if ( ( scOrthogonal.getType( ) & NUMERICAL ) == NUMERICAL )		{			dOrthogonalZero = getLocation( scOrthogonal, 0 );		}		else		{			dOrthogonalZero = scOrthogonal.getStart( );		}		double dBaseZero = ( ( scBase.getType( ) & NUMERICAL ) == IConstants.NUMERICAL && !oaxBase.isCategoryScale( ) ) ? getLocation( scBase,				0 )				: scBase.getStart( );		if ( scBase.getType( ) == TEXT || oaxBase.isCategoryScale( ) )		{			iUnitCount--;		}		double dX = 0, dY = 0, dLength = 0;		Location lo;		final int iBaseCount = dsiDataBase.size( );		final int iOrthogonalCount = dsiDataOrthogonal.size( );		DataPointHints[] dpa = null;		if ( iBaseCount != iOrthogonalCount ) // DO NOT COMPUTE DATA POINT		// HINTS		// FOR OUT-OF-SYNC DATA		{			logger.log( ILogger.INFORMATION,					Messages.getString( "exception.base.orthogonal.inconsistent.count", //$NON-NLS-1$							new Object[]{									new Integer( iBaseCount ),									new Integer( iOrthogonalCount )							},							rtc.getLocale( ) ) );		}		else		{			dpa = new DataPointHints[iBaseCount];			final boolean bScatter = ( oaxBase.getScale( ).getType( ) != IConstants.TEXT && !oaxBase.isCategoryScale( ) );			// OPTIMIZED PRE-FETCH FORMAT SPECIFIERS FOR ALL DATA POINTS			final DataPoint dp = seOrthogonal.getDataPoint( );			final EList el = dp.getComponents( );			DataPointComponent dpc;			DataPointComponentType dpct;			FormatSpecifier fsBase = null, fsOrthogonal = null, fsSeries = null;			for ( int i = 0; i < el.size( ); i++ )			{				dpc = (DataPointComponent) el.get( i );				dpct = dpc.getType( );				if ( dpct == DataPointComponentType.BASE_VALUE_LITERAL )				{					fsBase = dpc.getFormatSpecifier( );					if ( fsBase == null ) // BACKUP					{						fsBase = sdBase.getFormatSpecifier( );					}				}				else if ( dpct == DataPointComponentType.ORTHOGONAL_VALUE_LITERAL )				{					fsOrthogonal = dpc.getFormatSpecifier( );					if ( fsOrthogonal == null ) // BACKUP					{						fsOrthogonal = sdOrthogonal.getFormatSpecifier( );					}				}				else if ( dpct == DataPointComponentType.SERIES_VALUE_LITERAL )				{					fsSeries = dpc.getFormatSpecifier( );				}			}			dsiDataBase.reset( );			dsiDataOrthogonal.reset( );			for ( int i = 0; i < iBaseCount; i++ )			{				oDataBase = dsiDataBase.next( );				oDataOrthogonal = dsiDataOrthogonal.next( );				if ( !bScatter )				{					if ( aax.areAxesSwapped( ) )					{						dY = daTickCoordinates[0] - dUnitSize * i;						try						{							dX = getLocation( scOrthogonal, oDataOrthogonal );						}						catch ( IllegalArgumentException nvex )						{							//dX = dOrthogonalZero;							dX = Double.NaN;						}						catch ( ChartException dfex )						{							dX = dOrthogonalZero; // FOR CUSTOM DATA ELEMENTS						}					}					else					{						dX = daTickCoordinates[0] + dUnitSize * i;						try						{							dY = getLocation( scOrthogonal, oDataOrthogonal );						}						catch ( IllegalArgumentException nvex )						{							//dY = dOrthogonalZero;							dY = Double.NaN;						}						catch ( ChartException dfex )						{							dY = dOrthogonalZero; // FOR CUSTOM DATA ELEMENTS						}					}				}				else				// SCATTER CHARTS (BASE AXIS != CATEGORY AXIS)				{					try					{						dX = getLocation( scBase, oDataBase );					}					catch ( IllegalArgumentException nvex )					{						dX = dBaseZero;					}					catch ( ChartException dfex )					{						dX = dBaseZero; // FOR CUSTOM DATA ELEMENTS					}					try					{						dY = getLocation( scOrthogonal, oDataOrthogonal );					}					catch ( IllegalArgumentException nvex )					{						//dY = dOrthogonalZero; // MAP TO ZERO						dX = Double.NaN;					}					catch ( ChartException dfex )					{						dY = dOrthogonalZero; // FOR CUSTOM DATA ELEMENTS					}					if ( aax.areAxesSwapped( ) )					{						final double dTemp = dX;						dX = dY;						dY = dTemp;					}				}				lo = LocationImpl.create( dX, dY );				dLength = ( i < iTickCount - 1 ) ? daTickCoordinates[i + 1]						- daTickCoordinates[i] : 0;				dpa[i] = new DataPointHints( oDataBase,						oDataOrthogonal,						seOrthogonal.getSeriesIdentifier( ),						seOrthogonal.getDataPoint( ),						fsBase,						fsOrthogonal,						fsSeries,						lo,						dLength,						rtc );			}		}		return new SeriesRenderingHints( this,				oaxBase.getAxisCoordinate( ),				scOrthogonal.getStart( ),				dOrthogonalZero,				dSeriesThickness,				daTickCoordinates,				dpa,				scBase,				scOrthogonal,				ssl,				dsiDataBase,				dsiDataOrthogonal );	}