public Chart(ReportDefn r, ReportLink p, XmlNode xNode):base(r, p, xNode)
		{
			
            _Type=ChartTypeEnum.Column;
			_Subtype= new Expression(r,p,"Plain",ExpressionType.Enum); //AJM GJL 14082008 Allowing Expression
			_SeriesGroupings=null;
			_CategoryGroupings=null;
			_ChartData=null;
			_Legend=null;
			_CategoryAxis=null;
			_ValueAxis=null;
			_Title=null;
			_PointWidth=0;
            _Palette = new Expression(r, p, "Default", ExpressionType.Enum); //AJM GJL 14082008 Allowing Expression
			_ThreeDProperties=null;
			_PlotArea=null;
			_ChartElementOutput=ChartElementOutputEnum.Output;
            _isHYNEsWonderfulVector = new Expression(r, p, "False", ExpressionType.Boolean);
            _showTooltips = new Expression(r,p,"False",ExpressionType.Boolean);
            _showTooltipsX = new Expression(r, p, "False", ExpressionType.Boolean);
            _ToolTipXFormat = new Expression(r, p, "", ExpressionType.String);
            _ToolTipYFormat = new Expression(r, p, "", ExpressionType.String);

			// Loop thru all the child nodes
			foreach(XmlNode xNodeLoop in xNode.ChildNodes)
			{
				if (xNodeLoop.NodeType != XmlNodeType.Element)
					continue;
				switch (xNodeLoop.Name)
				{
					case "Type":
						_Type = ChartType.GetStyle(xNodeLoop.InnerText);
						if (_Type == ChartTypeEnum.Stock ||
							_Type == ChartTypeEnum.Unknown)
						{
							OwnerReport.rl.LogError(8, "Chart type '" + xNodeLoop.InnerText + "' is not currently supported.");
						}
						break;
					case "Subtype":
                        _Subtype = new Expression(r, p, xNodeLoop, ExpressionType.Enum); //AJM GJL 14082008
						break;
					case "SeriesGroupings":
						_SeriesGroupings = new SeriesGroupings(r, this, xNodeLoop);
						break;
					case "CategoryGroupings":
						_CategoryGroupings = new CategoryGroupings(r, this, xNodeLoop);
						break;
					case "ChartData":
						_ChartData = new ChartData(r, this, xNodeLoop);
						break;
					case "Legend":
						_Legend = new Legend(r, this, xNodeLoop);
						break;
					case "CategoryAxis":
						_CategoryAxis = new CategoryAxis(r, this, xNodeLoop);
						break;
					case "ValueAxis":
						_ValueAxis = new ValueAxis(r, this, xNodeLoop);
						break;
					case "Title":
						_Title = new Title(r, this, xNodeLoop);
						break;
					case "PointWidth":
						_PointWidth = XmlUtil.Integer(xNodeLoop.InnerText);
						break;
					case "Palette":
                        _Palette = new Expression(r, p, xNodeLoop, ExpressionType.Enum); //AJM GJL 14082008
						break;
					case "ThreeDProperties":
						_ThreeDProperties = new ThreeDProperties(r, this, xNodeLoop);
						break;
					case "PlotArea":
						_PlotArea = new PlotArea(r, this, xNodeLoop);
						break;
					case "ChartElementOutput":
						_ChartElementOutput = Oranikle.Report.Engine.ChartElementOutput.GetStyle(xNodeLoop.InnerText, OwnerReport.rl);
						break;
                    case "HyneWonderfulVector": //AJM GJL 14082008
                    case "RenderAsVector":
                    case "fyi:RenderAsVector":
                        _isHYNEsWonderfulVector = new Expression(r,p,xNodeLoop,ExpressionType.Boolean);
                        break;
                    case "fyi:tooltip":
                    case "fyi:Tooltip":
                        _showTooltips = new Expression(r, p, xNodeLoop, ExpressionType.Boolean);
                        break;
                    case "fyi:TooltipX":
                        _showTooltipsX = new Expression(r, p, xNodeLoop, ExpressionType.Boolean);
                        break;
                    case "fyi:TooltipYFormat":
                        _ToolTipYFormat = new Expression(r, p, xNodeLoop, ExpressionType.Boolean);
                        break;
                    case "fyi:TooltipXFormat":
                        _ToolTipXFormat = new Expression(r, p, xNodeLoop, ExpressionType.Boolean);
                        break;
					default:	
						if (DataRegionElement(xNodeLoop))	// try at DataRegion level
							break;
						// don't know this element - log it
						OwnerReport.rl.LogError(4, "Unknown Chart element '" + xNodeLoop.Name + "' ignored.");
						break;
				}
			}
			DataRegionFinish();			// Tidy up the DataRegion

			if (_SeriesGroupings == null && _CategoryGroupings == null)
				OwnerReport.rl.LogError(8, "Chart requires either the SeriesGroupings element or CategoryGroupings element or both.");

            if (OwnerReport.rl.MaxSeverity > 4)     // if we already have severe error don't check for these additional issues
                return;

            // Do some specific checking based on the type of the Chart specified
            switch (_Type)
            {
                case ChartTypeEnum.Bubble:
                    if (_ChartData == null || 
                        _ChartData.Items[0].Datapoints.Items[0].DataValues.Items.Count != 3)
                        OwnerReport.rl.LogError(8, "Bubble charts require three DataPoints defined.");
                    break;
                case ChartTypeEnum.Scatter:
                    if (_ChartData == null ||
                        _ChartData.Items[0].Datapoints.Items[0].DataValues.Items.Count != 2)
                        OwnerReport.rl.LogError(8, "Scatter charts require two DataPoints defined.");
                    break;
                default:
                    break;
            }
            
        }
		protected Size DrawTitleMeasure(Report rpt, Graphics g, Title t)
		{
			Size size=Size.Empty;

			if (t == null || t.Caption == null)
				return size;

			Row r = FirstChartRow(rpt);
			object title = t.Caption.Evaluate(rpt, r);
			if (t.Style != null)
				size = t.Style.MeasureString(rpt, g, title, t.Caption.GetTypeCode(), r, int.MaxValue);
			else
				size = Style.MeasureStringDefaults(rpt, g, title, t.Caption.GetTypeCode(), r, int.MaxValue);
			
			return size;
		}
        bool _CanOmit=false;	// When display values don't fit, is it OK to drop some from display

		public Axis(ReportDefn r, ReportLink p, XmlNode xNode) : base(r, p)
		{
			_Visible =false;
			_Style = null;
			_Title = null;
            _Title2 = null;// 20022008 AJM GJL
			_Margin = false;
			_MajorTickMarks = AxisTickMarksEnum.None;
			_MinorTickMarks = AxisTickMarksEnum.None;
			_MajorGridLines = null;
			_MinorGridLines = null;
			_MajorInterval = null;
			_MinorInterval =null;
			_Reverse = false;
			_CrossAt = 0;
			_Interlaced = false;
			_Scalar=false;
			_Min=null;
			_Max=null;
			_LogScale=false;
            _Month = false; //12052008 WP

			// Loop thru all the child nodes
			foreach(XmlNode xNodeLoop in xNode.ChildNodes)
			{
				if (xNodeLoop.NodeType != XmlNodeType.Element)
					continue;
				switch (xNodeLoop.Name)
				{
					case "Visible":
						_Visible = XmlUtil.Boolean(xNodeLoop.InnerText, OwnerReport.rl);
						break;
					case "Style":
						_Style = new Style(r, this, xNodeLoop);
						break;
					case "Title":
						_Title = new Title(r, this, xNodeLoop);
						break;
                    // 20022008 AJM GJL - Second Y axis
                    case "Title2":
                    case "fyi:Title2":
                        _Title2 = new Title(r, this, xNodeLoop);
                       break;
					case "Margin":
						_Margin = XmlUtil.Boolean(xNodeLoop.InnerText, OwnerReport.rl);
						break;
					case "MajorTickMarks":
						_MajorTickMarks = AxisTickMarks.GetStyle(xNodeLoop.InnerText, OwnerReport.rl);
						break;
					case "MinorTickMarks":
						_MinorTickMarks = AxisTickMarks.GetStyle(xNodeLoop.InnerText, OwnerReport.rl);
						break;
					case "MajorGridLines":
						_MajorGridLines = new ChartGridLines(r, this, xNodeLoop);
						break;
					case "MinorGridLines":
						_MinorGridLines = new ChartGridLines(r, this, xNodeLoop);
						break;
					case "MajorInterval":
						_MajorInterval = new Expression(OwnerReport, this, xNodeLoop, ExpressionType.Integer);
						OwnerReport.rl.LogError(4, "Axis element MajorInterval is currently ignored.");
						break;
					case "MinorInterval":
						_MinorInterval = new Expression(OwnerReport, this, xNodeLoop, ExpressionType.Integer);
						OwnerReport.rl.LogError(4, "Axis element MinorInterval is currently ignored.");
						break;
					case "Reverse":
						_Reverse = XmlUtil.Boolean(xNodeLoop.InnerText, OwnerReport.rl);
						break;
					case "CrossAt":
						_CrossAt = XmlUtil.Integer(xNodeLoop.InnerText);
						break;
					case "Interlaced":
						_Interlaced = XmlUtil.Boolean(xNodeLoop.InnerText, OwnerReport.rl);
						break;
					case "Scalar":
						_Scalar = XmlUtil.Boolean(xNodeLoop.InnerText, OwnerReport.rl);
						break;
					case "Min":
						_Min = new Expression(OwnerReport, this, xNodeLoop, ExpressionType.Integer);
						break;
					case "Max":
						_Max = new Expression(OwnerReport, this, xNodeLoop, ExpressionType.Integer);
						break;
					case "LogScale":
						_LogScale = XmlUtil.Boolean(xNodeLoop.InnerText, OwnerReport.rl);
						break;
                    case "Month":
                    case "fyi:Month":
                        _Month = XmlUtil.Boolean(xNodeLoop.InnerText, OwnerReport.rl);
                        break;
                    case "fyi:CanOmit":
                        _CanOmit = XmlUtil.Boolean(xNodeLoop.InnerText, OwnerReport.rl);
                        break;
					default:	
						// don't know this element - log it
						OwnerReport.rl.LogError(4, "Unknown Axis element '" + xNodeLoop.Name + "' ignored.");
						break;
				}
			}
		}
		protected void DrawTitle(Report rpt, Graphics g, Title t, System.Drawing.Rectangle rect)
		{
			if (t == null)
				return;

			if (t.Caption == null)
				return;

			Row r = FirstChartRow(rpt);
			object title = t.Caption.Evaluate(rpt, r);
			if (t.Style != null)
			{
				t.Style.DrawString(rpt, g, title, t.Caption.GetTypeCode(), r, rect);
				t.Style.DrawBorder(rpt, g, r, rect);
			}
			else
				Style.DrawStringDefaults(g, title, rect);

			return;
		}