Matrix _ChartMatrix; // Pseudo matrix to calculate chart data internal Chart(ReportDefn r, ReportLink p, XmlNode xNode):base(r, p, xNode) { _Type=ChartTypeEnum.Column; _Subtype=ChartSubTypeEnum.Plain; _SeriesGroupings=null; _CategoryGroupings=null; _ChartData=null; _Legend=null; _CategoryAxis=null; _ValueAxis=null; _Title=null; _PointWidth=0; _Palette=ChartPaletteEnum.Default; _ThreeDProperties=null; _PlotArea=null; _ChartElementOutput=ChartElementOutputEnum.Output; // 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.Scatter || _Type == ChartTypeEnum.Bubble || _Type == ChartTypeEnum.Stock || _Type == ChartTypeEnum.Unknown) { OwnerReport.rl.LogError(8, "Chart type '" + xNodeLoop.InnerText + "' is not currently supported."); } break; case "Subtype": _Subtype = ChartSubType.GetStyle(xNodeLoop.InnerText, OwnerReport.rl); 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 = ChartPalette.GetStyle(xNodeLoop.InnerText, OwnerReport.rl); break; case "ThreeDProperties": _ThreeDProperties = new ThreeDProperties(r, this, xNodeLoop); break; case "PlotArea": _PlotArea = new PlotArea(r, this, xNodeLoop); break; case "ChartElementOutput": _ChartElementOutput = fyiReporting.RDL.ChartElementOutput.GetStyle(xNodeLoop.InnerText, OwnerReport.rl); 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."); }
internal 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 = fyiReporting.RDL.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; } }
// Draws the Legend and then returns the rectangle it drew in protected System.Drawing.Rectangle DrawLegend(Report rpt, Graphics g, bool bMarker, bool bBeforePlotDrawn) { Legend l = _ChartDefn.Legend; if (l == null) { return(System.Drawing.Rectangle.Empty); } if (!l.Visible) { return(System.Drawing.Rectangle.Empty); } if (_ChartDefn.SeriesGroupings == null) { return(System.Drawing.Rectangle.Empty); } if (bBeforePlotDrawn) { if (this.IsLegendInsidePlotArea()) { return(System.Drawing.Rectangle.Empty); } } else if (!IsLegendInsidePlotArea()) // Only draw legend after if inside the plot { return(System.Drawing.Rectangle.Empty); } Font drawFont = null; Brush drawBrush = null; StringFormat drawFormat = null; // calculated bounding rectangle of the legend System.Drawing.Rectangle rRect; Style s = l.Style; try // no matter what we want to dispose of the graphic resources { if (s == null) { drawFont = new Font("Arial", 10); drawBrush = new SolidBrush(Color.Black); drawFormat = new StringFormat(); drawFormat.Alignment = StringAlignment.Near; } else { drawFont = s.GetFont(rpt, null); drawBrush = s.GetBrush(rpt, null); drawFormat = s.GetStringFormat(rpt, null); } int x, y, h; int maxTextWidth, maxTextHeight; drawFormat.FormatFlags |= StringFormatFlags.NoWrap; Size[] sizes = DrawLegendMeasure(rpt, g, drawFont, drawFormat, new SizeF(Layout.Width, Layout.Height), out maxTextWidth, out maxTextHeight); int boxSize = (int)(maxTextHeight * .8); int totalItemWidth = 0; // width of a legend item int totalWidth, totalHeight; // final height and width of legend // calculate the height and width of the rectangle switch (l.Layout) { case LegendLayoutEnum.Row: // we need to loop thru all the width totalWidth = 0; for (int i = 0; i < SeriesCount; i++) { totalWidth += (sizes[i].Width + (boxSize * 2)); } totalHeight = (int)(maxTextHeight + (maxTextHeight * .1)); h = totalHeight; totalItemWidth = maxTextWidth + boxSize * 2; drawFormat.Alignment = StringAlignment.Near; // Force alignment to near break; case LegendLayoutEnum.Table: case LegendLayoutEnum.Column: default: totalWidth = totalItemWidth = maxTextWidth + boxSize * 2; h = (int)(maxTextHeight + (maxTextHeight * .1)); totalHeight = h * SeriesCount; break; } // calculate the location of the legend rectangle if (this.IsLegendInsidePlotArea()) { switch (l.Position) { case LegendPositionEnum.BottomCenter: x = Layout.PlotArea.X + (Layout.PlotArea.Width / 2) - (totalWidth / 2); y = Layout.PlotArea.Y + Layout.PlotArea.Height - totalHeight - 2; break; case LegendPositionEnum.BottomLeft: case LegendPositionEnum.LeftBottom: x = Layout.PlotArea.X + 2; y = Layout.PlotArea.Y + Layout.PlotArea.Height - totalHeight - 2; break; case LegendPositionEnum.BottomRight: case LegendPositionEnum.RightBottom: x = Layout.PlotArea.X + Layout.PlotArea.Width - totalWidth; y = Layout.PlotArea.Y + Layout.PlotArea.Height - totalHeight - 2; break; case LegendPositionEnum.LeftCenter: x = Layout.PlotArea.X + 2; y = Layout.PlotArea.Y + (Layout.PlotArea.Height / 2) - (totalHeight / 2); break; case LegendPositionEnum.LeftTop: case LegendPositionEnum.TopLeft: x = Layout.PlotArea.X + 2; y = Layout.PlotArea.Y + 2; break; case LegendPositionEnum.RightCenter: x = Layout.PlotArea.X + Layout.PlotArea.Width - totalWidth - 2; y = Layout.PlotArea.Y + (Layout.PlotArea.Height / 2) - (totalHeight / 2); break; case LegendPositionEnum.TopCenter: x = Layout.PlotArea.X + (Layout.PlotArea.Width / 2) - (totalWidth / 2); y = Layout.PlotArea.Y + +2; break; case LegendPositionEnum.TopRight: case LegendPositionEnum.RightTop: default: x = Layout.PlotArea.X + Layout.PlotArea.Width - totalWidth - 2; y = Layout.PlotArea.Y + +2; break; } } else { switch (l.Position) { case LegendPositionEnum.BottomCenter: x = (Layout.Width / 2) - (totalWidth / 2); y = Layout.Height - totalHeight - 2; break; case LegendPositionEnum.BottomLeft: case LegendPositionEnum.LeftBottom: if (IsLegendInsidePlotArea()) { x = Layout.LeftMargin; } else { x = 0; } y = Layout.Height - totalHeight - 2; break; case LegendPositionEnum.BottomRight: case LegendPositionEnum.RightBottom: x = Layout.Width - totalWidth; y = Layout.Height - totalHeight - 2; break; case LegendPositionEnum.LeftCenter: x = 2; y = (Layout.Height / 2) - (totalHeight / 2); break; case LegendPositionEnum.LeftTop: case LegendPositionEnum.TopLeft: x = 2; y = Layout.TopMargin + 2; break; case LegendPositionEnum.RightCenter: x = Layout.Width - totalWidth - 2; y = (Layout.Height / 2) - (totalHeight / 2); break; case LegendPositionEnum.TopCenter: x = (Layout.Width / 2) - (totalWidth / 2); y = Layout.TopMargin + 2; break; case LegendPositionEnum.TopRight: case LegendPositionEnum.RightTop: default: x = Layout.Width - totalWidth - 2; y = Layout.TopMargin + 2; break; } } // We now know enough to calc the bounding rectangle of the legend rRect = new System.Drawing.Rectangle(x - 1, y - 1, totalWidth + 2, totalHeight + 2); if (s != null) { s.DrawBackground(rpt, g, null, rRect); // draw (or not draw) background s.DrawBorder(rpt, g, null, rRect); // draw (or not draw) border depending on style } for (int iCol = 1; iCol <= SeriesCount; iCol++) { string c = GetSeriesValue(rpt, iCol); System.Drawing.Rectangle rect; switch (l.Layout) { case LegendLayoutEnum.Row: rect = new System.Drawing.Rectangle(x + boxSize + boxSize / 2, y, totalItemWidth - boxSize - boxSize / 2, h); g.DrawString(c, drawFont, drawBrush, rect, drawFormat); DrawLegendBox(g, SeriesBrush[iCol - 1], bMarker? SeriesMarker[iCol - 1]: ChartMarkerEnum.None, x, y + 1, boxSize); x += (sizes[iCol - 1].Width + boxSize * 2); break; case LegendLayoutEnum.Table: case LegendLayoutEnum.Column: default: rect = new System.Drawing.Rectangle(x + boxSize + boxSize / 2, y, maxTextWidth, h); g.DrawString(c, drawFont, drawBrush, rect, drawFormat); DrawLegendBox(g, SeriesBrush[iCol - 1], bMarker? SeriesMarker[iCol - 1]: ChartMarkerEnum.None, x + 1, y, boxSize); y += h; break; } } } finally { if (drawFont != null) { drawFont.Dispose(); } if (drawBrush != null) { drawBrush.Dispose(); } if (drawFormat != null) { drawFormat.Dispose(); } } if (s != null) { rRect = s.PaddingAdjust(rpt, null, rRect, true); } return(rRect); }