| using System; | |||||
| using System.Xml.Linq; | |||||
| namespace Novacode | |||||
| { | |||||
| /// <summary> | |||||
| /// This element contains the 2-D bar or column series on this chart. | |||||
| /// 21.2.2.16 barChart (Bar Charts) | |||||
| /// </summary> | |||||
| public class BarChart : Chart | |||||
| { | |||||
| /// <summary> | |||||
| /// Specifies the possible directions for a bar chart. | |||||
| /// </summary> | |||||
| public BarDirection BarDirection | |||||
| { | |||||
| get | |||||
| { | |||||
| return XElementHelpers.GetValueToEnum<BarDirection>( | |||||
| ChartXml.Element(XName.Get("barDir", DocX.c.NamespaceName))); | |||||
| } | |||||
| set | |||||
| { | |||||
| XElementHelpers.SetValueFromEnum<BarDirection>( | |||||
| ChartXml.Element(XName.Get("barDir", DocX.c.NamespaceName)), value); | |||||
| } | |||||
| } | |||||
| /// <summary> | |||||
| /// Specifies the possible groupings for a bar chart. | |||||
| /// </summary> | |||||
| public BarGrouping BarGrouping | |||||
| { | |||||
| get | |||||
| { | |||||
| return XElementHelpers.GetValueToEnum<BarGrouping>( | |||||
| ChartXml.Element(XName.Get("grouping", DocX.c.NamespaceName))); | |||||
| } | |||||
| set | |||||
| { | |||||
| XElementHelpers.SetValueFromEnum<BarGrouping>( | |||||
| ChartXml.Element(XName.Get("grouping", DocX.c.NamespaceName)), value); | |||||
| } | |||||
| } | |||||
| /// <summary> | |||||
| /// Specifies that its contents contain a percentage between 0% and 500%. | |||||
| /// </summary> | |||||
| public Int32 GapWidth | |||||
| { | |||||
| get | |||||
| { | |||||
| return Convert.ToInt32( | |||||
| ChartXml.Element(XName.Get("gapWidth", DocX.c.NamespaceName)).Attribute(XName.Get("val")).Value); | |||||
| } | |||||
| set | |||||
| { | |||||
| if ((value < 1) || (value > 500)) | |||||
| throw new ArgumentException("GapWidth lay between 0% and 500%!"); | |||||
| ChartXml.Element(XName.Get("gapWidth", DocX.c.NamespaceName)).Attribute(XName.Get("val")).Value = value.ToString(); | |||||
| } | |||||
| } | |||||
| protected override XElement CreateChartXml() | |||||
| { | |||||
| return XElement.Parse( | |||||
| @"<c:barChart xmlns:c=""http://schemas.openxmlformats.org/drawingml/2006/chart""> | |||||
| <c:barDir val=""col""/> | |||||
| <c:grouping val=""clustered""/> | |||||
| <c:gapWidth val=""150""/> | |||||
| </c:barChart>"); | |||||
| } | |||||
| } | |||||
| /// <summary> | |||||
| /// Specifies the possible directions for a bar chart. | |||||
| /// 21.2.3.3 ST_BarDir (Bar Direction) | |||||
| /// </summary> | |||||
| public enum BarDirection | |||||
| { | |||||
| [XmlName("col")] | |||||
| Column, | |||||
| [XmlName("bar")] | |||||
| Bar | |||||
| } | |||||
| /// <summary> | |||||
| /// Specifies the possible groupings for a bar chart. | |||||
| /// 21.2.3.4 ST_BarGrouping (Bar Grouping) | |||||
| /// </summary> | |||||
| public enum BarGrouping | |||||
| { | |||||
| [XmlName("clustered")] | |||||
| Clustered, | |||||
| [XmlName("percentStacked")] | |||||
| PercentStacked, | |||||
| [XmlName("stacked")] | |||||
| Stacked, | |||||
| [XmlName("standard")] | |||||
| Standard | |||||
| } | |||||
| } |
| using System.IO.Packaging; | using System.IO.Packaging; | ||||
| using System.Collections; | using System.Collections; | ||||
| using System.Drawing; | using System.Drawing; | ||||
| using System.Reflection; | |||||
| namespace Novacode | namespace Novacode | ||||
| { | { | ||||
| /// <summary> | /// <summary> | ||||
| /// Represents a Chart in this document. | |||||
| /// Represents every Chart in this document. | |||||
| /// </summary> | /// </summary> | ||||
| public class Chart | |||||
| public abstract class Chart | |||||
| { | { | ||||
| private XElement ChartXml; | |||||
| private XElement ChartRootXml; | |||||
| protected XElement ChartXml { get; private set; } | |||||
| protected XElement ChartRootXml { get; private set; } | |||||
| public XDocument Xml { get; private set; } | public XDocument Xml { get; private set; } | ||||
| } | } | ||||
| } | } | ||||
| public virtual void AddSeries(Series series) | |||||
| { | |||||
| ChartXml.Add(series.Xml); | |||||
| } | |||||
| private ChartLegend legend; | private ChartLegend legend; | ||||
| public ChartLegend Legend { get { return legend; } } | public ChartLegend Legend { get { return legend; } } | ||||
| /// <summary> | |||||
| /// Specifies how blank cells shall be plotted on a chart | |||||
| /// </summary> | |||||
| public DisplayBlanksAs DisplayBlanksAs | |||||
| { | |||||
| get | |||||
| { | |||||
| String value = ChartRootXml.Element(XName.Get("dispBlanksAs", DocX.c.NamespaceName)).Attribute(XName.Get("val")).Value; | |||||
| switch (value) | |||||
| { | |||||
| case "gap": return DisplayBlanksAs.Gap; | |||||
| case "span": return DisplayBlanksAs.Span; | |||||
| case "zero": return DisplayBlanksAs.Zero; | |||||
| default: throw new NotImplementedException("This DisplayBlanksAsType was not implement!"); | |||||
| } | |||||
| } | |||||
| set | |||||
| { | |||||
| String newValue; | |||||
| switch (value) | |||||
| { | |||||
| case DisplayBlanksAs.Gap: newValue = "gap"; | |||||
| break; | |||||
| case DisplayBlanksAs.Span: newValue = "span"; | |||||
| break; | |||||
| case DisplayBlanksAs.Zero: newValue = "zero"; | |||||
| break; | |||||
| default: throw new NotImplementedException("This DisplayBlanksAsType was not implement!"); | |||||
| } | |||||
| ChartRootXml.Element(XName.Get("dispBlanksAs", DocX.c.NamespaceName)).Attribute(XName.Get("val")).Value = newValue; | |||||
| } | |||||
| } | |||||
| /// <summary> | /// <summary> | ||||
| /// Create an Chart for this document | /// Create an Chart for this document | ||||
| /// </summary> | /// </summary> | ||||
| <c:showPercent val=""0""/> | <c:showPercent val=""0""/> | ||||
| <c:showBubbleSize val=""0""/> | <c:showBubbleSize val=""0""/> | ||||
| </c:dLbls>"); | </c:dLbls>"); | ||||
| XElement axIDcat = XElement.Parse( | |||||
| @"<c:axId val=""154227840"" xmlns:c=""http://schemas.openxmlformats.org/drawingml/2006/chart""/>"); | |||||
| XElement axIDval = XElement.Parse( | |||||
| @"<c:axId val=""148921728"" xmlns:c=""http://schemas.openxmlformats.org/drawingml/2006/chart""/>"); | |||||
| ChartXml = XElement.Parse( | |||||
| @"<c:barChart xmlns:c=""http://schemas.openxmlformats.org/drawingml/2006/chart""> | |||||
| <c:barDir val=""col""/> | |||||
| <c:grouping val=""clustered""/> | |||||
| <c:gapWidth val=""150""/> | |||||
| <c:axId val=""148921728""/> | |||||
| <c:axId val=""154227840""/> | |||||
| </c:barChart>"); | |||||
| ChartXml.Add(dLbls); | |||||
| ChartXml = CreateChartXml(); | |||||
| ChartXml.Add(dLbls); | |||||
| ChartXml.Add(axIDval); | |||||
| ChartXml.Add(axIDcat); | |||||
| XElement catAx = XElement.Parse( | XElement catAx = XElement.Parse( | ||||
| @"<c:catAx xmlns:c=""http://schemas.openxmlformats.org/drawingml/2006/chart""> | @"<c:catAx xmlns:c=""http://schemas.openxmlformats.org/drawingml/2006/chart""> | ||||
| ChartXml, catAx, valAx); | ChartXml, catAx, valAx); | ||||
| } | } | ||||
| public void AddSeries(Series series) | |||||
| { | |||||
| ChartXml.Add(series.Xml); | |||||
| } | |||||
| protected abstract XElement CreateChartXml(); | |||||
| public void AddLegend() | public void AddLegend() | ||||
| { | { | ||||
| } | } | ||||
| } | } | ||||
| /// <summary> | /// <summary> | ||||
| /// Represents a chart series | /// Represents a chart series | ||||
| /// </summary> | /// </summary> | ||||
| } | } | ||||
| /// <summary> | /// <summary> | ||||
| /// Specifies the possible positions for a legend | |||||
| /// Specifies the possible positions for a legend. | |||||
| /// 21.2.3.24 ST_LegendPos (Legend Position) | |||||
| /// </summary> | /// </summary> | ||||
| public enum ChartLegendPosition | public enum ChartLegendPosition | ||||
| { | { | ||||
| Right, | Right, | ||||
| TopRight | TopRight | ||||
| } | } | ||||
| /// <summary> | |||||
| /// Specifies the possible ways to display blanks. | |||||
| /// 21.2.3.10 ST_DispBlanksAs (Display Blanks As) | |||||
| /// </summary> | |||||
| public enum DisplayBlanksAs | |||||
| { | |||||
| Gap, | |||||
| Span, | |||||
| Zero | |||||
| } | |||||
| } | } |
| using System; | |||||
| using System.Collections.Generic; | |||||
| using System.Linq; | |||||
| using System.Text; | |||||
| using System.Xml.Linq; | |||||
| namespace Novacode | |||||
| { | |||||
| /// <summary> | |||||
| /// This element contains the 2-D line chart series. | |||||
| /// 21.2.2.97 lineChart (Line Charts) | |||||
| /// </summary> | |||||
| public class LineChart: Chart | |||||
| { | |||||
| /// <summary> | |||||
| /// Specifies the kind of grouping for a column, line, or area chart. | |||||
| /// </summary> | |||||
| public Grouping Grouping | |||||
| { | |||||
| get | |||||
| { | |||||
| return XElementHelpers.GetValueToEnum<Grouping>( | |||||
| ChartXml.Element(XName.Get("grouping", DocX.c.NamespaceName))); | |||||
| } | |||||
| set | |||||
| { | |||||
| XElementHelpers.SetValueFromEnum<Grouping>( | |||||
| ChartXml.Element(XName.Get("grouping", DocX.c.NamespaceName)), value); | |||||
| } | |||||
| } | |||||
| protected override XElement CreateChartXml() | |||||
| { | |||||
| return XElement.Parse( | |||||
| @"<c:lineChart xmlns:c=""http://schemas.openxmlformats.org/drawingml/2006/chart""> | |||||
| <c:grouping val=""standard""/> | |||||
| </c:lineChart>"); | |||||
| } | |||||
| } | |||||
| /// <summary> | |||||
| /// Specifies the kind of grouping for a column, line, or area chart. | |||||
| /// 21.2.2.76 grouping (Grouping) | |||||
| /// </summary> | |||||
| public enum Grouping | |||||
| { | |||||
| [XmlName("percentStacked")] | |||||
| PercentStacked, | |||||
| [XmlName("stacked")] | |||||
| Stacked, | |||||
| [XmlName("standard")] | |||||
| Standard | |||||
| } | |||||
| } |
| using System; | |||||
| using System.Collections.Generic; | |||||
| using System.Linq; | |||||
| using System.Text; | |||||
| using System.Xml.Linq; | |||||
| namespace Novacode | |||||
| { | |||||
| /// <summary> | |||||
| /// This element contains the 2-D pie series for this chart. | |||||
| /// 21.2.2.141 pieChart (Pie Charts) | |||||
| /// </summary> | |||||
| public class PieChart : Chart | |||||
| { | |||||
| protected override XElement CreateChartXml() | |||||
| { | |||||
| return XElement.Parse( | |||||
| @"<c:pieChart xmlns:c=""http://schemas.openxmlformats.org/drawingml/2006/chart""> | |||||
| </c:pieChart>"); | |||||
| } | |||||
| } | |||||
| } |
| using System; | |||||
| using System.Linq; | |||||
| using System.Reflection; | |||||
| using System.Xml.Linq; | |||||
| namespace Novacode | |||||
| { | |||||
| internal static class XElementHelpers | |||||
| { | |||||
| /// <summary> | |||||
| /// Get value from XElement and convert it to enum | |||||
| /// </summary> | |||||
| /// <typeparam name="T">Enum type</typeparam> | |||||
| internal static T GetValueToEnum<T>(XElement element) | |||||
| { | |||||
| if (element == null) | |||||
| throw new ArgumentNullException("element"); | |||||
| String value = element.Attribute(XName.Get("val")).Value; | |||||
| foreach (T e in Enum.GetValues(typeof(T))) | |||||
| { | |||||
| FieldInfo fi = typeof(T).GetField(e.ToString()); | |||||
| if (fi.GetCustomAttributes(typeof(XmlNameAttribute), false).Count() == 0) | |||||
| throw new Exception(String.Format("Attribute 'XmlNameAttribute' is not assigned to {0} fields!", typeof(T).Name)); | |||||
| XmlNameAttribute a = (XmlNameAttribute)fi.GetCustomAttributes(typeof(XmlNameAttribute), false).First(); | |||||
| if (a.XmlName == value) | |||||
| return e; | |||||
| } | |||||
| throw new ArgumentException("Invalid element value!"); | |||||
| } | |||||
| /// <summary> | |||||
| /// Convert value to xml string and set it into XElement | |||||
| /// </summary> | |||||
| /// <typeparam name="T">Enum type</typeparam> | |||||
| internal static void SetValueFromEnum<T>(XElement element, T value) | |||||
| { | |||||
| if (element == null) | |||||
| throw new ArgumentNullException("element"); | |||||
| if (value == null) | |||||
| throw new ArgumentNullException("value"); | |||||
| FieldInfo fi = typeof(T).GetField(value.ToString()); | |||||
| if (fi.GetCustomAttributes(typeof(XmlNameAttribute), false).Count() == 0) | |||||
| throw new Exception(String.Format("Attribute 'XmlNameAttribute' is not assigned to {0} fields!", typeof(T).Name)); | |||||
| XmlNameAttribute a = (XmlNameAttribute)fi.GetCustomAttributes(typeof(XmlNameAttribute), false).First(); | |||||
| element.Attribute(XName.Get("val")).Value = a.XmlName; | |||||
| } | |||||
| } | |||||
| /// <summary> | |||||
| /// This attribute applied to enum's fields for definition their's real xml names in DocX file. | |||||
| /// </summary> | |||||
| /// <example> | |||||
| /// public enum MyEnum | |||||
| /// { | |||||
| /// [XmlName("one")] // This means, that xml element has 'val="one"' | |||||
| /// ValueOne, | |||||
| /// [XmlName("two")] // This means, that xml element has 'val="two"' | |||||
| /// ValueTwo | |||||
| /// } | |||||
| /// </example> | |||||
| [AttributeUsage(AttributeTargets.Field, Inherited = false, AllowMultiple = false)] | |||||
| internal sealed class XmlNameAttribute : Attribute | |||||
| { | |||||
| /// <summary> | |||||
| /// Real xml name | |||||
| /// </summary> | |||||
| public String XmlName { get; private set; } | |||||
| public XmlNameAttribute(String xmlName) | |||||
| { | |||||
| XmlName = xmlName; | |||||
| } | |||||
| } | |||||
| } |
| </ItemGroup> | </ItemGroup> | ||||
| <ItemGroup> | <ItemGroup> | ||||
| <Compile Include="Border.cs" /> | <Compile Include="Border.cs" /> | ||||
| <Compile Include="Chart.cs" /> | |||||
| <Compile Include="Charts\BarChart.cs" /> | |||||
| <Compile Include="Charts\Chart.cs" /> | |||||
| <Compile Include="Charts\LineChart.cs" /> | |||||
| <Compile Include="Charts\PieChart.cs" /> | |||||
| <Compile Include="Charts\XElementHelpers.cs" /> | |||||
| <Compile Include="Container.cs" /> | <Compile Include="Container.cs" /> | ||||
| <Compile Include="Footers.cs" /> | <Compile Include="Footers.cs" /> | ||||
| <Compile Include="Footer.cs" /> | <Compile Include="Footer.cs" /> |
| using (DocX document = DocX.Create(@"docs\Chart.docx")) | using (DocX document = DocX.Create(@"docs\Chart.docx")) | ||||
| { | { | ||||
| // Create chart. | // Create chart. | ||||
| Chart c = new Chart(); | |||||
| BarChart c = new BarChart(); | |||||
| c.BarDirection = BarDirection.Column; | |||||
| c.BarGrouping = BarGrouping.Standard; | |||||
| c.GapWidth = 400; | |||||
| c.AddLegend(ChartLegendPosition.Bottom, false); | c.AddLegend(ChartLegendPosition.Bottom, false); | ||||
| PieChart cc = new PieChart(); | |||||
| cc.AddLegend(ChartLegendPosition.Bottom, false); | |||||
| LineChart ccc = new LineChart(); | |||||
| ccc.AddLegend(ChartLegendPosition.Bottom, false); | |||||
| // Create data. | // Create data. | ||||
| List<ChartData> company1 = new List<ChartData>(); | List<ChartData> company1 = new List<ChartData>(); | ||||
| company1.Add(new ChartData() { Mounth = "January", Money = 100 }); | company1.Add(new ChartData() { Mounth = "January", Money = 100 }); | ||||
| s1.Color = Color.GreenYellow; | s1.Color = Color.GreenYellow; | ||||
| s1.Bind(company1, "Mounth", "Money"); | s1.Bind(company1, "Mounth", "Money"); | ||||
| c.AddSeries(s1); | c.AddSeries(s1); | ||||
| ccc.AddSeries(s1); | |||||
| Series s2 = new Series("Apple"); | Series s2 = new Series("Apple"); | ||||
| s2.Bind(company2, "Mounth", "Money"); | s2.Bind(company2, "Mounth", "Money"); | ||||
| c.AddSeries(s2); | |||||
| c.AddSeries(s2); | |||||
| cc.AddSeries(s2); | |||||
| ccc.AddSeries(s2); | |||||
| // Insert chart into document | // Insert chart into document | ||||
| document.InsertParagraph("Diagram").FontSize(20); | document.InsertParagraph("Diagram").FontSize(20); | ||||
| document.InsertParagraph("BeforeText"); | document.InsertParagraph("BeforeText"); | ||||
| document.InsertChartInTheDevelopment(c); | document.InsertChartInTheDevelopment(c); | ||||
| document.InsertChartInTheDevelopment(cc); | |||||
| document.InsertChartInTheDevelopment(ccc); | |||||
| document.InsertParagraph("AfterText"); | document.InsertParagraph("AfterText"); | ||||
| document.Save(); | document.Save(); | ||||
| } | } |