|  | /******************************************************************************* | 
|  | * You may amend and distribute as you like, but don't remove this header! | 
|  | * | 
|  | * EPPlus provides server-side generation of Excel 2007/2010 spreadsheets. | 
|  | * See http://www.codeplex.com/EPPlus for details. | 
|  | * | 
|  | * Copyright (C) 2011  Jan Källman | 
|  | * | 
|  | * This library is free software; you can redistribute it and/or | 
|  | * modify it under the terms of the GNU Lesser General Public | 
|  | * License as published by the Free Software Foundation; either | 
|  | * version 2.1 of the License, or (at your option) any later version. | 
|  |  | 
|  | * This library is distributed in the hope that it will be useful, | 
|  | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 
|  | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | 
|  | * See the GNU Lesser General Public License for more details. | 
|  | * | 
|  | * The GNU Lesser General Public License can be viewed at http://www.opensource.org/licenses/lgpl-license.php | 
|  | * If you unfamiliar with this license or have questions about it, here is an http://www.gnu.org/licenses/gpl-faq.html | 
|  | * | 
|  | * All code and executables are provided "as is" with no warranty either express or implied. | 
|  | * The author accepts no liability for any damage or loss of business that this product may cause. | 
|  | * | 
|  | * Code change notes: | 
|  | * | 
|  | * Author							Change						Date | 
|  | ******************************************************************************* | 
|  | * Jan Källman		Added		2009-10-01 | 
|  | * Jan Källman		License changed GPL-->LGPL 2011-12-16 | 
|  | *******************************************************************************/ | 
|  | using System; | 
|  | using System.Collections.Generic; | 
|  | using System.Globalization; | 
|  | using System.Text; | 
|  | using System.Xml; | 
|  | using System.IO; | 
|  | using OfficeOpenXml.Table.PivotTable; | 
|  | using OfficeOpenXml.Utils; | 
|  | using OfficeOpenXml.Packaging; | 
|  |  | 
|  | namespace OfficeOpenXml.Drawing.Chart | 
|  | { | 
|  | #region "Chart Enums" | 
|  | /// <summary> | 
|  | /// Chart type | 
|  | /// </summary> | 
|  | public enum eChartType | 
|  | { | 
|  | Area3D=-4098, | 
|  | AreaStacked3D=78, | 
|  | AreaStacked1003D=79, | 
|  | BarClustered3D= 60, | 
|  | BarStacked3D=61, | 
|  | BarStacked1003D=62, | 
|  | Column3D=-4100, | 
|  | ColumnClustered3D=54, | 
|  | ColumnStacked3D=55, | 
|  | ColumnStacked1003D=56, | 
|  | Line3D=-4101, | 
|  | Pie3D=-4102, | 
|  | PieExploded3D=70, | 
|  | Area=1, | 
|  | AreaStacked=76, | 
|  | AreaStacked100=77, | 
|  | BarClustered=57, | 
|  | BarOfPie=71, | 
|  | BarStacked=58, | 
|  | BarStacked100=59, | 
|  | Bubble=15, | 
|  | Bubble3DEffect=87, | 
|  | ColumnClustered=51, | 
|  | ColumnStacked=52, | 
|  | ColumnStacked100=53, | 
|  | ConeBarClustered=102, | 
|  | ConeBarStacked=103, | 
|  | ConeBarStacked100=104, | 
|  | ConeCol=105, | 
|  | ConeColClustered=99, | 
|  | ConeColStacked=100, | 
|  | ConeColStacked100=101, | 
|  | CylinderBarClustered=95, | 
|  | CylinderBarStacked=96, | 
|  | CylinderBarStacked100=97, | 
|  | CylinderCol=98, | 
|  | CylinderColClustered=92, | 
|  | CylinderColStacked=93, | 
|  | CylinderColStacked100=94, | 
|  | Doughnut=-4120, | 
|  | DoughnutExploded=80, | 
|  | Line=4, | 
|  | LineMarkers=65, | 
|  | LineMarkersStacked=66, | 
|  | LineMarkersStacked100=67, | 
|  | LineStacked=63, | 
|  | LineStacked100=64, | 
|  | Pie=5, | 
|  | PieExploded=69, | 
|  | PieOfPie=68, | 
|  | PyramidBarClustered=109, | 
|  | PyramidBarStacked=110, | 
|  | PyramidBarStacked100=111, | 
|  | PyramidCol=112, | 
|  | PyramidColClustered=106, | 
|  | PyramidColStacked=107, | 
|  | PyramidColStacked100=108, | 
|  | Radar=-4151, | 
|  | RadarFilled=82, | 
|  | RadarMarkers=81, | 
|  | StockHLC=88, | 
|  | StockOHLC=89, | 
|  | StockVHLC=90, | 
|  | StockVOHLC=91, | 
|  | Surface=83, | 
|  | SurfaceTopView=85, | 
|  | SurfaceTopViewWireframe=86, | 
|  | SurfaceWireframe=84, | 
|  | XYScatter=-4169, | 
|  | XYScatterLines=74, | 
|  | XYScatterLinesNoMarkers=75, | 
|  | XYScatterSmooth=72, | 
|  | XYScatterSmoothNoMarkers=73 | 
|  | } | 
|  | /// <summary> | 
|  | /// Bar or column | 
|  | /// </summary> | 
|  | public enum eDirection | 
|  | { | 
|  | Column, | 
|  | Bar | 
|  | } | 
|  | /// <summary> | 
|  | /// How the series are grouped | 
|  | /// </summary> | 
|  | public enum eGrouping | 
|  | { | 
|  | Standard, | 
|  | Clustered, | 
|  | Stacked, | 
|  | PercentStacked | 
|  | } | 
|  | /// <summary> | 
|  | /// Shape for bar charts | 
|  | /// </summary> | 
|  | public enum eShape | 
|  | { | 
|  | Box, | 
|  | Cone, | 
|  | ConeToMax, | 
|  | Cylinder, | 
|  | Pyramid, | 
|  | PyramidToMax | 
|  | } | 
|  | /// <summary> | 
|  | /// Smooth or lines markers | 
|  | /// </summary> | 
|  | public enum eScatterStyle | 
|  | { | 
|  | LineMarker, | 
|  | SmoothMarker, | 
|  | } | 
|  | public enum eRadarStyle | 
|  | { | 
|  | /// <summary> | 
|  | /// Specifies that the radar chart shall be filled and have lines but no markers. | 
|  | /// </summary> | 
|  | Filled, | 
|  | /// <summary> | 
|  | /// Specifies that the radar chart shall have lines and markers but no fill. | 
|  | /// </summary> | 
|  | Marker, | 
|  | /// <summary> | 
|  | /// Specifies that the radar chart shall have lines but no markers and no fill. | 
|  | /// </summary> | 
|  | Standard | 
|  | } | 
|  | /// <summary> | 
|  | /// Bar or pie | 
|  | /// </summary> | 
|  | public enum ePieType | 
|  | { | 
|  | Bar, | 
|  | Pie | 
|  | } | 
|  | /// <summary> | 
|  | /// Position of the labels | 
|  | /// </summary> | 
|  | public enum eLabelPosition | 
|  | { | 
|  | BestFit, | 
|  | Left, | 
|  | Right, | 
|  | Center, | 
|  | Top, | 
|  | Bottom, | 
|  | InBase, | 
|  | InEnd, | 
|  | OutEnd | 
|  | } | 
|  | /// <summary> | 
|  | /// Axis label position | 
|  | /// </summary> | 
|  | public enum eTickLabelPosition | 
|  | { | 
|  | High, | 
|  | Low, | 
|  | NextTo, | 
|  | None | 
|  | } | 
|  | /// <summary> | 
|  | /// Markerstyle | 
|  | /// </summary> | 
|  | public enum eMarkerStyle | 
|  | { | 
|  | Circle, | 
|  | Dash, | 
|  | Diamond, | 
|  | Dot, | 
|  | None, | 
|  | Picture, | 
|  | Plus, | 
|  | Square, | 
|  | Star, | 
|  | Triangle, | 
|  | X, | 
|  | } | 
|  | /// <summary> | 
|  | /// The build in style of the chart. | 
|  | /// </summary> | 
|  | public enum eChartStyle | 
|  | { | 
|  | None, | 
|  | Style1, | 
|  | Style2, | 
|  | Style3, | 
|  | Style4, | 
|  | Style5, | 
|  | Style6, | 
|  | Style7, | 
|  | Style8, | 
|  | Style9, | 
|  | Style10, | 
|  | Style11, | 
|  | Style12, | 
|  | Style13, | 
|  | Style14, | 
|  | Style15, | 
|  | Style16, | 
|  | Style17, | 
|  | Style18, | 
|  | Style19, | 
|  | Style20, | 
|  | Style21, | 
|  | Style22, | 
|  | Style23, | 
|  | Style24, | 
|  | Style25, | 
|  | Style26, | 
|  | Style27, | 
|  | Style28, | 
|  | Style29, | 
|  | Style30, | 
|  | Style31, | 
|  | Style32, | 
|  | Style33, | 
|  | Style34, | 
|  | Style35, | 
|  | Style36, | 
|  | Style37, | 
|  | Style38, | 
|  | Style39, | 
|  | Style40, | 
|  | Style41, | 
|  | Style42, | 
|  | Style43, | 
|  | Style44, | 
|  | Style45, | 
|  | Style46, | 
|  | Style47, | 
|  | Style48 | 
|  | } | 
|  | /// <summary> | 
|  | /// Type of Trendline for a chart | 
|  | /// </summary> | 
|  | public enum eTrendLine | 
|  | { | 
|  | /// <summary> | 
|  | /// Specifies the trendline shall be an exponential curve in the form | 
|  | /// </summary> | 
|  | Exponential, | 
|  | /// <summary> | 
|  | /// Specifies the trendline shall be a logarithmic curve in the form , where log is the natural | 
|  | /// </summary> | 
|  | Linear, | 
|  | /// <summary> | 
|  | /// Specifies the trendline shall be a logarithmic curve in the form , where log is the natural | 
|  | /// </summary> | 
|  | Logarithmic, | 
|  | /// <summary> | 
|  | /// Specifies the trendline shall be a moving average of period Period | 
|  | /// </summary> | 
|  | MovingAvgerage, | 
|  | /// <summary> | 
|  | /// Specifies the trendline shall be a polynomial curve of order Order in the form | 
|  | /// </summary> | 
|  | Polynomial, | 
|  | /// <summary> | 
|  | /// Specifies the trendline shall be a power curve in the form | 
|  | /// </summary> | 
|  | Power | 
|  | } | 
|  | /// <summary> | 
|  | /// Specifies the possible ways to display blanks | 
|  | /// </summary> | 
|  | public enum eDisplayBlanksAs | 
|  | { | 
|  | /// <summary> | 
|  | /// Blank values shall be left as a gap | 
|  | /// </summary> | 
|  | Gap, | 
|  | /// <summary> | 
|  | /// Blank values shall be spanned with a line (Line charts) | 
|  | /// </summary> | 
|  | Span, | 
|  | /// <summary> | 
|  | /// Blank values shall be treated as zero | 
|  | /// </summary> | 
|  | Zero | 
|  | } | 
|  | public enum eSizeRepresents | 
|  | { | 
|  | /// <summary> | 
|  | /// Specifies the area of the bubbles shall be proportional to the bubble size value. | 
|  | /// </summary> | 
|  | Area, | 
|  | /// <summary> | 
|  | /// Specifies the radius of the bubbles shall be proportional to the bubble size value. | 
|  | /// </summary> | 
|  | Width | 
|  | } | 
|  | #endregion | 
|  |  | 
|  |  | 
|  | /// <summary> | 
|  | /// Base class for Chart object. | 
|  | /// </summary> | 
|  | public class ExcelChart : ExcelDrawing | 
|  | { | 
|  | const string rootPath = "c:chartSpace/c:chart/c:plotArea"; | 
|  | //string _chartPath; | 
|  | protected internal ExcelChartSeries _chartSeries; | 
|  | internal ExcelChartAxis[] _axis; | 
|  | protected XmlHelper _chartXmlHelper; | 
|  | #region "Constructors" | 
|  | internal ExcelChart(ExcelDrawings drawings, XmlNode node, eChartType type, bool isPivot) : | 
|  | base(drawings, node, "xdr:graphicFrame/xdr:nvGraphicFramePr/xdr:cNvPr/@name") | 
|  | { | 
|  | ChartType = type; | 
|  | CreateNewChart(drawings, type, null); | 
|  |  | 
|  | Init(drawings, _chartNode); | 
|  |  | 
|  | _chartSeries = new ExcelChartSeries(this, drawings.NameSpaceManager, _chartNode, isPivot); | 
|  |  | 
|  | SetTypeProperties(); | 
|  | LoadAxis(); | 
|  | } | 
|  | internal ExcelChart(ExcelDrawings drawings, XmlNode node, eChartType type, ExcelChart topChart, ExcelPivotTable PivotTableSource) : | 
|  | base(drawings, node, "xdr:graphicFrame/xdr:nvGraphicFramePr/xdr:cNvPr/@name") | 
|  | { | 
|  | ChartType = type; | 
|  | CreateNewChart(drawings, type, topChart); | 
|  |  | 
|  | Init(drawings, _chartNode); | 
|  |  | 
|  | _chartSeries = new ExcelChartSeries(this, drawings.NameSpaceManager, _chartNode, PivotTableSource!=null); | 
|  | if (PivotTableSource != null) SetPivotSource(PivotTableSource); | 
|  |  | 
|  | SetTypeProperties(); | 
|  | if (topChart == null) | 
|  | LoadAxis(); | 
|  | else | 
|  | { | 
|  | _axis = topChart.Axis; | 
|  | if (_axis.Length > 0) | 
|  | { | 
|  | XAxis = _axis[0]; | 
|  | YAxis = _axis[1]; | 
|  | } | 
|  | } | 
|  | } | 
|  | internal ExcelChart(ExcelDrawings drawings, XmlNode node, Uri uriChart, ZipPackagePart part, XmlDocument chartXml, XmlNode chartNode) : | 
|  | base(drawings, node, "xdr:graphicFrame/xdr:nvGraphicFramePr/xdr:cNvPr/@name") | 
|  | { | 
|  | UriChart = uriChart; | 
|  | Part = part; | 
|  | ChartXml = chartXml; | 
|  | _chartNode = chartNode; | 
|  | InitChartLoad(drawings, chartNode); | 
|  | ChartType = GetChartType(chartNode.LocalName); | 
|  | } | 
|  | internal ExcelChart(ExcelChart topChart, XmlNode chartNode) : | 
|  | base(topChart._drawings, topChart.TopNode, "xdr:graphicFrame/xdr:nvGraphicFramePr/xdr:cNvPr/@name") | 
|  | { | 
|  | UriChart = topChart.UriChart; | 
|  | Part = topChart.Part; | 
|  | ChartXml = topChart.ChartXml; | 
|  | _plotArea = topChart.PlotArea; | 
|  | _chartNode = chartNode; | 
|  |  | 
|  | InitChartLoad(topChart._drawings, chartNode); | 
|  | } | 
|  | private void InitChartLoad(ExcelDrawings drawings, XmlNode chartNode) | 
|  | { | 
|  | //SetChartType(); | 
|  | bool isPivot = false; | 
|  | Init(drawings, chartNode); | 
|  | _chartSeries = new ExcelChartSeries(this, drawings.NameSpaceManager, _chartNode, isPivot /*ChartXml.SelectSingleNode(_chartPath, drawings.NameSpaceManager)*/); | 
|  | LoadAxis(); | 
|  | } | 
|  |  | 
|  | private void Init(ExcelDrawings drawings, XmlNode chartNode) | 
|  | { | 
|  | //_chartXmlHelper = new XmlHelper(drawings.NameSpaceManager, chartNode); | 
|  | _chartXmlHelper = XmlHelperFactory.Create(drawings.NameSpaceManager, chartNode); | 
|  | _chartXmlHelper.SchemaNodeOrder = new string[] { "title", "pivotFmt", "autoTitleDeleted", "view3D", "floor", "sideWall", "backWall", "plotArea", "wireframe", "barDir", "grouping", "scatterStyle", "radarStyle", "varyColors", "ser", "dLbls", "bubbleScale", "showNegBubbles", "dropLines", "upDownBars", "marker", "smooth", "shape", "legend", "plotVisOnly", "dispBlanksAs", "showDLblsOverMax", "overlap", "bandFmts", "axId", "spPr", "printSettings" }; | 
|  | WorkSheet = drawings.Worksheet; | 
|  | } | 
|  | #endregion | 
|  | #region "Private functions" | 
|  | private void SetTypeProperties() | 
|  | { | 
|  | /******* Grouping *******/ | 
|  | if (IsTypeClustered()) | 
|  | { | 
|  | Grouping = eGrouping.Clustered; | 
|  | } | 
|  | else if ( | 
|  | IsTypeStacked()) | 
|  | { | 
|  | Grouping = eGrouping.Stacked; | 
|  | } | 
|  | else if ( | 
|  | IsTypePercentStacked()) | 
|  | { | 
|  | Grouping = eGrouping.PercentStacked; | 
|  | } | 
|  |  | 
|  | /***** 3D Perspective *****/ | 
|  | if (IsType3D()) | 
|  | { | 
|  | View3D.RotY = 20; | 
|  | View3D.Perspective = 30;    //Default to 30 | 
|  | if (IsTypePieDoughnut()) | 
|  | { | 
|  | View3D.RotX = 30; | 
|  | } | 
|  | else | 
|  | { | 
|  | View3D.RotX = 15; | 
|  | } | 
|  | } | 
|  | } | 
|  | private void CreateNewChart(ExcelDrawings drawings, eChartType type, ExcelChart topChart) | 
|  | { | 
|  | if (topChart == null) | 
|  | { | 
|  | XmlElement graphFrame = TopNode.OwnerDocument.CreateElement("graphicFrame", ExcelPackage.schemaSheetDrawings); | 
|  | graphFrame.SetAttribute("macro", ""); | 
|  | TopNode.AppendChild(graphFrame); | 
|  | graphFrame.InnerXml = string.Format("<xdr:nvGraphicFramePr><xdr:cNvPr id=\"{0}\" name=\"Chart 1\" /><xdr:cNvGraphicFramePr /></xdr:nvGraphicFramePr><xdr:xfrm><a:off x=\"0\" y=\"0\" /> <a:ext cx=\"0\" cy=\"0\" /></xdr:xfrm><a:graphic><a:graphicData uri=\"http://schemas.openxmlformats.org/drawingml/2006/chart\"><c:chart xmlns:c=\"http://schemas.openxmlformats.org/drawingml/2006/chart\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\" r:id=\"rId1\" />   </a:graphicData>  </a:graphic>",_id); | 
|  | TopNode.AppendChild(TopNode.OwnerDocument.CreateElement("clientData", ExcelPackage.schemaSheetDrawings)); | 
|  |  | 
|  | var package = drawings.Worksheet._package.Package; | 
|  | UriChart = GetNewUri(package, "/xl/charts/chart{0}.xml"); | 
|  |  | 
|  | ChartXml = new XmlDocument(); | 
|  | ChartXml.PreserveWhitespace = ExcelPackage.preserveWhitespace; | 
|  | LoadXmlSafe(ChartXml, ChartStartXml(type), Encoding.UTF8); | 
|  |  | 
|  | // save it to the package | 
|  | Part = package.CreatePart(UriChart, "application/vnd.openxmlformats-officedocument.drawingml.chart+xml", _drawings._package.Compression); | 
|  |  | 
|  | StreamWriter streamChart = new StreamWriter(Part.GetStream(FileMode.Create, FileAccess.Write)); | 
|  | ChartXml.Save(streamChart); | 
|  | streamChart.Close(); | 
|  | package.Flush(); | 
|  |  | 
|  | var chartRelation = drawings.Part.CreateRelationship(UriHelper.GetRelativeUri(drawings.UriDrawing, UriChart), Packaging.TargetMode.Internal, ExcelPackage.schemaRelationships + "/chart"); | 
|  | graphFrame.SelectSingleNode("a:graphic/a:graphicData/c:chart", NameSpaceManager).Attributes["r:id"].Value = chartRelation.Id; | 
|  | package.Flush(); | 
|  | _chartNode = ChartXml.SelectSingleNode(string.Format("c:chartSpace/c:chart/c:plotArea/{0}", GetChartNodeText()), NameSpaceManager); | 
|  | } | 
|  | else | 
|  | { | 
|  | ChartXml = topChart.ChartXml; | 
|  | Part = topChart.Part; | 
|  | _plotArea = topChart.PlotArea; | 
|  | UriChart = topChart.UriChart; | 
|  | _axis = topChart._axis; | 
|  |  | 
|  | XmlNode preNode = _plotArea.ChartTypes[_plotArea.ChartTypes.Count - 1].ChartNode; | 
|  | _chartNode = ((XmlDocument)ChartXml).CreateElement(GetChartNodeText(), ExcelPackage.schemaChart); | 
|  | preNode.ParentNode.InsertAfter(_chartNode, preNode); | 
|  | if (topChart.Axis.Length == 0) | 
|  | { | 
|  | AddAxis(); | 
|  | } | 
|  | string serieXML = GetChartSerieStartXml(type, int.Parse(topChart.Axis[0].Id), int.Parse(topChart.Axis[1].Id), topChart.Axis.Length>2?int.Parse(topChart.Axis[2].Id) : -1); | 
|  | _chartNode.InnerXml = serieXML; | 
|  | } | 
|  | } | 
|  | private void LoadAxis() | 
|  | { | 
|  | XmlNodeList nl = _chartNode.SelectNodes("c:axId", NameSpaceManager); | 
|  | List<ExcelChartAxis> l = new List<ExcelChartAxis>(); | 
|  | foreach (XmlNode node in nl) | 
|  | { | 
|  | string id = node.Attributes["val"].Value; | 
|  | var axNode = ChartXml.SelectNodes(rootPath + string.Format("/*/c:axId[@val=\"{0}\"]", id), NameSpaceManager); | 
|  | if (axNode != null && axNode.Count>1) | 
|  | { | 
|  | foreach (XmlNode axn in axNode) | 
|  | { | 
|  | if (axn.ParentNode.LocalName.EndsWith("Ax")) | 
|  | { | 
|  | XmlNode axisNode = axNode[1].ParentNode; | 
|  | ExcelChartAxis ax = new ExcelChartAxis(NameSpaceManager, axisNode); | 
|  | l.Add(ax); | 
|  | } | 
|  | } | 
|  | } | 
|  | } | 
|  | _axis = l.ToArray(); | 
|  |  | 
|  | if(_axis.Length > 0) XAxis = _axis[0]; | 
|  | if (_axis.Length > 1) YAxis = _axis[1]; | 
|  | } | 
|  | //private void SetChartType() | 
|  | //{ | 
|  | //    ChartType = 0; | 
|  | //    //_plotArea = new ExcelChartPlotArea(NameSpaceManager, ChartXml.SelectSingleNode("c:chartSpace/c:chart/c:plotArea", NameSpaceManager)); | 
|  | //    int pos=0; | 
|  | //    foreach (XmlElement n in ChartXml.SelectSingleNode(rootPath, _drawings.NameSpaceManager).ChildNodes) | 
|  | //    { | 
|  | //        if (pos == 0) | 
|  | //        { | 
|  | //            ChartType = GetChartType(n.Name); | 
|  | //            if (ChartType != 0) | 
|  | //            { | 
|  | //                //_chartPath = rootPath + "/" + n.Name; | 
|  | //                PlotArea.ChartTypes.Add(this); | 
|  | //            } | 
|  | //        } | 
|  | //        else | 
|  | //        { | 
|  | //            var chartSerieType = GetChart(_drawings, TopNode/*, n*/); | 
|  | //            chartSerieType = GetChart(n, _drawings, TopNode, UriChart, Part, ChartXml, null, isPivot); | 
|  | //            PlotArea.ChartTypes.Add(chartSerieType); | 
|  | //            //var chartType = GetChartType(n.Name); | 
|  | //        } | 
|  | //        if (ChartType != 0) | 
|  | //        { | 
|  | //            pos++; | 
|  | //        } | 
|  | //    } | 
|  | //} | 
|  | internal virtual eChartType GetChartType(string name) | 
|  | { | 
|  |  | 
|  | switch (name) | 
|  | { | 
|  | case "area3DChart": | 
|  | if(Grouping==eGrouping.Stacked) | 
|  | { | 
|  | return eChartType.AreaStacked3D; | 
|  | } | 
|  | else if (Grouping == eGrouping.PercentStacked) | 
|  | { | 
|  | return eChartType.AreaStacked1003D; | 
|  | } | 
|  | else | 
|  | { | 
|  | return eChartType.Area3D; | 
|  | } | 
|  | case "areaChart": | 
|  | if (Grouping == eGrouping.Stacked) | 
|  | { | 
|  | return eChartType.AreaStacked; | 
|  | } | 
|  | else if (Grouping == eGrouping.PercentStacked) | 
|  | { | 
|  | return eChartType.AreaStacked100; | 
|  | } | 
|  | else | 
|  | { | 
|  | return eChartType.Area; | 
|  | } | 
|  | case "doughnutChart": | 
|  | return eChartType.Doughnut; | 
|  | case "pie3DChart": | 
|  | return eChartType.Pie3D; | 
|  | case "pieChart": | 
|  | return eChartType.Pie; | 
|  | case "radarChart": | 
|  | return eChartType.Radar; | 
|  | case "scatterChart": | 
|  | return eChartType.XYScatter; | 
|  | case "surface3DChart": | 
|  | case "surfaceChart": | 
|  | return eChartType.Surface; | 
|  | case "stockChart": | 
|  | return eChartType.StockHLC; | 
|  | default: | 
|  | return 0; | 
|  | } | 
|  | } | 
|  | #region "Xml init Functions" | 
|  | private string ChartStartXml(eChartType type) | 
|  | { | 
|  | StringBuilder xml=new StringBuilder(); | 
|  | int axID=1; | 
|  | int xAxID=2; | 
|  | int serAxID = IsTypeSurface() ? 3 : -1; | 
|  |  | 
|  | xml.Append("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>"); | 
|  | xml.AppendFormat("<c:chartSpace xmlns:c=\"{0}\" xmlns:a=\"{1}\" xmlns:r=\"{2}\">", ExcelPackage.schemaChart, ExcelPackage.schemaDrawings, ExcelPackage.schemaRelationships); | 
|  | xml.Append("<c:chart>"); | 
|  | xml.AppendFormat("{0}{1}<c:plotArea><c:layout/>",AddPerspectiveXml(type), AddSurfaceXml(type)); | 
|  |  | 
|  | string chartNodeText = GetChartNodeText(); | 
|  | xml.AppendFormat("<{0}>", chartNodeText); | 
|  | xml.Append(GetChartSerieStartXml(type, axID, xAxID, serAxID)); | 
|  | xml.AppendFormat("</{0}>", chartNodeText); | 
|  |  | 
|  | //Axis | 
|  | if (!IsTypePieDoughnut()) | 
|  | { | 
|  | if (IsTypeScatterBubble()) | 
|  | { | 
|  | xml.AppendFormat("<c:valAx><c:axId val=\"{0}\"/><c:scaling><c:orientation val=\"minMax\"/></c:scaling><c:delete val=\"0\"/><c:axPos val=\"b\"/><c:tickLblPos val=\"nextTo\"/><c:crossAx val=\"{1}\"/><c:crosses val=\"autoZero\"/></c:valAx>", axID, xAxID); | 
|  | } | 
|  | else | 
|  | { | 
|  | xml.AppendFormat("<c:catAx><c:axId val=\"{0}\"/><c:scaling><c:orientation val=\"minMax\"/></c:scaling><c:delete val=\"0\"/><c:axPos val=\"b\"/><c:tickLblPos val=\"nextTo\"/><c:crossAx val=\"{1}\"/><c:crosses val=\"autoZero\"/><c:auto val=\"1\"/><c:lblAlgn val=\"ctr\"/><c:lblOffset val=\"100\"/></c:catAx>", axID, xAxID); | 
|  | } | 
|  | xml.AppendFormat("<c:valAx><c:axId val=\"{1}\"/><c:scaling><c:orientation val=\"minMax\"/></c:scaling><c:delete val=\"0\"/><c:axPos val=\"l\"/><c:majorGridlines/><c:tickLblPos val=\"nextTo\"/><c:crossAx val=\"{0}\"/><c:crosses val=\"autoZero\"/><c:crossBetween val=\"between\"/></c:valAx>", axID, xAxID); | 
|  | if (serAxID==3) //Sureface Chart | 
|  | { | 
|  | xml.AppendFormat("<c:serAx><c:axId val=\"{0}\"/><c:scaling><c:orientation val=\"minMax\"/></c:scaling><c:delete val=\"0\"/><c:axPos val=\"b\"/><c:tickLblPos val=\"nextTo\"/><c:crossAx val=\"{1}\"/><c:crosses val=\"autoZero\"/></c:serAx>", serAxID, xAxID); | 
|  | } | 
|  | } | 
|  |  | 
|  | xml.AppendFormat("</c:plotArea><c:legend><c:legendPos val=\"r\"/><c:layout/><c:overlay val=\"0\" /></c:legend><c:plotVisOnly val=\"1\"/></c:chart>", axID, xAxID); | 
|  |  | 
|  | xml.Append("<c:printSettings><c:headerFooter/><c:pageMargins b=\"0.75\" l=\"0.7\" r=\"0.7\" t=\"0.75\" header=\"0.3\" footer=\"0.3\"/><c:pageSetup/></c:printSettings></c:chartSpace>"); | 
|  | return xml.ToString(); | 
|  | } | 
|  |  | 
|  | private string GetChartSerieStartXml(eChartType type, int axID, int xAxID, int serAxID) | 
|  | { | 
|  | StringBuilder xml = new StringBuilder(); | 
|  |  | 
|  | xml.Append(AddScatterType(type)); | 
|  | xml.Append(AddRadarType(type)); | 
|  | xml.Append(AddBarDir(type)); | 
|  | xml.Append(AddGrouping()); | 
|  | xml.Append(AddVaryColors()); | 
|  | xml.Append(AddHasMarker(type)); | 
|  | xml.Append(AddShape(type)); | 
|  | xml.Append(AddFirstSliceAng(type)); | 
|  | xml.Append(AddHoleSize(type)); | 
|  | if (ChartType == eChartType.BarStacked100 || | 
|  | ChartType == eChartType.BarStacked || | 
|  | ChartType == eChartType.ColumnStacked || | 
|  | ChartType == eChartType.ColumnStacked100) | 
|  | { | 
|  | xml.Append("<c:overlap val=\"100\"/>"); | 
|  | } | 
|  | if (IsTypeSurface()) | 
|  | { | 
|  | xml.Append("<c:bandFmts/>"); | 
|  | } | 
|  | xml.Append(AddAxisId(axID, xAxID, serAxID)); | 
|  |  | 
|  | return xml.ToString(); | 
|  | } | 
|  | private string AddAxisId(int axID,int xAxID, int serAxID) | 
|  | { | 
|  | if (!IsTypePieDoughnut()) | 
|  | { | 
|  | if (IsTypeSurface()) | 
|  | { | 
|  | return string.Format("<c:axId val=\"{0}\"/><c:axId val=\"{1}\"/><c:axId val=\"{2}\"/>", axID, xAxID, serAxID); | 
|  | } | 
|  | else | 
|  | { | 
|  | return string.Format("<c:axId val=\"{0}\"/><c:axId val=\"{1}\"/>", axID, xAxID); | 
|  | } | 
|  | } | 
|  | else | 
|  | { | 
|  | return ""; | 
|  | } | 
|  | } | 
|  | private string AddAxType() | 
|  | { | 
|  | switch(ChartType) | 
|  | { | 
|  | case eChartType.XYScatter: | 
|  | case eChartType.XYScatterLines: | 
|  | case eChartType.XYScatterLinesNoMarkers: | 
|  | case eChartType.XYScatterSmooth: | 
|  | case eChartType.XYScatterSmoothNoMarkers: | 
|  | case eChartType.Bubble: | 
|  | case eChartType.Bubble3DEffect: | 
|  | return "valAx"; | 
|  | default: | 
|  | return "catAx"; | 
|  | } | 
|  | } | 
|  | private string AddScatterType(eChartType type) | 
|  | { | 
|  | if (type == eChartType.XYScatter || | 
|  | type == eChartType.XYScatterLines || | 
|  | type == eChartType.XYScatterLinesNoMarkers || | 
|  | type == eChartType.XYScatterSmooth || | 
|  | type == eChartType.XYScatterSmoothNoMarkers) | 
|  | { | 
|  | return "<c:scatterStyle val=\"\" />"; | 
|  | } | 
|  | else | 
|  | { | 
|  | return ""; | 
|  | } | 
|  | } | 
|  | private string AddRadarType(eChartType type) | 
|  | { | 
|  | if (type == eChartType.Radar || | 
|  | type == eChartType.RadarFilled|| | 
|  | type == eChartType.RadarMarkers) | 
|  | { | 
|  | return "<c:radarStyle val=\"\" />"; | 
|  | } | 
|  | else | 
|  | { | 
|  | return ""; | 
|  | } | 
|  | } | 
|  | private string AddGrouping() | 
|  | { | 
|  | //IsTypeClustered() || IsTypePercentStacked() || IsTypeStacked() || | 
|  | if(IsTypeShape() || IsTypeLine()) | 
|  | { | 
|  | return "<c:grouping val=\"standard\"/>"; | 
|  | } | 
|  | else | 
|  | { | 
|  | return ""; | 
|  | } | 
|  | } | 
|  | private string AddHoleSize(eChartType type) | 
|  | { | 
|  | if (type == eChartType.Doughnut || | 
|  | type == eChartType.DoughnutExploded) | 
|  | { | 
|  | return "<c:holeSize val=\"50\" />"; | 
|  | } | 
|  | else | 
|  | { | 
|  | return ""; | 
|  | } | 
|  | } | 
|  | private string AddFirstSliceAng(eChartType type) | 
|  | { | 
|  | if (type == eChartType.Doughnut || | 
|  | type == eChartType.DoughnutExploded) | 
|  | { | 
|  | return "<c:firstSliceAng val=\"0\" />"; | 
|  | } | 
|  | else | 
|  | { | 
|  | return ""; | 
|  | } | 
|  | } | 
|  | private string AddVaryColors() | 
|  | { | 
|  | if (IsTypePieDoughnut()) | 
|  | { | 
|  | return "<c:varyColors val=\"1\" />"; | 
|  | } | 
|  | else | 
|  | { | 
|  | return "<c:varyColors val=\"0\" />"; | 
|  | } | 
|  | } | 
|  | private string AddHasMarker(eChartType type) | 
|  | { | 
|  | if (type == eChartType.LineMarkers || | 
|  | type == eChartType.LineMarkersStacked || | 
|  | type == eChartType.LineMarkersStacked100 /*|| | 
|  | type == eChartType.XYScatterLines || | 
|  | type == eChartType.XYScatterSmooth*/) | 
|  | { | 
|  | return "<c:marker val=\"1\"/>"; | 
|  | } | 
|  | else | 
|  | { | 
|  | return ""; | 
|  | } | 
|  | } | 
|  | private string AddShape(eChartType type) | 
|  | { | 
|  | if (IsTypeShape()) | 
|  | { | 
|  | return "<c:shape val=\"box\" />"; | 
|  | } | 
|  | else | 
|  | { | 
|  | return ""; | 
|  | } | 
|  | } | 
|  | private string AddBarDir(eChartType type) | 
|  | { | 
|  | if (IsTypeShape()) | 
|  | { | 
|  | return "<c:barDir val=\"col\" />"; | 
|  | } | 
|  | else | 
|  | { | 
|  | return ""; | 
|  | } | 
|  | } | 
|  | private string AddPerspectiveXml(eChartType type) | 
|  | { | 
|  | //Add for 3D sharts | 
|  | if (IsType3D()) | 
|  | { | 
|  | return "<c:view3D><c:perspective val=\"30\" /></c:view3D>"; | 
|  | } | 
|  | else | 
|  | { | 
|  | return ""; | 
|  | } | 
|  | } | 
|  | private string AddSurfaceXml(eChartType type) | 
|  | { | 
|  | if (IsTypeSurface()) | 
|  | { | 
|  | return AddSurfacePart("floor") + AddSurfacePart("sideWall") + AddSurfacePart("backWall"); | 
|  | } | 
|  | else | 
|  | { | 
|  | return ""; | 
|  | } | 
|  | } | 
|  |  | 
|  | private string AddSurfacePart(string name) | 
|  | { | 
|  | return string.Format("<c:{0}><c:thickness val=\"0\"/><c:spPr><a:noFill/><a:ln><a:noFill/></a:ln><a:effectLst/><a:sp3d/></c:spPr></c:{0}>", name); | 
|  | } | 
|  | #endregion | 
|  | #endregion | 
|  | #region "Chart type functions | 
|  | internal static bool IsType3D(eChartType chartType) | 
|  | { | 
|  | return chartType == eChartType.Area3D || | 
|  | chartType == eChartType.AreaStacked3D || | 
|  | chartType == eChartType.AreaStacked1003D || | 
|  | chartType == eChartType.BarClustered3D || | 
|  | chartType == eChartType.BarStacked3D || | 
|  | chartType == eChartType.BarStacked1003D || | 
|  | chartType == eChartType.Column3D || | 
|  | chartType == eChartType.ColumnClustered3D || | 
|  | chartType == eChartType.ColumnStacked3D || | 
|  | chartType == eChartType.ColumnStacked1003D || | 
|  | chartType == eChartType.Line3D || | 
|  | chartType == eChartType.Pie3D || | 
|  | chartType == eChartType.PieExploded3D || | 
|  | chartType == eChartType.ConeBarClustered || | 
|  | chartType == eChartType.ConeBarStacked || | 
|  | chartType == eChartType.ConeBarStacked100 || | 
|  | chartType == eChartType.ConeCol || | 
|  | chartType == eChartType.ConeColClustered || | 
|  | chartType == eChartType.ConeColStacked || | 
|  | chartType == eChartType.ConeColStacked100 || | 
|  | chartType == eChartType.CylinderBarClustered || | 
|  | chartType == eChartType.CylinderBarStacked || | 
|  | chartType == eChartType.CylinderBarStacked100 || | 
|  | chartType == eChartType.CylinderCol || | 
|  | chartType == eChartType.CylinderColClustered || | 
|  | chartType == eChartType.CylinderColStacked || | 
|  | chartType == eChartType.CylinderColStacked100 || | 
|  | chartType == eChartType.PyramidBarClustered || | 
|  | chartType == eChartType.PyramidBarStacked || | 
|  | chartType == eChartType.PyramidBarStacked100 || | 
|  | chartType == eChartType.PyramidCol || | 
|  | chartType == eChartType.PyramidColClustered || | 
|  | chartType == eChartType.PyramidColStacked || | 
|  | chartType == eChartType.PyramidColStacked100 || | 
|  | chartType == eChartType.Surface || | 
|  | chartType == eChartType.SurfaceTopView || | 
|  | chartType == eChartType.SurfaceTopViewWireframe || | 
|  | chartType == eChartType.SurfaceWireframe; | 
|  | } | 
|  | internal protected bool IsType3D() | 
|  | { | 
|  | return IsType3D(ChartType); | 
|  | } | 
|  | protected bool IsTypeLine() | 
|  | { | 
|  | return ChartType == eChartType.Line || | 
|  | ChartType == eChartType.LineMarkers || | 
|  | ChartType == eChartType.LineMarkersStacked100 || | 
|  | ChartType == eChartType.LineStacked || | 
|  | ChartType == eChartType.LineStacked100 || | 
|  | ChartType == eChartType.Line3D; | 
|  | } | 
|  | protected bool IsTypeScatterBubble() | 
|  | { | 
|  | return ChartType == eChartType.XYScatter || | 
|  | ChartType == eChartType.XYScatterLines || | 
|  | ChartType == eChartType.XYScatterLinesNoMarkers || | 
|  | ChartType == eChartType.XYScatterSmooth || | 
|  | ChartType == eChartType.XYScatterSmoothNoMarkers || | 
|  | ChartType == eChartType.Bubble || | 
|  | ChartType == eChartType.Bubble3DEffect; | 
|  | } | 
|  | protected bool IsTypeSurface() | 
|  | { | 
|  | return ChartType == eChartType.Surface || | 
|  | ChartType == eChartType.SurfaceTopView || | 
|  | ChartType == eChartType.SurfaceTopViewWireframe || | 
|  | ChartType == eChartType.SurfaceWireframe; | 
|  | } | 
|  | protected bool IsTypeShape() | 
|  | { | 
|  | return ChartType == eChartType.BarClustered3D || | 
|  | ChartType == eChartType.BarStacked3D || | 
|  | ChartType == eChartType.BarStacked1003D || | 
|  | ChartType == eChartType.BarClustered3D || | 
|  | ChartType == eChartType.BarStacked3D || | 
|  | ChartType == eChartType.BarStacked1003D || | 
|  | ChartType == eChartType.Column3D || | 
|  | ChartType == eChartType.ColumnClustered3D || | 
|  | ChartType == eChartType.ColumnStacked3D || | 
|  | ChartType == eChartType.ColumnStacked1003D || | 
|  | //ChartType == eChartType.3DPie || | 
|  | //ChartType == eChartType.3DPieExploded || | 
|  | //ChartType == eChartType.Bubble3DEffect || | 
|  | ChartType == eChartType.ConeBarClustered || | 
|  | ChartType == eChartType.ConeBarStacked || | 
|  | ChartType == eChartType.ConeBarStacked100 || | 
|  | ChartType == eChartType.ConeCol || | 
|  | ChartType == eChartType.ConeColClustered || | 
|  | ChartType == eChartType.ConeColStacked || | 
|  | ChartType == eChartType.ConeColStacked100 || | 
|  | ChartType == eChartType.CylinderBarClustered || | 
|  | ChartType == eChartType.CylinderBarStacked || | 
|  | ChartType == eChartType.CylinderBarStacked100 || | 
|  | ChartType == eChartType.CylinderCol || | 
|  | ChartType == eChartType.CylinderColClustered || | 
|  | ChartType == eChartType.CylinderColStacked || | 
|  | ChartType == eChartType.CylinderColStacked100 || | 
|  | ChartType == eChartType.PyramidBarClustered || | 
|  | ChartType == eChartType.PyramidBarStacked || | 
|  | ChartType == eChartType.PyramidBarStacked100 || | 
|  | ChartType == eChartType.PyramidCol || | 
|  | ChartType == eChartType.PyramidColClustered || | 
|  | ChartType == eChartType.PyramidColStacked || | 
|  | ChartType == eChartType.PyramidColStacked100; //|| | 
|  | //ChartType == eChartType.Doughnut || | 
|  | //ChartType == eChartType.DoughnutExploded; | 
|  | } | 
|  | protected internal bool IsTypePercentStacked() | 
|  | { | 
|  | return ChartType == eChartType.AreaStacked100 || | 
|  | ChartType == eChartType.BarStacked100 || | 
|  | ChartType == eChartType.BarStacked1003D || | 
|  | ChartType == eChartType.ColumnStacked100 || | 
|  | ChartType == eChartType.ColumnStacked1003D || | 
|  | ChartType == eChartType.ConeBarStacked100 || | 
|  | ChartType == eChartType.ConeColStacked100 || | 
|  | ChartType == eChartType.CylinderBarStacked100 || | 
|  | ChartType == eChartType.CylinderColStacked || | 
|  | ChartType == eChartType.LineMarkersStacked100 || | 
|  | ChartType == eChartType.LineStacked100 || | 
|  | ChartType == eChartType.PyramidBarStacked100 || | 
|  | ChartType == eChartType.PyramidColStacked100; | 
|  | } | 
|  | protected internal bool IsTypeStacked() | 
|  | { | 
|  | return ChartType == eChartType.AreaStacked || | 
|  | ChartType == eChartType.AreaStacked3D || | 
|  | ChartType == eChartType.BarStacked || | 
|  | ChartType == eChartType.BarStacked3D || | 
|  | ChartType == eChartType.ColumnStacked3D || | 
|  | ChartType == eChartType.ColumnStacked || | 
|  | ChartType == eChartType.ConeBarStacked || | 
|  | ChartType == eChartType.ConeColStacked || | 
|  | ChartType == eChartType.CylinderBarStacked || | 
|  | ChartType == eChartType.CylinderColStacked || | 
|  | ChartType == eChartType.LineMarkersStacked || | 
|  | ChartType == eChartType.LineStacked || | 
|  | ChartType == eChartType.PyramidBarStacked || | 
|  | ChartType == eChartType.PyramidColStacked; | 
|  | } | 
|  | protected bool IsTypeClustered() | 
|  | { | 
|  | return ChartType == eChartType.BarClustered || | 
|  | ChartType == eChartType.BarClustered3D || | 
|  | ChartType == eChartType.ColumnClustered3D || | 
|  | ChartType == eChartType.ColumnClustered || | 
|  | ChartType == eChartType.ConeBarClustered || | 
|  | ChartType == eChartType.ConeColClustered || | 
|  | ChartType == eChartType.CylinderBarClustered || | 
|  | ChartType == eChartType.CylinderColClustered || | 
|  | ChartType == eChartType.PyramidBarClustered || | 
|  | ChartType == eChartType.PyramidColClustered; | 
|  | } | 
|  | protected internal bool IsTypePieDoughnut() | 
|  | { | 
|  | return ChartType == eChartType.Pie || | 
|  | ChartType == eChartType.PieExploded || | 
|  | ChartType == eChartType.PieOfPie || | 
|  | ChartType == eChartType.Pie3D || | 
|  | ChartType == eChartType.PieExploded3D || | 
|  | ChartType == eChartType.BarOfPie || | 
|  | ChartType == eChartType.Doughnut || | 
|  | ChartType == eChartType.DoughnutExploded; | 
|  | } | 
|  | #endregion | 
|  | /// <summary> | 
|  | /// Get the name of the chart node | 
|  | /// </summary> | 
|  | /// <returns>The name</returns> | 
|  | protected string GetChartNodeText() | 
|  | { | 
|  | switch (ChartType) | 
|  | { | 
|  | case eChartType.Area3D: | 
|  | case eChartType.AreaStacked3D: | 
|  | case eChartType.AreaStacked1003D: | 
|  | return "c:area3DChart"; | 
|  | case eChartType.Area: | 
|  | case eChartType.AreaStacked: | 
|  | case eChartType.AreaStacked100: | 
|  | return "c:areaChart"; | 
|  | case eChartType.BarClustered: | 
|  | case eChartType.BarStacked: | 
|  | case eChartType.BarStacked100: | 
|  | case eChartType.ColumnClustered: | 
|  | case eChartType.ColumnStacked: | 
|  | case eChartType.ColumnStacked100: | 
|  | return "c:barChart"; | 
|  | case eChartType.BarClustered3D: | 
|  | case eChartType.BarStacked3D: | 
|  | case eChartType.BarStacked1003D: | 
|  | case eChartType.ColumnClustered3D: | 
|  | case eChartType.ColumnStacked3D: | 
|  | case eChartType.ColumnStacked1003D: | 
|  | case eChartType.ConeBarClustered: | 
|  | case eChartType.ConeBarStacked: | 
|  | case eChartType.ConeBarStacked100: | 
|  | case eChartType.ConeCol: | 
|  | case eChartType.ConeColClustered: | 
|  | case eChartType.ConeColStacked: | 
|  | case eChartType.ConeColStacked100: | 
|  | case eChartType.CylinderBarClustered: | 
|  | case eChartType.CylinderBarStacked: | 
|  | case eChartType.CylinderBarStacked100: | 
|  | case eChartType.CylinderCol: | 
|  | case eChartType.CylinderColClustered: | 
|  | case eChartType.CylinderColStacked: | 
|  | case eChartType.CylinderColStacked100: | 
|  | case eChartType.PyramidBarClustered: | 
|  | case eChartType.PyramidBarStacked: | 
|  | case eChartType.PyramidBarStacked100: | 
|  | case eChartType.PyramidCol: | 
|  | case eChartType.PyramidColClustered: | 
|  | case eChartType.PyramidColStacked: | 
|  | case eChartType.PyramidColStacked100: | 
|  | return "c:bar3DChart"; | 
|  | case eChartType.Bubble: | 
|  | case eChartType.Bubble3DEffect: | 
|  | return "c:bubbleChart"; | 
|  | case eChartType.Doughnut: | 
|  | case eChartType.DoughnutExploded: | 
|  | return "c:doughnutChart"; | 
|  | case eChartType.Line: | 
|  | case eChartType.LineMarkers: | 
|  | case eChartType.LineMarkersStacked: | 
|  | case eChartType.LineMarkersStacked100: | 
|  | case eChartType.LineStacked: | 
|  | case eChartType.LineStacked100: | 
|  | return "c:lineChart"; | 
|  | case eChartType.Line3D: | 
|  | return "c:line3DChart"; | 
|  | case eChartType.Pie: | 
|  | case eChartType.PieExploded: | 
|  | return "c:pieChart"; | 
|  | case eChartType.BarOfPie: | 
|  | case eChartType.PieOfPie: | 
|  | return "c:ofPieChart"; | 
|  | case eChartType.Pie3D: | 
|  | case eChartType.PieExploded3D: | 
|  | return "c:pie3DChart"; | 
|  | case eChartType.Radar: | 
|  | case eChartType.RadarFilled: | 
|  | case eChartType.RadarMarkers: | 
|  | return "c:radarChart"; | 
|  | case eChartType.XYScatter: | 
|  | case eChartType.XYScatterLines: | 
|  | case eChartType.XYScatterLinesNoMarkers: | 
|  | case eChartType.XYScatterSmooth: | 
|  | case eChartType.XYScatterSmoothNoMarkers: | 
|  | return "c:scatterChart"; | 
|  | case eChartType.Surface: | 
|  | case eChartType.SurfaceWireframe: | 
|  | return "c:surface3DChart"; | 
|  | case eChartType.SurfaceTopView: | 
|  | case eChartType.SurfaceTopViewWireframe: | 
|  | return "c:surfaceChart"; | 
|  | case eChartType.StockHLC: | 
|  | return "c:stockChart"; | 
|  | default: | 
|  | throw(new NotImplementedException("Chart type not implemented")); | 
|  | } | 
|  | } | 
|  | /// <summary> | 
|  | /// Add a secondary axis | 
|  | /// </summary> | 
|  | internal void AddAxis() | 
|  | { | 
|  | XmlElement catAx = ChartXml.CreateElement(string.Format("c:{0}",AddAxType()), ExcelPackage.schemaChart); | 
|  | int axID; | 
|  | if (_axis.Length == 0) | 
|  | { | 
|  | _plotArea.TopNode.AppendChild(catAx); | 
|  | axID = 1; | 
|  | } | 
|  | else | 
|  | { | 
|  | _axis[0].TopNode.ParentNode.InsertAfter(catAx, _axis[_axis.Length-1].TopNode); | 
|  | axID = int.Parse(_axis[0].Id) < int.Parse(_axis[1].Id) ? int.Parse(_axis[1].Id) + 1 : int.Parse(_axis[0].Id) + 1; | 
|  | } | 
|  |  | 
|  |  | 
|  | XmlElement valAx = ChartXml.CreateElement("c:valAx", ExcelPackage.schemaChart); | 
|  | catAx.ParentNode.InsertAfter(valAx, catAx); | 
|  |  | 
|  | if (_axis.Length == 0) | 
|  | { | 
|  | catAx.InnerXml = string.Format("<c:axId val=\"{0}\"/><c:scaling><c:orientation val=\"minMax\"/></c:scaling><c:delete val=\"0\" /><c:axPos val=\"b\"/><c:tickLblPos val=\"nextTo\"/><c:crossAx val=\"{1}\"/><c:crosses val=\"autoZero\"/><c:auto val=\"1\"/><c:lblAlgn val=\"ctr\"/><c:lblOffset val=\"100\"/>", axID, axID + 1); | 
|  | valAx.InnerXml = string.Format("<c:axId val=\"{1}\"/><c:scaling><c:orientation val=\"minMax\"/></c:scaling><c:delete val=\"0\" /><c:axPos val=\"l\"/><c:majorGridlines/><c:tickLblPos val=\"nextTo\"/><c:crossAx val=\"{0}\"/><c:crosses val=\"autoZero\"/><c:crossBetween val=\"between\"/>", axID, axID + 1); | 
|  | } | 
|  | else | 
|  | { | 
|  | catAx.InnerXml = string.Format("<c:axId val=\"{0}\"/><c:scaling><c:orientation val=\"minMax\"/></c:scaling><c:delete val=\"1\" /><c:axPos val=\"b\"/><c:tickLblPos val=\"none\"/><c:crossAx val=\"{1}\"/><c:crosses val=\"autoZero\"/>", axID, axID + 1); | 
|  | valAx.InnerXml = string.Format("<c:axId val=\"{0}\"/><c:scaling><c:orientation val=\"minMax\"/></c:scaling><c:delete val=\"0\" /><c:axPos val=\"r\"/><c:tickLblPos val=\"nextTo\"/><c:crossAx val=\"{1}\"/><c:crosses val=\"max\"/><c:crossBetween val=\"between\"/>", axID + 1, axID); | 
|  | } | 
|  |  | 
|  | if (_axis.Length == 0) | 
|  | { | 
|  | _axis = new ExcelChartAxis[2]; | 
|  | } | 
|  | else | 
|  | { | 
|  | ExcelChartAxis[] newAxis = new ExcelChartAxis[_axis.Length + 2]; | 
|  | Array.Copy(_axis, newAxis, _axis.Length); | 
|  | _axis = newAxis; | 
|  | } | 
|  |  | 
|  | _axis[_axis.Length - 2] = new ExcelChartAxis(NameSpaceManager, catAx); | 
|  | _axis[_axis.Length - 1] = new ExcelChartAxis(NameSpaceManager, valAx); | 
|  | foreach (var chart in _plotArea.ChartTypes) | 
|  | { | 
|  | chart._axis = _axis; | 
|  | } | 
|  | } | 
|  | internal void RemoveSecondaryAxis() | 
|  | { | 
|  | throw (new NotImplementedException("Not yet implemented")); | 
|  | } | 
|  | #region "Properties" | 
|  | /// <summary> | 
|  | /// Reference to the worksheet | 
|  | /// </summary> | 
|  | public ExcelWorksheet WorkSheet { get; internal set; } | 
|  | /// <summary> | 
|  | /// The chart xml document | 
|  | /// </summary> | 
|  | public XmlDocument ChartXml { get; internal set; } | 
|  | /// <summary> | 
|  | /// Type of chart | 
|  | /// </summary> | 
|  | public eChartType ChartType { get; internal set; } | 
|  | internal protected XmlNode _chartNode = null; | 
|  | internal XmlNode ChartNode | 
|  | { | 
|  | get | 
|  | { | 
|  | return _chartNode; | 
|  | } | 
|  | } | 
|  | /// <summary> | 
|  | /// Titel of the chart | 
|  | /// </summary> | 
|  | public ExcelChartTitle Title | 
|  | { | 
|  | get | 
|  | { | 
|  | if (_title == null) | 
|  | { | 
|  | _title = new ExcelChartTitle(NameSpaceManager, ChartXml.SelectSingleNode("c:chartSpace/c:chart", NameSpaceManager)); | 
|  | } | 
|  | return _title; | 
|  | } | 
|  | } | 
|  | /// <summary> | 
|  | /// Chart series | 
|  | /// </summary> | 
|  | public virtual ExcelChartSeries Series | 
|  | { | 
|  | get | 
|  | { | 
|  | return _chartSeries; | 
|  | } | 
|  | } | 
|  | /// <summary> | 
|  | /// An array containg all axis of all Charttypes | 
|  | /// </summary> | 
|  | public ExcelChartAxis[] Axis | 
|  | { | 
|  | get | 
|  | { | 
|  | return _axis; | 
|  | } | 
|  | } | 
|  | /// <summary> | 
|  | /// The XAxis | 
|  | /// </summary> | 
|  | public ExcelChartAxis XAxis | 
|  | { | 
|  | get; | 
|  | private set; | 
|  | } | 
|  | /// <summary> | 
|  | /// The YAxis | 
|  | /// </summary> | 
|  | public ExcelChartAxis YAxis | 
|  | { | 
|  | get; | 
|  | private set; | 
|  | } | 
|  | bool _secondaryAxis=false; | 
|  | /// <summary> | 
|  | /// If true the charttype will use the secondary axis. | 
|  | /// The chart must contain a least one other charttype that uses the primary axis. | 
|  | /// </summary> | 
|  | public bool UseSecondaryAxis | 
|  | { | 
|  | get | 
|  | { | 
|  | return _secondaryAxis; | 
|  | } | 
|  | set | 
|  | { | 
|  | if (_secondaryAxis != value) | 
|  | { | 
|  | if (value) | 
|  | { | 
|  | if (IsTypePieDoughnut()) | 
|  | { | 
|  | throw (new Exception("Pie charts do not support axis")); | 
|  | } | 
|  | else if (HasPrimaryAxis() == false) | 
|  | { | 
|  | throw (new Exception("Can't set to secondary axis when no serie uses the primary axis")); | 
|  | } | 
|  | if (Axis.Length == 2) | 
|  | { | 
|  | AddAxis(); | 
|  | } | 
|  | var nl = ChartNode.SelectNodes("c:axId", NameSpaceManager); | 
|  | nl[0].Attributes["val"].Value = Axis[2].Id; | 
|  | nl[1].Attributes["val"].Value = Axis[3].Id; | 
|  | XAxis = Axis[2]; | 
|  | YAxis = Axis[3]; | 
|  | } | 
|  | else | 
|  | { | 
|  | var nl = ChartNode.SelectNodes("c:axId", NameSpaceManager); | 
|  | nl[0].Attributes["val"].Value = Axis[0].Id; | 
|  | nl[1].Attributes["val"].Value = Axis[1].Id; | 
|  | XAxis = Axis[0]; | 
|  | YAxis = Axis[1]; | 
|  | } | 
|  | _secondaryAxis = value; | 
|  | } | 
|  | } | 
|  | } | 
|  | /// <summary> | 
|  | /// The build-in chart styles. | 
|  | /// </summary> | 
|  | public eChartStyle Style | 
|  | { | 
|  | get | 
|  | { | 
|  | XmlNode node = ChartXml.SelectSingleNode("c:chartSpace/c:style/@val", NameSpaceManager); | 
|  | if (node == null) | 
|  | { | 
|  | return eChartStyle.None; | 
|  | } | 
|  | else | 
|  | { | 
|  | int v; | 
|  | if (int.TryParse(node.Value, out v)) | 
|  | { | 
|  | return (eChartStyle)v; | 
|  | } | 
|  | else | 
|  | { | 
|  | return eChartStyle.None; | 
|  | } | 
|  | } | 
|  |  | 
|  | } | 
|  | set | 
|  | { | 
|  | if (value == eChartStyle.None) | 
|  | { | 
|  | XmlElement element = ChartXml.SelectSingleNode("c:chartSpace/c:style", NameSpaceManager) as XmlElement; | 
|  | if (element != null) | 
|  | { | 
|  | element.ParentNode.RemoveChild(element); | 
|  | } | 
|  | } | 
|  | else | 
|  | { | 
|  | XmlElement element = ChartXml.CreateElement("c:style", ExcelPackage.schemaChart); | 
|  | element.SetAttribute("val", ((int)value).ToString()); | 
|  | XmlElement parent = ChartXml.SelectSingleNode("c:chartSpace", NameSpaceManager) as XmlElement; | 
|  | parent.InsertBefore(element, parent.SelectSingleNode("c:chart", NameSpaceManager)); | 
|  | } | 
|  | } | 
|  | } | 
|  | const string _plotVisibleOnlyPath="../../c:plotVisOnly/@val"; | 
|  | /// <summary> | 
|  | /// Show data in hidden rows and columns | 
|  | /// </summary> | 
|  | public bool ShowHiddenData | 
|  | { | 
|  | get | 
|  | { | 
|  | //!!Inverted value!! | 
|  | return !_chartXmlHelper.GetXmlNodeBool(_plotVisibleOnlyPath); | 
|  | } | 
|  | set | 
|  | { | 
|  | //!!Inverted value!! | 
|  | _chartXmlHelper.SetXmlNodeBool(_plotVisibleOnlyPath, !value); | 
|  | } | 
|  | } | 
|  | const string _displayBlanksAsPath = "../../c:dispBlanksAs/@val"; | 
|  | /// <summary> | 
|  | /// Specifies the possible ways to display blanks | 
|  | /// </summary> | 
|  | public eDisplayBlanksAs DisplayBlanksAs | 
|  | { | 
|  | get | 
|  | { | 
|  | string v=_chartXmlHelper.GetXmlNodeString(_displayBlanksAsPath); | 
|  | if (string.IsNullOrEmpty(v)) | 
|  | { | 
|  | return eDisplayBlanksAs.Zero; //Issue 14715 Changed in Office 2010-? | 
|  | } | 
|  | else | 
|  | { | 
|  | return (eDisplayBlanksAs)Enum.Parse(typeof(eDisplayBlanksAs), v, true); | 
|  | } | 
|  | } | 
|  | set | 
|  | { | 
|  | _chartSeries.SetXmlNodeString(_displayBlanksAsPath, value.ToString().ToLower(CultureInfo.InvariantCulture)); | 
|  | } | 
|  | } | 
|  | const string _showDLblsOverMax = "../../c:showDLblsOverMax/@val"; | 
|  | /// <summary> | 
|  | /// Specifies data labels over the maximum of the chart shall be shown | 
|  | /// </summary> | 
|  | public bool ShowDataLabelsOverMaximum | 
|  | { | 
|  | get | 
|  | { | 
|  | return _chartXmlHelper.GetXmlNodeBool(_showDLblsOverMax, true); | 
|  | } | 
|  | set | 
|  | { | 
|  | _chartXmlHelper.SetXmlNodeBool(_showDLblsOverMax,value, true); | 
|  | } | 
|  | } | 
|  | private bool HasPrimaryAxis() | 
|  | { | 
|  | if (_plotArea.ChartTypes.Count == 1) | 
|  | { | 
|  | return false; | 
|  | } | 
|  | foreach (var chart in _plotArea.ChartTypes) | 
|  | { | 
|  | if (chart != this) | 
|  | { | 
|  | if (chart.UseSecondaryAxis == false && chart.IsTypePieDoughnut()==false) | 
|  | { | 
|  | return true; | 
|  | } | 
|  | } | 
|  | } | 
|  | return false; | 
|  | } | 
|  | ///// <summary> | 
|  | ///// Sets position of the axis of a chart-serie | 
|  | ///// </summary> | 
|  | ///// <param name="XAxis">Left or Right</param> | 
|  | ///// <param name="YAxis">Top or Bottom</param> | 
|  | //internal void SetAxis(eXAxisPosition XAxis, eYAxisPosition YAxis) | 
|  | //{ | 
|  | //    bool xAxisExists = false, yAxisExists = false; | 
|  | //    foreach (var axis in _axis) | 
|  | //    { | 
|  | //        if (axis.AxisPosition == (eAxisPosition)XAxis) | 
|  | //        { | 
|  | //            //Found | 
|  | //            xAxisExists=true; | 
|  | //            if (axis != this.XAxis) | 
|  | //            { | 
|  | //                CheckRemoveAxis(this.XAxis); | 
|  | //                this.XAxis = axis; | 
|  | //            } | 
|  | //        } | 
|  | //        else if (axis.AxisPosition == (eAxisPosition)YAxis) | 
|  | //        { | 
|  | //            yAxisExists = true; | 
|  | //            if (axis != this.YAxis) | 
|  | //            { | 
|  | //                CheckRemoveAxis(this.YAxis); | 
|  | //                this.YAxis = axis; | 
|  | //            } | 
|  | //        } | 
|  | //    } | 
|  |  | 
|  | //    if (!xAxisExists) | 
|  | //    { | 
|  | //        if (ExistsAxis(this.XAxis)) | 
|  | //        { | 
|  | //            AddAxis((eAxisPosition)XAxis); | 
|  | //            this.XAxis = Axis[Axis.Length - 1]; | 
|  | //        } | 
|  | //        else | 
|  | //        { | 
|  | //            this.XAxis.AxisPosition = (eAxisPosition)XAxis; | 
|  | //        } | 
|  | //    } | 
|  | //    if (!yAxisExists) | 
|  | //    { | 
|  | //        if (ExistsAxis(this.XAxis)) | 
|  | //        { | 
|  | //            AddAxis((eAxisPosition)YAxis); | 
|  | //            this.YAxis = Axis[Axis.Length - 1]; | 
|  | //        } | 
|  | //        else | 
|  | //        { | 
|  | //            this.YAxis.AxisPosition = (eAxisPosition)YAxis; | 
|  | //        } | 
|  | //    } | 
|  | //} | 
|  |  | 
|  | /// <summary> | 
|  | /// Remove all axis that are not used any more | 
|  | /// </summary> | 
|  | /// <param name="excelChartAxis"></param> | 
|  | private void CheckRemoveAxis(ExcelChartAxis excelChartAxis) | 
|  | { | 
|  | if (ExistsAxis(excelChartAxis)) | 
|  | { | 
|  | //Remove the axis | 
|  | ExcelChartAxis[] newAxis = new ExcelChartAxis[Axis.Length - 1]; | 
|  | int pos = 0; | 
|  | foreach (var ax in Axis) | 
|  | { | 
|  | if (ax != excelChartAxis) | 
|  | { | 
|  | newAxis[pos] = ax; | 
|  | } | 
|  | } | 
|  |  | 
|  | //Update all charttypes. | 
|  | foreach (ExcelChart chartType in _plotArea.ChartTypes) | 
|  | { | 
|  | chartType._axis = newAxis; | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | private bool ExistsAxis(ExcelChartAxis excelChartAxis) | 
|  | { | 
|  | foreach (ExcelChart chartType in _plotArea.ChartTypes) | 
|  | { | 
|  | if (chartType != this) | 
|  | { | 
|  | if (chartType.XAxis.AxisPosition == excelChartAxis.AxisPosition || | 
|  | chartType.YAxis.AxisPosition == excelChartAxis.AxisPosition) | 
|  | { | 
|  | //The axis exists | 
|  | return true; | 
|  | } | 
|  | } | 
|  | } | 
|  | return false; | 
|  | } | 
|  | ExcelChartPlotArea _plotArea = null; | 
|  | /// <summary> | 
|  | /// Plotarea | 
|  | /// </summary> | 
|  | public ExcelChartPlotArea PlotArea | 
|  | { | 
|  | get | 
|  | { | 
|  | if (_plotArea == null) | 
|  | { | 
|  | _plotArea = new ExcelChartPlotArea(NameSpaceManager, ChartXml.SelectSingleNode("c:chartSpace/c:chart/c:plotArea", NameSpaceManager), this); | 
|  | } | 
|  | return _plotArea; | 
|  | } | 
|  | } | 
|  | ExcelChartLegend _legend = null; | 
|  | /// <summary> | 
|  | /// Legend | 
|  | /// </summary> | 
|  | public ExcelChartLegend Legend | 
|  | { | 
|  | get | 
|  | { | 
|  | if (_legend == null) | 
|  | { | 
|  | _legend = new ExcelChartLegend(NameSpaceManager, ChartXml.SelectSingleNode("c:chartSpace/c:chart/c:legend", NameSpaceManager), this); | 
|  | } | 
|  | return _legend; | 
|  | } | 
|  |  | 
|  | } | 
|  | ExcelDrawingBorder _border = null; | 
|  | /// <summary> | 
|  | /// Border | 
|  | /// </summary> | 
|  | public ExcelDrawingBorder Border | 
|  | { | 
|  | get | 
|  | { | 
|  | if (_border == null) | 
|  | { | 
|  | _border = new ExcelDrawingBorder(NameSpaceManager, ChartXml.SelectSingleNode("c:chartSpace",NameSpaceManager), "c:spPr/a:ln"); | 
|  | } | 
|  | return _border; | 
|  | } | 
|  | } | 
|  | ExcelDrawingFill _fill = null; | 
|  | /// <summary> | 
|  | /// Fill | 
|  | /// </summary> | 
|  | public ExcelDrawingFill Fill | 
|  | { | 
|  | get | 
|  | { | 
|  | if (_fill == null) | 
|  | { | 
|  | _fill = new ExcelDrawingFill(NameSpaceManager, ChartXml.SelectSingleNode("c:chartSpace", NameSpaceManager), "c:spPr"); | 
|  | } | 
|  | return _fill; | 
|  | } | 
|  | } | 
|  | /// <summary> | 
|  | /// 3D-settings | 
|  | /// </summary> | 
|  | public ExcelView3D View3D | 
|  | { | 
|  | get | 
|  | { | 
|  | if (IsType3D()) | 
|  | { | 
|  | return new ExcelView3D(NameSpaceManager, ChartXml.SelectSingleNode("//c:view3D", NameSpaceManager)); | 
|  | } | 
|  | else | 
|  | { | 
|  | throw (new Exception("Charttype does not support 3D")); | 
|  | } | 
|  |  | 
|  | } | 
|  | } | 
|  | //string _groupingPath = "c:chartSpace/c:chart/c:plotArea/{0}/c:grouping/@val"; | 
|  | string _groupingPath = "c:grouping/@val"; | 
|  | public eGrouping Grouping | 
|  | { | 
|  | get | 
|  | { | 
|  | return GetGroupingEnum(_chartXmlHelper.GetXmlNodeString(_groupingPath)); | 
|  | } | 
|  | internal set | 
|  | { | 
|  | _chartXmlHelper.SetXmlNodeString(_groupingPath, GetGroupingText(value)); | 
|  | } | 
|  | } | 
|  | //string _varyColorsPath = "c:chartSpace/c:chart/c:plotArea/{0}/c:varyColors/@val"; | 
|  | string _varyColorsPath = "c:varyColors/@val"; | 
|  | /// <summary> | 
|  | /// If the chart has only one serie this varies the colors for each point. | 
|  | /// </summary> | 
|  | public bool VaryColors | 
|  | { | 
|  | get | 
|  | { | 
|  | return _chartXmlHelper.GetXmlNodeBool(_varyColorsPath); | 
|  | } | 
|  | set | 
|  | { | 
|  | if (value) | 
|  | { | 
|  | _chartXmlHelper.SetXmlNodeString(_varyColorsPath, "1"); | 
|  | } | 
|  | else | 
|  | { | 
|  | _chartXmlHelper.SetXmlNodeString(_varyColorsPath, "0"); | 
|  | } | 
|  | } | 
|  | } | 
|  | internal Packaging.ZipPackagePart Part { get; set; } | 
|  | /// <summary> | 
|  | /// Package internal URI | 
|  | /// </summary> | 
|  | internal Uri UriChart { get; set; } | 
|  | internal new string Id | 
|  | { | 
|  | get { return ""; } | 
|  | } | 
|  | ExcelChartTitle _title = null; | 
|  | #endregion | 
|  | #region "Grouping Enum Translation" | 
|  | private string GetGroupingText(eGrouping grouping) | 
|  | { | 
|  | switch (grouping) | 
|  | { | 
|  | case eGrouping.Clustered: | 
|  | return "clustered"; | 
|  | case eGrouping.Stacked: | 
|  | return "stacked"; | 
|  | case eGrouping.PercentStacked: | 
|  | return "percentStacked"; | 
|  | default: | 
|  | return "standard"; | 
|  |  | 
|  | } | 
|  | } | 
|  | private eGrouping GetGroupingEnum(string grouping) | 
|  | { | 
|  | switch (grouping) | 
|  | { | 
|  | case "stacked": | 
|  | return eGrouping.Stacked; | 
|  | case "percentStacked": | 
|  | return eGrouping.PercentStacked; | 
|  | default: //"clustered": | 
|  | return eGrouping.Clustered; | 
|  | } | 
|  | } | 
|  | #endregion | 
|  | internal static ExcelChart GetChart(ExcelDrawings drawings, XmlNode node/*, XmlNode chartTypeNode*/) | 
|  | { | 
|  | XmlNode chartNode = node.SelectSingleNode("xdr:graphicFrame/a:graphic/a:graphicData/c:chart", drawings.NameSpaceManager); | 
|  | if (chartNode != null) | 
|  | { | 
|  | var drawingRelation = drawings.Part.GetRelationship(chartNode.Attributes["r:id"].Value); | 
|  | var uriChart = UriHelper.ResolvePartUri(drawings.UriDrawing, drawingRelation.TargetUri); | 
|  |  | 
|  | var part = drawings.Part.Package.GetPart(uriChart); | 
|  | var chartXml = new XmlDocument(); | 
|  | LoadXmlSafe(chartXml, part.GetStream()); | 
|  |  | 
|  | ExcelChart topChart = null; | 
|  | foreach (XmlElement n in chartXml.SelectSingleNode(rootPath, drawings.NameSpaceManager).ChildNodes) | 
|  | { | 
|  | if (topChart == null) | 
|  | { | 
|  | topChart = GetChart(n, drawings, node, uriChart, part, chartXml, null); | 
|  | if(topChart!=null) | 
|  | { | 
|  | topChart.PlotArea.ChartTypes.Add(topChart); | 
|  | } | 
|  | } | 
|  | else | 
|  | { | 
|  | var subChart = GetChart(n, null, null, null, null, null, topChart); | 
|  | if (subChart != null) | 
|  | { | 
|  | topChart.PlotArea.ChartTypes.Add(subChart); | 
|  | } | 
|  | } | 
|  | } | 
|  | return topChart; | 
|  | } | 
|  | else | 
|  | { | 
|  | return null; | 
|  | } | 
|  | } | 
|  | internal static ExcelChart GetChart(XmlElement chartNode, ExcelDrawings drawings, XmlNode node,  Uri uriChart, Packaging.ZipPackagePart part, XmlDocument chartXml, ExcelChart topChart) | 
|  | { | 
|  | switch (chartNode.LocalName) | 
|  | { | 
|  | case "area3DChart": | 
|  | case "areaChart": | 
|  | case "stockChart": | 
|  | if (topChart == null) | 
|  | { | 
|  | return new ExcelChart(drawings, node, uriChart, part, chartXml, chartNode); | 
|  | } | 
|  | else | 
|  | { | 
|  | return new ExcelChart(topChart, chartNode); | 
|  | } | 
|  | case "surface3DChart": | 
|  | case "surfaceChart": | 
|  | if (topChart == null) | 
|  | { | 
|  | return new ExcelSurfaceChart(drawings, node, uriChart, part, chartXml, chartNode); | 
|  | } | 
|  | else | 
|  | { | 
|  | return new ExcelSurfaceChart(topChart, chartNode); | 
|  | } | 
|  | case "radarChart": | 
|  | if (topChart == null) | 
|  | { | 
|  | return new ExcelRadarChart(drawings, node, uriChart, part, chartXml, chartNode); | 
|  | } | 
|  | else | 
|  | { | 
|  | return new ExcelRadarChart(topChart, chartNode); | 
|  | } | 
|  | case "bubbleChart": | 
|  | if (topChart == null) | 
|  | { | 
|  | return new ExcelBubbleChart(drawings, node, uriChart, part, chartXml, chartNode); | 
|  | } | 
|  | else | 
|  | { | 
|  | return new ExcelBubbleChart(topChart, chartNode); | 
|  | } | 
|  | case "barChart": | 
|  | case "bar3DChart": | 
|  | if (topChart == null) | 
|  | { | 
|  | return new ExcelBarChart(drawings, node, uriChart, part, chartXml, chartNode); | 
|  | } | 
|  | else | 
|  | { | 
|  | return new ExcelBarChart(topChart, chartNode); | 
|  | } | 
|  | case "doughnutChart": | 
|  | if (topChart == null) | 
|  | { | 
|  | return new ExcelDoughnutChart(drawings, node, uriChart, part, chartXml, chartNode); | 
|  | } | 
|  | else | 
|  | { | 
|  | return new ExcelDoughnutChart(topChart, chartNode); | 
|  | } | 
|  | case "pie3DChart": | 
|  | case "pieChart": | 
|  | if (topChart == null) | 
|  | { | 
|  | return new ExcelPieChart(drawings, node, uriChart, part, chartXml, chartNode); | 
|  | } | 
|  | else | 
|  | { | 
|  | return new ExcelPieChart(topChart, chartNode); | 
|  | } | 
|  | case "ofPieChart": | 
|  | if (topChart == null) | 
|  | { | 
|  | return new ExcelOfPieChart(drawings, node, uriChart, part, chartXml, chartNode); | 
|  | } | 
|  | else | 
|  | { | 
|  | return new ExcelBarChart(topChart, chartNode); | 
|  | } | 
|  | case "lineChart": | 
|  | case "line3DChart": | 
|  | if (topChart == null) | 
|  | { | 
|  | return new ExcelLineChart(drawings, node, uriChart, part, chartXml, chartNode); | 
|  | } | 
|  | else | 
|  | { | 
|  | return new ExcelLineChart(topChart, chartNode); | 
|  | } | 
|  | case "scatterChart": | 
|  | if (topChart == null) | 
|  | { | 
|  | return new ExcelScatterChart(drawings, node, uriChart, part, chartXml, chartNode); | 
|  | } | 
|  | else | 
|  | { | 
|  | return new ExcelScatterChart(topChart, chartNode); | 
|  | } | 
|  | default: | 
|  | return null; | 
|  | } | 
|  | } | 
|  | internal static ExcelChart GetNewChart(ExcelDrawings drawings, XmlNode drawNode, eChartType chartType, ExcelChart topChart, ExcelPivotTable PivotTableSource) | 
|  | { | 
|  | switch(chartType) | 
|  | { | 
|  | case eChartType.Pie: | 
|  | case eChartType.PieExploded: | 
|  | case eChartType.Pie3D: | 
|  | case eChartType.PieExploded3D: | 
|  | return new ExcelPieChart(drawings, drawNode, chartType, topChart, PivotTableSource); | 
|  | case eChartType.BarOfPie: | 
|  | case eChartType.PieOfPie: | 
|  | return new ExcelOfPieChart(drawings, drawNode, chartType, topChart, PivotTableSource); | 
|  | case eChartType.Doughnut: | 
|  | case eChartType.DoughnutExploded: | 
|  | return new ExcelDoughnutChart(drawings, drawNode, chartType, topChart, PivotTableSource); | 
|  | case eChartType.BarClustered: | 
|  | case eChartType.BarStacked: | 
|  | case eChartType.BarStacked100: | 
|  | case eChartType.BarClustered3D: | 
|  | case eChartType.BarStacked3D: | 
|  | case eChartType.BarStacked1003D: | 
|  | case eChartType.ConeBarClustered: | 
|  | case eChartType.ConeBarStacked: | 
|  | case eChartType.ConeBarStacked100: | 
|  | case eChartType.CylinderBarClustered: | 
|  | case eChartType.CylinderBarStacked: | 
|  | case eChartType.CylinderBarStacked100: | 
|  | case eChartType.PyramidBarClustered: | 
|  | case eChartType.PyramidBarStacked: | 
|  | case eChartType.PyramidBarStacked100: | 
|  | case eChartType.ColumnClustered: | 
|  | case eChartType.ColumnStacked: | 
|  | case eChartType.ColumnStacked100: | 
|  | case eChartType.Column3D: | 
|  | case eChartType.ColumnClustered3D: | 
|  | case eChartType.ColumnStacked3D: | 
|  | case eChartType.ColumnStacked1003D: | 
|  | case eChartType.ConeCol: | 
|  | case eChartType.ConeColClustered: | 
|  | case eChartType.ConeColStacked: | 
|  | case eChartType.ConeColStacked100: | 
|  | case eChartType.CylinderCol: | 
|  | case eChartType.CylinderColClustered: | 
|  | case eChartType.CylinderColStacked: | 
|  | case eChartType.CylinderColStacked100: | 
|  | case eChartType.PyramidCol: | 
|  | case eChartType.PyramidColClustered: | 
|  | case eChartType.PyramidColStacked: | 
|  | case eChartType.PyramidColStacked100: | 
|  | return new ExcelBarChart(drawings, drawNode, chartType, topChart, PivotTableSource); | 
|  | case eChartType.XYScatter: | 
|  | case eChartType.XYScatterLines: | 
|  | case eChartType.XYScatterLinesNoMarkers: | 
|  | case eChartType.XYScatterSmooth: | 
|  | case eChartType.XYScatterSmoothNoMarkers: | 
|  | return new ExcelScatterChart(drawings, drawNode, chartType, topChart, PivotTableSource); | 
|  | case eChartType.Line: | 
|  | case eChartType.Line3D: | 
|  | case eChartType.LineMarkers: | 
|  | case eChartType.LineMarkersStacked: | 
|  | case eChartType.LineMarkersStacked100: | 
|  | case eChartType.LineStacked: | 
|  | case eChartType.LineStacked100: | 
|  | return new ExcelLineChart(drawings, drawNode, chartType, topChart, PivotTableSource); | 
|  | case eChartType.Bubble: | 
|  | case eChartType.Bubble3DEffect: | 
|  | return new ExcelBubbleChart(drawings, drawNode, chartType, topChart, PivotTableSource); | 
|  | case eChartType.Radar: | 
|  | case eChartType.RadarFilled: | 
|  | case eChartType.RadarMarkers: | 
|  | return new ExcelRadarChart(drawings, drawNode, chartType, topChart, PivotTableSource); | 
|  | case eChartType.Surface: | 
|  | case eChartType.SurfaceTopView: | 
|  | case eChartType.SurfaceTopViewWireframe: | 
|  | case eChartType.SurfaceWireframe: | 
|  | return new ExcelSurfaceChart(drawings, drawNode, chartType, topChart, PivotTableSource); | 
|  | default: | 
|  | return new ExcelChart(drawings, drawNode, chartType, topChart, PivotTableSource); | 
|  | } | 
|  | } | 
|  | public ExcelPivotTable PivotTableSource | 
|  | { | 
|  | get; | 
|  | private set; | 
|  | } | 
|  | internal void SetPivotSource(ExcelPivotTable pivotTableSource) | 
|  | { | 
|  | PivotTableSource = pivotTableSource; | 
|  | XmlElement chart = ChartXml.SelectSingleNode("c:chartSpace/c:chart", NameSpaceManager) as XmlElement; | 
|  |  | 
|  | var pivotSource = ChartXml.CreateElement("pivotSource", ExcelPackage.schemaChart); | 
|  | chart.ParentNode.InsertBefore(pivotSource, chart); | 
|  | pivotSource.InnerXml = string.Format("<c:name>[]{0}!{1}</c:name><c:fmtId val=\"0\"/>", PivotTableSource.WorkSheet.Name, pivotTableSource.Name); | 
|  |  | 
|  | var fmts = ChartXml.CreateElement("pivotFmts", ExcelPackage.schemaChart); | 
|  | chart.PrependChild(fmts); | 
|  | fmts.InnerXml = "<c:pivotFmt><c:idx val=\"0\"/><c:marker><c:symbol val=\"none\"/></c:marker></c:pivotFmt>"; | 
|  |  | 
|  | Series.AddPivotSerie(pivotTableSource); | 
|  | } | 
|  | internal override void DeleteMe() | 
|  | { | 
|  | try | 
|  | { | 
|  | Part.Package.DeletePart(UriChart); | 
|  | } | 
|  | catch (Exception ex) | 
|  | { | 
|  | throw (new InvalidDataException("EPPlus internal error when deleteing chart.", ex)); | 
|  | } | 
|  | base.DeleteMe(); | 
|  | } | 
|  | } | 
|  | } |