Chart axes in PowerPoint file - c#

I'm creating a chart (of ComboChart type) in the PPTX file using GemBox.Presentation (together with GemBox.Spreadsheet). I'm using the code from the PowerPoint Chart example and added parts of the Excel Combo Chart example.
This is what I have so far:
var presentation = new PresentationDocument();
var slide = presentation.Slides.AddNew(SlideLayoutType.Custom);
var chart = slide.Content.AddChart(GemBox.Presentation.ChartType.Combo, 25, 25, 300, 500);
var comboChart = (ComboChart)chart.ExcelChart;
var worksheet = comboChart.Worksheet;
worksheet.Cells["A1"].Value = "Name";
worksheet.Cells["A2"].Value = "John Doe";
worksheet.Cells["A3"].Value = "Fred Nurk";
worksheet.Cells["B1"].Value = "Salary";
worksheet.Cells["B2"].Value = 4023;
worksheet.Cells["B3"].Value = 3263;
worksheet.Cells["C1"].Value = "Max";
worksheet.Cells["C2"].Value = 4500;
worksheet.Cells["C3"].Value = 4300;
worksheet.Cells["D1"].Value = "Min";
worksheet.Cells["D2"].Value = 3000;
worksheet.Cells["D3"].Value = 2800;
comboChart.CategoryLabelsReference = "A2:A3";
var salaryChart = comboChart.Add(GemBox.Spreadsheet.Charts.ChartType.Column);
salaryChart.Series.Add("=B1", "B2:B3");
var minMaxChart = comboChart.Add(GemBox.Spreadsheet.Charts.ChartType.Line);
minMaxChart.Series.Add("=C1", "C2:C3");
minMaxChart.Series.Add("=D1", "D2:D3");
presentation.Save("output.pptx");
And this is what I get:
Now my problem is that I cannot find any way to access and format the Category axis and Vertical axis.
I tried to use chart, comboChart, salaryChart, and minMaxChart objects, but none of them have any axes properties!?
How can I, let's say, set the axes titles?

To set the axes of the Combo chart, you'll need to use the axes of one of its containing charts, so either salaryChart or minMaxChart.
Now the reason why you don't see any axes properties on them is that they are of a base type (ExcelChart). You need to cast them to a derived type, like this:
var salaryChart = (ColumnChart)comboChart.Add(GemBox.Spreadsheet.Charts.ChartType.Column);
salaryChart.Series.Add("=B1", "B2:B3");
salaryChart.Axes.Horizontal.Title.Text = "My Categories";
salaryChart.Axes.Vertical.Title.Text = "My Values";

Related

Dynamically creating charts

I am trying to dynamically create a chart for each drive in the computer, inside a form.
Each chart should be a pie chart that contains the amount of free space (colored green) and used space(colored red) in GBs.
But when I run the following code the only thing I see is blank rectangles with the titles of "C:\", "D:\" and so on.
Here is the code :
public static void DrawCharts()
{
Chart[] charts = new Chart[DriveInfo.GetDrives().Length];
DriveInfo[] drives = DriveInfo.GetDrives();
for (int i = 0; i < drives.Length; i++)
{
charts[i] = new Chart();
charts[i].Palette = ChartColorPalette.BrightPastel;
charts[i].Titles.Add(drives[i].Name);
charts[i].Series.Add("Storage");
charts[i].Series[0].ChartType = SeriesChartType.Pie;
charts[i].Location = new System.Drawing.Point(20 + i * 231, 30);
charts[i].Size = new System.Drawing.Size(230, 300);
DataPoint d = new DataPoint();
d.XValue = 1;
double[] p = { (double)drives[i].TotalFreeSpace / 1000000000 };
d.YValues = p;
d.Color = System.Drawing.Color.YellowGreen;
d.Label = "Free Space";
charts[i].Series[0].Points.Add(d);
d.Label = "Used Space";
d.XValue = 2;
double[] a = { (double)((drives[i].TotalSize - drives[i].TotalFreeSpace) / 1000000000) };
d.YValues = a;
d.Color = System.Drawing.Color.Red;
charts[i].Series[0].Points.Add(d);
Form1.tabs.TabPages[1].Controls.Add(charts[i]);
charts[i].Invalidate();
}
}
Thanks.
You are almost there.
But the most basic thing you need to add to a dynamically created chart..:
charts[i] = new Chart();
..is a ChartArea:
charts[i].ChartAreas.Add("CA1"); // pick your name!
Without it no Series can display..
Use it to style the axis with TickMarks, GridLines or Labels or to set Minima and Maxima and Intervals. Well, at least for most other ChartTypes; Pies don't need any of this anyway..
Note that you can have several ChartAreas in one Chart.
Also note that it still will display nothing until at least one Series has at least one DataPoint..

Separate Legends for Multiple ChartAreas in Single Chart

I cannot seem to get my individual subcharts (contained within my single chart object) to host individual legends for their respective data series. I would like to know if this is possible and, if so, what I can adjust in my code to achieve this effect.
Thanks for your help
Code is as follows:
chart_MyChart.Legends.Clear();
ChartArea chartArea_MyData = new ChartArea("My Data");
ChartArea chartArea_YourData = new ChartArea("Your Data");
ChartArea chartArea_OtherData = new ChartArea("Other Data");
chart_MyChart.ChartAreas.Clear();
chart_MyChart.ChartAreas.Add(chartArea_MyData);
chart_MyChart.ChartAreas.Add(chartArea_YourData);
chart_MyChart.ChartAreas.Add(chartArea_OtherData);
/* Chart Area: My Data */
Series series01 = this.chart_MyChart.Series.Add("My first series");
series01.ChartArea = chartArea_MyData.Name;
Series series02 = this.chart_MyChart.Series.Add("My second series");
series02.ChartArea = chartArea_MyData.Name;
Legend legend01 = new Legend(series01.Name);
Legend legend02 = new Legend(series02.Name);
legend01.DockedToChartArea = chartArea_MyData.Name;
legend02.DockedToChartArea = chartArea_MyData.Name;
chart_MyChart.Legends.Add(legend01);
chart_MyChart.Legends.Add(legend02);
/* Chart Area: Your Data */
Series series03 = this.chart_MyChart.Series.Add("Your first series");
series03.ChartArea = chartArea_YourData.Name;
Series series04 = this.chart_MyChart.Series.Add("Your second series");
series04.ChartArea = chartArea_YourData.Name;
Legend legend03 = new Legend(series03.Name);
Legend legend04 = new Legend(series04.Name);
legend03.DockedToChartArea = chartArea_YourData.Name;
legend04.DockedToChartArea = chartArea_YourData.Name;
chart_MyChart.Legends.Add(legend03);
chart_MyChart.Legends.Add(legend04);
/* Chart Area: Other Data */
Series series05 = this.chart_MyChart.Series.Add("Other series");
series05.ChartArea = chartArea_OtherData.Name;
Legend legend05 = new Legend(series05.Name);
legend05.DockedToChartArea = chartArea_OtherData.Name;
chart_MyChart.Legends.Add(legend05);
foreach(Legend legend in chart_MyChart.Legends)
{
legend.IsDockedInsideChartArea = true;
}
foreach(widget myWidget in some.widget)
{
series01.Points.AddXY(widget.timeStamp, widget.data1);
series02.Points.AddXY(widget.timeStamp, widget.data2);
series03.Points.AddXY(widget.timeStamp, widget.data3);
series04.Points.AddXY(widget.timeStamp, widget.data4);
series05.Points.AddXY(widget.timeStamp, widget.data5);
}
At first glance you seem to be missing the association between the series and the Legend this is from the WebSamples project that you can download here, it really helps to see a full source examples.
In the MultiLegends section, the code looks like this:
// Add a second legend
Legend secondLegend = new Legend("Second");
secondLegend.BackColor = Color.FromArgb(((System.Byte)(220)), ((System.Byte)(255)), ((System.Byte)(255)), ((System.Byte)(255)));
secondLegend.BorderColor = Color.Gray;
secondLegend.Font = this.Chart1.Legends["Default"].Font;
this.Chart1.Legends.Add(secondLegend);
// Associate Series 2 with the second legend
this.Chart1.Series["Series 2"].Legend = "Second";
The only thing that I didn't see in your code is that last line of association.

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;

Charts grid lines style

I am using the standard charts library from Visual Studio 2010.
The chart works fine but I am unable to change the axis grid line style.
These are the properties already set in Form1.Designers.cs
chartArea3.Name = "ChartArea1";
this.chart1.ChartAreas.Add(chartArea3);
legend3.Name = "Legend1";
this.chart1.Legends.Add(legend3);
this.chart1.Location = new System.Drawing.Point(12, 68);
this.chart1.Name = "chart1";
series5.ChartArea = "ChartArea1";
series5.ChartType = System.Windows.Forms.DataVisualization.Charting.SeriesChartType.Line;
series5.Color = System.Drawing.Color.Red;
series5.Legend = "Legend1";
series5.Name = "Temp";
series6.ChartArea = "ChartArea1";
series6.ChartType = System.Windows.Forms.DataVisualization.Charting.SeriesChartType.Line;
series6.Color = System.Drawing.Color.Blue;
series6.Legend = "Legend1";
series6.Name = "Umid";
this.chart1.Series.Add(series5);
this.chart1.Series.Add(series6);
this.chart1.Size = new System.Drawing.Size(647, 182);
this.chart1.TabIndex = 8;
this.chart1.Text = "chart1";
this.chart1.ChartAreas[0].AxisY.Interval=5;
I would like to have the axis grid type dots or dashdots. I have tried with:
this.chart1.ChartAreas[0].AxisX.LineDashStyle.??????
but then I do not know how to assign the property and/or if the above partial line of code is correct.
Finally I got it right:
this.chart1.ChartAreas[0].AxisX.MajorGrid.LineDashStyle = System.Windows.Forms.DataVisualization.Charting.ChartDashStyle.DashDotDot;
this.chart1.ChartAreas[0].AxisY.MajorGrid.LineDashStyle = System.Windows.Forms.DataVisualization.Charting.ChartDashStyle.DashDotDot;
This is working and gives access to the line style of the grid axes.
this.chart1.ChartAreas[0].AxisX.MajorGrid.LineDashStyle = System.Windows.Forms.DataVisualization.Charting.ChartDashStyle.availableStileSelectionHere;
You'll want to check out the ChartDashStyle enumeration. Your choices should be Dash, DashDot, DashDotDot, Dot, Solid, and NotSet.
AxisX is of type Charting.Axis so that's where the line type information is expressed.
So try:
this.chart1.ChartAreas[0].AxisX.LineDashStyle.Dot
or
this.chart1.ChartAreas[0].AxisX.LineDashStyle.DashDot

How can the UltraChart of Infragistics do even better?

I need to convince my management that we can do very nice plots using infragistics, up to know this is what I have:
In order have that here is my code :
//Set the chart titles
ChartPureAlpha.TitleTop.Text = TickerName;
//Set Chart legend
this.ChartPureAlpha.Legend.Visible = true;
this.ChartPureAlpha.Legend.Location = LegendLocation.Right;
this.ChartPureAlpha.Legend.Margins.Left = 5;
this.ChartPureAlpha.Legend.Margins.Right = 10;
this.ChartPureAlpha.Legend.Margins.Top = 15;
this.ChartPureAlpha.Legend.Margins.Bottom = 90;
this.ChartPureAlpha.Legend.SpanPercentage = 15;
this.ChartPureAlpha.LineChart.TreatDateTimeAsString = false;
this.ChartPureAlpha.ChartType = ChartType.ScatterChart;
this.ChartPureAlpha.ScatterChart.ConnectWithLines = true;
//ChartPureAlpha.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
this.ChartPureAlpha.Axis.X.Labels.ItemFormatString = "<ITEM_LABEL:dd-MM-yyyy>";
this.ChartPureAlpha.Axis.X.Labels.SeriesLabels.Font = new System.Drawing.Font("Verdana", 25);
this.ChartPureAlpha.Axis.X.Labels.SeriesLabels.Visible = true;
this.ChartPureAlpha.Axis.X.Labels.SeriesLabels.OrientationAngle = 315;
//ChartPureAlpha.Axis.X.TickmarkInterval = 1;
//ChartPureAlpha.Axis.X.TickmarkIntervalType = AxisIntervalType.Days;
//ChartPureAlpha.Axis.X.TickmarkStyle = AxisTickStyle.DataInterval;
// axis label
//ChartPureAlpha.TitleBottom.Text = "Date";
//ChartPureAlpha.TitleBottom.HorizontalAlign = StringAlignment.Center;
//ChartPureAlpha.TitleLeft.Text = "Raw Alpha)";
//ChartPureAlpha.TitleLeft.HorizontalAlign = StringAlignment.Center;
// Create and add series
ChartPureAlpha.Series.Add(dowjones);
I want to know how to :
reduce marker size
have the whole date (not truncated)
change the label font
After a few looking through the official 2011.2 infragistics help i found some issues for you:
reduce marker size: use the IconSize Property (Auto, Large, Medium, Small)
change the label font:this.ultraChart1.TitleTop.Font = new Font("Arial", 12, FontStyle.Bold | FontStyle.Underline, GraphicsUnit.Point);
have the whole date (not truncated): If the label is "My Text" and the Date is 5/10/2005 it would format the label as follows: "<ITEM_LABEL><DATA_VALUE:MMM-dd-yyyy>" = MyText May 10, 2005
hope that helps
Infragistics is already trying quite hard to advertise their charts, so why don't you just reuse their marketing material ?

Categories

Resources