How to put labels at the bottom of the chart - c#

I'm developing a logarithmic graph as shown below:
The labels of each point are located right next to the point, and this is what I do not want, because what I am looking for is that the labels are located at the bottom of the graph, just in the direction on the x axis that corresponds to it.
Its encoding with hard code is as follows:
Series series = Chart1.Series["Series1"];
Series seriesPuntos = new Series();
seriesPuntos.Points.AddXY(76.20, 100.0);
seriesPuntos.Points.AddXY(63.50, 100.0);
seriesPuntos.Points.AddXY(50.80, 100.0);
seriesPuntos.Points.AddXY(38.10, 100.0);
seriesPuntos.Points.AddXY(25.40, 98.6);
seriesPuntos.Points.AddXY(19.05, 90.0);
seriesPuntos.Points.AddXY(12.70, 83.0);
seriesPuntos.Points.AddXY(9.53, 75.9);
seriesPuntos.Points.AddXY(4.75, 59.8);
seriesPuntos.Points.AddXY(2.36, 46.8);
seriesPuntos.Points.AddXY(1.18, 39.3);
seriesPuntos.Points.AddXY(0.85, 36.8);
seriesPuntos.Points.AddXY(0.60, 30.7);
seriesPuntos.Points.AddXY(0.42, 27.1);
seriesPuntos.Points.AddXY(0.30, 25.7);
seriesPuntos.Points.AddXY(0.25, 24.0);
seriesPuntos.Points.AddXY(0.18, 21.9);
seriesPuntos.Points.AddXY(0.15, 20.6);
seriesPuntos.Points.AddXY(0.10, 19.7);
seriesPuntos.Points.AddXY(0.074, 18.3);
Chart1.Series.Add(seriesPuntos);
Chart1.Series[1].XValueType = ChartValueType.Double;
Chart1.Series[1].YValueType = ChartValueType.Double;
Chart1.Series[0].ChartType = SeriesChartType.Line;
Chart1.Series[1].ChartType = SeriesChartType.Point;
Chart1.Series[0].Color = Color.DarkRed;
Chart1.Series[0].BorderWidth = 1;
Chart1.Series[0].BorderDashStyle = ChartDashStyle.Dash;
Chart1.Series[1].Color = Color.DarkRed;
Chart1.Series[1].BorderWidth = 15;
Chart1.ChartAreas[0].BorderWidth = 1;
Chart1.ChartAreas[0].BorderDashStyle = ChartDashStyle.Solid;
Chart1.ChartAreas[0].AxisY.Interval = 2;
Chart1.ChartAreas[0].AxisX.Interval = 1;
Chart1.ChartAreas[0].AxisY.Minimum = 0;
Chart1.ChartAreas[0].AxisY.Maximum = 100;
Chart1.ChartAreas[0].AxisX.LabelStyle.Angle = 90;
series.Points.AddXY(76.20, 100.0);
series.Points.AddXY(63.50, 100.0);
series.Points.AddXY(50.80, 100.0);
series.Points.AddXY(38.10, 100.0);
series.Points.AddXY(25.40, 98.6);
series.Points.AddXY(19.05, 90.0);
series.Points.AddXY(12.70, 83.0);
series.Points.AddXY(9.53, 75.9);
series.Points.AddXY(4.75, 59.8);
series.Points.AddXY(2.36, 46.8);
series.Points.AddXY(1.18, 39.3);
series.Points.AddXY(0.85, 36.8);
series.Points.AddXY(0.60, 30.7);
series.Points.AddXY(0.42, 27.1);
series.Points.AddXY(0.30, 25.7);
series.Points.AddXY(0.25, 24.0);
series.Points.AddXY(0.18, 21.9);
series.Points.AddXY(0.15, 20.6);
series.Points.AddXY(0.10, 19.7);
series.Points.AddXY(0.074, 18.3);
Chart1.Series[0].XValueType = ChartValueType.Double;
Chart1.Series[0].YValueType = ChartValueType.Double;
Chart1.ChartAreas[0].AxisX.LabelStyle.Angle = 90;
Chart1.ChartAreas[0].AxisX.LabelAutoFitStyle = LabelAutoFitStyles.LabelsAngleStep90;
Chart1.ChartAreas[0].AxisX.IsLogarithmic = true;
Chart1.ChartAreas[0].AxisY.Title = "% QUE PASA EN PESO";
Chart1.ChartAreas[0].AxisY.TitleFont = new Font("Roboto", 11, FontStyle.Bold);
Chart1.ChartAreas[0].AxisX.Title = "ABERTURA (mm)";
Chart1.ChartAreas[0].AxisX.TitleFont = new Font("Roboto", 11, FontStyle.Bold);
Chart1.Series[0].IsValueShownAsLabel = true;
Chart1.Series[0].LabelBackColor = Color.White;
Chart1.Series[0].LabelAngle = 90;
Chart1.Series[0].IsXValueIndexed = true;
Chart1.Series[1].IsXValueIndexed = true;
View:
<asp:Chart ID="Chart1" runat="server" BorderlineWidth="14" Width="990px" Height="450" class="card-img-top" Style="width: auto; !important">
<Series>
<asp:Series Name="Series1" ChartType="Line"></asp:Series>
</Series>
<ChartAreas>
<asp:ChartArea Name="ChartArea1"></asp:ChartArea>
</ChartAreas>
<Titles>
<asp:Title Font="Roboto, 12pt, style=Bold" Name="Title1" Text="CURVA GRANULOMÉTRICA">
<Position Height="3.862135" Width="92" X="8" Y="1" />
</asp:Title>
</Titles>
</asp:Chart>
What I'm looking for is that the labels of each point are located at the bottom of the graph as shown below:

Your example don't seem to work, at least in my machine (and I found some indications online as well). You can't use AxisX.IsLogarithmic with Series.IsXValueIndexed.
I don't know why your code has two series with the same values.
If you want to use a line and highlight the points you should use the MarkerXXX properties:
series.ChartType = SeriesChartType.Line;
series.MarkerColor = Color.Red;
series.MarkerStyle = MarkerStyle.Circle;
series.MarkerSize = 4;
I don't think there is any way of doing what you want "off the shelf".
You have to use AxisX.CustomLabels. Something like:
var series = Chart1.Series["Series1"];
series.Points.AddXY(76.20, 100.0);
series.Points.AddXY(63.50, 100.0);
series.Points.AddXY(50.80, 100.0);
series.Points.AddXY(38.10, 100.0);
series.Points.AddXY(25.40, 98.6);
series.Points.AddXY(19.05, 90.0);
series.Points.AddXY(12.70, 83.0);
series.Points.AddXY(9.53, 75.9);
series.Points.AddXY(4.75, 59.8);
series.Points.AddXY(2.36, 46.8);
series.Points.AddXY(1.18, 39.3);
series.Points.AddXY(0.85, 36.8);
series.Points.AddXY(0.60, 30.7);
series.Points.AddXY(0.42, 27.1);
series.Points.AddXY(0.30, 25.7);
series.Points.AddXY(0.25, 24.0);
series.Points.AddXY(0.18, 21.9);
series.Points.AddXY(0.15, 20.6);
series.Points.AddXY(0.10, 19.7);
series.Points.AddXY(0.074, 18.3);
series.XValueType = ChartValueType.Double;
series.YValueType = ChartValueType.Double;
series.ChartType = SeriesChartType.Line;
series.Color = Color.DarkRed;
series.BorderWidth = 1;
series.BorderDashStyle = ChartDashStyle.Dash;
series.MarkerColor = Color.Red;
series.MarkerStyle = MarkerStyle.Circle;
series.MarkerSize = 4;
var chartArea = Chart1.ChartAreas[0];
chartArea.BorderWidth = 1;
chartArea.BorderDashStyle = ChartDashStyle.Solid;
chartArea.AxisY.Interval = 2;
chartArea.AxisY.Minimum = 0;
chartArea.AxisY.Maximum = 100;
chartArea.AxisY.Title = "% QUE PASA EN PESO";
chartArea.AxisY.TitleFont = new Font("Roboto", 11, FontStyle.Bold);
chartArea.AxisX.LabelStyle.Angle = -90;
chartArea.AxisX.Title = "ABERTURA (mm)";
chartArea.AxisX.TitleFont = new Font("Roboto", 11, FontStyle.Bold);
chartArea.AxisX.IsLogarithmic = true;
chartArea.AxisX.MinorGrid.Interval = 1;
chartArea.AxisX.MinorGrid.Enabled = true;
//Axis is in log, so the CustomLabels fromPosition and toPosition should be as well - This gave me a small headache
var logBase = Chart1.ChartAreas[0].AxisX.LogarithmBase;
//Define the interval to show the text
var customLabelInterval = Math.Log(0.01, logBase);
foreach (var seriesPoint in series.Points)
{
chartArea.AxisX.CustomLabels.Add(Math.Log(seriesPoint.XValue, logBase) - customLabelInterval, Math.Log(seriesPoint.XValue, logBase) + customLabelInterval, seriesPoint.XValue.ToString(CultureInfo.CurrentCulture));
}
Resulting in

Related

I have very similar charts in my c# form app (10-20). How can I program this charts with one method where I can pass the chart name as variable?

I have very similar charts in my c# form app (10-20) (Chart1,Chart2,Chart3.....). The only difference of the charts are the data series. Normally I have to repeat the same code 10–20 times in my project.
How can I program the charts with one method, that I can call multiple times, when I can pass the chart name as a variable. I have searched a lot but found really no solution for that.
My code for one chart is as following:
public void Draw_Chart()
{
chart1.Series.Clear();
chart1.Titles.Clear();
chart1.Legends.Clear();
var newSeries_1 = new Series();
var newSeries_2 = new Series();
newSeries_1.ChartType = SeriesChartType.Line;
newSeries_2.ChartType = SeriesChartType.Line;
chart1.Series.Add(newSeries_1);
chart1.Series.Add(newSeries_2);
List_X_Axis.Clear();
for (int w = 0 ; w <= 940; w++)
{
parameter_value_chartX[w] = w;
//parameter_value_chartY1[w] = 150;
//parameter_value_chartY1[w] = 250;
}
newSeries_1.Points.DataBindXY(parameter_value_chartX, parameter_value_chartY1);
newSeries_2.Points.DataBindXY(parameter_value_chartX, parameter_value_chartY2);
chart1.BackColor = Color.Gray;
chart1.ChartAreas[0].AxisX.Title = ".";
chart1.ChartAreas[0].AxisY.Title = "mm";
chart1.ChartAreas[0].AxisY.TitleForeColor = Color.Cyan;
chart1.ChartAreas[0].AxisY.LabelStyle.ForeColor = Color.Cyan;
chart1.ChartAreas[0].AxisX.Minimum = 0d;
chart1.Series[0].Color = Color.Cyan;
chart1.ChartAreas[0].AxisY.Minimum = cur_scale_min;
chart1.ChartAreas[0].AxisY.Maximum = cur_scale_max;
chart1.ChartAreas[0].AxisY2.Enabled = AxisEnabled.True;
chart1.ChartAreas[0].AxisY2.Minimum = pos_scale_min;
chart1.ChartAreas[0].AxisY2.Maximum = pos_scale_max;
chart1.ChartAreas[0].AxisY2.Title = "% of Max. Current";
chart1.ChartAreas[0].AxisY2.TitleForeColor = Color.Yellow;
chart1.ChartAreas[0].AxisY2.LabelStyle.ForeColor = Color.Yellow;
chart1.ChartAreas[0].AxisY2.MajorGrid.LineColor = Color.Silver;
chart1.ChartAreas[0].AxisY2.MajorTickMark.LineColor = Color.Silver;
chart1.Series[1].YAxisType = AxisType.Secondary;
chart1.Series[1].Color = Color.Yellow;
}
public void Draw_Chart(Chart chart, Series[] series)
{
...
chart.Series.Clear();
series.ForEach(s=>chart.Series.Add(s));
...
}
I found the solution acc. to Ralf's comment in the following way:
...
Draw_Chart(chart1);
...
Draw_Chart(chart2);
...
Draw_Chart(chart3);
...
public void Draw_Chart(Chart chart)
{
chart.Series.Clear();
chart.Titles.Clear();
chart.Legends.Clear();
var newSeries_1 = new Series();
var newSeries_2 = new Series();
newSeries_1.ChartType = SeriesChartType.Line;
newSeries_2.ChartType = SeriesChartType.Line;
chart.Series.Add(newSeries_1);
chart.Series.Add(newSeries_2);
...
}

Make YAxis match ticks in Microsoft.Chart

I am sure there is a way to do this. I have been looking for a while an just haven't found out. I have major and minor ticks defined in my chart but the values on the LH side of the Y Axis does not match the lines (every 20) in the chart. How can I make the values match the lines?
EDIT
Here are the lines of code that creates the values. These were created in Designer through editing the ChartAreas collection.
chartArea1.AxisX.MajorGrid.Interval = 20D;
chartArea1.AxisX.MajorTickMark.Interval = 10D;
chartArea1.AxisX.Maximum = 50D;
chartArea1.AxisX.Minimum = 0D;
chartArea1.AxisX2.Maximum = 50D;
chartArea1.AxisX2.Minimum = 0D;
chartArea1.AxisY.MajorGrid.Interval = 20D;
chartArea1.AxisY.Maximum = 420D;
chartArea1.AxisY.Minimum = 300D;
chartArea1.AxisY.MinorGrid.Interval = 10D;
chartArea1.AxisY2.Maximum = 420D;
chartArea1.AxisY2.Minimum = 300D;
chartArea1.Name = "ChartArea1";
this.chart1.ChartAreas.Add(chartArea1);
legend1.Name = "Legend1";
this.chart1.Legends.Add(legend1);
this.chart1.Location = new System.Drawing.Point(12, 27);
this.chart1.Name = "chart1";
series1.ChartArea = "ChartArea1";
series1.ChartType = System.Windows.Forms.DataVisualization.Charting.SeriesChartType.Point;
series1.IsValueShownAsLabel = true;
series1.Legend = "Legend1";
series1.Name = "TempHistory";
series2.ChartArea = "ChartArea1";
series2.ChartType = System.Windows.Forms.DataVisualization.Charting.SeriesChartType.Line;
series2.Legend = "Legend1";
series2.Name = "LowerLimit";
series3.ChartArea = "ChartArea1";
series3.ChartType = System.Windows.Forms.DataVisualization.Charting.SeriesChartType.Line;
series3.Legend = "Legend1";
series3.Name = "UpperLimit";
this.chart1.Series.Add(series1);
this.chart1.Series.Add(series2);
this.chart1.Series.Add(series3);
this.chart1.Size = new System.Drawing.Size(1326, 186);
this.chart1.TabIndex = 53;
this.chart1.Text = "chart1";
chartArea1.AxisY.Interval needs to equal chartArea1.AxisX.MajorGrid.Interval

How Do I Get The Scale of The Secondary Axis to be Based on My Series Values?

I'm using System.Web.UI.DataVisualization. Charting to create charts in MVC.
I have a chart displaying values in a StackedColumn100 SeriesChartType with the corresponding y-axis values on the primary y-axis on the left side.
Since it is a 100% stacked column series, the primary y-axis is scaled from 0 to 100.
I have then added a secondary series in the form of a Line SeriesChartType tied to a secondary axis (on the right side). I would like this axis to adjust its scale based on the values in the series but it doesn't. No matter what the highest value of this series is, the secondary y-axis also has a scale between 0 to 100.
If I manually set the maximum value for the secondary y-axis the following way:
chart.ChartAreas[0].AxisY2.Maximum = 20;. It works but I don't want to do that since the maximum value can differ greatly based on the search criteria used.
I have really tried to find a solution for this but I can't. According to the documentation and samples it seems that the scale should be based on the series values but I don't get it to work that way. Any help would be greatly appreciated!
Below is a stand alone test function that recreates the problem. I call the function from my view with the following line:
<p><img src="#Url.Action("CreateChart_TestSecondaryAxis")" /> </p>
public FileResult CreateChart_TestSecondaryAxis()
{
System.Web.UI.DataVisualization.Charting.Chart chart = new System.Web.UI.DataVisualization.Charting.Chart();
chart.Width = 800;
chart.Height = 400;
chart.BackColor = Color.FromArgb(211, 223, 240);
chart.BorderlineDashStyle = ChartDashStyle.Solid;
chart.BackSecondaryColor = Color.White;
chart.BackGradientStyle = GradientStyle.TopBottom;
chart.BorderlineWidth = 1;
chart.Palette = ChartColorPalette.BrightPastel;
chart.BorderlineColor = Color.FromArgb(26, 59, 105);
chart.RenderType = RenderType.BinaryStreaming;
chart.BorderSkin.SkinStyle = BorderSkinStyle.Emboss;
chart.AntiAliasing = AntiAliasingStyles.All;
chart.TextAntiAliasingQuality = TextAntiAliasingQuality.Normal;
ChartArea chartArea = new ChartArea();
chartArea.Name = "TestSecondaryAxis";
chartArea.BackColor = Color.Transparent;
chartArea.AxisX.IsLabelAutoFit = false;
chartArea.AxisY.IsLabelAutoFit = false;
chartArea.AxisX.LabelStyle.Font =
new Font("Verdana,Arial,Helvetica,sans-serif",
8F, FontStyle.Regular);
chartArea.AxisY.LabelStyle.Font =
new Font("Verdana,Arial,Helvetica,sans-serif",
8F, FontStyle.Regular);
chartArea.AxisY.LineColor = Color.FromArgb(64, 64, 64, 64);
chartArea.AxisX.LineColor = Color.FromArgb(64, 64, 64, 64);
chartArea.AxisY.MajorGrid.LineColor = Color.FromArgb(64, 64, 64, 64);
chartArea.AxisX.MajorGrid.LineColor = Color.FromArgb(64, 64, 64, 64);
chartArea.AxisX.Title = "Airport";
chartArea.AxisY.Title = "LandingConf";
chartArea.AxisY.TextOrientation = TextOrientation.Rotated270;
chartArea.AxisX.LabelStyle.IsEndLabelVisible = true;
chart.ChartAreas.Add(chartArea);
Series seriesPrimaryAxisConf3 = new Series();
seriesPrimaryAxisConf3.Name = "Conf 3";
seriesPrimaryAxisConf3.IsValueShownAsLabel = false;
seriesPrimaryAxisConf3.Color = Color.Blue;
seriesPrimaryAxisConf3.ChartType = SeriesChartType.StackedColumn100;
seriesPrimaryAxisConf3.BorderWidth = 2;
seriesPrimaryAxisConf3.ChartArea = "TestSecondaryAxis";
DataPoint point;
for (int i = 1; i < 11; i++)
{
point = new DataPoint();
point.AxisLabel = "Airport" + i.ToString();
point.YValues = new double[] { i };
seriesPrimaryAxisConf3.Points.Add(point);
}
chart.Series.Add(seriesPrimaryAxisConf3);
Series seriesPrimaryAxisConfFull = new Series();
seriesPrimaryAxisConfFull.Name = "Conf Full";
seriesPrimaryAxisConfFull.IsValueShownAsLabel = false;
seriesPrimaryAxisConfFull.Color = Color.Red;
seriesPrimaryAxisConfFull.ChartType = SeriesChartType.StackedColumn100;
seriesPrimaryAxisConfFull.BorderWidth = 2;
seriesPrimaryAxisConfFull.ChartArea = "TestSecondaryAxis";
for (int i = 1; i < 11; i++)
{
point = new DataPoint();
point.AxisLabel = "Airport" + i.ToString();
point.YValues = new double[] { 11-i };
seriesPrimaryAxisConfFull.Points.Add(point);
}
chart.Series.Add(seriesPrimaryAxisConfFull);
Series seriesSecondaryAxisNoOfFlights = new Series();
seriesSecondaryAxisNoOfFlights.Name = "NoOfFLights";
seriesSecondaryAxisNoOfFlights.IsValueShownAsLabel = false;
seriesSecondaryAxisNoOfFlights.Color = Color.Red;
seriesSecondaryAxisNoOfFlights.ChartType = SeriesChartType.Line;
seriesSecondaryAxisNoOfFlights.BorderWidth = 2;
seriesSecondaryAxisNoOfFlights.ChartArea = "TestSecondaryAxis";
for (int i = 1; i < 11; i++)
{
point = new DataPoint();
point.AxisLabel = "Airport" + i.ToString();
point.YValues = new double[] { i };
seriesSecondaryAxisNoOfFlights.Points.Add(point);
}
chart.Series.Add(seriesSecondaryAxisNoOfFlights);
chart.Series["NoOfFLights"].YAxisType = AxisType.Secondary;
chart.ChartAreas["TestSecondaryAxis"].AxisY2.LineColor = Color.Transparent;
chart.ChartAreas["TestSecondaryAxis"].AxisY2.MajorGrid.Enabled = false;
chart.ChartAreas["TestSecondaryAxis"].AxisY2.MajorTickMark.Enabled = false;
MemoryStream ms = new MemoryStream();
chart.SaveImage(ms);
return File(ms.GetBuffer(), #"image/png");
}
MSChart is a nice control but unfortunately Microsoft has always failed to properly document it.
And with the latest changes at MSDN things have gone from bad to worse, so I can't actually point to the rules that go for the various ChartTypes.
In your case I deduct this (rather wacky) rule:
To attach a non 100%-series to an indepently scaled secondary y-axis
it must be the first series but the stacked series still must be added
first.
So, if you want to get a result like this:
..you need to adapt the code. Here are the changes and additions needed..:
First we have to insert the line series at the front but do that after the stack100 series have beeen added..:
chart.Series.Insert(0, seriesSecondaryAxisNoOfFlights); // instead of adding it
Next we need to owner-draw the line as it would get burried under the columns otherwise.
Code the PostPaint event like this:
private void Chart_PostPaint(object sender, ChartPaintEventArgs e)
{
Chart chart = sender as Chart; //*
Series s = chart.Series[0]; // make sure to pick the right one!
Axis ax = chart.ChartAreas[0].AxisX;
Axis ay = chart.ChartAreas[0].AxisY2; // !!
var pts = s.Points.Select(x =>
new PointF((float)ax.ValueToPixelPosition(x.XValue),
(float)ay.ValueToPixelPosition(x.YValues[0])));
using (Pen pen = new Pen(s.Color, s.BorderWidth))
e.ChartGraphics.Graphics.DrawLines(pen, pts.ToArray());
}
For this to work the series need valid x-values. So add this line:
point.XValue = i; // set both x and y-values!
I also added a few nudges to the axis positioning:
ChartArea ca = chart.ChartAreas["TestSecondaryAxis"];
ca.AxisY.Maximum = 100;
ca.AxisX.Minimum = 0.5;
ca.AxisX.IntervalOffset = 0.5;

MS Chart Strip Lines Intraday

I use a line chart with double in Y axis and DateTime in X axis. My plot has only intraday data: I have one point each minutes between 8 am and 10 pm.
I want to underline certain periods of the plot. The first period begins at 8:50 and continues during 20 minutes. For this I use a stripLine with the following code:
var stripLine = new StripLine();
stripLine.BackColor = Color.White;
stripLine.BackGradientStyle = GradientStyle.TopBottom;
stripLine.BackImageTransparentColor = Color.White;
stripLine.BackSecondaryColor = Color.Transparent;
stripLine.Interval = 1;
stripLine.IntervalType = DateTimeIntervalType.Days;
stripLine.IntervalOffset = 50;
stripLine.IntervalOffsetType = DateTimeIntervalType.Minutes;
stripLine.StripWidth = 20;
stripLine.StripWidthType= DateTimeIntervalType.Minutes;
chartArea.AxisX.StripLines.Add(stripLine);
However I do not get the right result. Indeed, all my chart area is underlined by the strip line..
Here is a plot to illustrate what I want to achieve:
Your question is a bit obscure: your code is striplining the area vertically from 8:50 to 9:10 A.M.
Do you want to create Stripline every (x):50 to (x+1):10 ?
for(int i=0;i<24;i++)
{
var stripLine = new StripLine();
stripLine.BackColor = Color.White;
stripLine.BackGradientStyle = GradientStyle.TopBottom;
stripLine.BackImageTransparentColor = Color.White;
stripLine.BackSecondaryColor = Color.Transparent;
stripLine.Interval = (double)i;
stripLine.IntervalType = DateTimeIntervalType.Hours;
stripLine.IntervalOffset = 50;
stripLine.IntervalOffsetType = DateTimeIntervalType.Minutes;
stripLine.StripWidth = 20;
stripLine.StripWidthType = DateTimeIntervalType.Minutes;
Chart1.ChartAreas[0].AxisX.StripLines.Add(stripLine);
}
Should work.
Do you want to show the StripLine exactly at the points you showed?
var stripLine = new StripLine();
stripLine.BackColor = Color.White;
stripLine.BackGradientStyle = GradientStyle.TopBottom;
stripLine.BackImageTransparentColor = Color.White;
stripLine.BackSecondaryColor = Color.Transparent;
stripLine.Interval = 9;
stripLine.IntervalType = DateTimeIntervalType.Hours;
stripLine.IntervalOffset = 28;
stripLine.IntervalOffsetType = DateTimeIntervalType.Minutes;
stripLine.StripWidth = 8;
stripLine.StripWidthType= DateTimeIntervalType.Seconds;
chartArea.AxisX.StripLines.Add(stripLine);
Is the right solution.
A StripLine is a line and it will only allow you the add colored rectangles.
To create an area that follows your spline curve you need to either
draw it in the PostPaint event
or use an extra Series of type SplineArea
Here is the 2nd way:
..
Series s3 = chart.Series.Add("S3 ");
s1.ChartType = SeriesChartType.Spline;
s2.ChartType = SeriesChartType.Line;
s3.ChartType = SeriesChartType.SplineArea;
s2.Color = Color.Red;
s3.Color = Color.FromArgb(55, Color.RosyBrown);
for (int i = 0; i < 50; i++)
{
s1.Points.AddXY(i,20 - rnd.Next(10) );
s2.Points.AddXY(i,17);
if (i > 10 && i < 20) s3.Points.AddXY(i, s1.Points[i].YValues[0]);
}

Microsoft Chart, bar graph

I'm trying to make a bar graph, which have to show a bar graph of quality of some goods. My question is about how to make it happen. I'm not sure that the chart control can handle the criterias I want done.
If you imagine that you have a default product, and you want the quality of the barcode. The quality is describe from A(highest) to F(lowest). The output on the graph should be as followed.
http://billedeupload.dk/upload/files/2011-11/f4e132dd.jpg
The understanding of the graph is that it's showing you the quality of the barcode in as a whole, and individually as for example the quality "A". You can see how good the quality of "A" are, compared to the whole.
Can you do this i visual studio c#? And how?
Im using a winform! ;)
Edited:
I want to make it as a Stacked Bargraph. <-- answer to my own question.
Anybody who have a code example for newbies to coding?
Thanks!
The project is old, but I think the source code will help.
WpfSimpleChart
http://wpfsimplechart.codeplex.com/
You should refine your question yet, whether you want to do wpf or winforms.
EDIT
After refining the question, here is a cool charting lib for winforms.
ZedGraph
A flexible charting library for .NET
http://www.codeproject.com/KB/graphics/zedgraph.aspx
I am just getting back into MSChart, so I'll share my findings in hopes that it helps you (and you will check my answer as the correct answer)
I am using LINQPad (http://www.linqpad.net/) to learn MSChart. It is the fastest tool to write C# and render images. I was using Visual Studio, but it takes too much time to build the solution so I can see the results of my changes. I am 'hacking' at MSChart, so I needed faster responses.
I was following the tutorial at http://msdn.microsoft.com/en-us/library/dd489237.aspx to create my LINQPad C# program.
I hope this helps. You could just take my createChart function and drop it in your WinForms project. Take a look at the drawIt method, that is what brings together the stream into an actual graphic.
FYI,
I am using SysDraw = System.Drawing
SysDraw.Color blueStart = SysDraw.Color.FromArgb(124,195,215);
SysDraw.Color blueEnd = SysDraw.Color.FromArgb(74,166,192);
SysDraw.Color grayStart = SysDraw.Color.FromArgb(153,153,153);
SysDraw.Color grayEnd = SysDraw.Color.FromArgb(208,210,211);
SysDraw.Color orangeStart = SysDraw.Color.FromArgb(252,165,107);
SysDraw.Color orangeEnd = SysDraw.Color.FromArgb(255,104,4);
void Main()
{
//chart1 is from Microsoft's sample site
// other charts are using http://msdn.microsoft.com/en-us/library/dd489237.aspx
Chart chart1 = createChart1();
Chart chart2= createChart2(42, "Chart 2");
Chart chart3 = createChart2(99, "Chart 3");
Chart chart4 = createChart2(11, "Chart 4");
drawIt(chart2, chart2.Name);
drawIt(chart3, chart3.Name);
drawIt(chart4, chart4.Name);
drawIt(chart1, chart1.Name);
}
private void drawIt(Chart drawChart, string name)
{
System.IO.MemoryStream ms = new System.IO.MemoryStream();
drawChart.SaveImage(ms,SysDraw.Imaging.ImageFormat.Png);
SysDraw.Bitmap outImage = new SysDraw.Bitmap(ms);
outImage.Dump(name);
}
private void drawIt(string imageFilePath)
{
System.IO.MemoryStream ms = new System.IO.MemoryStream();
SysDraw.Bitmap outImage = new SysDraw.Bitmap(imageFilePath);
outImage.Dump(imageFilePath);
}
private Chart createChart2(double dataPointYvalue, string chartName)
{
string chartAreaName ="Area 1";
// Chart
// --------------------------------
Chart results = new Chart();
results.Name = chartName;
results.BorderSkin.SkinStyle = BorderSkinStyle.Emboss;
results.BorderSkin.SkinStyle = BorderSkinStyle.None;
SysDraw.Size size1 = new SysDraw.Size(480,30);
results.Size = size1;
// ChartAreas collection
// --------------------------------
ChartArea area1 =new ChartArea(chartAreaName);
area1.Area3DStyle.Enable3D=false;
//area1.Area3DStyle.Enable3D=true;
area1.Area3DStyle.WallWidth=10;
//area1.Area3DStyle.Inclination=10;
//area1.Area3DStyle.Perspective = 10;
area1.Area3DStyle.Rotation=1;
//area1.BorderDashStyle = ChartDashStyle.DashDot;
area1.BackGradientStyle = GradientStyle.TopBottom;
area1.BackColor = grayStart;
area1.BackSecondaryColor = grayEnd;
// Axes under Area collection
Axis axisX = new Axis();
axisX.LabelStyle.Interval = 1;
axisX.Title ="x axis";
axisX.IsMarginVisible=false;
axisX.Enabled = AxisEnabled.False;
Axis axisY = new Axis();
axisY.Title = "y axis";
axisY.IsMarginVisible=true;
axisY.Enabled = AxisEnabled.False;
area1.AxisX = axisX;
area1.AxisY = axisY;
results.ChartAreas.Add(area1);
// Series Collection Editor
// --------------------------------
Series series1 = new Series("Series 1");
series1.ChartArea = chartAreaName;
series1.ChartType = SeriesChartType.Bar;
series1.CustomProperties="DrawingStyle=Cylinder";
series1.Name = "BarChart";
series1.BackGradientStyle = GradientStyle.TopBottom;
series1.Color=blueStart;
series1.BackSecondaryColor = blueEnd;
// series1.BorderDashStyle= ChartDashStyle.DashDotDot;
// series1.BorderColor = SysDraw.Color.Red;
//series1.Points.AddY(42);
DataPoint dp = new DataPoint();
dp.Name="MyPoint";
dp.YValues= new double[]{dataPointYvalue};
series1.Points.Add(dp);
results.Series.Add(series1);
// Legend
// --------------------------------
// Legend legend = new Legend("Chart 2 Legend");
// legend.DockedToChartArea = "Chart 2 Area 1";
// legend.Docking = Docking.Right;
// legend.IsDockedInsideChartArea = true;
// results.Legends.Add(legend);
// series1.Legend = "Chart 2 Legend"; //You can assign each series to a different legend.
// Title
// --------------------------------
Title title = new Title(string.Format("Your whatever is {0}",dp.YValues[0]));
title.Docking = Docking.Right;
title.TextOrientation = TextOrientation.Horizontal;
//title.DockedToChartArea = chartAreaName;
//results.Titles.Add(title);
// Annotations
// --------------------------------
ArrowAnnotation arrowAnnt = new ArrowAnnotation();
arrowAnnt.AnchorDataPoint=dp;
arrowAnnt.Height=-5;
arrowAnnt.Width=0;
arrowAnnt.AnchorOffsetY=-2.5;
arrowAnnt.SmartLabelStyle.IsOverlappedHidden = false;
TextAnnotation textAnnt = new TextAnnotation();
textAnnt.AnchorDataPoint = dp;
textAnnt.AnchorOffsetX = -10;
textAnnt.ForeColor=SysDraw.Color.White;
textAnnt.Text = dp.YValues[0].ToString();
//results.Annotations.Add(arrowAnnt);
results.Annotations.Add(textAnnt);
return results;
}
private Chart createChart1()
{
Title title1 = new Title();
ChartArea chartArea1 = new ChartArea();
Legend legend1 = new Legend();
Series series1 = new Series();
DataPoint dataPoint1 = new DataPoint(0, 6);
DataPoint dataPoint2 = new DataPoint(0, 9);
DataPoint dataPoint3 = new DataPoint(0, 5);
DataPoint dataPoint4 = new DataPoint(0, 7.5);
DataPoint dataPoint5 = new DataPoint(0, 5.6999998092651367);
DataPoint dataPoint6 = new DataPoint(0, 7);
DataPoint dataPoint7 = new DataPoint(0, 8.5);
Series series2 = new Series();
DataPoint dataPoint8 = new DataPoint(0, 6);
DataPoint dataPoint9 = new DataPoint(0, 9);
DataPoint dataPoint10 = new DataPoint(0, 2);
DataPoint dataPoint11 = new DataPoint(0, 7);
DataPoint dataPoint12 = new DataPoint(0, 3);
DataPoint dataPoint13 = new DataPoint(0, 5);
DataPoint dataPoint14 = new DataPoint(0, 8);
Series series3 = new Series();
DataPoint dataPoint15 = new DataPoint(0, 4);
DataPoint dataPoint16 = new DataPoint(0, 2);
DataPoint dataPoint17 = new DataPoint(0, 1);
DataPoint dataPoint18 = new DataPoint(0, 3);
DataPoint dataPoint19 = new DataPoint(0, 2);
DataPoint dataPoint20 = new DataPoint(0, 3);
DataPoint dataPoint21 = new DataPoint(0, 5);
Chart results = new Chart();
//((System.ComponentModel.ISupportInitialize)(results)).BeginInit();
//
// resulting chart
//
results.BackColor = System.Drawing.Color.WhiteSmoke;
results.BackGradientStyle = GradientStyle.TopBottom;
results.BackSecondaryColor = System.Drawing.Color.White;
results.BorderlineColor = System.Drawing.Color.FromArgb(((int)(((byte)(26)))), ((int)(((byte)(59)))), ((int)(((byte)(105)))));
results.BorderlineDashStyle = ChartDashStyle.Solid;
results.BorderlineWidth = 2;
results.BorderSkin.SkinStyle = BorderSkinStyle.Emboss;
chartArea1.Area3DStyle.Enable3D = true;
chartArea1.Area3DStyle.Inclination = 15;
chartArea1.Area3DStyle.IsClustered = false;
chartArea1.Area3DStyle.IsRightAngleAxes = false;
chartArea1.Area3DStyle.PointGapDepth = 0;
chartArea1.Area3DStyle.Rotation = 10;
chartArea1.Area3DStyle.WallWidth = 0;
chartArea1.AxisX.LabelStyle.Font = new System.Drawing.Font("Trebuchet MS", 8.25F, System.Drawing.FontStyle.Bold);
chartArea1.AxisX.LineColor = System.Drawing.Color.FromArgb(((int)(((byte)(64)))), ((int)(((byte)(64)))), ((int)(((byte)(64)))), ((int)(((byte)(64)))));
chartArea1.AxisX.MajorGrid.LineColor = System.Drawing.Color.FromArgb(((int)(((byte)(64)))), ((int)(((byte)(64)))), ((int)(((byte)(64)))), ((int)(((byte)(64)))));
chartArea1.AxisY.LabelStyle.Font = new System.Drawing.Font("Trebuchet MS", 8.25F, System.Drawing.FontStyle.Bold);
chartArea1.AxisY.LineColor = System.Drawing.Color.FromArgb(((int)(((byte)(64)))), ((int)(((byte)(64)))), ((int)(((byte)(64)))), ((int)(((byte)(64)))));
chartArea1.AxisY.MajorGrid.LineColor = System.Drawing.Color.FromArgb(((int)(((byte)(64)))), ((int)(((byte)(64)))), ((int)(((byte)(64)))), ((int)(((byte)(64)))));
chartArea1.BackColor = System.Drawing.Color.WhiteSmoke;
chartArea1.BackSecondaryColor = System.Drawing.Color.White;
chartArea1.BorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(64)))), ((int)(((byte)(64)))), ((int)(((byte)(64)))), ((int)(((byte)(64)))));
chartArea1.Name = "Default";
chartArea1.ShadowColor = System.Drawing.Color.Transparent;
results.ChartAreas.Add(chartArea1);
results.Cursor = System.Windows.Forms.Cursors.Hand;
legend1.BackColor = System.Drawing.Color.Transparent;
legend1.Enabled = false;
legend1.Font = new System.Drawing.Font("Trebuchet MS", 8.25F, System.Drawing.FontStyle.Bold);
legend1.IsTextAutoFit = false;
legend1.Name = "Default";
results.Legends.Add(legend1);
results.Location = new System.Drawing.Point(16, 53);
results.Name = "chart1";
series1.BorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(180)))), ((int)(((byte)(26)))), ((int)(((byte)(59)))), ((int)(((byte)(105)))));
series1.ChartArea = "Default";
series1.Color = System.Drawing.Color.FromArgb(((int)(((byte)(220)))), ((int)(((byte)(65)))), ((int)(((byte)(140)))), ((int)(((byte)(240)))));
series1.Legend = "Default";
series1.Name = "Default";
series1.Points.Add(dataPoint1);
// series1.Points.Add(dataPoint2);
// series1.Points.Add(dataPoint3);
// series1.Points.Add(dataPoint4);
// series1.Points.Add(dataPoint5);
// series1.Points.Add(dataPoint6);
// series1.Points.Add(dataPoint7);
// series2.BorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(180)))), ((int)(((byte)(26)))), ((int)(((byte)(59)))), ((int)(((byte)(105)))));
// series2.ChartArea = "Default";
// series2.Color = System.Drawing.Color.FromArgb(((int)(((byte)(220)))), ((int)(((byte)(252)))), ((int)(((byte)(180)))), ((int)(((byte)(65)))));
// series2.Legend = "Default";
// series2.Name = "Series2";
// series2.Points.Add(dataPoint8);
// series2.Points.Add(dataPoint9);
// series2.Points.Add(dataPoint10);
// series2.Points.Add(dataPoint11);
// series2.Points.Add(dataPoint12);
// series2.Points.Add(dataPoint13);
// series2.Points.Add(dataPoint14);
// series3.BorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(180)))), ((int)(((byte)(26)))), ((int)(((byte)(59)))), ((int)(((byte)(105)))));
// series3.ChartArea = "Default";
// series3.Color = System.Drawing.Color.FromArgb(((int)(((byte)(220)))), ((int)(((byte)(224)))), ((int)(((byte)(64)))), ((int)(((byte)(10)))));
// series3.Legend = "Default";
// series3.Name = "Series3";
// series3.Points.Add(dataPoint15);
// series3.Points.Add(dataPoint16);
// series3.Points.Add(dataPoint17);
// series3.Points.Add(dataPoint18);
// series3.Points.Add(dataPoint19);
// series3.Points.Add(dataPoint20);
// series3.Points.Add(dataPoint21);
results.Series.Add(series1);
// results.Series.Add(series2);
// results.Series.Add(series3);
results.Size = new System.Drawing.Size(412, 296);
results.TabIndex = 1;
title1.Font = new System.Drawing.Font("Trebuchet MS", 14.25F, System.Drawing.FontStyle.Bold);
title1.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(26)))), ((int)(((byte)(59)))), ((int)(((byte)(105)))));
title1.Name = "Title1";
title1.ShadowColor = System.Drawing.Color.FromArgb(((int)(((byte)(32)))), ((int)(((byte)(0)))), ((int)(((byte)(0)))), ((int)(((byte)(0)))));
title1.ShadowOffset = 3;
title1.Text = "3D Cylinder";
results.Titles.Add(title1);
SysDraw.Size mySize = new SysDraw.Size(480, 170);
results.Size = mySize;
return results;
}

Categories

Resources