2013-03-22 15 views
5

przy użyciu C# z wykresem .NET.Uzyskaj wartość Y dla serii wykresów .NET z wartości X

Próbuję wykreślić kilka przebiegów i chcę przesunąć kursor myszy po obszarze wykresu i poproszę o wyświetlanie wartości Y każdej serii na wykresie w tej lokalizacji wartości X.

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

Trochę jak ten schemat powyżej. Poniżej znajduje się wersja mojego kodu:

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) 
      { 
       // 
      } 
     } 

To co mam, a teraz to tylko wyświetla wartość Y mojego położenia kursora myszy. Próbowałem innych kodów, próbując jakoś mapować wartości x na chart1.Series [], ale to też nie działa.

+0

Rozważ użycie ZedGraph, nie jest zły. – David

+0

Czy próbowałeś przejść przez kod z debuggerem, aby zobaczyć, co dzieje się nie tak? –

+0

Wygląda dokładnie tak jak dla mnie - Mam podobny kod (z wyjątkiem otrzymania wartości X, szukam go w serii, aby uzyskać najbliższą rzeczywistą wartość). Czy masz jakieś wyjątki? Czym jest "max"? –

Odpowiedz

4

(Jest to odpowiedź na wniosek o kodzie zajrzeć do najbliższego wartość otrzymuje coord pikseli).

robię to nieco inaczej od ciebie, bo ja rzeczywiście ustawienie wykresu " kursor”, gdy użytkownik przesuwa kursor myszy wokół, ale mam nadzieję, że to daje wystarczająco dużo informacji, aby dostosować go do swoich potrzeb ...

Oto jak obliczyć coord oś X dla klienta 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); 
    } 
} 

Biorąc pod uwagę wartość X zwróconą z powyższego spełnione hod, możemy spojrzeć w górę do najbliższej wartości poprzedzających:

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; 
} 

Wtedy masz indeks których można użyć, aby sprawdzić wartość od _chart.Series[SERIES_INDEX].Points

Nie jestem pewien, czy to pasuje do sposobu, w jaki Twoje dane są przechowywane na wykresach, ale tak to robię.

[EDYCJA] Oto brakująca metoda rozszerzenia BinarySearch. Dodaj go do klasy statycznej gdzieś dostępnej. Zastąp elementy "Kontrakty" własną obsługą błędów, jeśli nie korzystasz z Kontraktów Kodowych.

/// <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; 
} 
+0

Waston Dziękujemy za szybką odpowiedź. Próbuję zaimplementować twoją metodę, jednak nie mogę użyć BinarySearch na moim chart.Series [inex] .Point. Mówi mi, że BinarySearch nie jest zdefiniowany w 'System.Windows.Forms.DataVisualization.Charting.DataPointCollection " Nie jestem pewien, czy brakuje mi jakiegoś zastosowania lub czegoś, mogę użyć BinarySearch na moich listach – hansioux

+0

Och, przepraszam, zapomniałem, że miałem metodę rozszerzania dla binarnego przeszukiwania IList'a, tylko chwilkę, dodam to. –

Powiązane problemy