With MSChart, how to do round the edges of the bar graph? - graph

I am using System.Drawing to create the following image, but I want to switch over to MSChart (System.Windows.Forms.DataVisualization.Charting).
Has anyone been able to create the rounded edges that you see in my bar? Both bars (blue & gray) have rounded smooth edges.
UPDATE: (Adding a method returning my Chart that needs curves)
private MSChart.Chart createChart3(double dataPointYvalue, string chartName, MSChart.Axis yAxis, SysDraw.Size sizeChart)
{
// Chart
// --------------------------------
MSChart.Chart chart6 = new MSChart.Chart();
chart6.BorderlineWidth = 0;
chart6.BorderSkin.BackColor = SysDraw.Color.Empty;
//chart6.Name = chartName;
//chart6.Size = new SysDraw.Size(720, 90);
chart6.Width = 720;
chart6.Height = 90;
chart6.AntiAliasing = MSChart.AntiAliasingStyles.All;
chart6.TextAntiAliasingQuality=MSChart.TextAntiAliasingQuality.High;
chart6.IsSoftShadows = false;
// ChartAreas collection
// --------------------------------
string chartAreaName = "Default";
SysDraw.Font labelFont = new SysDraw.Font("Arial Narrow", 10,SysDraw.FontStyle.Regular);
SysDraw.Font labelFontBold = new SysDraw.Font("Arial Narrow", 10,SysDraw.FontStyle.Bold);
#region Chart Area
MSChart.ChartArea chartArea6 = new MSChart.ChartArea();
chartArea6.Area3DStyle.Enable3D = false;
chartArea6.BackGradientStyle = MSChart.GradientStyle.TopBottom;
chartArea6.BackColor = grayStart;
chartArea6.BackSecondaryColor = grayEnd;
chartArea6.BorderDashStyle=MSChart.ChartDashStyle.NotSet;
chartArea6.Name = chartAreaName;
// -- Axes under Area collection
// --------------------------------
chartArea6.AxisX.Enabled = MSChart.AxisEnabled.False;
chartArea6.AxisX.IsMarginVisible = false;
//chartArea6.AxisX.LabelStyle.Font = new SysDraw.Font("Trebuchet MS", 8.25F, SysDraw.FontStyle.Bold);
chartArea6.AxisX.LabelStyle.Font = labelFont;
chartArea6.AxisX.LabelStyle.Interval = 1D;
chartArea6.AxisX.LineColor = SysDraw.Color.FromArgb(((int)(((byte)(64)))), ((int)(((byte)(64)))), ((int)(((byte)(64)))), ((int)(((byte)(64)))));
chartArea6.AxisX.MajorGrid.LineColor = SysDraw.Color.FromArgb(((int)(((byte)(64)))), ((int)(((byte)(64)))), ((int)(((byte)(64)))), ((int)(((byte)(64)))));
chartArea6.AxisY.CustomLabels.Add(createLabelRegion(1,"Underweight",0D,18.49D,SysDraw.Color.FromArgb(((int)(((byte)(255)))), ((int)(((byte)(128)))), ((int)(((byte)(128)))))));
chartArea6.AxisY.CustomLabels.Add(createLabelRegion(1,"Normal",18.5D,24.9D,SysDraw.Color.Black));
chartArea6.AxisY.CustomLabels.Add(createLabelRegion(1,"Overweight",25D,29.9D,SysDraw.Color.FromArgb(((int)(((byte)(255)))), ((int)(((byte)(128)))), ((int)(((byte)(128)))))));
chartArea6.AxisY.CustomLabels.Add(createLabelRegion(1,"Obese",30D,50D,SysDraw.Color.Red));
chartArea6.AxisY.CustomLabels.Add(createLabelRegion(0,"18.5",15.5D,21.5D,SysDraw.Color.Black));
chartArea6.AxisY.CustomLabels.Add(createLabelRegion(0,"25",23D,27D,SysDraw.Color.Black));
chartArea6.AxisY.CustomLabels.Add(createLabelRegion(0,"30",28D,32D,SysDraw.Color.Black));
chartArea6.AxisY.Enabled = MSChart.AxisEnabled.True;
chartArea6.AxisY.Interval = 50D;
chartArea6.AxisY.Maximum = 50D;
chartArea6.AxisY.Minimum = 0D;
chartArea6.AxisY.IntervalType = MSChart.DateTimeIntervalType.Number;
//chartArea6.AxisY.LabelStyle.Font = new SysDraw.Font("Trebuchet MS", 8.25F, SysDraw.FontStyle.Bold);
chartArea6.AxisY.LabelStyle.Font = labelFontBold;
chartArea6.AxisY.LineColor = SysDraw.Color.FromArgb(((int)(((byte)(64)))), ((int)(((byte)(64)))), ((int)(((byte)(64)))), ((int)(((byte)(64)))));
chartArea6.AxisY.MajorGrid.LineColor = SysDraw.Color.FromArgb(((int)(((byte)(64)))), ((int)(((byte)(64)))), ((int)(((byte)(64)))), ((int)(((byte)(64)))));
chartArea6.AxisY.MajorTickMark.Enabled = false;
chartArea6.AxisY2.Enabled = MSChart.AxisEnabled.True;
chartArea6.AxisY2.Interval = 50D;
chartArea6.AxisY2.Maximum = 50D;
chartArea6.AxisY2.Minimum = 0D;
chartArea6.AxisY2.MajorTickMark.Enabled = false;
#endregion
chart6.ChartAreas.Add(chartArea6);
// Series Collection Editor
// --------------------------------
#region Series
// -- Datapoints
// --------------------------------
MSChart.DataPoint dataPoint19 = new MSChart.DataPoint(0D,dataPointYvalue);
MSChart.Series series7 = new MSChart.Series();
series7.BackGradientStyle = MSChart.GradientStyle.TopBottom;
series7.Color = blueStart;
series7.BackSecondaryColor = blueEnd;
series7.BorderColor = SysDraw.Color.FromArgb(((int)(((byte)(180)))), ((int)(((byte)(26)))), ((int)(((byte)(59)))), ((int)(((byte)(105)))));
series7.ChartArea = chartAreaName;
series7.ChartType = MSChart.SeriesChartType.Bar;
series7.Name = "PlotMemberValue";
series7.Points.Add(dataPoint19);
#endregion
chart6.Series.Add(series7);
// Legend
// --------------------------------
#region Legend
MSChart.Legend legend6 = new MSChart.Legend();
legend6.BackColor = SysDraw.Color.Transparent;
legend6.Enabled = false;
legend6.Font = new SysDraw.Font("Trebuchet MS", 8.25F, SysDraw.FontStyle.Bold);
legend6.IsTextAutoFit = false;
legend6.Name = "Default";
#endregion
//chart6.Legends.Add(legend6);
// Title
// --------------------------------
// Annotations
// --------------------------------
chart6.Annotations.Add(valueAnnotation(dataPoint19));
chart6.Annotations.Add(regionDividerLine(dataPoint19,chartAreaName,18.5D));
chart6.Annotations.Add(regionDividerLine(dataPoint19,chartAreaName,25D));
chart6.Annotations.Add(regionDividerLine(dataPoint19,chartAreaName,30D));
return chart6;
}

Can you provide the basic chart you are using and i can continue to get it closer however I believe you will be using
chart.BorderSkin.SkinStyle = BorderSkinStyle.Emboss;

The only way I can think of to do something like that would be to use the PostPaint event in order to draw on top of the standard square bars. You could try to hide the corner by drawing a transparent bitmap for example. It might be quite tricky to achieve pixel perfect alignment though. The code below demonstrate the principle only and does not resolve how to correctly position the bitmap.
private void chart1_PostPaint(object sender, System.Windows.Forms.DataVisualization.Charting.ChartPaintEventArgs e)
{
// Painting series object
if (e.ChartElement is System.Windows.Forms.DataVisualization.Charting.Series)
{
Series series = (Series)e.ChartElement;
foreach (DataPoint pt in series.Points)
{
// Load bitmap from resource
System.Drawing.Image bitmap = Properties.Resources.corners;
// Set Red color as transparent
ImageAttributes attrib = new ImageAttributes();
attrib.SetColorKey(Color.Red, Color.Red, ColorAdjustType.Default);
// Calculates marker position depending on the data point X and Y values
RectangleF imagePosition = RectangleF.Empty;
imagePosition.Y = (float)e.ChartGraphics.GetPositionFromAxis(
"Default", AxisName.X, pt.XValue);
imagePosition.X = (float)e.ChartGraphics.GetPositionFromAxis(
"Default", AxisName.Y, pt.YValues[0]);
imagePosition = e.ChartGraphics.GetAbsoluteRectangle(imagePosition);
imagePosition.Width = bitmap.Width;
imagePosition.Height = bitmap.Height;
imagePosition.X -= bitmap.Width - 1;
imagePosition.Y -= 1;
// Draw image
e.ChartGraphics.Graphics.DrawImage(bitmap,
Rectangle.Round(imagePosition),
0, 0, bitmap.Width, bitmap.Height,
GraphicsUnit.Pixel,
attrib);
// Dispose image object
bitmap.Dispose();
}
}

Related

EPPlus ColumnStacked chart data point colors

I am able to generate Column Stacked chart using EPPlus. There is is requirement to change the color of datapoint.
I found the solution of at enter link description here but it only changes the color of first datapoint of the series. Can I get help to change the color of other datapoints as well. Here is the concept that I am looking for enter image description here
Here is the function that helps to change datapoint first color
public void SetDataPointStyle(OfficeOpenXml.Drawing.Chart.ExcelChart chart, ExcelChartSerie series, int totalDataPoint, Color color)
{
var i = 0;
var found = false;
foreach (var s in chart.Series)
{
if (s == series)
{
found = true;
break;
}
++i;
}
if (!found) throw new InvalidOperationException("series not found.");
var nsm = chart.WorkSheet.Drawings.NameSpaceManager;
var nschart = nsm.LookupNamespace("c");
var nsa = nsm.LookupNamespace("a");
var node = chart.ChartXml.SelectSingleNode(#"c:chartSpace/c:chart/c:plotArea/c:barChart/c:ser[c:idx[#val='" + i.ToString(System.Globalization.CultureInfo.InvariantCulture) + "']]", nsm);
var doc = chart.ChartXml;
var spPr = doc.CreateElement("c:spPr", nschart);
var solidFill = spPr.AppendChild(doc.CreateElement("a:solidFill", nsa));
var srgbClr = solidFill.AppendChild(doc.CreateElement("a:srgbClr", nsa));
var valattrib = srgbClr.Attributes.Append(doc.CreateAttribute("val"));
valattrib.Value = ToHex(color).Substring(1);
//var ln = spPr.AppendChild(doc.CreateElement("a:ln", nsa));
//var lnSolidFill = ln.AppendChild(doc.CreateElement("a:solidFill", nsa));
//var lnSrgbClr = lnSolidFill.AppendChild(doc.CreateElement("a:srgbClr", nsa));
//var lnValattrib = lnSrgbClr.Attributes.Append(doc.CreateAttribute("val"));
//lnValattrib.Value = ToHex(Color.Gray).Substring(1);
node.AppendChild(spPr);
}
public String ToHex(Color c)
{
return "#" + c.R.ToString("X2") + c.G.ToString("X2") + c.B.ToString("X2");
}
SetDataPointStyle(chart, chart.Series[0], 1, Color.Tan);
You have to populate a series of data point colors per series. Here is an extension method that will set the series data points to random colors. Just have to specify the serie number. If pick your own colors just override the logic or send in an array to use:
public static void SetChartPointRandomColors(this ExcelChart chart, int serieNumber)
{
var chartXml = chart.ChartXml;
var nsa = chart.WorkSheet.Drawings.NameSpaceManager.LookupNamespace("a");
var nsuri = chartXml.DocumentElement.NamespaceURI;
var nsm = new XmlNamespaceManager(chartXml.NameTable);
nsm.AddNamespace("a", nsa);
nsm.AddNamespace("c", nsuri);
var serieNode = chart.ChartXml.SelectSingleNode(#"c:chartSpace/c:chart/c:plotArea/c:barChart/c:ser[c:idx[#val='" + serieNumber + "']]", nsm);
var serie = chart.Series[serieNumber];
var points = serie.Series.Length;
var rand = new Random(serieNumber);
for (var i = 1; i <= points; i++)
{
var dPt = chartXml.CreateNode(XmlNodeType.Element, "dPt", nsuri);
var idx = chartXml.CreateNode(XmlNodeType.Element, "idx", nsuri);
var att = chartXml.CreateAttribute("val", nsuri);
att.Value = i.ToString();
idx.Attributes.Append(att);
dPt.AppendChild(idx);
var srgbClr = chartXml.CreateNode(XmlNodeType.Element, "srgbClr", nsa);
att = chartXml.CreateAttribute("val");
//Generate a random color - override with own logic to specify
var color = Color.FromArgb(rand.Next(256), rand.Next(256), rand.Next(256));
att.Value = $"{color.R:X2}{color.G:X2}{color.B:X2}";
srgbClr.Attributes.Append(att);
var solidFill = chartXml.CreateNode(XmlNodeType.Element, "solidFill", nsa);
solidFill.AppendChild(srgbClr);
var spPr = chartXml.CreateNode(XmlNodeType.Element, "spPr", nsuri);
spPr.AppendChild(solidFill);
dPt.AppendChild(spPr);
serieNode.AppendChild(dPt);
}
}
Here is an example of usage:
[TestMethod]
public void Chart_BarChart_Colors_Test()
{
//Throw in some data
var datatable = new DataTable("tblData");
datatable.Columns.AddRange(new[]{new DataColumn("Col1", typeof(int)),new DataColumn("Col2", typeof(int)),new DataColumn("Col3", typeof(int))});
for (var i = 0; i < 10; i++){var row = datatable.NewRow();row[0] = i;row[1] = i * 10;row[2] = i * 15;datatable.Rows.Add(row);}
//Create a test file
var fileInfo = new FileInfo(#"c:\temp\Chart_BarChart_Colors.xlsx");
if (fileInfo.Exists)
fileInfo.Delete();
using (var pck = new ExcelPackage(fileInfo))
{
var workbook = pck.Workbook;
var worksheet = workbook.Worksheets.Add("Sheet1");
worksheet.Cells.LoadFromDataTable(datatable, true);
var chart = worksheet.Drawings.AddChart("chart test", eChartType.ColumnStacked);
chart.Series.Add(worksheet.Cells["B2:B11"], worksheet.Cells["A2:A11"]);
chart.Series.Add(worksheet.Cells["C2:C11"], worksheet.Cells["A2:A11"]);
chart.SetChartPointRandomColors(0);
chart.SetChartPointRandomColors(1);
pck.Save();
}
}
Will give you this:
I had a similar use case, I needed to set the color of a slice (datapoint) of a doughnut chart. This question/answer helped immensely and I figured I would share the result in case anyone else hits this issue.
Note 1: I am using C# 9 with nullability enabled; you can remove the !'s if you aren't using nullability.
Note 2: I have no use case for multiple series in a doughnut chart, so this is hardcoded to series 0. You can parameterize the SelectSingleNode index if this doesn't work for you.
public void SetDoughnutChartDataPointFill(ExcelChart chart, int dataPointIdx, Color color)
{
var nsm = chart.WorkSheet.Drawings.NameSpaceManager;
var nschart = nsm.LookupNamespace("c");
var nsa = nsm.LookupNamespace("a");
var node = chart.ChartXml.SelectSingleNode(#"c:chartSpace/c:chart/c:plotArea/c:doughnutChart/c:ser[c:idx[#val='0']]", nsm)!;
var doc = chart.ChartXml;
var dPt = doc.CreateElement("c:dPt", nschart);
var cdpIdx = doc.CreateElement("c:idx", nschart);
var valattr = cdpIdx.Attributes!.Append(doc.CreateAttribute("val"));
valattr.Value = dataPointIdx.ToString();
dPt.AppendChild(cdpIdx);
var spPr = doc.CreateElement("c:spPr", nschart);
var solidFill = spPr.AppendChild(doc.CreateElement("a:solidFill", nsa))!;
var srgbClr = solidFill.AppendChild(doc.CreateElement("a:srgbClr", nsa))!;
var valattrib = srgbClr.Attributes!.Append(doc.CreateAttribute("val"));
valattrib.Value = string.Format("{0:X2}{1:X2}{2:X2}", color.R, color.G, color.B);
dPt.AppendChild(spPr);
node.AppendChild(dPt);
}

Create a custom legend in tabular format - ASP.NET Chart

I am quite new to ASP.NET Charting and have a question about adding custom component to a bar chart. I am trying to create a custom legend in a tabular format. What I mean is my legend style is table. And I am creating each LegendItem from database values and adding it to chart.Legends[0].CustomItems collection.
I get the data but I am getting all the LegendItems in one row. I want to display each LegendItem on new row. My current code look like this -
chart.Legends.Add(new Legend
{
LegendStyle = LegendStyle.Table,
BorderColor = Color.Black,
BorderWidth = 1,
BorderDashStyle = ChartDashStyle.Solid,
Alignment = StringAlignment.Center,
DockedToChartArea = areaCounter.ToString(),
Docking = Docking.Bottom,
Name = "CustomLegend",
IsTextAutoFit = true,
InterlacedRows = true,
TableStyle = LegendTableStyle.Auto,
IsDockedInsideChartArea = false
});
LegendItem newItem = new LegendItem();
newItem.Cells.Add(LegendCellType.Text, " - value1 - ", ContentAlignment.MiddleCenter);
newItem.Cells.Add(LegendCellType.Text, " - State Average = - ", ContentAlignment.MiddleCenter);
newItem.Cells[1].CellSpan = 2;
newItem.BorderColor = Color.Black;
newItem.Cells.Add(LegendCellType.Text, " - ", ContentAlignment.MiddleCenter);
newItem.Cells.Add(LegendCellType.Text, " - top - ", ContentAlignment.MiddleCenter);
chart.Legends[1].CustomItems.Add(newItem);
LegendItem newItem1 = new LegendItem();
newItem1.Cells.Add(LegendCellType.Text, "value1", ContentAlignment.MiddleCenter);
newItem1.Cells.Add(LegendCellType.Text, "State Average =", ContentAlignment.MiddleCenter);
newItem1.Cells[1].CellSpan = 2;
newItem1.BorderColor = Color.Black;
newItem1.Cells.Add(LegendCellType.Text, "", ContentAlignment.MiddleCenter);
newItem1.Cells.Add(LegendCellType.Text, "top", ContentAlignment.MiddleCenter);
chart.Legends[1].CustomItems.Add(newItem1);
newItem and newItem1 both appear on same row as legend. Can you please help me solve this issue ? I'd really appreciate your help.
Found out that once I add HeaderSeparator to my custom Legend object and handle the chat object's CustomizeLegend event it worked as I wanted. The custom items are displayed on separate rows. Here are the changes that I did.
chart.Legends.Add(new Legend
{
LegendStyle = LegendStyle.Table,
BorderColor = Color.Black,
BorderWidth = 1,
BorderDashStyle = ChartDashStyle.Solid,
Alignment = StringAlignment.Center,
DockedToChartArea = areaCounter.ToString(),
Docking = Docking.Bottom,
Name = "CustomLegend",
IsTextAutoFit = true,
InterlacedRows = true,
TableStyle = LegendTableStyle.Tall,
HeaderSeparator = LegendSeparatorStyle.Line,
HeaderSeparatorColor = Color.Gray,
IsDockedInsideChartArea = false
});
LegendItem newItem3 = new LegendItem();
var strVal = item.Value;
foreach (var val in strVal)
{
newItem3.Cells.Add(LegendCellType.Text, val, ContentAlignment.BottomCenter);
}
chart.Legends["CustomLegend"].CustomItems.Add(newItem3);
chart.CustomizeLegend += chart_CustomizeLegend;
void chart_CustomizeLegend(object sender, CustomizeLegendEventArgs e)
{
Chart chart = sender as Chart;
if (chart == null) return;
foreach (var item in e.LegendItems)
{
item.SeparatorType = LegendSeparatorStyle.Line;
item.SeparatorColor = Color.Black;
}
}

xamarin core plot y-axis value

Hello guys I have a problem with core plot in xamarin. I managed to create a graph like below:
click here for the graph
I'm using this code:
/// <summary>
/// Configure the Axes of the graph
/// </summary>
void SetupAxes()
{
var plotspace = _graph.DefaultPlotSpace;
plotspace.AllowsUserInteraction = true;
var axisSet = (CPTXYAxisSet)_graph.AxisSet;
// Label x with a fixed interval policy
var x = axisSet.XAxis;
x.LabelingPolicy = CPTAxisLabelingPolicy.None;
x.Title = "X Axis";
x.TitleOffset = 0;
x.MinorTickLength = 5f;
x.MajorTickLength = 7f;
x.LabelOffset = 3;
x.MajorIntervalLength = 5;
x.MinorTicksPerInterval = 4;
// Label y with an automatic label policy.
var y = axisSet.YAxis;
y.LabelingPolicy = CPTAxisLabelingPolicy.None;
y.LabelOffset = 0;
y.Title = "Y Axis";
y.TitleOffset = 0;
y.MinorTickLength = 5f;
y.MajorTickLength = 7f;
y.LabelOffset = 3;
y.MajorIntervalLength = 5;
y.MinorTicksPerInterval = 4;
}
/// <summary>
/// Set up data source and configure plots
/// </summary>
void SetupBarPlots(List<float> inputSocket)
{
var barPlot = new CPTBarPlot
{
DataSource = new BarSourceData(inputSocket),
BaseValue = 0,
BarOffset = (NSDecimal)(-0.25),
Identifier = (NSString)"Bar Plot 1"
};
_graph.AddPlot(barPlot);
barPlot.Fill = new CPTFill(CPTColor.BrownColor);
_graph.AddPlot(barPlot, _graph.DefaultPlotSpace);
var space = _graph.DefaultPlotSpace as CPTXYPlotSpace;
space.ScaleToFitPlots(new CPTPlot[] { barPlot });
//get the highest value in the input data
var yMax = (decimal)inputSocket.Max();
decimal newYMax = yMax*2;
space.YRange = new CPTPlotRange(-20, new NSDecimalNumber(newYMax.ToString()).NSDecimalValue);
decimal newXMax = (decimal)space.XRange.MaxLimit + 2;
decimal newXMin = (decimal)space.XRange.MinLimit - 1;
space.XRange = new CPTPlotRange(new NSDecimalNumber(newXMin.ToString()).NSDecimalValue,
new NSDecimalNumber(newXMax.ToString()).NSDecimalValue);
//RectangleF(position x, position y, width, height
//AddSubview = adding a view on top of a View
_view.AddSubview(new CPTGraphHostingView(new RectangleF(20, 320, 662, 320))
{
HostedGraph = _graph
});
}
I want to show y value in the graph (red square in the image) so it could look like a proper graph. Anyone has an experience how to create graph using Xamarin/monotouch? There is not quite a lot of xamarin tutorial for core plot. Thanks before :)
Turns out I have to set labellingPolicy to Automatic. See below:
y.LabelingPolicy = CPTAxisLabelingPolicy.Automatic;
Then it will set the y axis value based on the data.

Adding text , image to asp.net chart control

I am using asp.net chart control to display chart on my website , below is the snippet of it:
The issue is i want to add the text and an arrow line on each point , so for instance on the point (60,october) I want to write text at this point: projection was highest and an arrow image.
Is it possible to acheive something like this, any suggestion or assistance will be highly appreciated, below is the code i have used to generate this chart:
double[] yValues = { 15, 60, 12, 13 };
string[] xValues = { "September", "October", "November", "December" };
chart.Width = 500;
chart.Height = 200;
chart.BorderSkin.SkinStyle = BorderSkinStyle.FrameThin1;
ChartArea ca = new ChartArea();
ca.Name = "Default";
ca.AxisX.LineColor = System.Drawing.ColorTranslator.FromHtml("#FEFEFE");
ca.AxisX.LineWidth = 3;
ca.AxisX.MajorGrid.LineDashStyle = ChartDashStyle.Dash;
ca.AxisX.MajorGrid.Enabled = false;
ca.AxisX.MajorTickMark.LineWidth = 2;
ca.AxisX.LabelStyle.Format = "L";
ca.AxisY.LineColor = System.Drawing.ColorTranslator.FromHtml("#FEFEFE");
ca.AxisY.LineWidth = 3;
ca.AxisY.MajorGrid.Enabled = true;
ca.AxisY.MajorTickMark.LineWidth = 2;
ca.AxisY.Title = "yaxis";
chart.ChartAreas.Add(ca);
Legend legend = new Legend();
chart.Legends.Add(legend);
Series series = new Series("Series1");
series.IsValueShownAsLabel = false;
series.MarkerStyle = MarkerStyle.Circle;
series.BorderWidth = 5;
series.ChartType = SeriesChartType.Line;
series.ShadowOffset = 2;
series.XValueType = ChartValueType.String;
series.YValueType = ChartValueType.Double;
series.Font = new System.Drawing.Font("Trebuchet MS", 8);
series.BorderColor = System.Drawing.ColorTranslator.FromHtml("#33CCFF");
series.Color = System.Drawing.ColorTranslator.FromHtml("#33CCFF");
chart.Series.Add(series);
chart.Series["Series1"].Points.DataBindXY(xValues, yValues);
chart.DataManipulator.InsertEmptyPoints(1, System.Web.UI.DataVisualization.Charting.IntervalType.Days, "Series1");
You need to search for the largest data point and use property
datapoint.Label = "projection was highest";
Also easiest way to highlight the point is to use datapoint.MarkerStyle property. You can draw an arrow but I dont think its worth the hassle.

Argument out of Exception unhandled in MigraDoc

static void Main(string[] args)
{
string saveFileAs = "D:\\Hello.pdf";
Program p = new Program();
Document doc = p.CreateDocument();
PdfDocumentRenderer renderer = new PdfDocumentRenderer(true, PdfSharp.Pdf.PdfFontEmbedding.Always);
renderer.Document = doc;
renderer.RenderDocument();
renderer.PdfDocument.Save("D:\\Hello.pdf");
Process.Start(saveFileAs);
}
public Document CreateDocument()
{
// Create a new MigraDoc document
this.document = new Document();
this.document.Info.Title = "A sample invoice";
this.document.Info.Subject = "Demonstrates how to create an invoice.";
this.document.Info.Author = "Chandana Amarnath";
DefineStyles();
CreatePage();
FillContent();
return this.document;
}
void CreatePage()
{
// Each MigraDoc document needs at least one section.
Section section = this.document.AddSection();
// Put a logo in the header
Image image = section.Headers.Primary.AddImage("D:\\Cubes.jpg");
image.Height = "2.5cm";
image.LockAspectRatio = true;
image.RelativeVertical = RelativeVertical.Line;
image.RelativeHorizontal = RelativeHorizontal.Margin;
image.Top = ShapePosition.Top;
image.Left = ShapePosition.Right;
image.WrapFormat.Style = WrapStyle.Through;
// Create footer
Paragraph paragraph = section.Footers.Primary.AddParagraph();
// The following one prints at the footer;
paragraph.AddText("Aldata Inc.");
paragraph.Format.Font.Size = 9;
paragraph.Format.Alignment = ParagraphAlignment.Center;
// Create the text frame for the address
this.addressFrame = section.AddTextFrame();
this.addressFrame.Height = "3.0cm";
this.addressFrame.Width = "7.0cm";
this.addressFrame.Left = ShapePosition.Left;
this.addressFrame.RelativeHorizontal = RelativeHorizontal.Margin;
this.addressFrame.Top = "5.0cm";
this.addressFrame.RelativeVertical = RelativeVertical.Page;
// Put sender in address frame
paragraph = this.addressFrame.AddParagraph("Aldata-Apollo Inc.");
paragraph.Format.Font.Name = "Times New Roman";
paragraph.Format.Font.Size = 7;
paragraph.Format.SpaceAfter = 3;
// Add the print date field
paragraph = section.AddParagraph();
paragraph.Format.SpaceBefore = "8cm";
paragraph.Style = "Reference";
paragraph.AddFormattedText("Section Comparator", TextFormat.Bold);
paragraph.AddTab();
paragraph.AddText("Date: ");
paragraph.AddDateField("dd.MM.yyyy");
// Create the item table
this.table = section.AddTable();
this.table.Style = "Table";
this.table.Borders.Color = Color.Parse("Black");
this.table.Borders.Width = 0.25;
this.table.Borders.Left.Width = 0.5;
this.table.Borders.Right.Width = 0.5;
this.table.Rows.LeftIndent = 0;
//************ Before you can add a row, you must define the columns **********
Column column = this.table.AddColumn("4cm");
column.Format.Alignment = ParagraphAlignment.Center;
column = this.table.AddColumn("3cm");
column.Format.Alignment = ParagraphAlignment.Right;
// Create the header of the table
Row row = table.AddRow();
row.HeadingFormat = true;
row.Format.Alignment = ParagraphAlignment.Center;
row.Format.Font.Bold = true;
row.Shading.Color = Color.Parse("White");
row.Cells[0].AddParagraph("Added");
row.Cells[0].Format.Font.Bold = true;
row.Cells[0].Format.Alignment = ParagraphAlignment.Center;
row.Cells[0].MergeRight = 3;
row = table.AddRow();
row.HeadingFormat = true;
row.Format.Alignment = ParagraphAlignment.Center;
row.Format.Font.Bold = true;
row.Cells[0].AddParagraph("Deleted Items");
row.Cells[0].Format.Font.Bold = true;
row.Cells[0].Format.Alignment = ParagraphAlignment.Left;
row.Cells[0].MergeRight = 3;
this.table.SetEdge(0, 0, 2, 3, Edge.Box, BorderStyle.Single, 0.75, Color.Empty);
}
void FillContent()
{
string xmlFileName = "C:\\Section.xml";
XPathDocument xPathDocument = new XPathDocument(xmlFileName);
XPathNavigator item = xPathDocument.CreateNavigator();
XPathNodeIterator iter = item.Select("/Hello/*");
while (iter.MoveNext())
{
string name = iter.Current.Name;
item = iter.Current;
Row row1 = this.table.AddRow();
Row row2 = this.table.AddRow();
row1.TopPadding = 1.5;
row1.Cells[0].Shading.Color = Color.Parse("Gray");
row1.Cells[0].VerticalAlignment = VerticalAlignment.Center;
row1.Cells[0].MergeDown = 1;
row1.Cells[1].Format.Alignment = ParagraphAlignment.Left;
row1.Cells[1].MergeRight = 3;
row1.Cells[0].AddParagraph(item.ToString());
Console.WriteLine(name + "\t:" +item);
}
Console.ReadKey();
}
I am writing code for generating my report in PDF using MigraDoc. I have downloaded the code from PDFSharp site. The following has 3 functions DefineStyles(), CreatePage(), FillContent(). I made changes in function CreatePage(), FillContent(); But when I am running the program I am getting error saying
Argument out of Exception:
Specified argument was out of the range of valid values.
In the CreatePage() I added 2 rows and 2 columns to a table. And in the FillContent() function I read my XML file. But I am unable to find where I am crossing my index range.
SOLVED
The problem is when I am setting the table.SetEdge(...). I am accessing the columns that I have not created.
Thank u all .. :)
At this step I was setting the rows that are not yet created.
this.table.SetEdge(0, 0, 2, 3, Edge.Box, BorderStyle.Single, 0.75, Color.Empty);
Instead of 3 which are the number of rows I should use 2.

Resources