I may be asking the wrong question, but what I need is to add a "Guide Line" to my windows form chart. In other words I have a chart with a simple data series and I need to draw a line on the y axis at the passing score, or 80%. I don't want to add a second series as the first series has an undetermined number of data points. Is there a simple way to simply draw one line on the y axis?
The dashed line below is what I am shooting for(it does not need the arrows).
100|
|
90|
| o
80|<----------------------->
|
70| o o
|
60| o
| o o
50|o o
|_________________________
1 2 3 4 5 6 7 8 9
Apologies for repeating Don Kirkby's answer, but I don't have the rep to add a comment yet.
Using HorizontalLineAnnotation you can set the ClipToChartArea which will limit the extent of the line to within the chart, to solve the problem you mentioned.
ChartArea area = ...;
var line = new HorizontalLineAnnotation();
line.IsInfinitive = true; // make the line infinite
line.ClipToChartArea = area.Name;
line.LineDashStyle = ChartDashStyle.Dash;
Assuming your y-axis holds values on a scale of 0..1 then you can attach the line to the Y-Axis using line.AxisY = area.AxisY, which results in its position being interpreted as an axis value, then set line.Y = 0.8; to attach at the 80% position.
You can add a StripLine.
Use StripWidth property to set line position:
var series = chart1.Series[0]; //series object
var chartArea = chart1.ChartAreas[series.ChartArea];
chartArea.AxisY.StripLines.Add(new StripLine
{
BorderDashStyle = ChartDashStyle.Dash,
BorderColor = Color.DarkBlue,
StripWidth = 80//Here is your y value
});
UPDATE: Previous version of this answer used Interval instead of StripWidth. As #dthor correctly pointed out in the comments setting the Interval will draw a repeated strip line. In the example above, Interval is set to 0 by default.
I've never used charts, but HorizontalLineAnnotation sounds promising.
You can add dots to the frame with a loop that has for example 900 loop for 1 to 9 values. For each loop the compiler will calculate the value and left a dot for that perimeter and another for the next one so it will looks like a line of a equation :)
Related
I have a candlestick chart which automatically updates with real time prices from a cryptocurrency exchange in the .NET forms. The goal is to make the bot preform actions when the price on chart passes one of the lines drawn by the user. So far I've come to the point of enabling line-drawing for users thanks to this article.
Could anyone please point me towards a method of detecting collision between the chart candles and the drawn lines? I feel like there must be an easier way than what I'm thinking of currently, just can't seem to figure out the way to it.
Using the exact solution for the line drawing as in the article, also posted code for the line-drawing below:
int index1 = 1;
int index2 = 4;
DataPoint left = chart.Series[0].Points[index1];
DataPoint right = chart.Series[0].Points[index2];
//Init the annotation
LineAnnotation line = new LineAnnotation();
line.AxisX = chart.ChartAreas[0].AxisX;
line.AxisY = chart.ChartAreas[0].AxisY;
line.IsSizeAlwaysRelative = false;
//Each point in a candlestick series has several y values, 0=high, 1=low, 2=open, 3=close
line.Y = left.YValues[1]; //low
line.X = left.XValue;
//If your data is indexed (your x values are Strings or you've set Series.IsXValueIndexed to true), use the data point index(+1) as the line X coordinate.
//line.X = index1 + 1;
//Use the width and height properties to determine the end position of the annotation.
line.Height = right.YValues[1] - left.YValues[1];
line.Width = right.XValue - left.XValue;
//Again, use the index if necessary
//line.Width = index2 - index1;
chart.Annotations.Add(line);
Just looking for a point in the direction of an easier solution, not the solution itself :) Thanks in advance!
So it sounds like you are asking is if a Point (Geometry) is above or below a line.
Here are the assumption (which you can change later to fit your needs):
an external resource is giving you a specific value (Y) at a specific point in time (X), which will call the Integral point XY.
The user has drawn a line which gives you a starting point (x1, y1) and an end point (x2, y2).
The graphs X component is in minutes, with each tick horizontally is 1 minute.
The graphs Y component is in dollars, with each tick is $25.
The user has drawn a line from (1:00pm, $50) to (1:05pm, $75).
We get an Integral Point XY at 1:10pm of $125.
What is the value of the line at 1:10pm so you can compare it to the Integral Point XY.
Based on my comments of Trigonometry..
We know the adjacent length is: 1:05 - 1:00 = 5
We know the opposite length is: 75 - 25 = 50
Using the formula: atan(opposite / adjacent) = angle
We calculate that the angle is: atan(50 / 5) = 1.47112767rad (radians)
Now we simply reverse our math:
We know the adjacent length is: 1:10 - 1:00 = 10
We know our Angle in Radians: 1.47112767
Using the formula: adjacent * tan(angle) = opposite
We calculate that the opposite is: 10 * tan(1.47112767) = ~$99.999999 or $100
$125 is above $100, do what you want.
So basically I have a graph as below in the image, I am going to be implementing some check boxes to enable and disable each line graph.
My main question is:
As you can see on the graphs there is dips in the data down to ZERO - How do I get these to automatically highlight for the user to see!
I.e. Set a point on the X Axis that displays interval!
One way would be to add a another Series of ChartType Point and add only those Zero Points as red dots..:
// add a new Series:
Series sz = chart1.Series.Add("Zeroes");
sz.ChartType = SeriesChartType.Point;
sz.Color = Color.Red;
sz.BorderWidth = 3;
// add Points wherever the other series is zero or less
foreach (DataPoint dp in chart1.Series[0].Points )
{
if (dp.YValues[0] <= 0) sz.Points.AddXY(dp.XValue, 0);
}
If you need to check on more Series you can repeat the loop for them..
I am drawing a line on a graph from numbers read from a text file. There is a number on each line of the file which corresponds to the X co-ordinate while the Y co-ordinate is the line it is on.
The requirements have now changed to include "special events" where if the number on the line is followed by the word special a spike will appear like image below:
Currently the only way I can find is to use a line for each spike, however there could be a large of these special events and so needs to be modular. This seems an efficient and bad way to program it.
Is it possible to add the spikes to the same graph line? Or is it possible to use just one additional line and have it broken (invisible) and only show where the spikes are meant to be seen?
I have looked at using bar graphs but due to other items on the graph I cannot.
The DataPoints of a Line Chart are connected so it is not possble to really break it apart. However each segment leading to a DataPoint can have its own color and that includes Color.Transparent which lends itself to a simple trick..
Without adding extra Series or Annotations, your two questions can be solved like this:
To simply add the 'spikes' you show us in the 2nd graph, all you need to do is to insert 2 suitable datapoints, the 2nd being identical to the point the spike is connected to.
To add an unconnected line you need to 'jump' to its beginning by adding one extra point with a transparent color.
Here are two example methods:
void addSpike(Series s, int index, double spikeWidth)
{
DataPoint dp = s.Points[index];
DataPoint dp1 = new DataPoint(dp.XValue + spikeWidth, dp.YValues[0]);
s.Points.Insert(index+1, dp1);
s.Points.Insert(index+2, dp);
}
void addLine(Series s, int index, double spikeDist, double spikeWidth)
{
DataPoint dp = s.Points[index];
DataPoint dp1 = new DataPoint(dp.XValue + spikeDist, dp.YValues[0]);
DataPoint dp2 = new DataPoint(dp.XValue + spikeWidth, dp.YValues[0]);
DataPoint dp0 = dp.Clone();
dp1.Color = Color.Transparent;
dp2.Color = dp.Color;
dp2.BorderWidth = 2; // optional
dp0.Color = Color.Transparent;
s.Points.Insert(index + 1, dp1);
s.Points.Insert(index + 2, dp2);
s.Points.Insert(index + 3, dp0);
}
You can call them like this:
addSpike(chart1.Series[0], 3, 50d);
addLine(chart1.Series[0], 6, 30d, 80d);
Note that they add 2 or 3 DataPoints to the Points collection!
Of course you can set the Color and width (aka BorderWidth) of the extra lines as you wish and also include them in the params list..
If you want to keep the points collection unchanged you also can simply create one 'spikes series' and add the spike points there. The trick is to 'jump' to the new points with a transparent line!
I'm trying to use the chart control on a windows form and have it working, plotting some real time data, however before the data arrives nothing is displayed. I would like to show an empty graph with an X Y of 10 30 but still have the graph auto range if values go above this.
I cannot find a property to show the "blank" graph it this possible and if so how?
thanks
You can hide all data of a Series by making its line color Transparent. If you also set its LegendText to be " " all you can see are the Axis ticks. you can control them by adding a few Points and by setting the Minimum and Maximum values:
// short reference for our dummy:
Series S0 = chart1.Series[0];
// a simple type
S0.ChartType = SeriesChartType.Line;
// set 10 point with x-values going from 0-100 and y-values going from 1-10:
for (int i = 0; i < 100; i +=10) S0.Points.AddXY(i , i / 10);
// or add only a few, e.g. the first and last points:
//S0.Points.AddXY(100, 10);
//S0.Points.AddXY(0, 10);
// hide the line:
S0.Color = Color.Transparent;
// hide the legend text (it will still take up a little space, though)
S0.LegendText = " ";
// limit the axis to the target values
chart1.ChartAreas[0].AxisX.Maximum = 100;
chart1.ChartAreas[0].AxisX.Minimum = 0;
The result looks like an empty chart:
So, I am trying to plot the graph and I have 3 fastlines in the Tchart, It seems like the graph are correct but there is something I need to set with labels of axes, What I get is this,
[my graph with x labels as 0 0 0 0 1 1 1 1 ]
http://s8.postimage.org/t7tappekl/image.png
[I want something like this]
http://s7.postimage.org/amltkb917/untitled.png
and what I want to get is something like this , the actual x labels as these . X labels are seconds.
I have already tried setting the valueformat for series and chart lablels. It did not work,
How should I do this? and also I am trying to zoom and scroll up the y axes to set the focus like the image 2. the y graph always starts from 0 , but initially is there any way to set the focus on starting point i.e.81
Thank you so much!
You can set desired increment for the bottom axis labels using the so called Increment property, for example:
tChart1.Axes.Bottom.Increment = 0.1;
For changing axes range you can use SetMinMax or Minimum and Maximum properties:
tChart1.Axes.Left.SetMinMax(50, 100);
or
tChart1.Axes.Left.AutomaticMinimum = false;
tChart1.Axes.Left.Minimum = 50;
tChart1.Axes.Left.AutomaticMaximum = false;
tChart1.Axes.Left.Maximum = 100;
Finally, you can change the chart view perspective changing some of the following properties:
tChart1.Aspect.View3D = true;
tChart1.Aspect.Orthogonal = false;
tChart1.Aspect.Chart3DPercent = 50;
tChart1.Aspect.Elevation = 0;
tChart1.Aspect.Rotation = 345;
tChart1.Aspect.Perspective = 50;
BTW, you'll find more information about axis settings in tutorial 4. Tutorials can be found a TeeChart's program group.