Free cookie consent management tool by TermsFeed Policy Generator

source: stable/HeuristicLab.ExtLibs/HeuristicLab.EPPlus/4.0.3/EPPlus-4.0.3/Drawing/Chart/ExcelChart.cs @ 13400

Last change on this file since 13400 was 12074, checked in by sraggl, 9 years ago

#2341: Added EPPlus-4.0.3 to ExtLibs

File size: 74.3 KB
Line 
1/*******************************************************************************
2 * You may amend and distribute as you like, but don't remove this header!
3 *
4 * EPPlus provides server-side generation of Excel 2007/2010 spreadsheets.
5 * See http://www.codeplex.com/EPPlus for details.
6 *
7 * Copyright (C) 2011  Jan Källman
8 *
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
13
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
17 * See the GNU Lesser General Public License for more details.
18 *
19 * The GNU Lesser General Public License can be viewed at http://www.opensource.org/licenses/lgpl-license.php
20 * If you unfamiliar with this license or have questions about it, here is an http://www.gnu.org/licenses/gpl-faq.html
21 *
22 * All code and executables are provided "as is" with no warranty either express or implied.
23 * The author accepts no liability for any damage or loss of business that this product may cause.
24 *
25 * Code change notes:
26 *
27 * Author             Change            Date
28 *******************************************************************************
29 * Jan Källman    Added   2009-10-01
30 * Jan Källman    License changed GPL-->LGPL 2011-12-16
31 *******************************************************************************/
32using System;
33using System.Collections.Generic;
34using System.Globalization;
35using System.Text;
36using System.Xml;
37using System.IO;
38using OfficeOpenXml.Table.PivotTable;
39using OfficeOpenXml.Utils;
40using OfficeOpenXml.Packaging;
41
42namespace OfficeOpenXml.Drawing.Chart
43{
44    #region "Chart Enums"
45    /// <summary>
46    /// Chart type
47    /// </summary>
48    public enum eChartType
49    {
50        Area3D=-4098,
51        AreaStacked3D=78,
52        AreaStacked1003D=79,
53        BarClustered3D= 60,
54        BarStacked3D=61,
55        BarStacked1003D=62,
56        Column3D=-4100,
57        ColumnClustered3D=54,
58        ColumnStacked3D=55,
59        ColumnStacked1003D=56,
60        Line3D=-4101,
61        Pie3D=-4102,
62        PieExploded3D=70,
63        Area=1,
64        AreaStacked=76,
65        AreaStacked100=77,
66        BarClustered=57,
67        BarOfPie=71,
68        BarStacked=58,
69        BarStacked100=59,
70        Bubble=15,
71        Bubble3DEffect=87,
72        ColumnClustered=51,
73        ColumnStacked=52,
74        ColumnStacked100=53,
75        ConeBarClustered=102,
76        ConeBarStacked=103,
77        ConeBarStacked100=104,
78        ConeCol=105,
79        ConeColClustered=99,
80        ConeColStacked=100,
81        ConeColStacked100=101,
82        CylinderBarClustered=95,
83        CylinderBarStacked=96,
84        CylinderBarStacked100=97,
85        CylinderCol=98,
86        CylinderColClustered=92,
87        CylinderColStacked=93,
88        CylinderColStacked100=94,
89        Doughnut=-4120,
90        DoughnutExploded=80,
91        Line=4,
92        LineMarkers=65,
93        LineMarkersStacked=66,
94        LineMarkersStacked100=67,
95        LineStacked=63,
96        LineStacked100=64,
97        Pie=5,
98        PieExploded=69,
99        PieOfPie=68,
100        PyramidBarClustered=109,
101        PyramidBarStacked=110,
102        PyramidBarStacked100=111,
103        PyramidCol=112,
104        PyramidColClustered=106,
105        PyramidColStacked=107,
106        PyramidColStacked100=108,
107        Radar=-4151,
108        RadarFilled=82,
109        RadarMarkers=81,
110        StockHLC=88,
111        StockOHLC=89,
112        StockVHLC=90,
113        StockVOHLC=91,
114        Surface=83,
115        SurfaceTopView=85,
116        SurfaceTopViewWireframe=86,
117        SurfaceWireframe=84,
118        XYScatter=-4169,
119        XYScatterLines=74,
120        XYScatterLinesNoMarkers=75,
121        XYScatterSmooth=72,
122        XYScatterSmoothNoMarkers=73
123}
124    /// <summary>
125    /// Bar or column
126    /// </summary>
127    public enum eDirection
128    {
129        Column,
130        Bar
131    }
132    /// <summary>
133    /// How the series are grouped
134    /// </summary>
135    public enum eGrouping
136    {
137        Standard,
138        Clustered,
139        Stacked,
140        PercentStacked
141    }
142    /// <summary>
143    /// Shape for bar charts
144    /// </summary>
145    public enum eShape
146    {
147        Box,
148        Cone,
149        ConeToMax,
150        Cylinder,
151        Pyramid,
152        PyramidToMax
153    }
154    /// <summary>
155    /// Smooth or lines markers
156    /// </summary>
157    public enum eScatterStyle
158    {
159        LineMarker,
160        SmoothMarker,
161     }
162    public enum eRadarStyle
163    {
164        /// <summary>
165        /// Specifies that the radar chart shall be filled and have lines but no markers.
166        /// </summary>
167        Filled,
168        /// <summary>
169        /// Specifies that the radar chart shall have lines and markers but no fill.
170        /// </summary>
171        Marker,
172        /// <summary>
173        /// Specifies that the radar chart shall have lines but no markers and no fill.
174        /// </summary>
175        Standard
176    }
177    /// <summary>
178    /// Bar or pie
179    /// </summary>
180    public enum ePieType
181    {
182        Bar,
183        Pie
184    }
185    /// <summary>
186    /// Position of the labels
187    /// </summary>
188    public enum eLabelPosition
189    {
190        BestFit,
191        Left,
192        Right,
193        Center,
194        Top,
195        Bottom,
196        InBase,
197        InEnd,
198        OutEnd
199    }
200    /// <summary>
201    /// Axis label position
202    /// </summary>
203    public enum eTickLabelPosition
204    {
205        High,
206        Low,
207        NextTo,
208        None
209    }
210    /// <summary>
211    /// Markerstyle
212    /// </summary>
213    public enum eMarkerStyle
214    {       
215        Circle,
216        Dash,
217        Diamond,
218        Dot,
219        None,
220        Picture,
221        Plus,
222        Square,
223        Star,
224        Triangle,
225        X,
226    }
227    /// <summary>
228    /// The build in style of the chart.
229    /// </summary>
230    public enum eChartStyle
231    {
232        None,
233        Style1,
234        Style2,
235        Style3,
236        Style4,
237        Style5,
238        Style6,
239        Style7,
240        Style8,
241        Style9,
242        Style10,
243        Style11,
244        Style12,
245        Style13,
246        Style14,
247        Style15,
248        Style16,
249        Style17,
250        Style18,
251        Style19,
252        Style20,
253        Style21,
254        Style22,
255        Style23,
256        Style24,
257        Style25,
258        Style26,
259        Style27,
260        Style28,
261        Style29,
262        Style30,
263        Style31,
264        Style32,
265        Style33,
266        Style34,
267        Style35,
268        Style36,
269        Style37,
270        Style38,
271        Style39,
272        Style40,
273        Style41,
274        Style42,
275        Style43,
276        Style44,
277        Style45,
278        Style46,
279        Style47,
280        Style48
281    }
282    /// <summary>
283    /// Type of Trendline for a chart
284    /// </summary>
285    public enum eTrendLine
286    {
287        /// <summary>
288        /// Specifies the trendline shall be an exponential curve in the form
289        /// </summary>
290        Exponential,
291        /// <summary>
292        /// Specifies the trendline shall be a logarithmic curve in the form , where log is the natural
293        /// </summary>
294        Linear,
295        /// <summary>
296        /// Specifies the trendline shall be a logarithmic curve in the form , where log is the natural
297        /// </summary>
298        Logarithmic,
299        /// <summary>
300        /// Specifies the trendline shall be a moving average of period Period
301        /// </summary>
302        MovingAvgerage,
303        /// <summary>
304        /// Specifies the trendline shall be a polynomial curve of order Order in the form
305        /// </summary>
306        Polynomial,
307        /// <summary>
308        /// Specifies the trendline shall be a power curve in the form
309        /// </summary>
310        Power
311    }
312    /// <summary>
313    /// Specifies the possible ways to display blanks
314    /// </summary>
315    public enum eDisplayBlanksAs
316    {
317        /// <summary>
318        /// Blank values shall be left as a gap
319        /// </summary>
320        Gap,
321        /// <summary>
322        /// Blank values shall be spanned with a line (Line charts)
323        /// </summary>
324        Span,
325        /// <summary>
326        /// Blank values shall be treated as zero
327        /// </summary>
328        Zero
329    }
330    public enum eSizeRepresents
331    {
332        /// <summary>
333        /// Specifies the area of the bubbles shall be proportional to the bubble size value.
334        /// </summary>
335        Area,
336        /// <summary>
337        /// Specifies the radius of the bubbles shall be proportional to the bubble size value.
338        /// </summary>
339        Width
340    }
341    #endregion
342   
343   
344    /// <summary>
345   /// Base class for Chart object.
346   /// </summary>
347    public class ExcelChart : ExcelDrawing
348    {
349       const string rootPath = "c:chartSpace/c:chart/c:plotArea";
350       //string _chartPath;
351       protected internal ExcelChartSeries _chartSeries;
352       internal ExcelChartAxis[] _axis;
353       protected XmlHelper _chartXmlHelper;
354       #region "Constructors"
355       internal ExcelChart(ExcelDrawings drawings, XmlNode node, eChartType type, bool isPivot) :
356           base(drawings, node, "xdr:graphicFrame/xdr:nvGraphicFramePr/xdr:cNvPr/@name")
357       {
358           ChartType = type;
359           CreateNewChart(drawings, type, null);
360
361           Init(drawings, _chartNode);
362
363           _chartSeries = new ExcelChartSeries(this, drawings.NameSpaceManager, _chartNode, isPivot);
364
365           SetTypeProperties();
366           LoadAxis();
367       }
368       internal ExcelChart(ExcelDrawings drawings, XmlNode node, eChartType type, ExcelChart topChart, ExcelPivotTable PivotTableSource) :
369           base(drawings, node, "xdr:graphicFrame/xdr:nvGraphicFramePr/xdr:cNvPr/@name")
370       {
371           ChartType = type;
372           CreateNewChart(drawings, type, topChart);
373
374           Init(drawings, _chartNode);
375
376           _chartSeries = new ExcelChartSeries(this, drawings.NameSpaceManager, _chartNode, PivotTableSource!=null);
377           if (PivotTableSource != null) SetPivotSource(PivotTableSource);
378
379           SetTypeProperties();
380           if (topChart == null)
381               LoadAxis();
382           else
383           {
384               _axis = topChart.Axis;
385               if (_axis.Length > 0)
386               {
387                   XAxis = _axis[0];
388                   YAxis = _axis[1];
389               }
390           }
391       }
392       internal ExcelChart(ExcelDrawings drawings, XmlNode node, Uri uriChart, ZipPackagePart part, XmlDocument chartXml, XmlNode chartNode) :
393           base(drawings, node, "xdr:graphicFrame/xdr:nvGraphicFramePr/xdr:cNvPr/@name")
394       {
395           UriChart = uriChart;
396           Part = part;
397           ChartXml = chartXml;
398           _chartNode = chartNode;
399           InitChartLoad(drawings, chartNode);
400           ChartType = GetChartType(chartNode.LocalName);
401       }
402       internal ExcelChart(ExcelChart topChart, XmlNode chartNode) :
403           base(topChart._drawings, topChart.TopNode, "xdr:graphicFrame/xdr:nvGraphicFramePr/xdr:cNvPr/@name")
404       {
405           UriChart = topChart.UriChart;
406           Part = topChart.Part;
407           ChartXml = topChart.ChartXml;
408           _plotArea = topChart.PlotArea;
409           _chartNode = chartNode;
410
411           InitChartLoad(topChart._drawings, chartNode);
412       }
413       private void InitChartLoad(ExcelDrawings drawings, XmlNode chartNode)
414       {
415           //SetChartType();
416           bool isPivot = false;
417           Init(drawings, chartNode);
418           _chartSeries = new ExcelChartSeries(this, drawings.NameSpaceManager, _chartNode, isPivot /*ChartXml.SelectSingleNode(_chartPath, drawings.NameSpaceManager)*/);
419           LoadAxis();
420       }
421
422       private void Init(ExcelDrawings drawings, XmlNode chartNode)
423       {
424           //_chartXmlHelper = new XmlHelper(drawings.NameSpaceManager, chartNode);
425           _chartXmlHelper = XmlHelperFactory.Create(drawings.NameSpaceManager, chartNode);
426           _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" };
427           WorkSheet = drawings.Worksheet;
428       }
429       #endregion
430       #region "Private functions"
431       private void SetTypeProperties()
432       {
433           /******* Grouping *******/
434           if (IsTypeClustered())
435           {
436               Grouping = eGrouping.Clustered;
437           }
438           else if (
439               IsTypeStacked())
440           {
441               Grouping = eGrouping.Stacked;
442           }
443           else if (
444           IsTypePercentStacked())
445           {
446               Grouping = eGrouping.PercentStacked;
447           }
448
449           /***** 3D Perspective *****/
450           if (IsType3D())             
451           {
452               View3D.RotY = 20;
453               View3D.Perspective = 30;    //Default to 30
454               if (IsTypePieDoughnut())
455               {
456                   View3D.RotX = 30;
457               }
458               else
459               {
460                   View3D.RotX = 15;
461               }
462           }
463       }
464       private void CreateNewChart(ExcelDrawings drawings, eChartType type, ExcelChart topChart)
465       {
466           if (topChart == null)
467           {
468               XmlElement graphFrame = TopNode.OwnerDocument.CreateElement("graphicFrame", ExcelPackage.schemaSheetDrawings);
469               graphFrame.SetAttribute("macro", "");
470               TopNode.AppendChild(graphFrame);
471               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);
472               TopNode.AppendChild(TopNode.OwnerDocument.CreateElement("clientData", ExcelPackage.schemaSheetDrawings));
473
474               var package = drawings.Worksheet._package.Package;
475               UriChart = GetNewUri(package, "/xl/charts/chart{0}.xml");
476
477               ChartXml = new XmlDocument();
478               ChartXml.PreserveWhitespace = ExcelPackage.preserveWhitespace;
479               LoadXmlSafe(ChartXml, ChartStartXml(type), Encoding.UTF8);
480
481               // save it to the package
482               Part = package.CreatePart(UriChart, "application/vnd.openxmlformats-officedocument.drawingml.chart+xml", _drawings._package.Compression);
483
484               StreamWriter streamChart = new StreamWriter(Part.GetStream(FileMode.Create, FileAccess.Write));
485               ChartXml.Save(streamChart);
486               streamChart.Close();
487               package.Flush();
488
489               var chartRelation = drawings.Part.CreateRelationship(UriHelper.GetRelativeUri(drawings.UriDrawing, UriChart), Packaging.TargetMode.Internal, ExcelPackage.schemaRelationships + "/chart");
490               graphFrame.SelectSingleNode("a:graphic/a:graphicData/c:chart", NameSpaceManager).Attributes["r:id"].Value = chartRelation.Id;
491               package.Flush();
492               _chartNode = ChartXml.SelectSingleNode(string.Format("c:chartSpace/c:chart/c:plotArea/{0}", GetChartNodeText()), NameSpaceManager);
493           }
494           else
495           {
496               ChartXml = topChart.ChartXml;
497               Part = topChart.Part;
498               _plotArea = topChart.PlotArea;
499               UriChart = topChart.UriChart;
500               _axis = topChart._axis;
501
502               XmlNode preNode = _plotArea.ChartTypes[_plotArea.ChartTypes.Count - 1].ChartNode;
503               _chartNode = ((XmlDocument)ChartXml).CreateElement(GetChartNodeText(), ExcelPackage.schemaChart);
504               preNode.ParentNode.InsertAfter(_chartNode, preNode);
505               if (topChart.Axis.Length == 0)
506               {
507                   AddAxis();
508               }
509               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);
510               _chartNode.InnerXml = serieXML;
511           }
512       }
513       private void LoadAxis()
514       {
515           XmlNodeList nl = _chartNode.SelectNodes("c:axId", NameSpaceManager);
516           List<ExcelChartAxis> l = new List<ExcelChartAxis>();
517           foreach (XmlNode node in nl)
518           {
519               string id = node.Attributes["val"].Value;
520               var axNode = ChartXml.SelectNodes(rootPath + string.Format("/*/c:axId[@val=\"{0}\"]", id), NameSpaceManager);
521               if (axNode != null && axNode.Count>1)
522               {
523                   foreach (XmlNode axn in axNode)
524                   {
525                       if (axn.ParentNode.LocalName.EndsWith("Ax"))
526                       {
527                           XmlNode axisNode = axNode[1].ParentNode;
528                           ExcelChartAxis ax = new ExcelChartAxis(NameSpaceManager, axisNode);
529                           l.Add(ax);
530                       }
531                   }
532               }
533           }
534           _axis = l.ToArray();
535
536           if(_axis.Length > 0) XAxis = _axis[0];
537           if (_axis.Length > 1) YAxis = _axis[1];
538       }
539       //private void SetChartType()
540       //{
541       //    ChartType = 0;
542       //    //_plotArea = new ExcelChartPlotArea(NameSpaceManager, ChartXml.SelectSingleNode("c:chartSpace/c:chart/c:plotArea", NameSpaceManager));
543       //    int pos=0;
544       //    foreach (XmlElement n in ChartXml.SelectSingleNode(rootPath, _drawings.NameSpaceManager).ChildNodes)
545       //    {
546       //        if (pos == 0)
547       //        {
548       //            ChartType = GetChartType(n.Name);
549       //            if (ChartType != 0)
550       //            {
551       //                //_chartPath = rootPath + "/" + n.Name;
552       //                PlotArea.ChartTypes.Add(this);
553       //            }
554       //        }
555       //        else
556       //        {
557       //            var chartSerieType = GetChart(_drawings, TopNode/*, n*/);
558       //            chartSerieType = GetChart(n, _drawings, TopNode, UriChart, Part, ChartXml, null, isPivot);
559       //            PlotArea.ChartTypes.Add(chartSerieType);
560       //            //var chartType = GetChartType(n.Name);
561       //        }
562       //        if (ChartType != 0)
563       //        {
564       //            pos++;
565       //        }
566       //    }
567       //}
568       internal virtual eChartType GetChartType(string name)
569       {
570           
571           switch (name)
572           {
573               case "area3DChart":
574                   if(Grouping==eGrouping.Stacked)
575                   {
576                       return eChartType.AreaStacked3D;
577                   }
578                   else if (Grouping == eGrouping.PercentStacked)
579                   {
580                       return eChartType.AreaStacked1003D;
581                   }
582                   else
583                   {
584                       return eChartType.Area3D;
585                   }
586               case "areaChart":
587                   if (Grouping == eGrouping.Stacked)
588                   {
589                       return eChartType.AreaStacked;
590                   }
591                   else if (Grouping == eGrouping.PercentStacked)
592                   {
593                       return eChartType.AreaStacked100;
594                   }
595                   else
596                   {
597                       return eChartType.Area;
598                   }
599               case "doughnutChart":
600                   return eChartType.Doughnut;
601               case "pie3DChart":
602                   return eChartType.Pie3D;
603               case "pieChart":
604                   return eChartType.Pie;
605               case "radarChart":
606                   return eChartType.Radar;
607               case "scatterChart":
608                   return eChartType.XYScatter;
609               case "surface3DChart":
610               case "surfaceChart":
611                   return eChartType.Surface;
612               case "stockChart":
613                   return eChartType.StockHLC;
614               default:
615                   return 0;
616           }           
617       }
618       #region "Xml init Functions"
619       private string ChartStartXml(eChartType type)
620       {
621           StringBuilder xml=new StringBuilder();
622           int axID=1;
623           int xAxID=2;
624           int serAxID = IsTypeSurface() ? 3 : -1;
625
626           xml.Append("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>");
627           xml.AppendFormat("<c:chartSpace xmlns:c=\"{0}\" xmlns:a=\"{1}\" xmlns:r=\"{2}\">", ExcelPackage.schemaChart, ExcelPackage.schemaDrawings, ExcelPackage.schemaRelationships);       
628           xml.Append("<c:chart>");
629           xml.AppendFormat("{0}{1}<c:plotArea><c:layout/>",AddPerspectiveXml(type), AddSurfaceXml(type));
630
631           string chartNodeText = GetChartNodeText();
632           xml.AppendFormat("<{0}>", chartNodeText);
633           xml.Append(GetChartSerieStartXml(type, axID, xAxID, serAxID));
634           xml.AppendFormat("</{0}>", chartNodeText);
635
636           //Axis
637           if (!IsTypePieDoughnut())
638           {
639               if (IsTypeScatterBubble())
640               {
641                   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);
642               }
643               else
644               {
645                   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);
646               }
647               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);
648               if (serAxID==3) //Sureface Chart
649               {
650                   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);
651               }
652           }
653
654           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);
655
656           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>");         
657           return xml.ToString();
658       }
659
660       private string GetChartSerieStartXml(eChartType type, int axID, int xAxID, int serAxID)
661       {
662           StringBuilder xml = new StringBuilder();
663
664           xml.Append(AddScatterType(type));
665           xml.Append(AddRadarType(type));
666           xml.Append(AddBarDir(type));
667           xml.Append(AddGrouping());
668           xml.Append(AddVaryColors());
669           xml.Append(AddHasMarker(type));
670           xml.Append(AddShape(type));
671           xml.Append(AddFirstSliceAng(type));
672           xml.Append(AddHoleSize(type));
673           if (ChartType == eChartType.BarStacked100 ||
674               ChartType == eChartType.BarStacked ||
675               ChartType == eChartType.ColumnStacked ||
676               ChartType == eChartType.ColumnStacked100)
677           {
678               xml.Append("<c:overlap val=\"100\"/>");
679           }
680           if (IsTypeSurface())
681           {
682               xml.Append("<c:bandFmts/>");
683           }
684           xml.Append(AddAxisId(axID, xAxID, serAxID));
685
686           return xml.ToString();
687       }
688       private string AddAxisId(int axID,int xAxID, int serAxID)
689       {
690           if (!IsTypePieDoughnut())
691           {
692               if (IsTypeSurface())
693               {                                     
694                   return string.Format("<c:axId val=\"{0}\"/><c:axId val=\"{1}\"/><c:axId val=\"{2}\"/>", axID, xAxID, serAxID);
695               }
696               else
697               {
698                   return string.Format("<c:axId val=\"{0}\"/><c:axId val=\"{1}\"/>", axID, xAxID);
699               }
700           }
701           else
702           {
703               return "";
704           }
705       }
706       private string AddAxType()
707       {
708           switch(ChartType)
709           {
710               case eChartType.XYScatter:
711               case eChartType.XYScatterLines:
712               case eChartType.XYScatterLinesNoMarkers:
713               case eChartType.XYScatterSmooth:
714               case eChartType.XYScatterSmoothNoMarkers:
715               case eChartType.Bubble:
716               case eChartType.Bubble3DEffect:
717                   return "valAx";
718               default:
719                   return "catAx";
720           }
721       }
722       private string AddScatterType(eChartType type)
723       {
724           if (type == eChartType.XYScatter ||
725               type == eChartType.XYScatterLines ||
726               type == eChartType.XYScatterLinesNoMarkers ||
727               type == eChartType.XYScatterSmooth ||
728               type == eChartType.XYScatterSmoothNoMarkers)
729           {
730               return "<c:scatterStyle val=\"\" />";
731           }
732           else
733           {
734               return "";
735           }
736       }
737       private string AddRadarType(eChartType type)
738       {
739           if (type == eChartType.Radar ||
740               type == eChartType.RadarFilled||
741               type == eChartType.RadarMarkers)
742           {
743               return "<c:radarStyle val=\"\" />";
744           }
745           else
746           {
747               return "";
748           }
749       }
750       private string AddGrouping()
751       {
752           //IsTypeClustered() || IsTypePercentStacked() || IsTypeStacked() ||
753           if(IsTypeShape() || IsTypeLine())
754           {
755               return "<c:grouping val=\"standard\"/>";
756           }
757           else
758           {
759               return "";
760           }
761       }
762       private string AddHoleSize(eChartType type)
763       {
764           if (type == eChartType.Doughnut ||
765               type == eChartType.DoughnutExploded)
766           {
767               return "<c:holeSize val=\"50\" />";
768           }
769           else
770           {
771               return "";
772           }
773       }
774       private string AddFirstSliceAng(eChartType type)
775       {
776           if (type == eChartType.Doughnut ||
777               type == eChartType.DoughnutExploded)
778           {
779               return "<c:firstSliceAng val=\"0\" />";
780           }
781           else
782           {
783               return "";
784           }
785       }
786       private string AddVaryColors()
787       {
788           if (IsTypePieDoughnut())
789           {
790               return "<c:varyColors val=\"1\" />";
791           }
792           else
793           {
794               return "<c:varyColors val=\"0\" />";
795           }
796       }
797       private string AddHasMarker(eChartType type)
798       {
799           if (type == eChartType.LineMarkers ||
800               type == eChartType.LineMarkersStacked ||
801               type == eChartType.LineMarkersStacked100 /*||
802               type == eChartType.XYScatterLines ||
803               type == eChartType.XYScatterSmooth*/)
804           {
805               return "<c:marker val=\"1\"/>";
806           }
807           else
808           {
809               return "";
810           }
811       }
812       private string AddShape(eChartType type)
813       {
814           if (IsTypeShape())
815           {
816               return "<c:shape val=\"box\" />";
817           }
818           else
819           {
820               return "";
821           }
822       }
823       private string AddBarDir(eChartType type)
824       {
825           if (IsTypeShape())
826            {
827                return "<c:barDir val=\"col\" />";
828            }
829            else
830            {
831                return "";
832            }
833       }
834       private string AddPerspectiveXml(eChartType type)
835        {
836          //Add for 3D sharts
837            if (IsType3D())
838            {
839                return "<c:view3D><c:perspective val=\"30\" /></c:view3D>";
840            }
841            else
842            {
843                return "";
844            }
845        }
846       private string AddSurfaceXml(eChartType type)
847       {
848           if (IsTypeSurface())
849           {
850               return AddSurfacePart("floor") + AddSurfacePart("sideWall") + AddSurfacePart("backWall");
851           }
852           else
853           {
854               return "";
855           }
856       }
857
858       private string AddSurfacePart(string name)
859       {
860           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);
861       }
862       #endregion
863       #endregion
864       #region "Chart type functions
865       internal static bool IsType3D(eChartType chartType)
866        {
867            return chartType == eChartType.Area3D ||
868                            chartType == eChartType.AreaStacked3D ||
869                            chartType == eChartType.AreaStacked1003D ||
870                            chartType == eChartType.BarClustered3D ||
871                            chartType == eChartType.BarStacked3D ||
872                            chartType == eChartType.BarStacked1003D ||
873                            chartType == eChartType.Column3D ||
874                            chartType == eChartType.ColumnClustered3D ||
875                            chartType == eChartType.ColumnStacked3D ||
876                            chartType == eChartType.ColumnStacked1003D ||
877                            chartType == eChartType.Line3D ||
878                            chartType == eChartType.Pie3D ||
879                            chartType == eChartType.PieExploded3D ||
880                            chartType == eChartType.ConeBarClustered ||
881                            chartType == eChartType.ConeBarStacked ||
882                            chartType == eChartType.ConeBarStacked100 ||
883                            chartType == eChartType.ConeCol ||
884                            chartType == eChartType.ConeColClustered ||
885                            chartType == eChartType.ConeColStacked ||
886                            chartType == eChartType.ConeColStacked100 ||
887                            chartType == eChartType.CylinderBarClustered ||
888                            chartType == eChartType.CylinderBarStacked ||
889                            chartType == eChartType.CylinderBarStacked100 ||
890                            chartType == eChartType.CylinderCol ||
891                            chartType == eChartType.CylinderColClustered ||
892                            chartType == eChartType.CylinderColStacked ||
893                            chartType == eChartType.CylinderColStacked100 ||
894                            chartType == eChartType.PyramidBarClustered ||
895                            chartType == eChartType.PyramidBarStacked ||
896                            chartType == eChartType.PyramidBarStacked100 ||
897                            chartType == eChartType.PyramidCol ||
898                            chartType == eChartType.PyramidColClustered ||
899                            chartType == eChartType.PyramidColStacked ||
900                            chartType == eChartType.PyramidColStacked100 ||
901                            chartType == eChartType.Surface ||
902                            chartType == eChartType.SurfaceTopView ||
903                            chartType == eChartType.SurfaceTopViewWireframe ||
904                            chartType == eChartType.SurfaceWireframe;
905        }
906       internal protected bool IsType3D()
907       {
908            return IsType3D(ChartType);
909       }
910        protected bool IsTypeLine()
911       {
912           return ChartType == eChartType.Line ||
913                   ChartType == eChartType.LineMarkers ||
914                   ChartType == eChartType.LineMarkersStacked100 ||
915                   ChartType == eChartType.LineStacked ||
916                   ChartType == eChartType.LineStacked100 ||
917                   ChartType == eChartType.Line3D;
918       }
919       protected bool IsTypeScatterBubble()
920       {
921           return ChartType == eChartType.XYScatter ||
922                   ChartType == eChartType.XYScatterLines ||
923                   ChartType == eChartType.XYScatterLinesNoMarkers ||
924                   ChartType == eChartType.XYScatterSmooth ||
925                   ChartType == eChartType.XYScatterSmoothNoMarkers ||
926                   ChartType == eChartType.Bubble ||
927                   ChartType == eChartType.Bubble3DEffect;
928       }
929        protected bool IsTypeSurface()
930        {
931            return ChartType == eChartType.Surface ||
932                   ChartType == eChartType.SurfaceTopView ||
933                   ChartType == eChartType.SurfaceTopViewWireframe ||
934                   ChartType == eChartType.SurfaceWireframe;
935        }
936       protected bool IsTypeShape()
937       {
938            return ChartType == eChartType.BarClustered3D ||
939                    ChartType == eChartType.BarStacked3D ||
940                    ChartType == eChartType.BarStacked1003D ||
941                    ChartType == eChartType.BarClustered3D ||
942                    ChartType == eChartType.BarStacked3D ||
943                    ChartType == eChartType.BarStacked1003D ||
944                    ChartType == eChartType.Column3D ||
945                    ChartType == eChartType.ColumnClustered3D ||
946                    ChartType == eChartType.ColumnStacked3D ||
947                    ChartType == eChartType.ColumnStacked1003D ||
948                //ChartType == eChartType.3DPie ||
949                //ChartType == eChartType.3DPieExploded ||
950                    //ChartType == eChartType.Bubble3DEffect ||
951                    ChartType == eChartType.ConeBarClustered ||
952                    ChartType == eChartType.ConeBarStacked ||
953                    ChartType == eChartType.ConeBarStacked100 ||
954                    ChartType == eChartType.ConeCol ||
955                    ChartType == eChartType.ConeColClustered ||
956                    ChartType == eChartType.ConeColStacked ||
957                    ChartType == eChartType.ConeColStacked100 ||
958                    ChartType == eChartType.CylinderBarClustered ||
959                    ChartType == eChartType.CylinderBarStacked ||
960                    ChartType == eChartType.CylinderBarStacked100 ||
961                    ChartType == eChartType.CylinderCol ||
962                    ChartType == eChartType.CylinderColClustered ||
963                    ChartType == eChartType.CylinderColStacked ||
964                    ChartType == eChartType.CylinderColStacked100 ||
965                    ChartType == eChartType.PyramidBarClustered ||
966                    ChartType == eChartType.PyramidBarStacked ||
967                    ChartType == eChartType.PyramidBarStacked100 ||
968                    ChartType == eChartType.PyramidCol ||
969                    ChartType == eChartType.PyramidColClustered ||
970                    ChartType == eChartType.PyramidColStacked ||
971                    ChartType == eChartType.PyramidColStacked100; //||
972                    //ChartType == eChartType.Doughnut ||
973                    //ChartType == eChartType.DoughnutExploded;
974        }
975        protected internal bool IsTypePercentStacked()
976        {
977            return ChartType == eChartType.AreaStacked100 ||
978                           ChartType == eChartType.BarStacked100 ||
979                           ChartType == eChartType.BarStacked1003D ||
980                           ChartType == eChartType.ColumnStacked100 ||
981                           ChartType == eChartType.ColumnStacked1003D ||
982                           ChartType == eChartType.ConeBarStacked100 ||
983                           ChartType == eChartType.ConeColStacked100 ||
984                           ChartType == eChartType.CylinderBarStacked100 ||
985                           ChartType == eChartType.CylinderColStacked ||
986                           ChartType == eChartType.LineMarkersStacked100 ||
987                           ChartType == eChartType.LineStacked100 ||
988                           ChartType == eChartType.PyramidBarStacked100 ||
989                           ChartType == eChartType.PyramidColStacked100;
990        }
991        protected internal bool IsTypeStacked()
992        {
993            return ChartType == eChartType.AreaStacked ||
994                           ChartType == eChartType.AreaStacked3D ||
995                           ChartType == eChartType.BarStacked ||
996                           ChartType == eChartType.BarStacked3D ||
997                           ChartType == eChartType.ColumnStacked3D ||
998                           ChartType == eChartType.ColumnStacked ||
999                           ChartType == eChartType.ConeBarStacked ||
1000                           ChartType == eChartType.ConeColStacked ||
1001                           ChartType == eChartType.CylinderBarStacked ||
1002                           ChartType == eChartType.CylinderColStacked ||
1003                           ChartType == eChartType.LineMarkersStacked ||
1004                           ChartType == eChartType.LineStacked ||
1005                           ChartType == eChartType.PyramidBarStacked ||
1006                           ChartType == eChartType.PyramidColStacked;
1007        }
1008        protected bool IsTypeClustered()
1009        {
1010            return ChartType == eChartType.BarClustered ||
1011                           ChartType == eChartType.BarClustered3D ||
1012                           ChartType == eChartType.ColumnClustered3D ||
1013                           ChartType == eChartType.ColumnClustered ||
1014                           ChartType == eChartType.ConeBarClustered ||
1015                           ChartType == eChartType.ConeColClustered ||
1016                           ChartType == eChartType.CylinderBarClustered ||
1017                           ChartType == eChartType.CylinderColClustered ||
1018                           ChartType == eChartType.PyramidBarClustered ||
1019                           ChartType == eChartType.PyramidColClustered;
1020        }
1021        protected internal bool IsTypePieDoughnut()
1022        {
1023            return ChartType == eChartType.Pie ||
1024                           ChartType == eChartType.PieExploded ||
1025                           ChartType == eChartType.PieOfPie ||
1026                           ChartType == eChartType.Pie3D ||
1027                           ChartType == eChartType.PieExploded3D ||
1028                           ChartType == eChartType.BarOfPie ||
1029                           ChartType == eChartType.Doughnut ||
1030                           ChartType == eChartType.DoughnutExploded;
1031        }
1032        #endregion
1033       /// <summary>
1034       /// Get the name of the chart node
1035       /// </summary>
1036       /// <returns>The name</returns>
1037        protected string GetChartNodeText()
1038        {
1039            switch (ChartType)
1040            {
1041                case eChartType.Area3D:
1042                case eChartType.AreaStacked3D:
1043                case eChartType.AreaStacked1003D:
1044                    return "c:area3DChart";
1045                case eChartType.Area:
1046                case eChartType.AreaStacked:
1047                case eChartType.AreaStacked100:
1048                    return "c:areaChart";
1049                case eChartType.BarClustered:
1050                case eChartType.BarStacked:
1051                case eChartType.BarStacked100:
1052                case eChartType.ColumnClustered:
1053                case eChartType.ColumnStacked:
1054                case eChartType.ColumnStacked100:
1055                    return "c:barChart";
1056                case eChartType.BarClustered3D:
1057                case eChartType.BarStacked3D:
1058                case eChartType.BarStacked1003D:
1059                case eChartType.ColumnClustered3D:
1060                case eChartType.ColumnStacked3D:
1061                case eChartType.ColumnStacked1003D:
1062                case eChartType.ConeBarClustered:
1063                case eChartType.ConeBarStacked:
1064                case eChartType.ConeBarStacked100:
1065                case eChartType.ConeCol:
1066                case eChartType.ConeColClustered:
1067                case eChartType.ConeColStacked:
1068                case eChartType.ConeColStacked100:
1069                case eChartType.CylinderBarClustered:
1070                case eChartType.CylinderBarStacked:
1071                case eChartType.CylinderBarStacked100:
1072                case eChartType.CylinderCol:
1073                case eChartType.CylinderColClustered:
1074                case eChartType.CylinderColStacked:
1075                case eChartType.CylinderColStacked100:
1076                case eChartType.PyramidBarClustered:
1077                case eChartType.PyramidBarStacked:
1078                case eChartType.PyramidBarStacked100:
1079                case eChartType.PyramidCol:
1080                case eChartType.PyramidColClustered:
1081                case eChartType.PyramidColStacked:
1082                case eChartType.PyramidColStacked100:
1083                    return "c:bar3DChart";
1084                case eChartType.Bubble:
1085                case eChartType.Bubble3DEffect:
1086                    return "c:bubbleChart";
1087                case eChartType.Doughnut:
1088                case eChartType.DoughnutExploded:
1089                    return "c:doughnutChart";
1090                case eChartType.Line:
1091                case eChartType.LineMarkers:
1092                case eChartType.LineMarkersStacked:
1093                case eChartType.LineMarkersStacked100:
1094                case eChartType.LineStacked:
1095                case eChartType.LineStacked100:
1096                    return "c:lineChart";
1097                case eChartType.Line3D:
1098                    return "c:line3DChart";
1099                case eChartType.Pie:
1100                case eChartType.PieExploded:
1101                    return "c:pieChart";
1102                case eChartType.BarOfPie:
1103                case eChartType.PieOfPie:
1104                    return "c:ofPieChart";
1105                case eChartType.Pie3D:
1106                case eChartType.PieExploded3D:
1107                    return "c:pie3DChart";
1108                case eChartType.Radar:
1109                case eChartType.RadarFilled:
1110                case eChartType.RadarMarkers:
1111                    return "c:radarChart";
1112                case eChartType.XYScatter:
1113                case eChartType.XYScatterLines:
1114                case eChartType.XYScatterLinesNoMarkers:
1115                case eChartType.XYScatterSmooth:
1116                case eChartType.XYScatterSmoothNoMarkers:
1117                    return "c:scatterChart";
1118                case eChartType.Surface:
1119                case eChartType.SurfaceWireframe:
1120                    return "c:surface3DChart";
1121                case eChartType.SurfaceTopView:
1122                case eChartType.SurfaceTopViewWireframe:
1123                    return "c:surfaceChart";
1124                case eChartType.StockHLC:
1125                    return "c:stockChart";
1126                default:
1127                    throw(new NotImplementedException("Chart type not implemented"));
1128            }
1129        }
1130        /// <summary>
1131        /// Add a secondary axis
1132        /// </summary>
1133        internal void AddAxis()
1134        {
1135            XmlElement catAx = ChartXml.CreateElement(string.Format("c:{0}",AddAxType()), ExcelPackage.schemaChart);
1136            int axID;
1137            if (_axis.Length == 0)
1138            {
1139                _plotArea.TopNode.AppendChild(catAx);
1140                axID = 1;
1141            }
1142            else
1143            {
1144                _axis[0].TopNode.ParentNode.InsertAfter(catAx, _axis[_axis.Length-1].TopNode);
1145                axID = int.Parse(_axis[0].Id) < int.Parse(_axis[1].Id) ? int.Parse(_axis[1].Id) + 1 : int.Parse(_axis[0].Id) + 1;
1146            }
1147
1148
1149            XmlElement valAx = ChartXml.CreateElement("c:valAx", ExcelPackage.schemaChart);
1150            catAx.ParentNode.InsertAfter(valAx, catAx);
1151
1152            if (_axis.Length == 0)
1153            {
1154                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);
1155                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);
1156            }
1157            else
1158            {
1159                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);
1160                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);
1161            }
1162
1163            if (_axis.Length == 0)
1164            {
1165                _axis = new ExcelChartAxis[2];
1166            }
1167            else
1168            {
1169                ExcelChartAxis[] newAxis = new ExcelChartAxis[_axis.Length + 2];
1170                Array.Copy(_axis, newAxis, _axis.Length);
1171                _axis = newAxis;
1172            }
1173
1174            _axis[_axis.Length - 2] = new ExcelChartAxis(NameSpaceManager, catAx);
1175            _axis[_axis.Length - 1] = new ExcelChartAxis(NameSpaceManager, valAx);
1176            foreach (var chart in _plotArea.ChartTypes)
1177            {
1178                chart._axis = _axis;
1179            }
1180        }
1181        internal void RemoveSecondaryAxis()
1182        {
1183            throw (new NotImplementedException("Not yet implemented"));
1184        }
1185        #region "Properties"
1186        /// <summary>
1187        /// Reference to the worksheet
1188        /// </summary>
1189        public ExcelWorksheet WorkSheet { get; internal set; }
1190        /// <summary>
1191        /// The chart xml document
1192        /// </summary>
1193        public XmlDocument ChartXml { get; internal set; }
1194        /// <summary>
1195        /// Type of chart
1196        /// </summary>
1197        public eChartType ChartType { get; internal set; }
1198        internal protected XmlNode _chartNode = null;
1199        internal XmlNode ChartNode
1200        {
1201            get
1202            {
1203                return _chartNode;
1204            }
1205        }
1206        /// <summary>
1207        /// Titel of the chart
1208        /// </summary>
1209        public ExcelChartTitle Title
1210        {
1211            get
1212            {
1213                if (_title == null)
1214                {
1215                    _title = new ExcelChartTitle(NameSpaceManager, ChartXml.SelectSingleNode("c:chartSpace/c:chart", NameSpaceManager));
1216                }
1217                return _title;
1218            }
1219        }
1220        /// <summary>
1221        /// Chart series
1222        /// </summary>
1223        public virtual ExcelChartSeries Series
1224        {
1225            get
1226            {
1227                return _chartSeries;
1228            }
1229        }
1230        /// <summary>
1231        /// An array containg all axis of all Charttypes
1232        /// </summary>
1233        public ExcelChartAxis[] Axis
1234        {
1235            get
1236            {
1237                return _axis;
1238            }
1239        }
1240        /// <summary>
1241        /// The XAxis
1242        /// </summary>
1243        public ExcelChartAxis XAxis
1244        {
1245            get;
1246            private set;
1247        }
1248        /// <summary>
1249        /// The YAxis
1250        /// </summary>
1251        public ExcelChartAxis YAxis
1252        {
1253            get;
1254            private set;
1255        }
1256        bool _secondaryAxis=false;
1257        /// <summary>
1258        /// If true the charttype will use the secondary axis.
1259        /// The chart must contain a least one other charttype that uses the primary axis.
1260        /// </summary>
1261        public bool UseSecondaryAxis
1262        {
1263            get
1264            {
1265                return _secondaryAxis;
1266            }
1267            set
1268            {
1269                 if (_secondaryAxis != value)
1270                {
1271                    if (value)
1272                    {
1273                        if (IsTypePieDoughnut())
1274                        {
1275                            throw (new Exception("Pie charts do not support axis"));
1276                        }
1277                        else if (HasPrimaryAxis() == false)
1278                        {
1279                            throw (new Exception("Can't set to secondary axis when no serie uses the primary axis"));
1280                        }
1281                        if (Axis.Length == 2)
1282                        {
1283                            AddAxis();
1284                        }
1285                        var nl = ChartNode.SelectNodes("c:axId", NameSpaceManager);
1286                        nl[0].Attributes["val"].Value = Axis[2].Id;
1287                        nl[1].Attributes["val"].Value = Axis[3].Id;
1288                        XAxis = Axis[2];
1289                        YAxis = Axis[3];
1290                    }
1291                    else
1292                    {
1293                        var nl = ChartNode.SelectNodes("c:axId", NameSpaceManager);
1294                        nl[0].Attributes["val"].Value = Axis[0].Id;
1295                        nl[1].Attributes["val"].Value = Axis[1].Id;
1296                        XAxis = Axis[0];
1297                        YAxis = Axis[1];
1298                    }
1299                    _secondaryAxis = value;
1300                }
1301            }
1302        }
1303        /// <summary>
1304        /// The build-in chart styles.
1305        /// </summary>
1306        public eChartStyle Style
1307        {
1308            get
1309            {
1310                XmlNode node = ChartXml.SelectSingleNode("c:chartSpace/c:style/@val", NameSpaceManager);
1311                if (node == null)
1312                {
1313                    return eChartStyle.None;
1314                }
1315                else
1316                {
1317                    int v;
1318                    if (int.TryParse(node.Value, out v))
1319                    {
1320                        return (eChartStyle)v;
1321                    }
1322                    else
1323                    {
1324                        return eChartStyle.None;
1325                    }
1326                }
1327
1328            }
1329            set
1330            {
1331                if (value == eChartStyle.None)
1332                {
1333                    XmlElement element = ChartXml.SelectSingleNode("c:chartSpace/c:style", NameSpaceManager) as XmlElement;
1334                    if (element != null)
1335                    {
1336                        element.ParentNode.RemoveChild(element);
1337                    }
1338                }
1339                else
1340                {
1341                    XmlElement element = ChartXml.CreateElement("c:style", ExcelPackage.schemaChart);
1342                    element.SetAttribute("val", ((int)value).ToString());
1343                    XmlElement parent = ChartXml.SelectSingleNode("c:chartSpace", NameSpaceManager) as XmlElement;
1344                    parent.InsertBefore(element, parent.SelectSingleNode("c:chart", NameSpaceManager));
1345                }
1346            }
1347        }
1348        const string _plotVisibleOnlyPath="../../c:plotVisOnly/@val";
1349        /// <summary>
1350        /// Show data in hidden rows and columns
1351        /// </summary>
1352        public bool ShowHiddenData
1353        {
1354            get
1355            {
1356                //!!Inverted value!!
1357                return !_chartXmlHelper.GetXmlNodeBool(_plotVisibleOnlyPath);
1358            }
1359            set
1360            {
1361                //!!Inverted value!!
1362                _chartXmlHelper.SetXmlNodeBool(_plotVisibleOnlyPath, !value);
1363            }
1364        }
1365        const string _displayBlanksAsPath = "../../c:dispBlanksAs/@val";
1366        /// <summary>
1367        /// Specifies the possible ways to display blanks
1368        /// </summary>
1369        public eDisplayBlanksAs DisplayBlanksAs
1370        {
1371            get
1372            {
1373                string v=_chartXmlHelper.GetXmlNodeString(_displayBlanksAsPath);
1374                if (string.IsNullOrEmpty(v))
1375                {
1376                    return eDisplayBlanksAs.Zero; //Issue 14715 Changed in Office 2010-?
1377                }
1378                else
1379                {
1380                    return (eDisplayBlanksAs)Enum.Parse(typeof(eDisplayBlanksAs), v, true);
1381                }
1382            }
1383            set
1384            {
1385                _chartSeries.SetXmlNodeString(_displayBlanksAsPath, value.ToString().ToLower(CultureInfo.InvariantCulture));
1386            }
1387        }
1388        const string _showDLblsOverMax = "../../c:showDLblsOverMax/@val";
1389        /// <summary>
1390        /// Specifies data labels over the maximum of the chart shall be shown
1391        /// </summary>
1392        public bool ShowDataLabelsOverMaximum
1393        {
1394            get
1395            {
1396                return _chartXmlHelper.GetXmlNodeBool(_showDLblsOverMax, true);
1397            }
1398            set
1399            {
1400                _chartXmlHelper.SetXmlNodeBool(_showDLblsOverMax,value, true);
1401            }
1402        }
1403        private bool HasPrimaryAxis()
1404        {
1405            if (_plotArea.ChartTypes.Count == 1)
1406            {
1407                return false;
1408            }
1409            foreach (var chart in _plotArea.ChartTypes)
1410            {
1411                if (chart != this)
1412                {
1413                    if (chart.UseSecondaryAxis == false && chart.IsTypePieDoughnut()==false)
1414                    {
1415                        return true;
1416                    }
1417                }
1418            }
1419            return false;
1420        }
1421        ///// <summary>
1422        ///// Sets position of the axis of a chart-serie
1423        ///// </summary>
1424        ///// <param name="XAxis">Left or Right</param>
1425        ///// <param name="YAxis">Top or Bottom</param>
1426        //internal void SetAxis(eXAxisPosition XAxis, eYAxisPosition YAxis)
1427        //{
1428        //    bool xAxisExists = false, yAxisExists = false;
1429        //    foreach (var axis in _axis)
1430        //    {
1431        //        if (axis.AxisPosition == (eAxisPosition)XAxis)
1432        //        {
1433        //            //Found
1434        //            xAxisExists=true;
1435        //            if (axis != this.XAxis)
1436        //            {
1437        //                CheckRemoveAxis(this.XAxis);
1438        //                this.XAxis = axis;
1439        //            }
1440        //        }
1441        //        else if (axis.AxisPosition == (eAxisPosition)YAxis)
1442        //        {
1443        //            yAxisExists = true;
1444        //            if (axis != this.YAxis)
1445        //            {
1446        //                CheckRemoveAxis(this.YAxis);
1447        //                this.YAxis = axis;
1448        //            }
1449        //        }
1450        //    }
1451
1452        //    if (!xAxisExists)
1453        //    {
1454        //        if (ExistsAxis(this.XAxis))
1455        //        {
1456        //            AddAxis((eAxisPosition)XAxis);
1457        //            this.XAxis = Axis[Axis.Length - 1];
1458        //        }
1459        //        else
1460        //        {
1461        //            this.XAxis.AxisPosition = (eAxisPosition)XAxis;
1462        //        }
1463        //    }
1464        //    if (!yAxisExists)
1465        //    {
1466        //        if (ExistsAxis(this.XAxis))
1467        //        {
1468        //            AddAxis((eAxisPosition)YAxis);
1469        //            this.YAxis = Axis[Axis.Length - 1];
1470        //        }
1471        //        else
1472        //        {
1473        //            this.YAxis.AxisPosition = (eAxisPosition)YAxis;
1474        //        }
1475        //    }
1476        //}
1477
1478        /// <summary>
1479        /// Remove all axis that are not used any more
1480        /// </summary>
1481        /// <param name="excelChartAxis"></param>
1482        private void CheckRemoveAxis(ExcelChartAxis excelChartAxis)
1483        {
1484            if (ExistsAxis(excelChartAxis))
1485            {
1486                //Remove the axis
1487                ExcelChartAxis[] newAxis = new ExcelChartAxis[Axis.Length - 1];
1488                int pos = 0;
1489                foreach (var ax in Axis)
1490                {
1491                    if (ax != excelChartAxis)
1492                    {
1493                        newAxis[pos] = ax;
1494                    }
1495                }
1496
1497                //Update all charttypes.
1498                foreach (ExcelChart chartType in _plotArea.ChartTypes)
1499                {
1500                    chartType._axis = newAxis;
1501                }
1502            }
1503        }
1504
1505        private bool ExistsAxis(ExcelChartAxis excelChartAxis)
1506        {
1507            foreach (ExcelChart chartType in _plotArea.ChartTypes)
1508            {
1509                if (chartType != this)
1510                {
1511                    if (chartType.XAxis.AxisPosition == excelChartAxis.AxisPosition ||
1512                       chartType.YAxis.AxisPosition == excelChartAxis.AxisPosition)
1513                    {
1514                        //The axis exists
1515                        return true;
1516                    }
1517                }
1518            }
1519            return false;
1520        }
1521        ExcelChartPlotArea _plotArea = null;
1522        /// <summary>
1523        /// Plotarea
1524        /// </summary>
1525        public ExcelChartPlotArea PlotArea
1526        {
1527            get
1528            {
1529                if (_plotArea == null)
1530                {
1531                    _plotArea = new ExcelChartPlotArea(NameSpaceManager, ChartXml.SelectSingleNode("c:chartSpace/c:chart/c:plotArea", NameSpaceManager), this);
1532                }
1533                return _plotArea;
1534            }
1535        }
1536        ExcelChartLegend _legend = null;
1537        /// <summary>
1538        /// Legend
1539        /// </summary>
1540        public ExcelChartLegend Legend
1541        {
1542            get
1543            {
1544                if (_legend == null)
1545                {
1546                    _legend = new ExcelChartLegend(NameSpaceManager, ChartXml.SelectSingleNode("c:chartSpace/c:chart/c:legend", NameSpaceManager), this);
1547                }
1548                return _legend;
1549            }
1550
1551        }
1552        ExcelDrawingBorder _border = null;
1553        /// <summary>
1554        /// Border
1555        /// </summary>
1556        public ExcelDrawingBorder Border
1557        {
1558            get
1559            {
1560                if (_border == null)
1561                {
1562                    _border = new ExcelDrawingBorder(NameSpaceManager, ChartXml.SelectSingleNode("c:chartSpace",NameSpaceManager), "c:spPr/a:ln");
1563                }
1564                return _border;
1565            }
1566        }
1567        ExcelDrawingFill _fill = null;
1568        /// <summary>
1569        /// Fill
1570        /// </summary>
1571        public ExcelDrawingFill Fill
1572        {
1573            get
1574            {
1575                if (_fill == null)
1576                {
1577                    _fill = new ExcelDrawingFill(NameSpaceManager, ChartXml.SelectSingleNode("c:chartSpace", NameSpaceManager), "c:spPr");
1578                }
1579                return _fill;
1580            }
1581        }
1582        /// <summary>
1583        /// 3D-settings
1584        /// </summary>
1585        public ExcelView3D View3D
1586        {
1587            get
1588            {
1589                if (IsType3D())
1590                {
1591                    return new ExcelView3D(NameSpaceManager, ChartXml.SelectSingleNode("//c:view3D", NameSpaceManager));
1592                }
1593                else
1594                {
1595                    throw (new Exception("Charttype does not support 3D"));
1596                }
1597
1598            }
1599        }
1600        //string _groupingPath = "c:chartSpace/c:chart/c:plotArea/{0}/c:grouping/@val";
1601        string _groupingPath = "c:grouping/@val";
1602        public eGrouping Grouping
1603        {
1604            get
1605            {
1606                return GetGroupingEnum(_chartXmlHelper.GetXmlNodeString(_groupingPath));
1607            }
1608            internal set
1609            {
1610                _chartXmlHelper.SetXmlNodeString(_groupingPath, GetGroupingText(value));
1611            }
1612        }
1613        //string _varyColorsPath = "c:chartSpace/c:chart/c:plotArea/{0}/c:varyColors/@val";
1614        string _varyColorsPath = "c:varyColors/@val";
1615        /// <summary>
1616        /// If the chart has only one serie this varies the colors for each point.
1617        /// </summary>
1618        public bool VaryColors
1619        {
1620            get
1621            {
1622                return _chartXmlHelper.GetXmlNodeBool(_varyColorsPath);
1623            }
1624            set
1625            {
1626                if (value)
1627                {
1628                    _chartXmlHelper.SetXmlNodeString(_varyColorsPath, "1");
1629                }
1630                else
1631                {
1632                    _chartXmlHelper.SetXmlNodeString(_varyColorsPath, "0");
1633                }
1634            }
1635        }
1636        internal Packaging.ZipPackagePart Part { get; set; }
1637        /// <summary>
1638        /// Package internal URI
1639        /// </summary>
1640        internal Uri UriChart { get; set; }
1641        internal new string Id
1642        {
1643            get { return ""; }
1644        }
1645        ExcelChartTitle _title = null;
1646        #endregion
1647       #region "Grouping Enum Translation"
1648        private string GetGroupingText(eGrouping grouping)
1649       {
1650           switch (grouping)
1651           {
1652               case eGrouping.Clustered:
1653                   return "clustered";
1654               case eGrouping.Stacked:
1655                   return "stacked";
1656               case eGrouping.PercentStacked:
1657                   return "percentStacked";
1658               default:
1659                   return "standard";
1660
1661           }
1662       }
1663       private eGrouping GetGroupingEnum(string grouping)
1664       {
1665           switch (grouping)
1666           {
1667               case "stacked":
1668                   return eGrouping.Stacked;
1669               case "percentStacked":
1670                   return eGrouping.PercentStacked;
1671               default: //"clustered":               
1672                   return eGrouping.Clustered;
1673           }         
1674       }
1675       #endregion
1676       internal static ExcelChart GetChart(ExcelDrawings drawings, XmlNode node/*, XmlNode chartTypeNode*/)
1677       {
1678           XmlNode chartNode = node.SelectSingleNode("xdr:graphicFrame/a:graphic/a:graphicData/c:chart", drawings.NameSpaceManager);
1679           if (chartNode != null)
1680           {
1681               var drawingRelation = drawings.Part.GetRelationship(chartNode.Attributes["r:id"].Value);
1682               var uriChart = UriHelper.ResolvePartUri(drawings.UriDrawing, drawingRelation.TargetUri);
1683
1684               var part = drawings.Part.Package.GetPart(uriChart);
1685               var chartXml = new XmlDocument();
1686               LoadXmlSafe(chartXml, part.GetStream());
1687
1688               ExcelChart topChart = null;
1689               foreach (XmlElement n in chartXml.SelectSingleNode(rootPath, drawings.NameSpaceManager).ChildNodes)
1690                {
1691                    if (topChart == null)
1692                    {
1693                        topChart = GetChart(n, drawings, node, uriChart, part, chartXml, null);
1694                        if(topChart!=null)
1695                        {
1696                            topChart.PlotArea.ChartTypes.Add(topChart);
1697                        }
1698                    }
1699                    else
1700                    {
1701                        var subChart = GetChart(n, null, null, null, null, null, topChart);
1702                        if (subChart != null)
1703                        {
1704                            topChart.PlotArea.ChartTypes.Add(subChart);
1705                        }
1706                    }
1707                }               
1708                return topChart;
1709           }
1710           else
1711           {
1712               return null;
1713           }           
1714       }
1715       internal static ExcelChart GetChart(XmlElement chartNode, ExcelDrawings drawings, XmlNode node,  Uri uriChart, Packaging.ZipPackagePart part, XmlDocument chartXml, ExcelChart topChart)
1716       {
1717           switch (chartNode.LocalName)
1718           {
1719               case "area3DChart":
1720               case "areaChart":
1721               case "stockChart":
1722                   if (topChart == null)
1723                   {
1724                       return new ExcelChart(drawings, node, uriChart, part, chartXml, chartNode);
1725                   }
1726                   else
1727                   {
1728                       return new ExcelChart(topChart, chartNode);
1729                   }
1730               case "surface3DChart":
1731               case "surfaceChart":
1732                   if (topChart == null)
1733                   {
1734                       return new ExcelSurfaceChart(drawings, node, uriChart, part, chartXml, chartNode);
1735                   }
1736                   else
1737                   {
1738                       return new ExcelSurfaceChart(topChart, chartNode);
1739                   }
1740               case "radarChart":
1741                   if (topChart == null)
1742                   {
1743                       return new ExcelRadarChart(drawings, node, uriChart, part, chartXml, chartNode);
1744                   }
1745                   else
1746                   {
1747                       return new ExcelRadarChart(topChart, chartNode);
1748                   }
1749               case "bubbleChart":
1750                   if (topChart == null)
1751                   {
1752                       return new ExcelBubbleChart(drawings, node, uriChart, part, chartXml, chartNode);
1753                   }
1754                   else
1755                   {
1756                       return new ExcelBubbleChart(topChart, chartNode);
1757                   }
1758               case "barChart":
1759               case "bar3DChart":
1760                   if (topChart == null)
1761                   {
1762                       return new ExcelBarChart(drawings, node, uriChart, part, chartXml, chartNode);
1763                   }
1764                   else
1765                   {
1766                       return new ExcelBarChart(topChart, chartNode);
1767                   }
1768               case "doughnutChart":
1769                   if (topChart == null)
1770                   {
1771                       return new ExcelDoughnutChart(drawings, node, uriChart, part, chartXml, chartNode);
1772                   }
1773                   else
1774                   {
1775                       return new ExcelDoughnutChart(topChart, chartNode);
1776                   }
1777               case "pie3DChart":
1778               case "pieChart":
1779                   if (topChart == null)
1780                   {
1781                       return new ExcelPieChart(drawings, node, uriChart, part, chartXml, chartNode);
1782                   }
1783                   else
1784                   {
1785                       return new ExcelPieChart(topChart, chartNode);
1786                   }
1787           case "ofPieChart":
1788                   if (topChart == null)
1789                   {
1790                       return new ExcelOfPieChart(drawings, node, uriChart, part, chartXml, chartNode);
1791                   }
1792                   else
1793                   {
1794                       return new ExcelBarChart(topChart, chartNode);
1795                   }
1796               case "lineChart":
1797               case "line3DChart":
1798                   if (topChart == null)
1799                   {
1800                       return new ExcelLineChart(drawings, node, uriChart, part, chartXml, chartNode);
1801                   }
1802                   else
1803                   {
1804                       return new ExcelLineChart(topChart, chartNode);
1805                   }
1806               case "scatterChart":
1807                   if (topChart == null)
1808                   {
1809                       return new ExcelScatterChart(drawings, node, uriChart, part, chartXml, chartNode);
1810                   }
1811                   else
1812                   {
1813                       return new ExcelScatterChart(topChart, chartNode);
1814                   }
1815               default:
1816                   return null;
1817           }       
1818       }
1819       internal static ExcelChart GetNewChart(ExcelDrawings drawings, XmlNode drawNode, eChartType chartType, ExcelChart topChart, ExcelPivotTable PivotTableSource)
1820       {
1821            switch(chartType)
1822            {
1823                case eChartType.Pie:
1824                case eChartType.PieExploded:
1825                case eChartType.Pie3D:
1826                case eChartType.PieExploded3D:
1827                    return new ExcelPieChart(drawings, drawNode, chartType, topChart, PivotTableSource);
1828                case eChartType.BarOfPie:
1829                case eChartType.PieOfPie:
1830                    return new ExcelOfPieChart(drawings, drawNode, chartType, topChart, PivotTableSource);
1831                case eChartType.Doughnut:
1832                case eChartType.DoughnutExploded:
1833                    return new ExcelDoughnutChart(drawings, drawNode, chartType, topChart, PivotTableSource);
1834                case eChartType.BarClustered:
1835                case eChartType.BarStacked:
1836                case eChartType.BarStacked100:
1837                case eChartType.BarClustered3D:
1838                case eChartType.BarStacked3D:
1839                case eChartType.BarStacked1003D:
1840                case eChartType.ConeBarClustered:
1841                case eChartType.ConeBarStacked:
1842                case eChartType.ConeBarStacked100:
1843                case eChartType.CylinderBarClustered:
1844                case eChartType.CylinderBarStacked:
1845                case eChartType.CylinderBarStacked100:
1846                case eChartType.PyramidBarClustered:
1847                case eChartType.PyramidBarStacked:
1848                case eChartType.PyramidBarStacked100:
1849                case eChartType.ColumnClustered:
1850                case eChartType.ColumnStacked:
1851                case eChartType.ColumnStacked100:
1852                case eChartType.Column3D:
1853                case eChartType.ColumnClustered3D:
1854                case eChartType.ColumnStacked3D:
1855                case eChartType.ColumnStacked1003D:
1856                case eChartType.ConeCol:
1857                case eChartType.ConeColClustered:
1858                case eChartType.ConeColStacked:
1859                case eChartType.ConeColStacked100:
1860                case eChartType.CylinderCol:
1861                case eChartType.CylinderColClustered:
1862                case eChartType.CylinderColStacked:
1863                case eChartType.CylinderColStacked100:
1864                case eChartType.PyramidCol:
1865                case eChartType.PyramidColClustered:
1866                case eChartType.PyramidColStacked:
1867                case eChartType.PyramidColStacked100:
1868                    return new ExcelBarChart(drawings, drawNode, chartType, topChart, PivotTableSource);
1869                case eChartType.XYScatter:
1870                case eChartType.XYScatterLines:
1871                case eChartType.XYScatterLinesNoMarkers:
1872                case eChartType.XYScatterSmooth:
1873                case eChartType.XYScatterSmoothNoMarkers:
1874                    return new ExcelScatterChart(drawings, drawNode, chartType, topChart, PivotTableSource);
1875                case eChartType.Line:
1876                case eChartType.Line3D:
1877                case eChartType.LineMarkers:
1878                case eChartType.LineMarkersStacked:
1879                case eChartType.LineMarkersStacked100:
1880                case eChartType.LineStacked:
1881                case eChartType.LineStacked100:
1882                    return new ExcelLineChart(drawings, drawNode, chartType, topChart, PivotTableSource);
1883                case eChartType.Bubble:
1884                case eChartType.Bubble3DEffect:
1885                    return new ExcelBubbleChart(drawings, drawNode, chartType, topChart, PivotTableSource);
1886                case eChartType.Radar:
1887                case eChartType.RadarFilled:
1888                case eChartType.RadarMarkers:
1889                    return new ExcelRadarChart(drawings, drawNode, chartType, topChart, PivotTableSource);
1890                case eChartType.Surface:
1891                case eChartType.SurfaceTopView:
1892                case eChartType.SurfaceTopViewWireframe:
1893                case eChartType.SurfaceWireframe:
1894                    return new ExcelSurfaceChart(drawings, drawNode, chartType, topChart, PivotTableSource);
1895                default:
1896                    return new ExcelChart(drawings, drawNode, chartType, topChart, PivotTableSource);
1897            }
1898        }
1899        public ExcelPivotTable PivotTableSource
1900        {
1901            get;
1902            private set;
1903        }
1904       internal void SetPivotSource(ExcelPivotTable pivotTableSource)
1905       {
1906           PivotTableSource = pivotTableSource;
1907           XmlElement chart = ChartXml.SelectSingleNode("c:chartSpace/c:chart", NameSpaceManager) as XmlElement;
1908
1909           var pivotSource = ChartXml.CreateElement("pivotSource", ExcelPackage.schemaChart);
1910           chart.ParentNode.InsertBefore(pivotSource, chart);
1911           pivotSource.InnerXml = string.Format("<c:name>[]{0}!{1}</c:name><c:fmtId val=\"0\"/>", PivotTableSource.WorkSheet.Name, pivotTableSource.Name);
1912
1913           var fmts = ChartXml.CreateElement("pivotFmts", ExcelPackage.schemaChart);
1914           chart.PrependChild(fmts);
1915           fmts.InnerXml = "<c:pivotFmt><c:idx val=\"0\"/><c:marker><c:symbol val=\"none\"/></c:marker></c:pivotFmt>";
1916
1917           Series.AddPivotSerie(pivotTableSource);
1918       }
1919       internal override void DeleteMe()
1920       {
1921           try
1922           {
1923               Part.Package.DeletePart(UriChart);
1924           }
1925           catch (Exception ex)
1926           {
1927               throw (new InvalidDataException("EPPlus internal error when deleteing chart.", ex));
1928           }
1929           base.DeleteMe();
1930       }
1931    }
1932}
Note: See TracBrowser for help on using the repository browser.