How to set Yaxis Minimum scale using using C#.net in Excel - c#

I'm using Interop excel 12.0 to create a chart.
My assigned datarange to yaxis starts from 7/5/2010 till 8/29/2011. but Y axis on chart starts from 7/12/2010 and ends at 8/22/2011 however the chart line growth shows the datas from start to end
myChart.Chart.ChartWizard(xlWorkSheet.get_Range("A1", "B62"),misValue, misValue, misValue,misValue, Excel.XlRowCol.xlColumns, false,
"Space Used Trend Report for databases DLP01P, DLP07P, DPN01P and DUV01P", "Date", "GB", misValue);
Font f = new System.Drawing.Font(FontFamily.GenericSansSerif, 10.0f);
myChart.Chart.ChartTitle.Characters.Font.Size = f.Size;
chartPage.HasTitle = true;
//Trend Line setting
//Creating a series
Excel.Series series = (Excel.Series)chartPage.SeriesCollection(1);
//Setting the series to Secondary (y) axis so as to format the same
series.AxisGroup = Excel.XlAxisGroup.xlSecondary;
//Setting the trendline type
Excel.Trendlines trendlines = (Excel.Trendlines)series.Trendlines(System.Type.Missing);
Excel.Trendline trendline = trendlines.Add(Microsoft.Office.Interop.Excel.XlTrendlineType.xlLinear, 2,
0, misValue, misValue, misValue, false, false, misValue);
//Creating a variable for yaxis and assigning the chart's y axis to the same
Excel.Axis yaxis = (Excel.Axis)chartPage.Axes(Excel.XlAxisType.xlCategory, series.AxisGroup);
yaxis.MajorUnit = 14;
yaxis.MinorUnit = 7;
yaxis.Format.Line.BackColor.RGB = Color.Red.ToArgb();
yaxis.Format.Line.ForeColor.RGB = Color.Red.ToArgb();
yaxis.MajorUnitScale = Excel.XlTimeUnit.xlDays;
yaxis.MinorUnitScale = Excel.XlTimeUnit.xlDays;
yaxis.MinimumScaleIsAuto = false;
yaxis.MinimumScale = ?????
the minimum scale is taking only double values.

If I understand you well, this is what you're looking for: in Excel a date is the day number since 1-1-1900. If you want to calculate that in C# code, keep in mind that in Excel 1900 is a leap year (which it is not, of course, but this originates from compatibility with Lotus 123!), so 7/12/2010 would be 40519.00.

Try something like this, just change the values
{
chartPrincipal.YAxis.ScaleRange.ValueHigh = 100;
chartPrincipal.YAxis.ScaleRange.ValueLow = 0;
}

Related

Change Date format in chart axis but not in excel

I am trying to get a xlWorkSheet range and format it to "MMM/YYYY" in the xAxis of a chart. But I dont want to change the date format in that WorkSheet cells where I am taking the info and where I want to keep having a "MM/YYYY" format.
I've already formatted the row to "MM/YYYY" and "MMM/YYYY", but not to use one in the excel table and the other one in just the chart.
My code is:
ChartObject myChart
Chart chartPage = myChart.Chart;
chartPage.ChartType = XlChartType.xlArea;
var yAxis = (Axis)chartPage.Axes(XlAxisType.xlValue, XlAxisGroup.xlPrimary);
Axis.HasTitle = false;
Range chartRange = xlWorkSheet.Range[xlWorkSheet.Cells[4, 1],
xlWorkSheet.Cells[rows, columns]];
Range x_Range = xlWorkSheet.Range[xlWorkSheet.Cells[1, 2], xlWorkSheet.Cells[1, columnsCount]];
Range x_Range2 = x_Range.EntireRow.NumberFormat("MMM/YYYY");
Axis xAxis = (Axis)chartPage.Axes(XlAxisType.xlValue, XlAxisGroup.xlPrimary);
xAxis.CategoryNames = x_Range2;
(...series definition... and rest of code)

How to use one Series with multiple ChartAreas?

I have a Chart with three ChartAreas. The first chart area, chartarea1 plots data from series1, chartarea2 plots series2. But then I'd like chartarea3 to plot series1 and series2. All my searches return ways of plotting multiple Series on a ChartArea and I don't have a problem with that, what I want to do is plot a Series on multiple ChartAreas. Is there a way to do this? The Series["item"].ChartArea property only sets one ChartArea.
This is my attempt, I tried creating series3 and series4 and assigned them series1 and series2 respectively, but it's not working (I suspect because they are reference-types and it doesn't actually clone series1 and series2 which I feel like I am going to have to do).
ChartArea chartarea1 = new ChartArea();
chartarea1.Name = "chartarea1";
chart1.ChartAreas.Add(chartarea1);
Series series1 = new Series();
series1.Name = "series1";
series1.ChartType = SeriesChartType.Line;
chart1.Series.Add(series1);
chart1.Series["series1"].ChartArea = "chartarea1";
chart1.Series["series1"].Points.DataBindY(someArray1);
ChartArea chartarea2 = new ChartArea();
chartarea2.Name = "chartarea2";
chart1.ChartAreas.Add(chartarea2);
Series series2 = new Series();
series2.Name = "series2";
series2.ChartType = SeriesChartType.Line;
chart1.Series.Add(series2);
chart1.Series["series2"].ChartArea = "chartarea2";
chart1.Series["series2"].Points.DataBindY(someArray2);
ChartArea chartarea3 = new ChartArea();
chartarea3.Name = "chartarea3";
chart1.ChartAreas.Add(chartarea3);
Series series3 = series1;
Series series4 = series2;
series3.Name = "series3";
series4.Name = "series4";
chart1.Series["series3"].ChartArea = "chartarea3";
chart1.Series["series4"].ChartArea = "chartarea3";
chart1.Invalidate();
As of now, when I exclude the code involving chartarea3, series3 and series4, it plots as I would expect: two line graphs, first showing the data from someArray1 and the second below, which shows the data from someArray2. But if I include the the rest of the code, then the form shows a large blank space where chartarea1 and chartarea2 are supposed to be, then chartarea3 below with sommeArray1 and sommeArray2 plotted.
Thanks in advance.

How to position excel chart using c#

I am developing a excel chart programmatically using c# and excel interop dll.
I develop this kind of chart. here is the screen shot
But i want chart like..(New Chart)
Here i am giving my full code. please see to it and guide me what extra code i need to make new chart.
Excel Data..
Excel.ChartObjects xlCharts = (Excel.ChartObjects)xlWorkSheet.ChartObjects(Type.Missing);
Excel.ChartObject myChart;
Excel.Range chartRange;
Excel.Chart chartPage;
myChart = (Excel.ChartObject)xlCharts.Add(630, 20, 300, 250);
chartRange = xlWorkSheet.Range["AW2", "BA5"];
chartPage = myChart.Chart;
chartPage.Legend.Delete();
myChart.Height = 380;
myChart.Width = 565;
myChart.Chart.HasDataTable = true;
myChart.Chart.DataTable.Font.Size = 10;
myChart.Chart.DataTable.Font.Name = "+Body";
chartPage.SetSourceData(chartRange, misValue);
chartPage.ChartType = Excel.XlChartType.xlLineMarkers;
I solved problem. Now just add some lines of code in above given code. Call this function chart_series_design(chartPage, "", ""); at the end. Function is like
public void chart_series_design(Excel.Chart chartPage,string xmsg,string ymsg)
{
chartPage.set_HasAxis(Excel.XlAxisType.xlValue, Excel.XlAxisGroup.xlSecondary, true);
chartPage.set_HasAxis(Excel.XlAxisType.xlSeriesAxis, Excel.XlAxisGroup.xlSecondary, true);
chartPage.set_HasAxis(Excel.XlAxisType.xlCategory, Excel.XlAxisGroup.xlSecondary, true);
chartPage.set_HasAxis(Excel.XlAxisType.xlValue, Excel.XlAxisGroup.xlPrimary, true);
chartPage.set_HasAxis(Excel.XlAxisType.xlSeriesAxis, Excel.XlAxisGroup.xlPrimary, true);
chartPage.set_HasAxis(Excel.XlAxisType.xlCategory, Excel.XlAxisGroup.xlPrimary, true);
Excel.Series series = (Excel.Series)chartPage.SeriesCollection(1);
series.AxisGroup = Excel.XlAxisGroup.xlSecondary;
series.AxisGroup = Excel.XlAxisGroup.xlPrimary;
series.Format.Line.Weight = 1.0F;
series.Format.Line.Visible = MsoTriState.msoFalse; //Tri-State
series.Format.Line.ForeColor.RGB = (int)Microsoft.Office.Interop.Excel.XlRgbColor.rgbWhite;
series = (Excel.Series)chartPage.SeriesCollection(2);
series.AxisGroup = Excel.XlAxisGroup.xlSecondary;
series.AxisGroup = Excel.XlAxisGroup.xlPrimary;
series.Format.Line.Weight = 1.0F;
series.Format.Line.Visible = MsoTriState.msoFalse; //Tri-State
series.Format.Line.ForeColor.RGB = (int)Microsoft.Office.Interop.Excel.XlRgbColor.rgbWhite;
series = (Excel.Series)chartPage.SeriesCollection(3);
series.AxisGroup = Excel.XlAxisGroup.xlSecondary;
series.AxisGroup = Excel.XlAxisGroup.xlPrimary;
series.Format.Line.Weight = 1.0F;
series.Format.Line.Visible = MsoTriState.msoFalse; //Tri-State
series.Format.Line.ForeColor.RGB = (int)Microsoft.Office.Interop.Excel.XlRgbColor.rgbWhite;
series = (Excel.Series)chartPage.SeriesCollection(4);
series.AxisGroup = Excel.XlAxisGroup.xlSecondary;
series.AxisGroup = Excel.XlAxisGroup.xlPrimary;
series.Format.Line.Weight = 1.0F;
series.Format.Line.Visible = MsoTriState.msoFalse; //Tri-State
series.Format.Line.ForeColor.RGB = (int)Microsoft.Office.Interop.Excel.XlRgbColor.rgbWhite;
Excel.Axis axis;
axis = (Excel.Axis)chartPage.Axes(Excel.XlAxisType.xlCategory, Excel.XlAxisGroup.xlPrimary);
axis.HasTitle = true;
axis.AxisTitle.Text = xmsg;
axis = (Excel.Axis)chartPage.Axes(Excel.XlAxisType.xlValue, Excel.XlAxisGroup.xlPrimary);
axis.HasTitle = true;
axis.AxisTitle.Text = ymsg;
}

Plotting overlapping column or bar chart

I need to plot 4 series data to MSChart using column or bar type. Can I plot those 4 series so that the data is overlapped instead of being stacked.
I just found there is a ChartGroup.Overlap property for office Excel.
How can I do it in MSChart? If not, what chart control can do this? Any info will be much appreciated.
C# chart has properties for each series. The "column" chart type has property especially for that overlapping problem
chart_1.Series["col_name"].CustomProperties = "DrawSideBySide=False";
Not sure if this is the ideal solution but if you create two ChartAreas in a chart and then just plot one on top of the other you can overlap series. This requires a lot of fiddling around with positions, sizes, axis etc to get them to line up so requires a bit of effort but produces the following
Chart _chart = new Chart();
TabPage2.Controls.Add(_chart);
_chart.Location = new Point(469, 37);
_chart.Name = "chart1";
_chart.Size = new Size(448, 260);
DataTable dt1 = new DataTable();
dt1.Columns.Add("XVals", typeof(string));
dt1.Columns.Add("YVals1", typeof(int));
dt1.Columns.Add("YVals2", typeof(int));
foreach (string c in "ABCDEF".ToCharArray()) {
dt1.Rows.Add(c, Convert.ToInt32(Math.Ceiling(VBMath.Rnd() * 20)), Convert.ToInt32(Math.Ceiling(VBMath.Rnd() * 20)));
}
ChartArea firstArea = _chart.ChartAreas.Add("First Area");
Series seriesFirst = _chart.Series.Add("First Series");
seriesFirst.ChartType = SeriesChartType.Column;
ChartArea secondArea = _chart.ChartAreas.Add("Second Area");
secondArea.BackColor = Color.Transparent;
secondArea.AlignmentOrientation = AreaAlignmentOrientations.All;
secondArea.AlignmentStyle = AreaAlignmentStyles.All;
secondArea.AlignWithChartArea = firstArea.Name;
secondArea.AxisY.LabelStyle.Enabled = false;
secondArea.AxisX.LabelStyle.Enabled = false;
Series seriesSecond = _chart.Series.Add("Second Series");
seriesSecond.ChartType = SeriesChartType.Column;
seriesSecond.ChartArea = secondArea.Name;
_chart.DataSource = dt1;
seriesFirst.Points.DataBind(dt1.DefaultView, "XVals", "YVals1", null);
seriesSecond.Points.DataBind(dt1.DefaultView, "XVals", "YVals2", null);
//Aligning the Y axis of the two chart areas
//I am assuming here the x values for both series are similar and dont need to be altered
//If using bar chart then x axis would be modifed not the y axis
secondArea.AxisY = firstArea.AxisY;
// *** Set locational values here for your first chart area***
int heightAboveChartArea = 20;
int heightBelowChartArea = 20;
int axisLabelHeight = 40;
int widthLeftOfChartArea = 20;
int widthRightOfChartArea = 20;
int heightPerBar = 20;
int numberOfPoints = _chart.Series(0).Points.Count;
// *** The following code should not normally be modified ***
_chart.ChartAreas(0).Position.X = widthLeftOfChartArea / _chart.Width * 100;
_chart.ChartAreas(0).Position.Width = 100 - (widthRightOfChartArea / _chart.Width * 100) - _chart.ChartAreas(0).Position.X;
_chart.ChartAreas(0).Position.Y = (heightAboveChartArea / _chart.Height * 100);
_chart.ChartAreas(0).Position.Height = 100 - (heightBelowChartArea / _chart.Height * 100) - _chart.ChartAreas(0).Position.Y;

How can I avoid that ZedGraph relabels my YAxis, dividing by 1000?

I am creating a C# visual studio forms application that uses zedgraph to chart the data that the program collects but I am running into the following issue when plotting the data:
My y-axis values are usually in the 100,000+ range so when zed graph plots the value it labels the y-axis labels with stuff like 0, 10, 15, 20, 25 and then on the y-axis label it will append "(10^3)" to the title and will plot the values accordingly. What I want to do is have it label the y-axis either with values like 0, 10,000, 15,000, 20,000 etc or 0, 10k, 15k, 20k and so on and not have it adjust the y-axis title.
I tried setting YAxis.Scale.MajorStep = double.Parse("10000"); but the only effect that has is to add a ton of more tick lines on the y-axis but no other effect. Here is my code that graphs the data:
private void createGraph()
{
GraphPane myPane = zdc_graph.GraphPane;
myPane.CurveList.Clear();
myPane.GraphObjList.Clear();
myPane.Title.Text = this.monitoredHost.hostName + "\nWorkState[" +
this.monitoredHost.currentWorkState + "]";
myPane.XAxis.Title.Text = "";
myPane.YAxis.Title.Text = "OPS Per Second";
myPane.YAxis.Scale.FontSpec.FontColor = Color.Blue;
myPane.YAxis.Title.FontSpec.FontColor = Color.Blue;
myPane.YAxis.Scale.MaxAuto = true;
myPane.Y2Axis.Title.Text = "Reading";
myPane.Y2Axis.IsVisible = true;
myPane.Y2Axis.Scale.FontSpec.FontColor = Color.Red;
myPane.Y2Axis.Title.FontSpec.FontColor = Color.Red;
myPane.XAxis.Type = AxisType.Date;
myPane.XAxis.Scale.Format = "T";
myPane.XAxis.Scale.MajorUnit = DateUnit.Second;
myPane.YAxis.Scale.Min = 0;
myPane.YAxis.Scale.MajorStep = double.Parse("10000");
myPane.Y2Axis.Scale.Min = 0;
LineItem kpiCurve = myPane.AddCurve("OPS Per Second",
this.monitoredHost.graphKpiList,
Color.Blue,SymbolType.Circle);
LineItem pwrCurve = myPane.AddCurve("Reading",
this.monitoredHost.graphPwrList, Color.Red,
SymbolType.Circle);
kpiCurve.Line.Width = 2.0F;
kpiCurve.Symbol.Size = 4.0F;
kpiCurve.Symbol.Fill = new Fill(Color.White);
pwrCurve.Line.Width = 2.0F;
pwrCurve.Symbol.Size = 4.0F;
pwrCurve.Symbol.Fill = new Fill(Color.White);
pwrCurve.IsY2Axis = true;
myPane.Chart.Fill = new Fill(Color.White, Color.FromArgb(255, 255, 210), -45F);
zdc_graph.AxisChange();
zdc_graph.Refresh();
}
I hope this makes sense. Thanks for the help.
ZedGraph is attempting to detect magnitude and simplify the graph. You can turn this off with the following:
myPane.YAxis.Scale.MagAuto = false;
This will result in y-axis labels like 100000.
If you want to format the label with a separator comma like 100,000:
myPane.YAxis.Scale.Format = "#,#";
Finally, if you prefer to show 100k, you'll need to subscribe to the ScaleFormatEvent and return your own format, like this:
myPane.YAxis.ScaleFormatEvent += new Axis.ScaleFormatHandler(YAxis_ScaleFormatEvent);
string YAxis_ScaleFormatEvent(GraphPane pane, Axis axis, double val, int index)
{
return String.Format("{0}k", val / 1000);
}
I am having similar problem. So applying your method it works on the application but i also want to print out the graph in a PDF file (using MigraDoc) but it does work.
public Bitmap printGraphPane()
{
ZedGraphControl graph = new ZedGraphControl();
GraphPane newGP = myPane.GraphPane;
//newGP.YAxis.Scale.Mag = 0;
//newGP.YAxis.Scale.Format = "#";
//newGP.YAxis.ScaleFormatEvent += new Axis.ScaleFormatHandler(YAxis_ScaleFormatEvent);
Bitmap bit = new Bitmap(newGraph.Width, newGraph.Height);
newGraph.ClientSize = bit.Size;
newGraph.DrawToBitmap(bit, new Rectangle(0, 0, newGraph.Width, newGraph.Height));
return bit;
}

Categories

Resources