Kaynağa Gözat

I have added chart's functionality (Bar, Line and Pie charts) with the legend, axis and 3D.

Also have changed our example.
master
DragonFire_cp 14 yıl önce
ebeveyn
işleme
6b142e0016

+ 121
- 0
DocX/Charts/Axis.cs Dosyayı Görüntüle

@@ -0,0 +1,121 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;
namespace Novacode
{
/// <summary>
/// Axis base class
/// </summary>
public abstract class Axis
{
/// <summary>
/// ID of this Axis
/// </summary>
public String Id
{
get
{
return Xml.Element(XName.Get("axId", DocX.c.NamespaceName)).Attribute(XName.Get("val")).Value;
}
}
/// <summary>
/// Return true if this axis is visible
/// </summary>
public Boolean IsVisible
{
get
{
return Xml.Element(XName.Get("delete", DocX.c.NamespaceName)).Attribute(XName.Get("val")).Value == "0";
}
set
{
if (value)
Xml.Element(XName.Get("delete", DocX.c.NamespaceName)).Attribute(XName.Get("val")).Value = "0";
else
Xml.Element(XName.Get("delete", DocX.c.NamespaceName)).Attribute(XName.Get("val")).Value = "1";
}
}
/// <summary>
/// Axis xml element
/// </summary>
internal XElement Xml { get; set; }
internal Axis(XElement xml)
{
Xml = xml;
}
public Axis(String id)
{ }
}
/// <summary>
/// Represents Category Axes
/// </summary>
public class CategoryAxis : Axis
{
internal CategoryAxis(XElement xml)
: base(xml)
{ }
public CategoryAxis(String id)
: base(id)
{
Xml = XElement.Parse(String.Format(
@"<c:catAx xmlns:c=""http://schemas.openxmlformats.org/drawingml/2006/chart"">
<c:axId val=""{0}""/>
<c:scaling>
<c:orientation val=""minMax""/>
</c:scaling>
<c:delete val=""0""/>
<c:axPos val=""b""/>
<c:majorTickMark val=""out""/>
<c:minorTickMark val=""none""/>
<c:tickLblPos val=""nextTo""/>
<c:crossAx val=""154227840""/>
<c:crosses val=""autoZero""/>
<c:auto val=""1""/>
<c:lblAlgn val=""ctr""/>
<c:lblOffset val=""100""/>
<c:noMultiLvlLbl val=""0""/>
</c:catAx>", id));
}
}
/// <summary>
/// Represents Values Axes
/// </summary>
public class ValueAxis : Axis
{
internal ValueAxis(XElement xml)
: base(xml)
{ }
public ValueAxis(String id)
: base(id)
{
Xml = XElement.Parse(String.Format(
@"<c:valAx xmlns:c=""http://schemas.openxmlformats.org/drawingml/2006/chart"">
<c:axId val=""{0}""/>
<c:scaling>
<c:orientation val=""minMax""/>
</c:scaling>
<c:delete val=""0""/>
<c:axPos val=""l""/>
<c:numFmt sourceLinked=""0"" formatCode=""General""/>
<c:majorGridlines/>
<c:majorTickMark val=""out""/>
<c:minorTickMark val=""none""/>
<c:tickLblPos val=""nextTo""/>
<c:crossAx val=""148921728""/>
<c:crosses val=""autoZero""/>
<c:crossBetween val=""between""/>
</c:valAx>", id));
}
}
}

+ 194
- 139
DocX/Charts/Chart.cs Dosyayı Görüntüle

@@ -19,8 +19,16 @@ namespace Novacode
protected XElement ChartXml { get; private set; }
protected XElement ChartRootXml { get; private set; }
/// <summary>
/// The xml representation of this chart
/// </summary>
public XDocument Xml { get; private set; }
#region Series
/// <summary>
/// Chart's series
/// </summary>
public List<Series> Series
{
get
@@ -34,44 +42,124 @@ namespace Novacode
}
}
public virtual void AddSeries(Series series)
/// <summary>
/// Return maximum count of series
/// </summary>
public virtual Int16 MaxSeriesCount { get { return Int16.MaxValue; } }
/// <summary>
/// Add a new series to this chart
/// </summary>
public void AddSeries(Series series)
{
if (ChartXml.Elements(XName.Get("ser", DocX.c.NamespaceName)).Count() == MaxSeriesCount)
throw new InvalidOperationException("Maximum series for this chart is" + MaxSeriesCount.ToString() + "and have exceeded!");
ChartXml.Add(series.Xml);
}
private ChartLegend legend;
public ChartLegend Legend { get { return legend; } }
#endregion
#region Legend
/// <summary>
/// Specifies how blank cells shall be plotted on a chart
/// Chart's legend.
/// If legend doesn't exist property is null.
/// </summary>
public DisplayBlanksAs DisplayBlanksAs
public ChartLegend Legend { get; private set; }
/// <summary>
/// Add standart legend to the chart.
/// </summary>
public void AddLegend()
{
AddLegend(ChartLegendPosition.Right, false);
}
/// <summary>
/// Add a legend with parameters to the chart.
/// </summary>
public void AddLegend(ChartLegendPosition position, Boolean overlay)
{
if (Legend != null)
RemoveLegend();
Legend = new ChartLegend(position, overlay);
ChartRootXml.Add(Legend.Xml);
}
/// <summary>
/// Remove the legend from the chart.
/// </summary>
public void RemoveLegend()
{
Legend.Xml.Remove();
Legend = null;
}
#endregion
#region Axis
/// <summary>
/// Represents the category axis
/// </summary>
public CategoryAxis CategoryAxis { get; private set; }
/// <summary>
/// Represents the values axis
/// </summary>
public ValueAxis ValueAxis { get; private set; }
/// <summary>
/// Represents existing the axis
/// </summary>
public virtual Boolean IsAxisExist { get { return true; } }
#endregion
/// <summary>
/// Get or set 3D view for this chart
/// </summary>
public Boolean View3D
{
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!");
}
return ChartXml.Name.LocalName.Contains("3D");
}
set
{
String newValue;
switch (value)
if (value)
{
if (!View3D)
{
String currentName = ChartXml.Name.LocalName;
ChartXml.Name = XName.Get(currentName.Replace("Chart", "3DChart"), DocX.c.NamespaceName);
}
}
else
{
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!");
if (View3D)
{
String currentName = ChartXml.Name.LocalName;
ChartXml.Name = XName.Get(currentName.Replace("3DChart", "Chart"), DocX.c.NamespaceName);
}
}
ChartRootXml.Element(XName.Get("dispBlanksAs", DocX.c.NamespaceName)).Attribute(XName.Get("val")).Value = newValue;
}
}
/// <summary>
/// Specifies how blank cells shall be plotted on a chart
/// </summary>
public DisplayBlanksAs DisplayBlanksAs
{
get
{
return XElementHelpers.GetValueToEnum<DisplayBlanksAs>(
ChartRootXml.Element(XName.Get("dispBlanksAs", DocX.c.NamespaceName)));
}
set
{
XElementHelpers.SetValueFromEnum<DisplayBlanksAs>(
ChartRootXml.Element(XName.Get("dispBlanksAs", DocX.c.NamespaceName)), value);
}
}
@@ -80,6 +168,7 @@ namespace Novacode
/// </summary>
public Chart()
{
// Create global xml
Xml = XDocument.Parse
(@"<?xml version=""1.0"" encoding=""UTF-8"" standalone=""yes""?>
<c:chartSpace xmlns:c=""http://schemas.openxmlformats.org/drawingml/2006/chart"" xmlns:a=""http://schemas.openxmlformats.org/drawingml/2006/main"" xmlns:r=""http://schemas.openxmlformats.org/officeDocument/2006/relationships"">
@@ -92,98 +181,57 @@ namespace Novacode
</c:chart>
</c:chartSpace>");
ChartRootXml = Xml.Root.Element(XName.Get("chart", DocX.c.NamespaceName));
ChartRootXml.Add(CreatePlotArea());
}
private XElement CreatePlotArea()
{
XElement dLbls = XElement.Parse(
@"<c:dLbls xmlns:c=""http://schemas.openxmlformats.org/drawingml/2006/chart"">
<c:showLegendKey val=""0""/>
<c:showVal val=""0""/>
<c:showCatName val=""0""/>
<c:showSerName val=""0""/>
<c:showPercent val=""0""/>
<c:showBubbleSize val=""0""/>
</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""/>");
// Create a real chart xml in an inheritor
ChartXml = CreateChartXml();
ChartXml.Add(dLbls);
ChartXml.Add(axIDval);
ChartXml.Add(axIDcat);
XElement catAx = XElement.Parse(
@"<c:catAx xmlns:c=""http://schemas.openxmlformats.org/drawingml/2006/chart"">
<c:axId val=""148921728""/>
<c:scaling>
<c:orientation val=""minMax""/>
</c:scaling>
<c:delete val=""0""/>
<c:axPos val=""b""/>
<c:majorTickMark val=""out""/>
<c:minorTickMark val=""none""/>
<c:tickLblPos val=""nextTo""/>
<c:crossAx val=""154227840""/>
<c:crosses val=""autoZero""/>
<c:auto val=""1""/>
<c:lblAlgn val=""ctr""/>
<c:lblOffset val=""100""/>
<c:noMultiLvlLbl val=""0""/>
</c:catAx>");
XElement valAx = XElement.Parse(
@"<c:valAx xmlns:c=""http://schemas.openxmlformats.org/drawingml/2006/chart"">
<c:axId val=""154227840""/>
<c:scaling>
<c:orientation val=""minMax""/>
</c:scaling>
<c:delete val=""0""/>
<c:axPos val=""l""/>
<c:numFmt sourceLinked=""0"" formatCode=""General""/>
<c:majorGridlines/>
<c:majorTickMark val=""out""/>
<c:minorTickMark val=""none""/>
<c:tickLblPos val=""nextTo""/>
<c:crossAx val=""148921728""/>
<c:crosses val=""autoZero""/>
<c:crossBetween val=""between""/>
</c:valAx>");
return new XElement(
// Create result plotarea element
XElement plotAreaXml = new XElement(
XName.Get("plotArea", DocX.c.NamespaceName),
new XElement(XName.Get("layout", DocX.c.NamespaceName)),
ChartXml, catAx, valAx);
}
ChartXml);
protected abstract XElement CreateChartXml();
// Set labels
XElement dLblsXml = XElement.Parse(
@"<c:dLbls xmlns:c=""http://schemas.openxmlformats.org/drawingml/2006/chart"">
<c:showLegendKey val=""0""/>
<c:showVal val=""0""/>
<c:showCatName val=""0""/>
<c:showSerName val=""0""/>
<c:showPercent val=""0""/>
<c:showBubbleSize val=""0""/>
<c:showLeaderLines val=""1""/>
</c:dLbls>");
ChartXml.Add(dLblsXml);
// if axes exists, create their
if (IsAxisExist)
{
CategoryAxis = new CategoryAxis("148921728");
ValueAxis = new ValueAxis("154227840");
XElement axIDcatXml = XElement.Parse(String.Format(
@"<c:axId val=""{0}"" xmlns:c=""http://schemas.openxmlformats.org/drawingml/2006/chart""/>", CategoryAxis.Id));
XElement axIDvalXml = XElement.Parse(String.Format(
@"<c:axId val=""{0}"" xmlns:c=""http://schemas.openxmlformats.org/drawingml/2006/chart""/>", ValueAxis.Id));
public void AddLegend()
{
AddLegend(ChartLegendPosition.Right, false);
}
ChartXml.Add(axIDcatXml);
ChartXml.Add(axIDvalXml);
public void AddLegend(ChartLegendPosition position, Boolean overlay)
{
if (legend != null)
RemoveLegend();
legend = new ChartLegend(position, overlay);
ChartRootXml.Add(legend.Xml);
}
plotAreaXml.Add(CategoryAxis.Xml);
plotAreaXml.Add(ValueAxis.Xml);
}
public void RemoveLegend()
{
legend.Xml.Remove();
legend = null;
ChartRootXml = Xml.Root.Element(XName.Get("chart", DocX.c.NamespaceName));
ChartRootXml.Add(plotAreaXml);
}
/// <summary>
/// An abstract method which creates the current chart xml
/// </summary>
protected abstract XElement CreateChartXml();
}
/// <summary>
/// Represents a chart series
@@ -286,6 +334,34 @@ namespace Novacode
index++;
}
}
public void Bind(IList categories, IList values)
{
if (categories.Count != values.Count)
throw new ArgumentException("Categories count must equal to Values count");
XElement ptCount = new XElement(XName.Get("ptCount", DocX.c.NamespaceName), new XAttribute(XName.Get("val"), categories.Count));
XElement formatCode = new XElement(XName.Get("formatCode", DocX.c.NamespaceName), "General");
strCache.RemoveAll();
numCache.RemoveAll();
strCache.Add(ptCount);
numCache.Add(ptCount);
numCache.Add(formatCode);
XElement pt;
for (int index = 0; index < categories.Count; index++)
{
pt = new XElement(XName.Get("pt", DocX.c.NamespaceName), new XAttribute(XName.Get("idx"), index),
new XElement(XName.Get("v", DocX.c.NamespaceName), categories[index].ToString()));
strCache.Add(pt);
pt = new XElement(XName.Get("pt", DocX.c.NamespaceName), new XAttribute(XName.Get("idx"), index),
new XElement(XName.Get("v", DocX.c.NamespaceName), values[index].ToString()));
numCache.Add(pt);
index++;
}
}
}
/// <summary>
@@ -315,19 +391,13 @@ namespace Novacode
{
get
{
switch (Xml.Element(XName.Get("legendPos", DocX.c.NamespaceName)).Attribute("val").Value)
{
case "t": return ChartLegendPosition.Top;
case "b": return ChartLegendPosition.Bottom;
case "l": return ChartLegendPosition.Left;
case "r": return ChartLegendPosition.Right;
case "tr": return ChartLegendPosition.TopRight;
default: throw new NotImplementedException();
}
return XElementHelpers.GetValueToEnum<ChartLegendPosition>(
Xml.Element(XName.Get("legendPos", DocX.c.NamespaceName)));
}
set
{
Xml.Element(XName.Get("legendPos", DocX.c.NamespaceName)).Attribute("val").Value = GetPositionValue(value);
XElementHelpers.SetValueFromEnum<ChartLegendPosition>(
Xml.Element(XName.Get("legendPos", DocX.c.NamespaceName)), value);
}
}
@@ -335,7 +405,7 @@ namespace Novacode
{
Xml = new XElement(
XName.Get("legend", DocX.c.NamespaceName),
new XElement(XName.Get("legendPos", DocX.c.NamespaceName), new XAttribute("val", GetPositionValue(position))),
new XElement(XName.Get("legendPos", DocX.c.NamespaceName), new XAttribute("val", XElementHelpers.GetXmlNameFromEnum<ChartLegendPosition>(position))),
new XElement(XName.Get("overlay", DocX.c.NamespaceName), new XAttribute("val", GetOverlayValue(overlay)))
);
}
@@ -351,29 +421,6 @@ namespace Novacode
else
return "0";
}
/// <summary>
/// ECMA-376, page 3906
/// 21.2.3.24 ST_LegendPos (Legend Position)
/// </summary>
private String GetPositionValue(ChartLegendPosition position)
{
switch (position)
{
case ChartLegendPosition.Top:
return "t";
case ChartLegendPosition.Bottom:
return "b";
case ChartLegendPosition.Left:
return "l";
case ChartLegendPosition.Right:
return "r";
case ChartLegendPosition.TopRight:
return "tr";
default:
throw new NotImplementedException();
}
}
}
/// <summary>
@@ -382,10 +429,15 @@ namespace Novacode
/// </summary>
public enum ChartLegendPosition
{
[XmlName("t")]
Top,
[XmlName("b")]
Bottom,
[XmlName("l")]
Left,
[XmlName("r")]
Right,
[XmlName("tr")]
TopRight
}
@@ -395,8 +447,11 @@ namespace Novacode
/// </summary>
public enum DisplayBlanksAs
{
[XmlName("gap")]
Gap,
[XmlName("span")]
Span,
[XmlName("zero")]
Zero
}
}
}

+ 3
- 0
DocX/Charts/PieChart.cs Dosyayı Görüntüle

@@ -12,6 +12,9 @@ namespace Novacode
/// </summary>
public class PieChart : Chart
{
public override Boolean IsAxisExist { get { return false; } }
public override Int16 MaxSeriesCount { get { return 1; } }
protected override XElement CreateChartXml()
{
return XElement.Parse(

+ 10
- 1
DocX/Charts/XElementHelpers.cs Dosyayı Görüntüle

@@ -37,6 +37,15 @@ namespace Novacode
{
if (element == null)
throw new ArgumentNullException("element");
element.Attribute(XName.Get("val")).Value = GetXmlNameFromEnum<T>(value);
}
/// <summary>
/// Return xml string for this value
/// </summary>
/// <typeparam name="T">Enum type</typeparam>
internal static String GetXmlNameFromEnum<T>(T value)
{
if (value == null)
throw new ArgumentNullException("value");
@@ -44,7 +53,7 @@ namespace Novacode
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;
return a.XmlName;
}
}

+ 1
- 1
DocX/DocX.cs Dosyayı Görüntüle

@@ -2948,7 +2948,7 @@ namespace Novacode
/// <summary>
/// Insert a chart in document
/// </summary>
public void InsertChartInTheDevelopment(Chart chart)
public void InsertChart(Chart chart)
{
// Create a new chart part uri.
String chartPartUriPath = String.Empty;

+ 1
- 0
DocX/DocX.csproj Dosyayı Görüntüle

@@ -87,6 +87,7 @@
</ItemGroup>
<ItemGroup>
<Compile Include="Border.cs" />
<Compile Include="Charts\Axis.cs" />
<Compile Include="Charts\BarChart.cs" />
<Compile Include="Charts\Chart.cs" />
<Compile Include="Charts\LineChart.cs" />

+ 44
- 13
Examples/Program.cs Dosyayı Görüntüle

@@ -14,12 +14,7 @@ namespace Examples
class Program
{
static void Main(string[] args)
{
// In the development...
BarChartAlpha();
PieChartAlpha();
LineChartAlpha();
{
// Easy
Console.WriteLine("\nRunning Easy Examples");
HelloWorld();
@@ -31,6 +26,11 @@ namespace Examples
Equations();
BarChart();
PieChart();
LineChart();
Chart3D();
// Intermediate
Console.WriteLine("\nRunning Intermediate Examples");
CreateInvoice();
@@ -44,6 +44,8 @@ namespace Examples
Console.ReadKey();
}
#region Charts
private class ChartData
{
public String Mounth { get; set; }
@@ -68,7 +70,7 @@ namespace Examples
}
}
private static void BarChartAlpha()
private static void BarChart()
{
// Create new document.
using (DocX document = DocX.Create(@"docs\BarChart.docx"))
@@ -95,12 +97,12 @@ namespace Examples
// Insert chart into document
document.InsertParagraph("Diagram").FontSize(20);
document.InsertChartInTheDevelopment(c);
document.InsertChart(c);
document.Save();
}
}
private static void PieChartAlpha()
private static void PieChart()
{
// Create new document.
using (DocX document = DocX.Create(@"docs\PieChart.docx"))
@@ -119,12 +121,12 @@ namespace Examples
// Insert chart into document
document.InsertParagraph("Diagram").FontSize(20);
document.InsertChartInTheDevelopment(c);
document.InsertChart(c);
document.Save();
}
}
private static void LineChartAlpha()
private static void LineChart()
{
// Create new document.
using (DocX document = DocX.Create(@"docs\LineChart.docx"))
@@ -148,11 +150,38 @@ namespace Examples
// Insert chart into document
document.InsertParagraph("Diagram").FontSize(20);
document.InsertChartInTheDevelopment(c);
document.InsertChart(c);
document.Save();
}
}
private static void Chart3D()
{
// Create new document.
using (DocX document = DocX.Create(@"docs\3DChart.docx"))
{
// Create chart.
BarChart c = new BarChart();
c.View3D = true;
// Create data.
List<ChartData> company1 = ChartData.CreateCompanyList1();
// Create and add series
Series s = new Series("Microsoft");
s.Color = Color.GreenYellow;
s.Bind(company1, "Mounth", "Money");
c.AddSeries(s);
// Insert chart into document
document.InsertParagraph("3D Diagram").FontSize(20);
document.InsertChart(c);
document.Save();
}
}
#endregion
/// <summary>
/// Create a document with two equations.
/// </summary>
@@ -728,12 +757,14 @@ namespace Examples
Paragraph p = document.InsertParagraph();
// Append some text and add formatting.
p.Append("Hello World")
p.Append("Hello World!^011Hello World!")
.Font(new FontFamily("Times New Roman"))
.FontSize(32)
.Color(Color.Blue)
.Bold();
// Save this document to disk.
document.Save();
Console.WriteLine("\tCreated: docs\\Hello World.docx\n");

Loading…
İptal
Kaydet