Avatar of jackjohnson44
jackjohnson44 asked on

c# ms chart how do I add a vertical line?

I have a chart control where I map out a line which is curved.  I want to add a few different vertical lines.  Basically I want to do something like new line(x=5)

How I'm currently drawing:

for (double i = currentPriceOfUnderlying * .5; i < currentPriceOfUnderlying * 1.5; i = i + .1)
{
          totalAtThisStrik = somefunction(i)
      chart1.Series["Series1"].Points.Add(new DataPoint(i, totalAtThisStrike));
}
C#.NET Programming

Avatar of undefined
Last Comment
Robert Schutt

8/22/2022 - Mon
ASKER CERTIFIED SOLUTION
Robert Schutt

Log in or sign up to see answer
Become an EE member today7-DAY FREE TRIAL
Members can start a 7-Day Free trial then enjoy unlimited access to the platform
Sign up - Free for 7 days
or
Learn why we charge membership fees
We get it - no one likes a content blocker. Take one extra minute and find out why we block content.
See how we're fighting big data
Not exactly the question you had in mind?
Sign up for an EE membership and get your own personalized solution. With an EE membership, you can ask unlimited troubleshooting, research, or opinion questions.
ask a question
ASKER
jackjohnson44

Thanks!
ASKER
jackjohnson44

I don't actually understand what you did here.  Sorry for the delay.

I was looking to put in a vertical line.  Why is there a mention of xValMin, xValMax?  Why is my other variables relavent here like currentPriceOfUnderlying?


Can you please explain what you did?  

Thanks


        private void PaintVerticalChartLine(Chart chart, ChartGraphics chartGraphics, double xval)
        {
            double x = chart.ChartAreas["ChartArea1"].AxisX.ValueToPixelPosition(xval);
            double y0 = chart.ChartAreas["ChartArea1"].AxisY.ValueToPixelPosition(chart.ChartAreas["ChartArea1"].AxisY.Minimum);
            double y1 = chart.ChartAreas["ChartArea1"].AxisY.ValueToPixelPosition(chart.ChartAreas["ChartArea1"].AxisY.Maximum);

            int pointMax = chart.Series["Series1"].Points.Count - 1;
            int pointNum = (int) Math.Round((double) pointMax*(xval - xvalMin)/(xvalMax - xvalMin));
            double y2 = (int) chart.ChartAreas["ChartArea1"].AxisY.ValueToPixelPosition(chart.Series["Series1"].Points[pointNum].YValues[0]);

            chartGraphics.Graphics.DrawLine(new Pen(Color.Silver, 5), (float) x, (float) (y0 - 1), (float) x, (float) (y1 + 1));
            chartGraphics.Graphics.DrawLine(new Pen(Color.Red, 3), (float) x, (float) (y0 - 2), (float) x, (float) y2);
        }
ASKER
jackjohnson44

Also, is there a way to call this without binding to an event?  I'd like to call it with parameters I can pass.  I am not sure how to access chartGraphics.
Experts Exchange has (a) saved my job multiple times, (b) saved me hours, days, and even weeks of work, and often (c) makes me look like a superhero! This place is MAGIC!
Walt Forbes
Robert Schutt

Well to start with the last question: that's the point, e.chartGraphics is only available in the PostPaint event. There may be a way but I haven't seen a clean way to do that.

In a previous solution I have set AxisX.Minimum and Maximum to the range needed to avoid having gaps left and right. In this solution I did it a bit different to let that part work the way it does by default. What stayed the same is that I used the Points array to determine the value based on the fact that you use a constant step in you x values. There's probably a better way for that using the chart methods (eliminating the need for defining min/max as well) but I was looking for a solution and came up with this.

What you want probably would take subclassing the Chart class and make a new method to paint a vertical line. It would still need to figure out where to draw the line exactly but maybe it would be easier to access the various min/max positions. It should be possible to clean up the current code for the purpose of not using min/max.
ASKER
jackjohnson44

Thanks.  Can you please explain the code inside the if statement? I don't understand it at all, or why min and max are used at all.  Does that correspond to the size of my grid?

This is my first use of the Chart and I really don't get it at all.
Robert Schutt

Sure: the check on xval is done because an error would occur when trying to do the calculations I do later on with a value that lies outside the bounds of the chart.

This is because of the way I get to the y value needed. Note that this is only because I chose to do something 'fancy' i.e. show a red line up to the y value at that point inside the grey line which goes all the way up. So, to get the x value I do something which may not be needed at all (once more, sorry): calculate the index in the point array that is closest to the x value where the line needs to be drawn. This can be done with a simple linear equation because the points are evenly spaced on the x axis.

Note that I did all this because I was under the impression that you did have some more experience with Charts (if only from previous questions) and would like to see something spiffy instead of a solution that you could have gotten by googling. But in retrospect sorry about that, I should have tried to come up with a straightforward solution first.

One way to get rid of all that unnecessary complex stuff, if you need only the full line, is to use this instead:
        private void PaintVerticalChartLine(Chart chart, ChartGraphics chartGraphics, double xval) {
            double x = chart.ChartAreas["ChartArea1"].AxisX.ValueToPixelPosition(xval);
            double y0 = chart.ChartAreas["ChartArea1"].AxisY.ValueToPixelPosition(chart.ChartAreas["ChartArea1"].AxisY.Minimum);
            double y1 = chart.ChartAreas["ChartArea1"].AxisY.ValueToPixelPosition(chart.ChartAreas["ChartArea1"].AxisY.Maximum);
            chartGraphics.Graphics.DrawLine(new Pen(Color.Silver, 5), (float)x, (float)(y0 - 1), (float)x, (float)(y1 + 1));
        }

Open in new window

You do still need to do this in a paint event because those methods (ValueToPixel) don't work otherwise. A downside is that the lines are drawn even when outside the bounds of the chart.
Get an unlimited membership to EE for less than $4 a week.
Unlimited question asking, solutions, articles and more.