从X值获取整个.NET图表系列的Y值 [英] Get Y value across .NET chart series from X value

查看:89
本文介绍了从X值获取整个.NET图表系列的Y值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在C#和.NET图表中使用

using C# with .NET chart.

我正在尝试绘制几个波形图,希望在图表区域内移动鼠标,并在其X值位置的工具提示中显示图表中每个系列的Y值.

I am trying to graph several waveforms, and I wish to move my mouse across the chart area, and have my tooltip display the Y value of each series in the chart at this X value location.

|      at xValue 12    |                                     |
|      _ = 3           |                                     |
|      * = 2           |                                * *  |
|              ________|______________________________*_____ |
|             /        |                             *       |
| __________*/*********|*****************************        |
|        *             |                                     |
|       *              |                                     |
|______________________|_____________________________________|

类似上面的图.下面是我的代码的版本:

Kind of like this diagram above. Below is a version of my code:

void chart1_MouseMove(object sender, MouseEventArgs e)
        {
            var pos = e.Location;
            _point.X = e.Location.X;
            _point.Y = e.Location.Y;

            try
            {
                if ((chart1.ChartAreas[0].AxisX.PixelPositionToValue(e.X) >= 0) && (chart1.ChartAreas[0].AxisX.PixelPositionToValue(e.X) <= max))
                {
                    //Crossair
                    chart1.ChartAreas[0].CursorX.SetCursorPixelPosition(_point, true);

                    //Tooltips
                    double xValue = chart1.ChartAreas[0].AxisX.PixelPositionToValue(e.X);
                    double yValue = chart1.ChartAreas[0].AxisY.PixelPositionToValue(e.Y);
                    string all_Data_Values = "";

                    foreach (var series in chart1.Series)
                    {
                        all_Data_Values = all_Data_Values + Environment.NewLine + series.Name + ": " + yValue;
                    }

                    tooltip.Show("At " + Math.Truncate(xValue * 1000) / 1000 + all_Data_Values, this.chart1, pos.X - 40, pos.Y - 20);
                }
            }
            catch (Exception exception)
            {
               //
            }
        }

这就是我所拥有的,现在它仅显示我的鼠标光标位置的Y值.我尝试了其他代码,试图以某种方式将x值映射到chart1.Series [],但它也不起作用.

This is what I have, and right now it only displays the Y value of my mouse cursor location. I have tried other codes, trying to somehow map the x values into chart1.Series[] but it didn't work either.

推荐答案

(这是对代码请求的回应,该代码是在给定像素坐标的情况下查找最接近的值.)

(This is in response to the request for code to look up the nearest value given a pixel coord.)

我的操作与您的操作有所不同,因为实际上是在用户移动鼠标时设置图表的光标",但是希望这会为您提供足够的信息,以使其适应您的需求. ..

I'm doing it a bit differently from you, because I'm actually setting the chart's "cursor" as the user moves the mouse around, but hopefully this will give you enough information for you to adapt it to your needs...

这是我为客户的X坐标计算X轴坐标的方法:

Here's how I calculate the X axis coord for a client X coord:

private double calcCursorGraphX(int clientX)
{
    var xAxis = _chart.ChartAreas[CHART_INDEX].AxisX;
    int xRight = (int) xAxis.ValueToPixelPosition(xAxis.Maximum) - 1;
    int xLeft = (int) xAxis.ValueToPixelPosition(xAxis.Minimum);

    if (clientX > xRight)
    {
        return xAxis.Maximum;
    }
    else if (clientX < xLeft)
    {
        return xAxis.Minimum;
    }
    else
    {
        return xAxis.PixelPositionToValue(clientX);
    }
}

鉴于上述方法返回的X值,我们可以查找最接近的前一个值:

Given an X value returned from the above method, we can look up the nearest preceeding value:

private int nearestPreceedingValue(double x)
{
    var bpData  = _chart.Series[SERIES_INDEX].Points;
    int bpIndex = bpData.BinarySearch(x, (xVal, point) => Math.Sign(x - point.XValue));

    if (bpIndex < 0)
    {
        bpIndex = ~bpIndex;                // BinarySearch() returns the index of the next element LARGER than the target.
        bpIndex = Math.Max(0, bpIndex-1);  // We want the value of the previous element, so we must decrement the returned index.
    }                                      // If this is before the start of the graph, use the first valid data point.

    return bpIndex;
}

然后您就有一个索引,可用于从_chart.Series[SERIES_INDEX].Points

Then you have an index which you can use to look up the value from _chart.Series[SERIES_INDEX].Points

我不确定这是否适合您的数据在图表中的存储方式,但这就是我的方法.

I'm not sure if this fits with the way that your data is stored in the charts, but that's how I do it.

这是缺少的BinarySearch扩展方法.将其添加到可访问的静态类中.如果您不使用代码合同,则用自己的错误处理替换合同"内容.

Here's the missing BinarySearch extension method. Add it to a static class somewhere accessible. Replace the "Contracts" stuff with your own error handling if you're not using Code Contracts.

/// <summary>
/// Searches the entire sorted IList{T} for an element using the specified comparer 
/// and returns the zero-based index of the element.
/// </summary>
/// <typeparam name="TItem">The type of the item.</typeparam>
/// <typeparam name="TSearch">The type of the searched item.</typeparam>
/// <param name="list">The list to be searched.</param>
/// <param name="value">The value to search for.</param>
/// <param name="comparer">The comparer that is used to compare the value with the list items.</param>
/// <returns>
/// The zero-based index of item in the sorted IList{T}, if item is found; 
/// otherwise, a negative number that is the bitwise complement of the index of the next element that is larger than item,
/// or - if there is no larger element - the bitwise complement of Count.
/// </returns>

public static int BinarySearch<TItem, TSearch>(this IList<TItem> list, TSearch value, Func<TSearch, TItem, int> comparer)
{
    Contract.Requires(list != null);
    Contract.Requires(comparer != null);

    int lower = 0;
    int upper = list.Count - 1;

    while (lower <= upper)
    {
        int middle = lower + (upper - lower) / 2;
        int comparisonResult = comparer(value, list[middle]);

        if (comparisonResult < 0)
        {
            upper = middle - 1;
        }
        else if (comparisonResult > 0)
        {
            lower = middle + 1;
        }
        else
        {
            return middle;
        }
    }

    return ~lower;
}

这篇关于从X值获取整个.NET图表系列的Y值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆