Free cookie consent management tool by TermsFeed Policy Generator

source: branches/Breadcrumbs/HeuristicLab.ExtLibs/HeuristicLab.EPPlus/3.1.3/EPPlus-3.1.3/Drawing/Chart/ExcelChart.cs @ 11571

Last change on this file since 11571 was 9580, checked in by sforsten, 12 years ago

#1730:

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