1

I have a program running on a server which contacts Online-APIs for their Data every 5 seconds. The data gets saved in a Database as pairs. One pair consists of a UNIX-Timestamp and a double value. In my C# application, I want to show the values of 2 APIs at the same time. The X-Axis contains the timestamps and the Y-Axis the double values. It is guaranteed that both series have the same X-Values - only the Y-Values are different. It looks like this:

The chart

You can see that I already added the ChartArea[0].CursorX to the chart (the green line). It gets updated like this:

private void chart1_MouseMove(object sender, MouseEventArgs e)
        {
            Point p = new Point(e.X, e.Y);

            chart1.ChartAreas[0].CursorX.SetCursorPixelPosition(p, true);

            DateTime t = DateTime.FromOADate(chart1.ChartAreas[0].AxisX.PixelPositionToValue(e.X));
            graph_time.Text = t.ToLongTimeString();

        }

So the green CursorX gets set to the X position of the mouse. However, I set its interval to 5 Seconds.

  • First Question

I'm trying to show the X-Value of the CursorX in a label with these lines

    DateTime t = DateTime.FromOADate(chart1.ChartAreas[0].AxisX.PixelPositionToValue(e.X));
graph_time.Text = t.ToLongTimeString();

The problem is, it shows the X-Value from the position of the real cursor (which I'm hiding) instead of the green line. How can I get the value on the X-Axis of the green line?

  • Second Question

I also want to show the value of the intersections of the Green/Blue and Green/Red lines in two seperate Labels. Does anyone have a idea how to do that? I read about HitTest, but you need a X and Y value for it. I'd need something like a Vertical HitTest.

  • Third and last question

Is there any possibility to bind the green line (ChartArea.CursorX) to the actual exisiting DataPoints instead of setting a interval? Because there are two problems with it: 1. When the pairs for the chart look like this (timestamp,value) {2, 1.23}, {7, 43.2}, {12, 5.3} and the CursorX interval is set to 5 seconds, the CursorX stops at X = 0,5,10 instead of X = 2,7,12. 2. Sometimes the time difference between two pairs is not excatly 5 seconds, it can sometimes be 4 or 6. That's very a 5 second interval creates mistakes - because I want the CusorX only to stop at the exisiting DataPoints.

So, thats it. I tried the Charts in C# for the first time today and a lot of cool ideas came into my head - with a lot of problems to realize them. Hopefully some of you are good at C# charts and can help me out :)

Thanks!

Bobface
  • 2,782
  • 4
  • 24
  • 61

2 Answers2

0

Let me try to answer without testing..:

1 - Use CursorX.Position to get at the x-value the cursor sits on

2 - Find the two data points before and after the cursor and interpolate their Y-values. You can use LINQ to find the two points.. See here for an example how to search in the points collection.

3 - See 2! Pick the first or second or closest point; you need to set the Interval to 0 for this.

Community
  • 1
  • 1
TaW
  • 53,122
  • 8
  • 69
  • 111
0

I tried around a little bit yesterday evening and the solution for my problem is actually way easier than I thought. It pretty much works like the answer from TaW

        private void chart1_MouseMove(object sender, MouseEventArgs e)
        {
            if (e.X < 0 || e.Y < 0 || e.Location == prevPos)
                return;
            prevPos = e.Location;
            if (this.graphShowingData == false)
                return;

            Point p = new Point(e.X, e.Y);
            double searchVal = chart1.ChartAreas[0].AxisX.PixelPositionToValue(e.X);

            foreach (DataPoint dp in chart1.Series["Series1"].Points)
            {
                if(dp.XValue >= searchVal)
                {
                    chart1.ChartAreas[0].CursorX.SetCursorPosition(dp.XValue);
                    foreach(double yD in dp.YValues)
                    {
                        val_series1.Text = Math.Round(yD, 4).ToString();
                    }
                    break;
                }
            }

            foreach (DataPoint dp in chart1.Series["Series2"].Points)
            {
                if (dp.XValue >= searchVal)
                {
                    foreach (double yD in dp.YValues)
                    {
                        val_series2.Text = Math.Round(yD, 4).ToString();
                    }
                    break;
                }
            }


            DateTime t = DateTime.FromOADate(chart1.ChartAreas[0].CursorX.Position);
            graph_time.Text = t.ToLongTimeString();

        }

This code solves all of my three questions above.

Bobface
  • 2,782
  • 4
  • 24
  • 61