deleting a graph from an excel file - c#

I have a function here that takes a worksheet and generates a graph from it. I would like to delete the graph, from the excel sheet, after I save it I have tried .delete() but that just threw and error, how do I go about doing that
private void GenerateGraph(Worksheet worksheet, int lastRow, int lastColumn, string filename)
{
string topLeft = ToCell(0, 0);
string bottomRight = ToCell(lastRow - 1, lastColumn - 1);
worksheet.get_Range(ToCell(0, 0), missing).Formula = "Max(B2:" + bottomRight + ")";
worksheet.get_Range(ToCell(0, 0), missing).FormulaHidden = true;
worksheet.get_Range(ToCell(0, 0), missing).Calculate();
Range range = (Range)worksheet.Cells[1,1];
string small = (string)range.Value2;
double min = Convert.ToDouble(small);
worksheet.get_Range(ToCell(0,0),missing).Formula = "";
//Generates the graph
range = worksheet.get_Range(topLeft, bottomRight);
ChartObjects Xlchart = (ChartObjects)worksheet.ChartObjects(missing);
ChartObject chart = (ChartObject)Xlchart.Add(20, 160, 600, 500);
Excel.Chart myChart = chart.Chart;
myChart.SetSourceData(range, missing);
//sets the y axis
Axis axis = (Axis)myChart.Axes(XlAxisType.xlValue, XlAxisGroup.xlPrimary);
axis.MinimumScaleIsAuto = true;
axis.MaximumScaleIsAuto = true;
axis.HasTitle = true;
axis.AxisTitle.Text = "Measure (m)";
axis.CrossesAt = (int)(min-1);
//sets the x axis
Axis xAxis = (Axis)myChart.Axes(XlAxisType.xlCategory, XlAxisGroup.xlPrimary);
xAxis.HasTitle = true;
xAxis.AxisTitle.Text = "Position (m)";
//makes the graph a line graph
myChart.ChartType = XlChartType.xlXYScatterLinesNoMarkers;
//titles the graph
myChart.HasTitle = true;
myChart.ChartTitle.Text = "Profiles";
//saves the graph
myChart.Export(filename, "JPG", missing);
//
//here is where I would like to delete the graph
//
}

If mychart.delete doesn't do it, try mychart.parent.delete

Related

How to plot a 3D Graph to represent an object in space

I have a robot that outputs x,y,z position in space. My problem is that I can only find 2D plot in windows forms using chart.
I want to plot my robot in 3D space. Any tools I can use??
Something similar to this:
I need a free software solution for this
EDIT:
My 2D graph atm:
chart1.ChartAreas[0].AxisX.Minimum = 0;
chart1.ChartAreas[0].AxisX.Maximum = 12;
chart1.ChartAreas[0].AxisX.Interval = 1;
chart1.ChartAreas[0].AxisY.Minimum = 0;
chart1.ChartAreas[0].AxisY.Maximum = 7;
chart1.ChartAreas[0].AxisY.Interval = 1;
//example
posicao_atual_master.X = 10;
posicao_atual_master.Y = 5;
chart1.Series[0].Points.Clear();
chart1.Series[0].Points.AddXY(posicao_atual_master.X, posicao_atual_master.Y);
DESIGNER:
// chart1
//
chartArea1.AxisX.MajorGrid.Enabled = false;
chartArea1.AxisX.MajorTickMark.Enabled = false;
chartArea1.AxisY.MajorGrid.Enabled = false;
chartArea1.AxisY.MajorTickMark.Enabled = false;
chartArea1.Name = "ChartArea1";
chartArea1.Position.Auto = false;
chartArea1.Position.Height = 100F;
chartArea1.Position.Width = 90F;
this.chart1.ChartAreas.Add(chartArea1);
legend1.BackColor = System.Drawing.Color.Transparent;
legend1.BorderColor = System.Drawing.Color.Transparent;
legend1.Font = new System.Drawing.Font("Microsoft Sans Serif", 4F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Millimeter, ((byte)(1)), true);
legend1.IsTextAutoFit = false;
legend1.Name = "legen";
legend1.TableStyle = System.Windows.Forms.DataVisualization.Charting.LegendTableStyle.Tall;
this.chart1.Legends.Add(legend1);
this.chart1.Location = new System.Drawing.Point(543, 49);
this.chart1.Name = "chart1";
series1.ChartArea = "ChartArea1";
series1.ChartType = System.Windows.Forms.DataVisualization.Charting.SeriesChartType.Point;
series1.Color = System.Drawing.Color.Transparent;
series1.Legend = "legen";
series1.MarkerBorderColor = System.Drawing.Color.Black;
series1.MarkerImage = "C:\\Users\\Tiago\\Desktop\\CODIGO_TESE_FINAL_BACKUP1408_BOM\\C# - AR.Drone SDK\\AR.Dron" +
"e\\icone_drone_verde.png";
series1.MarkerImageTransparentColor = System.Drawing.Color.Red;
series1.Name = "Master";
series2.ChartArea = "ChartArea1";
series2.ChartType = System.Windows.Forms.DataVisualization.Charting.SeriesChartType.Point;
series2.Legend = "legen";
series2.MarkerImage = "C:\\Users\\Tiago\\Desktop\\CODIGO_TESE_FINAL_BACKUP1408_BOM\\Fotos dos Relatórios\\icon" +
"e_drone_vermelho.png";
series2.Name = "Slave";
this.chart1.Series.Add(series1);
this.chart1.Series.Add(series2);
this.chart1.Size = new System.Drawing.Size(1159, 359);
this.chart1.TabIndex = 7;
this.chart1.Text = "chart1";
this.chart1.MouseDown += new System.Windows.Forms.MouseEventHandler(this.chart1_MouseDown);
this.chart1.MouseMove += new System.Windows.Forms.MouseEventHandler(this.chart1_MouseMove);
this.chart1.MouseUp += new System.Windows.Forms.MouseEventHandler(this.chart1_MouseUp);
EDIT: IMAGE
You are correct, there is no proper way to use a real z-axis in the Chart control.
It does have a 3D style though, which can be used for a reasonably nice ChartArea.
You will have to do the painting of the graph in code though, as the built-in z-axis only support as many, or rather as few discret values as you have Series in the chart.
This is ok for some things, like a color cube, but when you need arbitryry data values it just won't do.
Instead you can do this:
Store the z-value of each DataPoint along with the Y-value in the YValues array.
For this you need a ChartType that supports several YValues
Code one of the xxxPaint events to draw the graphics
For this you need a conversion from values to pixels
First we prepare the chart. Many details are up to your needs;
void prepare3dChart(Chart chart, ChartArea ca)
{
ca.Area3DStyle.Enable3D = true; // set the chartarea to 3D!
ca.AxisX.Minimum = -250;
ca.AxisY.Minimum = -250;
ca.AxisX.Maximum = 250;
ca.AxisY.Maximum = 250;
ca.AxisX.Interval = 50;
ca.AxisY.Interval = 50;
ca.AxisX.Title = "X-Achse";
ca.AxisY.Title = "Y-Achse";
ca.AxisX.MajorGrid.Interval = 250;
ca.AxisY.MajorGrid.Interval = 250;
ca.AxisX.MinorGrid.Enabled = true;
ca.AxisY.MinorGrid.Enabled = true;
ca.AxisX.MinorGrid.Interval = 50;
ca.AxisY.MinorGrid.Interval = 50;
ca.AxisX.MinorGrid.LineColor = Color.LightSlateGray;
ca.AxisY.MinorGrid.LineColor = Color.LightSlateGray;
// we add two series:
chart.Series.Clear();
for (int i = 0; i < 2; i++)
{
Series s = chart.Series.Add("S" + i.ToString("00"));
s.ChartType = SeriesChartType.Bubble; // this ChartType has a YValue array
s.MarkerStyle = MarkerStyle.Circle;
s["PixelPointWidth"] = "100";
s["PixelPointGapDepth"] = "1";
}
chart.ApplyPaletteColors();
addTestData(chart);
}
Here we add some test data:
void addTestData(Chart chart)
{
Random rnd = new Random(9);
for (int i = 0; i < 100; i++)
{
double x = Math.Cos(i/10f )*88 + rnd.Next(5);
double y = Math.Sin(i/11f)*88 + rnd.Next(5);
double z = Math.Sqrt(i*2f)*88 + rnd.Next(5);
AddXY3d( chart.Series[0], x, y, z);
AddXY3d( chart.Series[1], x-111, y-222, z);
}
}
The DataPoints are added with this routine:
int AddXY3d(Series s, double xVal, double yVal, double zVal)
{
int p = s.Points.AddXY(xVal, yVal, zVal);
// the DataPoint are transparent to the regular chart drawing:
s.Points[p].Color = Color.Transparent;
return p;
}
If this Paint event we draw the data as we like it. Here are either Lines or Points:
private void chart1_PostPaint(object sender, ChartPaintEventArgs e)
{
Chart chart = sender as Chart;
if (chart .Series.Count < 1) return;
if (chart .Series[0].Points.Count < 1) return;
ChartArea ca = chart .ChartAreas[0];
e.ChartGraphics.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
List<List<PointF>> data = new List<List<PointF>>();
foreach (Series s in chart .Series)
data.Add(GetPointsFrom3D(ca, s, s.Points.ToList(), e.ChartGraphics));
renderLines(data, e.ChartGraphics.Graphics, chart , true); // pick one!
renderPoints(data, e.ChartGraphics.Graphics, chart , 6); // pick one!
}
The coodinates are calculated using axis methods:
List<PointF> GetPointsFrom3D(ChartArea ca, Series s,
List<DataPoint> dPoints, ChartGraphics cg)
{
var p3t = dPoints.Select(x => new Point3D((float)ca.AxisX.ValueToPosition(x.XValue),
(float)ca.AxisY.ValueToPosition(x.YValues[0]),
(float)ca.AxisY.ValueToPosition(x.YValues[1]))).ToArray();
ca.TransformPoints(p3t.ToArray());
return p3t.Select(x => cg.GetAbsolutePoint(new PointF(x.X, x.Y))).ToList();
}
The actual drawing happens in these routines; one draws lines the other dots:
void renderLines(List<List<PointF>> data, Graphics graphics, Chart chart, bool curves)
{
for (int i = 0; i < chart.Series.Count; i++)
{
if (data[i].Count > 1)
using (Pen pen = new Pen(Color.FromArgb(64, chart.Series[i].Color), 2.5f))
if (curves) graphics.DrawCurve(pen, data[i].ToArray());
else graphics.DrawLines(pen, data[i].ToArray());
}
}
void renderPoints(List<List<PointF>> data, Graphics graphics, Chart chart, float width)
{
for (int s = 0; s < chart.Series.Count; s++)
{
Series S = chart.Series[s];
for (int p = 0; p < S.Points.Count; p++)
using (SolidBrush brush = new SolidBrush(Color.FromArgb(64, S.Color)))
graphics.FillEllipse(brush, data[s][p].X-width/2,
data[s][p].Y-width/2,width, width);
}
}
Other drawing routines like meshes or areas can be coded just as well.. Simply add new routines using user GDI+ methods like DrawCurve or FillPolygon or maybe even DrawImage..
You can set the ChartArea.Area3DStyle.Rotation and the ChartArea.Area3DStyle.Inclination for different views, as can be seen in the animation.
Edit I have update the PostPaint method to minimze dependencies.

image displays size issue [duplicate]

This question already has answers here:
How to resize an iTextSharp.text.Image size into my code?
(3 answers)
Closed 8 years ago.
I am trying to display some images in pdf using iTextSharp.Its working fine but my problem is, some images displays in zooming from its actual size like below image,
The code I tried to display is,
iTextSharp.text.Font fontH1 = new iTextSharp.text.Font(Currier, 18, iTextSharp.text.Font.BOLD);
Document doc1 = new Document();
string path1 = Environment.GetFolderPath(Environment.SpecialFolder.CommonDocuments);
path1 = path1 + "\\DOC\\Mathematicsquestions.pdf";
iTextSharp.text.Rectangle pageSize1 = doc1.PageSize;
PdfWriter pdf = PdfWriter.GetInstance(doc1, new FileStream(path1, FileMode.Create));
doc1.Open();
pdf.Open();
PdfPTable table = new PdfPTable(2);
//actual width of table in points
table.TotalWidth = 500f;
//fix the absolute width of the table
table.LockedWidth = true;
//relative col widths in proportions - 1/3 and 2/3
float[] widths = new float[] { 0.15f, 2.5f };
table.SetWidths(widths);
table.HorizontalAlignment = 0;
//leave a gap before and after the table
table.SpacingBefore = 0f;
table.SpacingAfter = 0f;
PdfPCell cell = new PdfPCell(new Phrase("MATHEMATICS", fontH1));
cell.Colspan = 2;
cell.Border = 0;
cell.HorizontalAlignment = 1;
table.AddCell(cell);
PdfPCell cell1 = new PdfPCell(new Phrase(" "));
cell1.Colspan = 2;
cell1.Border = 0;
cell1.HorizontalAlignment = 1;
table.AddCell(cell1);
for (int i = 0; i < mach.Count; i++)
{
string temsub = mach[i].ToString();
var quepaper1 = from fm in en.Entrance_jee where fm.En_Chapter == temsub select fm;
foreach (Entrance_jee re in quepaper1)
{
if (newsno == 0)
{
newsno = 1;
}
else
{
newsno = newsno + 1;
}
if (re.En_Isimage == true)
{
imgepath = path + re.En_Questionpage1 + ".png";
imgepath2 = path + re.En_Answer + ".png";
filename = System.IO.Path.GetFileName(imgepath);
filename2 = System.IO.Path.GetFileName(imgepath2);
decfile = decfile1 + "\\R1\\CF\\" + filename;
decfile2 = decfile1 + "\\R1\\CF\\" + filename2;
string status = encobj.DecryptFile(imgepath, decfile);
status = encobj.DecryptFile(imgepath2, decfile2);
if (status == "decrypted")
{
byte[] file = File.ReadAllBytes(decfile);
File.Delete(decfile);
iTextSharp.text.Image img1 = iTextSharp.text.Image.GetInstance(file);
byte[] file2 = File.ReadAllBytes(decfile2);
File.Delete(decfile2);
iTextSharp.text.Image img2 = iTextSharp.text.Image.GetInstance(file2);
//iTextSharp.text.pdf.PdfPCell imgCell1 = new iTextSharp.text.pdf.PdfPCell();
//imgCell1.AddElement(new Chunk(img2, 0, 0));
table.AddCell(newsno.ToString());
table.AddCell(img1);
table.AddCell(" ");
table.AddCell(img2);
}
}
else
{
table.AddCell(newsno.ToString());
table.AddCell(re.En_Questionpage1.ToString());
table.AddCell(" ");
table.AddCell(re.En_Answer.ToString());
}
}
}
doc1.Add(table);
doc1.Close();
Updated : Here is my orginal images,
Someone tell me where I am wrong?
The image appears to be scaled to the full width of the table. You need to scale it to your exact size requirements.
Try something like
iTextSharp.text.Image img1 = iTextSharp.text.Image.GetInstance(file);
iTextSharp.text.Image img2 = iTextSharp.text.Image.GetInstance(file2);
img1.ScaleToFit(500f, 37f);
img2.ScaleToFit(81f, 36f);
Or alternatively you can add a container within the cell with the required dimensions and add the image to it. See full details on - http://www.mikesdotnetting.com/article/87/itextsharp-working-with-images

Add percent symbol to label on y axis in StackedColumn100

How do I format the Y axis label so it includes % symbol when using StackedColumn100?
I am using System.Windows.Forms.DataVisualization.Charting.Series charts.
here is my method for defining the chart look and feel (so far)...
private Series SetSeriesStyleStackedColumnPercentage(string sessionname, string color)
{
Series series = new Series(sessionname);
series.ChartType = SeriesChartType.StackedColumn100;
series.Color = Color.FromArgb(byte.Parse(color.Split(',')[0]),
byte.Parse(color.Split(',')[1]),
byte.Parse(color.Split(',')[2]),
byte.Parse(color.Split(',')[3]));
series.BorderWidth = 1;
series.BorderColor = Color.FromArgb(255, 0, 0, 0);
series.IsVisibleInLegend = true;
series.IsValueShownAsLabel = false;
return series;
}
There is no magic needed, just escape the percent character:
chart1.ChartAreas[yourCharArea].AxisY.LabelStyle.Format = "###0\\%";
or
chart1.ChartAreas[yourCharArea].AxisY.LabelStyle.Format = "###0.0\\%";
or whatever numeric formatting you need..

Draw ecg graph dynamically with gap between x axis interval would be 25mm while printing on paper

I have made a chart that export in PDF. But client wants that gap between each x axis interval will be 25 mm as it is ECG graph and gap between each y axis should be 5mm when printed on paper.
I have a CSV file which contains x axis data in milliseconds and y axis data, I have to show x axis in seconds with interval of 1 sec. I have break the CSV data in list so that each graph can contain only 7 sec in x axis. Functionality is working fine, but how can I adjust the graph so that while printing on paper the ECG graph can shows x axis interval gap with 25 mm. Is there any third party tool by which it can be achieved or can be shown like it has been draw on graph paper( graph background or ECG graph background) with 25mm /Sec on X Axis
As it has to be export so I can't use java script or jquery because it omits tag.
below is my code
private Byte[] GetChart(List<string[]> data)
{
var chart = new Chart
{
Width = 1000,
Height = 450,
RenderType = RenderType.ImageTag,
AntiAliasing = AntiAliasingStyles.All,
TextAntiAliasingQuality = TextAntiAliasingQuality.High
};
chart.Titles.Add(string.Empty);
chart.Titles[0].Font = new System.Drawing.Font("Arial", 16f);
chart.ChartAreas.Add("");
chart.ChartAreas[0].AxisX.Title = "Speed:25/Sec";
chart.ChartAreas[0].AxisY.Title = "Gain:10mm/mV";
chart.ChartAreas[0].AxisX.TitleFont = new System.Drawing.Font("Arial", 12f);
chart.ChartAreas[0].AxisY.TitleFont = new System.Drawing.Font("Arial", 12f);
chart.ChartAreas[0].AxisX.LabelStyle.Font = new System.Drawing.Font("Arial", 10f);
chart.ChartAreas[0].AxisX.LabelStyle.Angle = -90;
chart.ChartAreas[0].BackColor = System.Drawing.Color.White;
chart.ChartAreas[0].AxisX.IntervalOffsetType = DateTimeIntervalType.Auto;
chart.ChartAreas[0].AxisY.IntervalOffsetType = DateTimeIntervalType.Auto;
chart.ChartAreas[0].AxisX.Interval = 1;
chart.Series.Add("");
chart.Series[0].ChartType = SeriesChartType.Line;
foreach (var item in data)
{
double xval = Convert.ToDouble(item[0]) / 1000;
chart.Series[0].Points.AddXY(xval, item[1]);
}
using (var chartimage = new MemoryStream())
{
chart.SaveImage(chartimage, ChartImageFormat.Png);
return chartimage.GetBuffer();
}
}
public ActionResult ExportDataToPDF()
{
//Create the PDF Document
Document pdfDoc = new Document(PageSize.A4);
pdfDoc.SetMargins(30f, 30f, 60f, 30f);
//open the stream
pdfDoc.Open();
List<string[]> data = GetCSVData();
if (data.Count > 0)
{
double d = 0;
double.TryParse(data.LastOrDefault()[0], out d);
d = d / 1000;
double totalchart = Math.Ceiling(d / 7);
long startrange = 0; long endrange = 7000;
for (int i = 0; i < totalchart; i++)
{
var lst = data.Where(e => Convert.ToDouble(e[0]) > startrange && Convert.ToDouble(e[0]) <= endrange).ToList();
var image = iTextSharp.text.Image.GetInstance(GetChart(lst));
image.ScalePercent(50f);
pdfDoc.Add(image);
startrange = endrange;
endrange = endrange + 7000;
}
}
pdfDoc.Close();
Response.ContentType = "application/pdf";
Response.AddHeader("content-disposition", "attachment;" + "filename=EcgReport.pdf");
Response.Cache.SetCacheability(HttpCacheability.NoCache);
Response.Write(pdfDoc);
Response.End();
return View();
}
public List<string[]> GetCSVData()
{
var csv = new List<string[]>(); // or, List<YourClass>
string path = Server.MapPath("~/Files/ecg_asc1011100000318g_20121115144350032.csv");
var lines = System.IO.File.ReadAllLines(path);
string[] myColumns = new string[90];
foreach (string line in lines)
{
csv.Add(line.Split(',')); // or, populate YourClass
}
return csv;
}

how to get a value and not the formula

I am trying to obtain the minimum value from a worksheet however when I generate the minimum and place it in a cell, and then extract that value I am getting the entire formula and not the double value in the cell.... what am I doing wrong? Below is my generate graph method.
Another thing, I would also like to delete the graph after I save it I have tried .delete() but that just threw and error, how do I go about doing that
private void GenerateGraph(Worksheet worksheet, int lastRow, int lastColumn, string filename)
{
string topLeft = ToCell(0, 0);
string bottomRight = ToCell(lastRow - 1, lastColumn - 1);
worksheet.get_Range(ToCell(0, 0), missing).Formula = "Max(B2:" + bottomRight + ")";
worksheet.get_Range(ToCell(0, 0), missing).FormulaHidden = true;
worksheet.get_Range(ToCell(0, 0), missing).Calculate();
Range range = (Range)worksheet.Cells[1,1];
//
//here is where my problem is, small is being given the formula from above
//
string small = (string)range.Value2;
double min = Convert.ToDouble(small);
worksheet.get_Range(ToCell(0,0),missing).Formula = "";
//Generates the graph
range = worksheet.get_Range(topLeft, bottomRight);
ChartObjects Xlchart = (ChartObjects)worksheet.ChartObjects(missing);
ChartObject chart = (ChartObject)Xlchart.Add(20, 160, 600, 500);
Excel.Chart myChart = chart.Chart;
myChart.SetSourceData(range, missing);
//sets the y axis
Axis axis = (Axis)myChart.Axes(XlAxisType.xlValue, XlAxisGroup.xlPrimary);
axis.MinimumScaleIsAuto = true;
axis.MaximumScaleIsAuto = true;
axis.HasTitle = true;
axis.AxisTitle.Text = "Measure (m)";
axis.CrossesAt = (int)(min-1);
//sets the x axis
Axis xAxis = (Axis)myChart.Axes(XlAxisType.xlCategory, XlAxisGroup.xlPrimary);
xAxis.HasTitle = true;
xAxis.AxisTitle.Text = "Position (m)";
//makes the graph a line graph
myChart.ChartType = XlChartType.xlXYScatterLinesNoMarkers;
//titles the graph
myChart.HasTitle = true;
myChart.ChartTitle.Text = "Profiles";
//saves the graph
myChart.Export(filename, "JPG", missing);
//
//here is where I would like to delete the graph
//
}
You need:
Formula = "=Max(B2:" + bottomRight + ")"
You were missing the equals sign in the formula.

Categories