ASP.NET (C#) Graph - c#

I am wondering how can I remove the 3 horizontal red lines on the stock graph as shown in image bellow. Please ignore the dots/squares on the image they are irrelevant. I think I have searched every google page there is and went through every option asp.net has... and could not figure out it. Any help is greatly appreciated!
Code that generated this graph:
Double[] test = new Double[] { 10, 50 };
Chart1.Series[0].ChartType = SeriesChartType.Stock;
Chart1.Series[0].YAxisType = AxisType.Primary;
Chart1.Series[0].Color = Color.Red;
Chart1.Series[0].BorderWidth = 10;
Chart1.ChartAreas[0].AxisY.MajorGrid.Enabled = false;
Chart1.ChartAreas[0].AxisX.MajorGrid.Enabled = false;
Chart1.Series[0]["PixelPointWidth"] = "5";
Chart1.Series.Add(new Series("Test Series"));
Chart1.Series[1].ChartType = SeriesChartType.Point;
Chart1.Series[1].YAxisType = AxisType.Primary;
Chart1.Series[1].Color = Color.Black;
Chart1.Series[1].BorderWidth = 3;
Chart1.Series[1].MarkerSize = 15;
Chart1.Series.Add(new Series("New Series"));
Chart1.Series[2].ChartType = SeriesChartType.Point;
Chart1.Series[2].YAxisType = AxisType.Primary;
Chart1.Series[2].Color = Color.Orange;
Chart1.Series[2].BorderWidth = 3;
Chart1.Series[2].MarkerSize = 15;
Chart1.Series[0].Points.Add(new Double[] {-10, 50});
Chart1.Series[1].Points.Add(25);
Chart1.Series[2].Points.Add(20);
for (int i = 0; i < 2; i++)
{
Chart1.Series[0].Points.Add(test);
Chart1.Series[1].Points.Add(25);
Chart1.Series[2].Points.Add(20);
}

Okay, after looking into it obsessively, I think that I have a solution. Just adding the two Y values, the chart has a default value of zero for a marker (high or low?). By specifying that you will add the four values (open, close, high, low - not certain about the high/low order), you can hide those lines by making them fall within your open/close range, and by setting the PixelPointWidth to equal or less then your BorderWidth.
// IMPORTANT: add the ", 4" to indicate that you have the four Y values
Chart1.Series.Add(new Series("Stock", 4));
Chart1.Series["Stock"].ChartType = SeriesChartType.Stock;
Chart1.Series["Stock"].YAxisType = AxisType.Primary;
Chart1.Series["Stock"].Color = Color.Red;
Chart1.Series["Stock"].BorderWidth = 10;
Chart1.ChartAreas[0].AxisY.MajorGrid.Enabled = false;
Chart1.ChartAreas[0].AxisX.MajorGrid.Enabled = false;
// Set <= BorderWidth, so that it's effectively hidden
Chart1.Series["Stock"]["PixelPointWidth"] = "10";
Chart1.Series["Stock"].Points.AddY(10, 50, 20, 30); // open, close, high, low.
That was a little hard to track down. Whew.

Related

Visual bug when inputting numbers too high into a Windows Form app line graph

I am using C# to try to input numbers into a line graph from a text file. The numbers in the text file are big, as in -30000. Every time I input a large number into the graph, I get a visual glitch that turns the graph black. Am I doing something wrong or is it a bug?
void ChartLoad()
{
var chart = LineGraph.ChartAreas[0];
chart.AxisX.IntervalType =
System.Windows.Forms.DataVisualization.Charting.DateTimeIntervalType.Number;
chart.AxisX.LabelStyle.Format = "";
chart.AxisY.LabelStyle.Format = "";
chart.AxisX.LabelStyle.IsEndLabelVisible = true;
chart.AxisX.Interval = 0.5;
chart.AxisY.Interval = 10;
LineGraph.Series[0].IsVisibleInLegend = false;
LineGraph.Series.Add("Line1");
LineGraph.Series["Line1"].ChartType =
System.Windows.Forms.DataVisualization.Charting.SeriesChartType.Line;
LineGraph.Series["Line1"].Color = Color.Green;
LineGraph.Series.Add("Line2");
LineGraph.Series["Line2"].ChartType =
System.Windows.Forms.DataVisualization.Charting.SeriesChartType.Line;
LineGraph.Series["Line2"].Color = Color.Blue;
LineGraph.Series["Line1"].Points.AddXY(30000, 30000);
LineGraph.Series["Line1"].Points.AddXY(-30000, -30000);
}
The problem is the grid. You have an amazingly small intervall compared to the range of your values. The grid is so tight that it webbes a narrow carpet of gridlines onto your chart.
You could solve it by
switching of the grid:
chart.AxisX.MinorGrid.Enabled = false;
chart.AxisX.MajorGrid.Enabled = false;
chart.AxisY.MajorGrid.Enabled = false;
chart.AxisY.MinorGrid.Enabled = false;
Or by adjusting the axes intervalls to a reasonable number depending on the range of your values. You will see immidiately a difference when you set the interval to:
chart.AxisX.Interval = 10000;
chart.AxisY.Interval = 10000;
Here is a method that could do this for you:
private void AddValuesAndAdjustInterval(string series, double xValue, double yValue)
{
LineGraph.Series[series].Points.AddXY(xValue, yValue);
var chart = LineGraph.ChartAreas[0];
double maxValueX = LineGraph.Series[series].Points.Select(x=> x.XValue).Max();
double minValueX = LineGraph.Series[series].Points.Select(x=> x.XValue).Min();
double maxValueY = LineGraph.Series[series].Points.SelectMany(x=> x.YValues).Max();
double minValueY = LineGraph.Series[series].Points.SelectMany(x => x.YValues).Min();
int stepSize = 20; // the smaller this value the larger the grid separation
chart.AxisX.Interval = (maxValueX - minValueX) / stepSize;
chart.AxisY.Interval = (maxValueY - minValueY) / stepSize;
}
Now you can use it to add values:
AddValuesAndAdjustInterval("Line1", 30000, 30000);
AddValuesAndAdjustInterval("Line1", -30000, -30000);

Scrolling/Moving MS chart area to highlighted datapoint when in zoom state

In windows form, I am displaying data in MS Chart from Datagridview.
When selecting an row in the datagridview, I am highlighting the corresponding datapoint in the chart with different color.
When chart is in zoom state , if a datapoint is highlighted newly and if it is not in the visible state, I have to scroll/move the chart to highlighted datapoint.
chart.ChartAreas.Add("LineGraphHistory");
chart.ChartAreas["LineGraphHistory"].AxisX.Title = "X Axis";
chart.ChartAreas["LineGraphHistory"].AxisX.MajorGrid.LineColor = System.Drawing.Color.Black;
chart.ChartAreas["LineGraphHistory"].AxisX.MajorGrid.LineDashStyle = System.Windows.Forms.DataVisualization.Charting.ChartDashStyle.Dash;
chart.ChartAreas["LineGraphHistory"].AxisY.Title = "Y Axis";
chart.ChartAreas["LineGraphHistory"].AxisY.MajorGrid.LineColor = Color.Black;
chart.ChartAreas["LineGraphHistory"].AxisY.MajorGrid.LineDashStyle = System.Windows.Forms.DataVisualization.Charting.ChartDashStyle.Dash;
chart.ChartAreas["LineGraphHistory"].BackColor = Color.White;
chart.ChartAreas["LineGraphHistory"].CursorX.IsUserEnabled = true;
chart.ChartAreas["LineGraphHistory"].CursorX.IsUserSelectionEnabled = true;
chart.ChartAreas["LineGraphHistory"].CursorX.Interval = 0;
chart.ChartAreas["LineGraphHistory"].AxisX.ScaleView.Zoomable = true;
chart.ChartAreas["LineGraphHistory"].AxisX.ScrollBar.Enabled = true;
chart.Legends.Add("Legend");
chart.Legends["Legend"].BorderColor = Color.Tomato;
chart.DataSource = CSVDataTable;
chart.ChartAreas["LineGraphHistory"].AxisX.IntervalType = DateTimeIntervalType.Seconds;
chart.ChartAreas["LineGraphHistory"].AxisX.LabelStyle.Format ="dd-MM-yyyy\n hh:mm:ss"; ;
chart.Series[s].XValueType =ChartValueType.DateTime ;
chart.DataBind();
chart.Update();
private void cDataGrid_SelectionChanged(object sender, EventArgs e)
{
int nCount = csvDataGrid.SelectedRows.Count;
if (nCount > 0)
{
for (int i = 0; i < nCount; i++)
{
int index = csvDataGrid.SelectedRows[i].Index;
if (index >= csvDataGrid.Rows.Count-1)
return;
for (int k = 0; k < chart.Series.Count; k++)
{
DataPointCollection pr = chart.Series[k].Points;
pr[index].MarkerColor = Color.DarkGoldenrod;
pr[index].MarkerStyle = MarkerStyle.Star10;
pr[index].MarkerSize = 20;
// chart.
}
chart.Update();
}
}
}
How to achieve this?
As Taw suggested I tried to set scaleview position.
I have 10 datapoints. The range of x value of datapoints are 20 to 200. Each x value has equal difference of 20. The view size is 100. In zoom mode, when I scrolling to maximum the x range is 101 to 200 in the view , the last point is displayed as 5th point in the view. Whereas if I use your code to set scaleview position to highlight last datapoint , the x range becomes 180 to 240 and highlighted last datpoint is visible as first range.
Why paintviewmin and paintviewmax values are changing?
The images are
You need to calculate the offset from the DataPoint dp.XValue, maybe like this:
Axis ax = chart.ChartAreas[0].AxisX;
var size = ax.ScaleView.ViewMaximum - ax.ScaleView.ViewMinimum;
ax.ScaleView.Position = dp.XValue - size / 2.0;
Example:
Update: When smaller data sets are displayed the automatically added margins mess up the simple calculation above. To avoid this you can add:
chart.ChartAreas[0].AxisX.IsMarginVisible = false;

Why I can't see the Scrollbar in ChartArea of MSChart?

I make a c#
Bnnn
chart program.
And, I use the MSChart.
I setup the Scrollbar information on ChartArea Collection.
When execute my program, the scrollbar is not visible... what's wrong with my ChartArea Collection.
And, I try to coding for setting scrollbar like this.
chart1.ChartAreas[0].AxisX.ScrollBar.IsPositionedInside = true;
chart1.ChartAreas[0].AxisX.ScrollBar.Size = 10;
chart1.ChartAreas[0].AxisX.ScrollBar.Enabled = true;
chart1.ChartAreas[0].AxisX.ScrollBar.IsPositionedInside = true;
chart1.ChartAreas[0].AxisX.ScrollBar.Size = 10;
chart1.ChartAreas[0].AxisX.ScrollBar.Enabled = true;
chart1.ChartAreas[0].AxisX.ScrollBar.ButtonStyle = ScrollBarButtonStyles.SmallScroll;
chart1.ChartAreas[0].AxisX.ScrollBar.BackColor = Color.LightGray;
chart1.ChartAreas[0].AxisX.ScrollBar.ButtonColor = Color.Gray;
chart1.ChartAreas[0].AxisX.ScrollBar.LineColor = Color.Black;
chart1.ChartAreas[0].AxisX.Minimum = 0;
chart1.ChartAreas[0].AxisX.Maximum = 10;
chart1.ChartAreas[0].AxisY.Minimum = 0;
chart1.ChartAreas[0].AxisY.Maximum = 100;
chart1.ChartAreas[0].AxisX.Interval = 1;
chart1.Series["Series1"].Points.AddXY(0, 0);
chart1.Series["Series2"].Points.AddXY(0, 0);
chart1.Series["Series3"].Points.AddXY(0, 0);
Is it any wrong?.
You are setting some properties on the AxisX scroll bar twice (such as Size and Enabled), but you are not setting them for the AxisY.
I suspect that you did a cut and past and forgot to change some X to Y ....

How to make line chart start from 0 X-Axis

I create a line chart, but I want to display the chart begin from 0 in X-axis.
How can I do this.
I try some method but still did not get what I want.
Chart1.ChartAreas[0].AxisX.Interval = 0;
Chart1.ChartAreas[0].AxisX.IsStartedFromZero = true;
Chart1.ChartAreas[0].AxisX.Minimum = 0;
Chart1.ChartAreas[0].AxisX.Crossing = 0;
This is what I do now
This is what I want
And one more, how can I set major and minor unit in the chart..?
my code here
protected void Page_Load(object sender, EventArgs e)
{
System.Drawing.Font axisFont = new System.Drawing.Font("Arial", 8, System.Drawing.FontStyle.Bold);
System.Drawing.Font titleFont = new System.Drawing.Font("Arial", 10, System.Drawing.FontStyle.Bold);
Chart1.Width = 600;
Chart1.Height = 400;
Chart1.BorderlineColor = System.Drawing.Color.Black;
Chart1.BorderlineWidth = 1;
Chart1.BorderlineDashStyle = ChartDashStyle.Solid;
double[] min = { 60.9, 0, 28.81, 7.27 };
double[] ave = { 60.9, 0, 28.81, 7.27 };
double[] max = { 5167.72, 1.27, 4176.16, 2566.59 };
Chart1.Series["Series1"].ChartArea = "ChartArea1";
Chart1.Series["Series2"].ChartArea = "ChartArea1";
Chart1.Series["Series3"].ChartArea = "ChartArea1";
Chart1.Series["Series1"].Points.AddXY("Step 1-2", max[0]);
Chart1.Series["Series2"].Points.AddXY("Step 1-2", ave[0]);
Chart1.Series["Series3"].Points.AddXY("Step 1-2", min[0]);
Chart1.Series["Series1"].Points.AddXY("Step 2-3", max[1]);
Chart1.Series["Series2"].Points.AddXY("Step 2-3", ave[1]);
Chart1.Series["Series3"].Points.AddXY("Step 2-3", min[1]);
Chart1.Series["Series1"].Points.AddXY("Step 3-4", max[2]);
Chart1.Series["Series2"].Points.AddXY("Step 3-4", ave[2]);
Chart1.Series["Series3"].Points.AddXY("Step 3-4", min[2]);
Chart1.Series["Series1"].Points.AddXY("Step 4-5", max[3]);
Chart1.Series["Series2"].Points.AddXY("Step 4-5", ave[3]);
Chart1.Series["Series3"].Points.AddXY("Step 4-5", min[3]);
String hour1 = "hh";
Chart1.Titles.Add("Cycle Time : "+hour1);
Chart1.Titles[0].Font = titleFont;
Chart1.Series["Series1"].MarkerStyle = System.Web.UI.DataVisualization.Charting.MarkerStyle.Triangle;
Chart1.Series["Series2"].MarkerStyle = System.Web.UI.DataVisualization.Charting.MarkerStyle.Square;
Chart1.Series["Series3"].MarkerStyle = System.Web.UI.DataVisualization.Charting.MarkerStyle.Diamond;
Chart1.Series["Series1"].MarkerSize = 15;
Chart1.Series["Series2"].MarkerSize = 15;
Chart1.Series["Series3"].MarkerSize = 15;
Chart1.Legends.Add("Legend1");
Chart1.Series["Series1"].LegendText = "Max";
Chart1.Series["Series2"].LegendText = "Ave";
Chart1.Series["Series3"].LegendText = "Min";
Chart1.Series["Series1"].Legend = "Legend1";
Chart1.Series["Series2"].Legend = "Legend1";
Chart1.Series["Series3"].Legend = "Legend1";
Chart1.Series["Series1"].IsVisibleInLegend = true;
Chart1.Series["Series2"].IsVisibleInLegend = true;
Chart1.Series["Series3"].IsVisibleInLegend = true;
//This part I try to make the graph start from 0 in X-axis but not work
//Chart1.ChartAreas[0].AxisX.Interval = 0;
//Chart1.ChartAreas[0].AxisX.IsStartedFromZero = true;
//Chart1.ChartAreas[0].AxisX.Minimum = 0;
//Chart1.ChartAreas[0].AxisX.Crossing = 0;
//Chart1.ChartAreas[0].AxisX.Minimum = 0;
//Chart1.ChartAreas[0].Position.Auto = false;
Chart1.ChartAreas[0].AxisX.TitleFont = axisFont;
Chart1.ChartAreas[0].AxisY.TitleFont = axisFont;
Chart1.ChartAreas[0].AxisX.Title = "Step";
Chart1.ChartAreas[0].AxisY.Title = "Time (" + hour1 + ")";
Chart1.ChartAreas[0].BackColor = System.Drawing.Color.AliceBlue;
Chart1.ChartAreas[0].AxisX.MajorGrid.Enabled = false;
Chart1.ChartAreas[0].AxisY.MajorGrid.LineColor = System.Drawing.ColorTranslator.FromHtml("#D5E8F5");
}
I had a similar issue, and found that the solution was to set the IsMarginVisible flag to false:
chart1.ChartAreas[0].AxisX.IsMarginVisible = false;
Hope this helps.
The Chart control decides by his own where to start the Axes, and more importantly where to end them, because it could create problems in displaying the points.
Say that you have a point in (-1,0), if you decided to start the X-Axis from 0 what should the chart control do? Display the series starting from unknown? Erase the point?
In your chart every point has 2 values, a string value for the X-Axis and a double for the Y-Axis.
The strings are stored in the chart in alphabetical order, and it also checks whether some are equals or not (so you don't have 3 *Step 1-3*s).
It also give the strings a position value, starting obviously from 0.
But what is the 0 position value string?
Answer: there is no 0 position value string possible.
In fact, if you try something like
Chart1.Series["Series1"].Points.AddXY(string.Empty, 1.0);
Chart1.Series["Series2"].Points.AddXY(string.Empty, 2.0);
Chart1.Series["Series3"].Points.AddXY(string.Empty, 3.0);
The chart control will automatically add a label for the empty string called 1, showing the position value.
The only way for setting major and minor unit in the chart is by adding or removing data from the chart.
Another workaround could be this:
Chart1.Series["SeriesMin"].Points.AddXY(0, max[0]);
Chart1.Series["SeriesAve"].Points.AddXY(0, ave[0]);
Chart1.Series["SeriesMax"].Points.AddXY(0, min[0]);
Chart1.Series["SeriesMin"].Points[0].AxisLabel = "Step 1-2";
Chart1.Series["SeriesAve"].Points[0].AxisLabel = "Step 1-2";
Chart1.Series["SeriesMax"].Points[0].AxisLabel = "Step 1-2";
Then you could add all your so far not working code
Chart1.ChartAreas[0].AxisX.Interval = 0;
Chart1.ChartAreas[0].AxisX.IsStartedFromZero = true;
Chart1.ChartAreas[0].AxisX.Minimum = 0;
Chart1.ChartAreas[0].AxisX.Crossing = 0;
Chart1.ChartAreas[0].AxisX.Minimum = 0;
//Chart1.ChartAreas[0].Position.Auto = false; //EXCEPT THIS ONE!!
Worked like a charm, exceedingly boring if you had to add more data not from a db.

How can I see 2 Series over my chart on the same graph when values are different (very high and very low)

I define 2 Series (I am using Telerik) that represent my Network Traffic rate (MBit/sec and Packet/sec):
AreaSeries series;
AreaSeries series2;
series = new AreaSeries();
radChartView1.Series.Add(series);
series.BorderColor = Color.SteelBlue;
series.BackColor = Color.FromArgb(20, Color.SkyBlue);
series.BorderWidth = 1;
series.HorizontalAxis.ShowLabels = false;
series.VerticalAxis.ShowLabels = false;
series2 = new AreaSeries();
radChartView1.Series.Add(series2);
series2.BorderColor = Color.Gray;
series2.BackColor = Color.FromArgb(20, Color.Gray);
series2.BorderWidth = 1;
series2.HorizontalAxis.ShowLabels = false;
series2.VerticalAxis.ShowLabels = false;
My chart received the real time data via Timer:
private void timerStatistics_Tick(object sender, EventArgs e)
{
try
{
if (series.DataPoints.Count > 40)
series.DataPoints.RemoveAt(0);
series.DataPoints.Add(new Telerik.Charting.CategoricalDataPoint(AdapterStatistics.BitsPerSecond * 0.000001));
if (series2.DataPoints.Count > 40)
series2.DataPoints.RemoveAt(0);
series2.DataPoints.Add(new Telerik.Charting.CategoricalDataPoint(AdapterStatistics.PacketsPerSecond));
}
catch (Exception)
{ }
}
And my problem is that because my 2 values are very different i only can see one of my Series (usually Packet/sec) because for example MBit/sec get the value 1.4 and Packet/sec get the value 200 so from my chart i can see the biggest value, the lowest value is so small that it cannot be seen (see my screenshot inside the red rectangle a very small blue line... ):
How to fix it?
Not sure how it applies to Telerik controls, but in the regular chart control, you can have 2 x-axes and 2 y-axes, and assign different series to use different axes. Thus, you could do something like:
series.YAxisType = AxisType.Primary;
series2.YAxisType = AxisType.Secondary;
Axis yaxis1 = chart.ChartAreas[0].AxisY;
Axis yaxis2 = chart.ChartAreas[0].AxisY2;
yaxis1.Maximum = 1e6;
yaxis2.Maximum = 1e3;
Looks like it's very similar using Telerik controls, taken straight from the Telerik website (http://www.telerik.com/help/winforms/chartview-axes-multiple-axes.html):
LinearAxis verticalAxis1 = new LinearAxis();
verticalAxis1.AxisType = AxisType.Second;
LinearAxis verticalAxis2 = new LinearAxis();
verticalAxis2.AxisType = AxisType.Second;
verticalAxis2.HorizontalLocation = AxisHorizontalLocation.Right;
series.HorizontalAxis = horizontalAxis;
series.VerticalAxis = verticalAxis1;
series2.HorizontalAxis = horizontalAxis;
series2.VerticalAxis = verticalAxis2;

Categories