I am having some trouble with my C# chart.
I want to create a winnings chart.
This chart is what I want to create:
I currently have this:
WinChart.ChartAreas[0].AxisY.Title = "$ USD";
WinChart.ChartAreas[0].AxisY.Minimum = -1;
WinChart.ChartAreas[0].AxisY.Maximum = 1;
WinChart.ChartAreas[0].AxisX.Title = "Tourneys";
WinChart.ChartAreas[0].AxisX.Minimum = 0;
WinChart.ChartAreas[0].AxisX.IsStartedFromZero = true;
WinChart.Series[0].Points.Add(0);
WinChart.Series[0].Points.Add(0.10);
WinChart.Series[0].Points.Add(0.20);
WinChart.Series[0].Points.Add(0.30);
WinChart.Series[0].Points.Add(-0.50);
WinChart.Series[0].Points.Add(-0.60);
WinChart.Series[0].Points.Add(-0.70);
How can I make it start at the coordinates 0,0 and how do I make a middle line that is $0 ?
Documentation link: http://msdn.microsoft.com/en-us/library/system.windows.forms.datavisualization.charting.aspx
I'm going to assume some thing. WinChart is probably inheriting from Chart:
public class WinChart : Chart { }
and that ChartAreas is a ChartAreaCollection object and the same with Series
So I would do something like:
WinChart.ChartAreas[0].AxisY.Title = "$ USD";
WinChart.ChartAreas[0].AxisY.Minimum = -1;
WinChart.ChartAreas[0].AxisY.Maximum = 1;
WinChart.ChartAreas[0].AxisY.Interval = 0.2; // adjusts y axis scale
WinChart.ChartAreas[0].AxisX.Title = "Tourneys";
WinChart.ChartAreas[0].AxisX.Minimum = 0;
Series series = new Series();
series.Points.Add(0,0);
...
series.Points.Add(5, 1.05);
WinChart.Series.Add(series);
//repeat last five lines to add second line to graph
Related
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..
I'm trying to add a tooltip to chart series but the every series has zero points. How is that possible because the chart is drawing as it should be?
Here is the code for the tooltip:
ChartDurchflussKW.DataSource = dsDurchflussProKW.Tables[0];
ChartDurchflussKW.DataBind();
for (int i = 1; i < dsDurchflussProKW.Tables[0].Columns.Count; i++)
{
ChartDurchflussKW.Series.Add(dsDurchflussProKW.Tables[0].Columns[i].ColumnName.ToString());
ChartDurchflussKW.Series[ChartDurchflussKW.Series.Count - 1].XValueMember = "KW";
ChartDurchflussKW.Series[ChartDurchflussKW.Series.Count - 1].YValueMembers = dsDurchflussProKW.Tables[0].Columns[i].ColumnName.ToString();
foreach (System.Web.UI.DataVisualization.Charting.DataPoint dp in ChartDurchflussKW.Series[ChartDurchflussKW.Series.Count - 1].Points)
{
dp.IsValueShownAsLabel = true;
dp.LabelFormat = "N";
dp.LabelBackColor = Color.White;
dp.LabelAngle = -90;
dp.ToolTip = "KW " + dp.AxisLabel.ToString() + ": " + dp.YValues[0].ToString("N0");
}
}
The chart is drawed with the values as expected but without the tooltips:
So the chart must have at least one point for every series or where did he get his values for drawing? Thanks!
Found the error: After adding the series I have to databind() the chart. At this moment the series have their points. After that in the next loop I can edit the points.
I am trying to draw a vertical line that is anchored to a point. I tried to use the height of my Y axis which is fixed to draw the line, but it wasn't centered correctly. So right now I have an infinite line, but that I want is the line to just fill the graph like so
VerticalLineAnnotation lineannot = new VerticalLineAnnotation();
lineannot.AnchorDataPoint = chart.Series[item].Points.Last();
lineannot.LineColor = Color.Red;
lineannot.Width = 3;
lineannot.Visible = true;
lineannot.IsInfinitive = true;
chart.Annotations.Add(lineannot);
IsInfinitive is complemented by ClipToChartArea; you can set the line to be clipped to a ChartArea like this:
lineannot.ClipToChartArea = chart.ChartAreas[item].Name;
assuming item is the right area name or index..
Note that ClipToChartArea takes the name of the chart area!
This is the simplest way to do it.
It is also possible to control an annotation's position and size directly:
// Note that directly after adding points this will return NaN:
double maxDataPoint = chart1.ChartAreas[0].AxisY.Maximum;
double minDataPoint = chart1.ChartAreas[0].AxisY.Minimum;
LineAnnotation annotation2 = new LineAnnotation();
annotation2.IsSizeAlwaysRelative = false;
annotation2.AxisX = chart1.ChartAreas[0].AxisX;
annotation2.AxisY = chart1.ChartAreas[0].AxisY;
annotation2.AnchorY = minDataPoint;
annotation2.Height = maxDataPoint - minDataPoint;;
annotation2.Width = 0;
annotation2.LineWidth = 2;
annotation2.StartCap = LineAnchorCapStyle.None;
annotation2.EndCap = LineAnchorCapStyle.None;
annotation2.AnchorX = 21; // <- your point
annotation2.LineColor = Color.Pink; // <- your color
chart1.Annotations.Add(annotation2);
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;
I have a win forms chart control with a RangeBar type chart where I add Series and DataPoints as follows:
public void AddSeries(List<Machine> machines)
{
string mID="";
chart.ChartAreas[0].AxisX.Minimum =0;
chart.ChartAreas[0].AxisX.Maximum =machines.Count+1;
int x = 1;
foreach (var m in machines)
{
if (x < 4)
{
mID = m.idMachine.ToString();
chart.Series.Add(new Series(mID));
chart.Series[mID].YValuesPerPoint = 2;
chart.Series[mID].Color = Color.Magenta;
chart.Series[mID].ChartType = SeriesChartType.RangeBar;
chart.Series[mID]["PointWidth"] = "0.7";
chart.Series[mID].IsVisibleInLegend = false;
chart.Series[mID].AxisLabel = m.MachineNo + "_" + m.idMachine;
chart.Series[mID]["DrawSideBySide"] = "true";
DateTime dt = new DateTime(2010, 1, 6);
chart.Series[mID].Points.AddXY(x, dt.ToOADate(), dt.AddDays(1).ToOADate());
}
x++;
}
}
My chart then looks as follows:
What I want is the DataPoints of Series P01_67 and P03_69 to be correctly aligned (in the middle of the series line) as with the Series P02_68. Any ideas how I can do this? Thanks!
If you want them aligned you need to set this property
chart.Series[mID]["DrawSideBySide"] = "false";
But then your series will not be drawn side by site and will overlap
Or you can try to remove the empty series from the Chart. ( Then you will need to take care of the Labels )
Eg:-
Check Here for more information