Specific way to show a serie in MSChart using c# - c#

I wonder if there is any way to show this serie as follows, the chartype is column.
I'm aware that I need an (X,Y) pair to show the datapoint in the graph, but the thing is that I need to show a Y value in a range of x, to clarify this, let's put an example:
The X axis shows the hours and Y axis production values, in this case the production started at 7:30, so from 7:30 to 8 the production was let's say 20 units; from 8-9, 60 units; 9-10, 45 units and from 10-10:35 18 units.
Can I accomplish that with MSChart, or perhaps any other one that you guys suggest me? This is a winform app.
Thanks

You should take a look at the MS Chart site. The Downloads tab has WinForms examples that you can download as a WinForms project, run in Visual Studio, and view the code for the chart you want. The Chart controls are included with .Net 4, but can be downloaded and added as a reference for .Net 3.5.
What you want is a Column chart. You set the values as a series on the chart, and then you can pick the width of the column to show the range of x-values you want.
The basic idea is you create a Chart, ChartArea, and Series, and optionally a Title and Legend.
You add one or more Series objects to the ChartArea, then add the ChartArea, Title, and Legend to the Chart.
You add DataPoints individually to the Series, as in the example below, or you set the Chart.DataSource to something like a DataTable and use DataBinding.
Here's a snippet from the Column Chart example:
System.Windows.Forms.DataVisualization.Charting.Chart chart1 = new System.Windows.Forms.DataVisualization.Charting.Chart();
System.Windows.Forms.DataVisualization.Charting.ChartArea chartArea1 = new System.Windows.Forms.DataVisualization.Charting.ChartArea();
System.Windows.Forms.DataVisualization.Charting.Legend legend1 = new System.Windows.Forms.DataVisualization.Charting.Legend();
System.Windows.Forms.DataVisualization.Charting.Series series1 = new System.Windows.Forms.DataVisualization.Charting.Series();
System.Windows.Forms.DataVisualization.Charting.DataPoint dataPoint1 = new System.Windows.Forms.DataVisualization.Charting.DataPoint(36890, 32);
System.Windows.Forms.DataVisualization.Charting.DataPoint dataPoint2 = new System.Windows.Forms.DataVisualization.Charting.DataPoint(36891, 56);
System.Windows.Forms.DataVisualization.Charting.DataPoint dataPoint3 = new System.Windows.Forms.DataVisualization.Charting.DataPoint(36892, 35);
System.Windows.Forms.DataVisualization.Charting.DataPoint dataPoint4 = new System.Windows.Forms.DataVisualization.Charting.DataPoint(36893, 12);
System.Windows.Forms.DataVisualization.Charting.DataPoint dataPoint5 = new System.Windows.Forms.DataVisualization.Charting.DataPoint(36894, 35);
System.Windows.Forms.DataVisualization.Charting.DataPoint dataPoint6 = new System.Windows.Forms.DataVisualization.Charting.DataPoint(36895, 6);
System.Windows.Forms.DataVisualization.Charting.DataPoint dataPoint7 = new System.Windows.Forms.DataVisualization.Charting.DataPoint(36896, 23);
System.Windows.Forms.DataVisualization.Charting.Series series2 = new System.Windows.Forms.DataVisualization.Charting.Series();
System.Windows.Forms.DataVisualization.Charting.Title title1 = new System.Windows.Forms.DataVisualization.Charting.Title();
chart1.BackGradientStyle = System.Windows.Forms.DataVisualization.Charting.GradientStyle.TopBottom;
chart1.BorderlineDashStyle = System.Windows.Forms.DataVisualization.Charting.ChartDashStyle.Solid;
chart1.BorderlineWidth = 2;
chart1.BorderSkin.SkinStyle = System.Windows.Forms.DataVisualization.Charting.BorderSkinStyle.Emboss;
chartArea1.Area3DStyle.Inclination = 15;
chartArea1.Area3DStyle.IsClustered = true;
chartArea1.Area3DStyle.IsRightAngleAxes = false;
chartArea1.Area3DStyle.Perspective = 10;
chartArea1.Area3DStyle.Rotation = 10;
chartArea1.Area3DStyle.WallWidth = 0;
chartArea1.AxisX.LabelAutoFitMaxFontSize = 8;
chartArea1.AxisX.LabelStyle.Font = new System.Drawing.Font("Trebuchet MS", 8.25F, System.Drawing.FontStyle.Bold);
chartArea1.AxisX.LabelStyle.Format = "MM-dd";
chartArea1.AxisX.LabelStyle.IsEndLabelVisible = false;
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.LabelAutoFitMaxFontSize = 8;
chartArea1.AxisY.LabelStyle.Font = new System.Drawing.Font("Trebuchet MS", 8.25F, System.Drawing.FontStyle.Bold);
chartArea1.AxisY.LabelStyle.Format = "C0";
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.OldLace;
chartArea1.BackGradientStyle = System.Windows.Forms.DataVisualization.Charting.GradientStyle.TopBottom;
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;
chart1.ChartAreas.Add(chartArea1);
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";
chart1.Legends.Add(legend1);
chart1.Location = new System.Drawing.Point(16, 64);
chart1.Name = "chart1";
series1.BorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(180)))), ((int)(((byte)(26)))), ((int)(((byte)(59)))), ((int)(((byte)(105)))));
series1.ChartArea = "Default";
series1.Legend = "Default";
series1.Name = "Series1";
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);
series1.XValueType = System.Windows.Forms.DataVisualization.Charting.ChartValueType.DateTime;
chart1.Series.Add(series1);
chart1.Size = new System.Drawing.Size(412, 296);
chart1.TabIndex = 0;
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 = "Column Chart";
chart1.Titles.Add(title1);

Related

How do i adjust the Y Axis scale for the line chart using c#

I am using System.Web.UI.DataVisualization.Charting to generate line chart which I am populating at run-time. Y axis of the graph is a percent value that currently scales from -150% to +150%. I want to adjust the scale so that Y Axis label will always scale from -100% to +100%. Any help is appreciated. Thank you.
This is the sample code i have for the chart:
Chart c = new Chart();
c.AntiAliasing = AntiAliasingStyles.All;
c.TextAntiAliasingQuality = TextAntiAliasingQuality.High;
c.Width = 800;
c.Height = 450;
ChartArea ca = new ChartArea();
ca.Position.X = 0;
ca.Position.Y = 10;
ca.Position.Width = 100;
ca.Position.Height = 80;
ca.BackColor = Color.FromArgb(248, 248, 248);
ca.BackSecondaryColor = Color.FromArgb(255, 255, 255);
ca.BackGradientStyle = GradientStyle.TopBottom;
ca.AxisY.IsMarksNextToAxis = true;
ca.AxisY.LineColor = Color.FromArgb(157, 157, 157);
ca.AxisY.MajorTickMark.Enabled = true;
ca.AxisY.MajorTickMark.LineColor = Color.FromArgb(157, 157, 157);
ca.AxisY.LabelStyle.ForeColor = Color.FromArgb(89, 89, 89);
ca.AxisY.LabelStyle.Format = "{0:p}";
ca.AxisY.LabelStyle.IsEndLabelVisible = true;
ca.AxisY.Interval = 1;
ca.AxisY.LabelStyle.Font = new Font("Calibri", 4, FontStyle.Regular);
ca.AxisY.MajorGrid.LineColor = Color.FromArgb(234, 234, 234);
ca.AxisX.IsMarksNextToAxis = true;
ca.AxisX.LineColor = Color.FromArgb(157, 157, 157);
ca.AxisX.MajorTickMark.Enabled = true;
ca.AxisX.MajorTickMark.LineColor = Color.FromArgb(157, 157, 157);
ca.AxisX.LabelStyle.IsEndLabelVisible = true;
ca.AxisX.LabelStyle.ForeColor = Color.FromArgb(89, 89, 89);
ca.AxisX.MajorGrid.LineWidth = 0;
ca.AxisX.IsMarginVisible = false;
ca.AxisX.Interval = 0;
c.ChartAreas.Add(ca);
List<RawData> rawData = (List<RawData>)rawDataDao.GetDataByDateRange(start.Value, end.Value);
if(rawData.Count > 0)
{
Series s = new Series();
s.Font = new Font("Lucida Sans Unicode", 6f);
s.Color = System.Drawing.ColorTranslator.FromHtml(GetCombinedColorByIndex(possibleSensors.IndexOf(sensor)));
s.BorderColor = Color.FromArgb(159, 27, 13);
s.BackSecondaryColor = Color.FromArgb(173, 32, 11);
s.BackGradientStyle = GradientStyle.LeftRight;
s.ChartType = SeriesChartType.Line;
s.XValueType = ChartValueType.DateTime;
s.Name = sensor.SensorName;
foreach (RawData d in workingRawData)
{
System.DateTime x = DateTime.Parse(d.Dt.Value.ToString("", CultureInfo.CreateSpecificCulture("en-US")));
DataPoint p = new DataPoint(x.ToOADate(), Convert.ToDouble(d.Reading));
p.AxisLabel = d.Dt.Value.ToString();
s.Points.Add(p);
}
c.Series.Add(s);
}
If the axis is zoomable, set the scaleview to the range you need
ca.AxisY.ScaleView.Zoom(-100, 100);

remove white spaces below winforms graph

I have created a chart in winforms and host it in WPF using winformhost. When I am implementing this in wpf, there is a space below my graph. If I reduce the size of chart, chart becomes small. How to remove that space below the graph?
Here is my code.
XAML.cs
var chartArea = new ChartArea("EQGraph");
Chart chart1 = this.FindName("EQGraph") as Chart;
chart1.ChartAreas.Add("EQGraph");
chart1.Series.Add("Front Left");
chart1.ChartAreas[0].AxisX.Maximum = 20000;
chart1.ChartAreas[0].AxisX.Minimum = 10;
chart1.ChartAreas[0].AxisX.IsLogarithmic = true;
chart1.ChartAreas[0].AxisX.MinorGrid.Interval = 1;
chart1.ChartAreas[0].AxisX.MinorGrid.Enabled = true;
chart1.ChartAreas[0].AxisY.Maximum = 20;
chart1.ChartAreas[0].AxisY.Minimum = -50;
chart1.ChartAreas[0].AxisY.Interval = 5;
chart1.ChartAreas[0].AxisX.MinorGrid.LineDashStyle = System.Windows.Forms.DataVisualization.Charting.ChartDashStyle.DashDotDot;
chart1.ChartAreas[0].AxisY.MajorGrid.LineDashStyle = System.Windows.Forms.DataVisualization.Charting.ChartDashStyle.DashDotDot;
chart1.ChartAreas[0].AxisX.LabelStyle.Font = new System.Drawing.Font("Trebuchet MS", 10F, System.Drawing.FontStyle.Bold);
chart1.ChartAreas[0].AxisY.LabelStyle.Font = new System.Drawing.Font("Trebuchet MS", 10F, System.Drawing.FontStyle.Bold);
chart1.ChartAreas[0].AxisX.Title = "Frequency(Hz)";
chart1.ChartAreas[0].AxisY.Title = "Gain";
int[] xValuesFrontLeft = { 10, 100, 1000, 5000, 4200, 8499 };
int[] yValuesFrontLeft = { 16, 10, -5, -10, 35, -40 };
chart1.Series["Front Left"].Points.DataBindXY(xValuesFrontLeft, yValuesFrontLeft);
chart1.Series["Front Left"].ChartType = SeriesChartType.Spline;
XAML
<DockPanel Grid.Column="3" Grid.Row="1" Grid.RowSpan="9" Background="#FFFBF9F9">
<WindowsFormsHost x:Name="host" Height="500">
<winformchart:Chart x:Name="EQGraph" Dock="Fill">
<winformchart:Chart.Series >
<winformchart:Series Name="series" ChartType="Line"/>
</winformchart:Chart.Series>
<winformchart:Chart.ChartAreas>
<winformchart:ChartArea/>
</winformchart:Chart.ChartAreas>
</winformchart:Chart>
</WindowsFormsHost>
</DockPanel>
I don't think you need to create new ChartArea to place your graph, because your graph is placed inside WindowsFormsHost in XAML already, and it's docked, so it will be the same size as it's host. Use that chart like this:
// Remove these lines
// var chartArea = new ChartArea("EQGraph");
// Chart chart1 = this.FindName("EQGraph") as Chart;
// chart1.ChartAreas.Add("EQGraph");
// Now you will be adding values, series and properties to your graph inside WinFormsHost
Chart chart1 = EQGraph;
You could also replace chart1 with EQGraph inside your code directly, at all places:
EQGraph.Series.Add("Front Left");
EQGraph.ChartAreas[0].AxisX.Maximum = 20000;
EQGraph.ChartAreas[0].AxisX.Minimum = 10;
EQGraph.ChartAreas[0].AxisX.IsLogarithmic = true;
EQGraph.ChartAreas[0].AxisX.MinorGrid.Interval = 1;
EQGraph.ChartAreas[0].AxisX.MinorGrid.Enabled = true;
EQGraph.ChartAreas[0].AxisY.Maximum = 20;
EQGraph.ChartAreas[0].AxisY.Minimum = -50;
EQGraph.ChartAreas[0].AxisY.Interval = 5;
EQGraph.ChartAreas[0].AxisX.MinorGrid.LineDashStyle = System.Windows.Forms.DataVisualization.Charting.ChartDashStyle.DashDotDot;
EQGraph.ChartAreas[0].AxisY.MajorGrid.LineDashStyle = System.Windows.Forms.DataVisualization.Charting.ChartDashStyle.DashDotDot;
EQGraph.ChartAreas[0].AxisX.LabelStyle.Font = new System.Drawing.Font("Trebuchet MS", 10F, System.Drawing.FontStyle.Bold);
EQGraph.ChartAreas[0].AxisY.LabelStyle.Font = new System.Drawing.Font("Trebuchet MS", 10F, System.Drawing.FontStyle.Bold);
EQGraph.ChartAreas[0].AxisX.Title = "Frequency(Hz)";
EQGraph.ChartAreas[0].AxisY.Title = "Gain";
int[] xValuesFrontLeft = { 10, 100, 1000, 5000, 4200, 8499 };
int[] yValuesFrontLeft = { 16, 10, -5, -10, 35, -40 };
EQGraph.Series["Front Left"].Points.DataBindXY(xValuesFrontLeft, yValuesFrontLeft);
EQGraph.Series["Front Left"].ChartType =SeriesChartType.Spline;

Resetting mschart with new series doesn't change yaxis range

I have a ms chart which shows a series which falls in the range 0.0004 to 0.0007.
When I clear the chart and add a new series, it doesn't show anything since the new series falls in the range 0.0001 to 0.0003 and the chart still shows the Y axis labels from 0.0004 to 0.0007
Here is how I am doing it.
UpdateGraphswithnewdata()
{
Chart1.Series.Clear();
Series1.ChartType = System.Windows.Forms.DataVisualization.Charting.SeriesChartType.Line;
Series1.Name = "Series1";
Series1.Color = Color.Red;
Series1.MarkerSize = 5;
Series1.MarkerStyle = System.Windows.Forms.DataVisualization.Charting.MarkerStyle.Circle;
for (int i = 0; i < SitesList.Count; i++)
{
Series1.Points.AddXY((double)SitesList[i], Math.Round((double)RmseList[i], 4));
}
Chart1.ChartAreas[0].AxisY.IsStartedFromZero = false;
Chart1.ChartAreas[0].AxisY.Title = "RMSE";
Chart1.ChartAreas[0].AxisX.Title = "Site#";
Chart1.Series.Add(Series1);
}
What is it that I have to reset?
Got it. I had to clear chartareas and add them again. Thanks digEmAll you pointed me to the right direction.This worked for me.
var chartarea = new System.Windows.Forms.DataVisualization.Charting.ChartArea();
Chart1.ChartAreas.Clear();
Chart1.ChartAreas.Add(chartarea);

How to draw Chart based on DataTable from console application?

How to use System.Windows.Forms.DataVisualization.Charting.Chart inside console application to draw an graph and save it to file?
//populate dataset with some demo data..
DataSet dataSet = new DataSet();
DataTable dt = new DataTable();
dt.Columns.Add("Name", typeof(string));
dt.Columns.Add("Counter", typeof(int));
DataRow r1 = dt.NewRow();
r1[0] = "Demo";
r1[1] = 8;
dt.Rows.Add(r1);
DataRow r2 = dt.NewRow();
r2[0] = "Second";
r2[1] = 15;
dt.Rows.Add(r2);
dataSet.Tables.Add(dt);
//prepare chart control...
Chart chart = new Chart();
chart.DataSource = dataSet.Tables[0];
chart.Width = 600;
chart.Height = 350;
//create serie...
Series serie1 = new Series();
serie1.Name = "Serie1";
serie1.Color = Color.FromArgb(112, 255, 200);
serie1.BorderColor = Color.FromArgb(164, 164, 164);
serie1.ChartType = SeriesChartType.Column;
serie1.BorderDashStyle = ChartDashStyle.Solid;
serie1.BorderWidth = 1;
serie1.ShadowColor = Color.FromArgb(128, 128, 128);
serie1.ShadowOffset = 1;
serie1.IsValueShownAsLabel = true;
serie1.XValueMember = "Name";
serie1.YValueMembers = "Counter";
serie1.Font = new Font("Tahoma", 8.0f);
serie1.BackSecondaryColor = Color.FromArgb(0, 102, 153);
serie1.LabelForeColor = Color.FromArgb(100, 100, 100);
chart.Series.Add(serie1);
//create chartareas...
ChartArea ca = new ChartArea();
ca.Name = "ChartArea1";
ca.BackColor = Color.White;
ca.BorderColor = Color.FromArgb(26, 59, 105);
ca.BorderWidth = 0;
ca.BorderDashStyle = ChartDashStyle.Solid;
ca.AxisX = new Axis();
ca.AxisY = new Axis();
chart.ChartAreas.Add(ca);
//databind...
chart.DataBind();
//save result...
chart.SaveImage(#"c:\myChart.png", ChartImageFormat.Png);
Add this declaration on top of your class:
using System.Windows.Forms.DataVisualization.Charting;
Plot sin(x) between 0 and 2pi.
You have to add "System.Windows.Forms.DataVisualization.dll" and "System.Drawing.dll" to your project.
Good Luck :)
//
// chart
//
System.Windows.Forms.DataVisualization.Charting.Chart chart = new System.Windows.Forms.DataVisualization.Charting.Chart();
chart.Size = new System.Drawing.Size(640, 320);
chart.ChartAreas.Add("ChartArea1");
chart.Legends.Add("legend1");
// Plot {sin(x), 0, 2pi}
chart.Series.Add("sin");
chart.Series["sin"].LegendText = "Sin(x)";
chart.Series["sin"].ChartType = System.Windows.Forms.DataVisualization.Charting.SeriesChartType.Spline;
for (double x = 0; x < 2 * Math.PI; x += 0.01)
{
chart.Series["sin"].Points.AddXY(x, Math.Sin(x));
}
// Save sin_0_2pi.png image file
chart.SaveImage("sin_0_2pi.png", System.Drawing.Imaging.ImageFormat.Png);

Connect two UIElement with Arc

I have two UIElements(i.e. rectangles) in Canvas and their coordinates. How can I connect them with arc in code behind?
No need to get an exact hit on the rectangles (or other objects): make sure the Z ordering is correct. arc.SetValue(Canvas.ZIndex, -1) will push it to the background. If you want a perpendicular hit, you'll need to break out the algebra :/
For the arc: (see http://msdn.microsoft.com/en-us/library/ms751808.aspx), it needs to be contained in a PathFigure.
Edit: this shows two connected rectangles. The line simple runs between the two centers. The arc starts on one center (the pathFigure startpoint), first argument is the center of the second object.
r1 = new Rectangle();
r1.Margin = new Thickness(50, 50, 0, 0);
r1.VerticalAlignment = System.Windows.VerticalAlignment.Top;
r1.HorizontalAlignment = System.Windows.HorizontalAlignment.Left;
r1.Height = 50;
r1.Width= 50;
r1.Fill = new SolidColorBrush(Colors.Red);
r2 = new Rectangle();
r2.Width = 50;
r2.Height = 50;
r2.Fill = new SolidColorBrush(Colors.Blue);
r2.Margin = new Thickness(350, 450, 0, 0);
r2.VerticalAlignment = System.Windows.VerticalAlignment.Top;
r2.HorizontalAlignment = System.Windows.HorizontalAlignment.Left;
l = new Line();
l.X1 = 75;
l.Y1 = 75;
l.X2 = 375;
l.Y2 = 475;
l.Fill = new SolidColorBrush(Colors.Purple);
l.Stroke = new SolidColorBrush(Colors.Purple);
l.StrokeThickness = 2;
l.SetValue(Canvas.ZIndexProperty, -1);
PathGeometry myPathGeometry = new PathGeometry();
// Create a figure.
PathFigure pathFigure1 = new PathFigure();
pathFigure1.StartPoint = new Point(75, 75);
pathFigure1.Segments.Add(
new ArcSegment(
new Point(375, 475),
new Size(50, 50),
45,
true, /* IsLargeArc */
SweepDirection.Clockwise,
true /* IsStroked */ ));
myPathGeometry.Figures.Add(pathFigure1);
// Display the PathGeometry.
Path myPath = new Path();
myPath.Stroke = Brushes.Black;
myPath.StrokeThickness = 1;
myPath.Data = myPathGeometry;
myPath.SetValue(Canvas.ZIndexProperty, -1);
LayoutRoot.Children.Add(r1);
LayoutRoot.Children.Add(r2);
LayoutRoot.Children.Add(l);
LayoutRoot.Children.Add(myPath);

Categories