Your Privacy Matters: We use our own and third-party cookies to improve your experience on our website. By continuing to use the website we understand that you accept their use. Cookie Policy
110
UltraChart cross hair and the retrieval of all vertical values in the chart
posted

Hi,

following situation: I have a chart that contains multiple chart components. The x-Axis is time based and has a well known range. The values are not previously known and neither is the type of contained chart. So some are histogramcharts, some are linecharts, ..

At this point I wanted to retrieve the values that appear on the vertical axis of the current mouse position (i.e. chart 1 has at time X this value, chart 2 has at time X that value, ...). If there would be no value at this exact position, I could at all times linearily interpolate it with the two containing values to the left and to the right.

Now what I tried to accomplish it was:

* activate the cross hair
* attach to the UltraChart.MouseMove event
* calculate back the X position relative to the UltraChart component to the time based on the time range displayed and the width of the UltraChart
* last but not least iterate over the chart components (stored in the UltraChart.Series property) and retrieve the value at the selected time

And here the problems:

* cross hair works fine
* event is triggered, fine
* the width of the UltraChart component does not match the UltraChart.Width property and there is no UltraChart.RenderWidth property; is there another property? The chart property tells me it is aroud 1600px, but truly is around 2200px if I move the mouse on it and output the position. Or is there some kind of scaling property that I need to include in my calculation?
* under the assumption the calculation at point 3 worked and produced a valid result, would I really have to search linearly the two values I want using the UltraChart.Series property?

glad and happy for any kind of help,
vazlav

Parents
  • 110
    posted

    I actually got it working slightly, but still the results are not exact enough due to the lacking calculation of the current timestamp (xPercentTime). This piece of code may help whoever reads this topic and want to try it out for himself. Is there a way to get the xAxis value (DateTime) a bit more accurate?

            void Chart_MouseMove(object sender, MouseEventArgs e)
            {
                int leftBounds = 90;
                int rightBounds = 9;
                double xPos = e.Location.X - leftBounds;
                double width = chartPnl.Width - leftBounds - rightBounds;
                double xPercent = xPos / width;
                if ( xPercent >= 0 && xPercent <= 1)
                {
                    DateTime xPercentTime = lastTimeAxisZoomFrom_ + TimeSpan.FromSeconds(((lastTimeAxisZoomTo_ - lastTimeAxisZoomFrom_).TotalSeconds * xPercent));

                    Dictionary<string, double> values = RetrieveValuesAt(xPercentTime);
                    // do something with the values that were retrieved
                }
            }

            private Dictionary<string, double> RetrieveValuesAt(DateTime xPercentTime)
            {
                Dictionary<string, double> values = new Dictionary<string, double>();
                if (chartDescription_.HasSeries)
                {
                    foreach (ISeries series in chartDescription_.Series)
                    {
                        for (int i = 0; i < series.GetPoints().Count - 1; i++)
                        {
                            NumericTimeDataPoint point1 = series.GetPoints()[i] as NumericTimeDataPoint;
                            NumericTimeDataPoint point2 = series.GetPoints()[i + 1] as NumericTimeDataPoint;
                            if (point1 != null && point2 != null)
                            {
                                if (!point1.Empty && !point2.Empty)
                                {
                                    if (point1.TimeValue <= xPercentTime && point2.TimeValue >= xPercentTime)
                                    {
                                        // linear interpolation
                                        TimeSpan xRange = point2.TimeValue - point1.TimeValue;
                                        double yRange = point2.NumericValue - point1.NumericValue;
                                        double k = (yRange) / xRange.TotalSeconds;
                                        double x = k * (xPercentTime - point1.TimeValue).TotalSeconds + point1.NumericValue;
                                        if (values.ContainsKey(series.Label))
                                        {
                                            values.Remove(series.Label);
                                        }
                                        values.Add(series.Label, x);
                                        break;
                                    }
                                }
                                else
                                {
                                    // no value at all
                                }
                            }
                            else
                            {
                                IDataPoint pointA = series.GetPoints()[i];
                                if (pointA != null)
                                {
                                    Console.WriteLine("--UNSUPPORTED pointA.type = {0}", pointA.GetType());
                                }
                            }
                        }
                    }
                }
                return values;
            }

Reply Children
No Data