2013-03-22 2 views
5

mit C# mit .NET-Diagramm.Erhalten Sie Y-Wert über .NET-Diagramm-Serie von X-Wert

Ich versuche, mehrere Wellenformen graphisch darzustellen, und ich möchte meine Maus über den Diagrammbereich bewegen, und mein Tooltip den Y-Wert jeder Serie in der Tabelle auf dieser X-Wert Position angezeigt haben.

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

Wie oben in diesem Diagramm. Nachfolgend finden Sie eine Version meines 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) 
      { 
       // 
      } 
     } 

Dies ist, was ich habe, und jetzt zeigt es nur den Y-Wert meiner Mauscursorposition ein. Ich habe andere Codes ausprobiert und versucht, die x-Werte irgendwie in chart1.Series [] zu mappen, aber es hat auch nicht funktioniert.

+0

Betrachten Sie ZedGraph, es ist nicht schlecht. – David

+0

Haben Sie versucht, mit dem Debugger durch den Code zu gehen, um zu sehen, was schief läuft? –

+0

Sieht für mich richtig aus - Ich habe einen ähnlichen Code (außer dass ich den X-Wert bekommen habe, schaue ich in der Serie nach, um den nächsten tatsächlichen Wert zu erhalten). Erhalten Sie irgendwelche Ausnahmen? Was ist 'max'? –

Antwort

4

(Dies ist als Reaktion auf den Antrag auf Code, um den nächstgelegenen Wert eines Pixel-Koordinaten zum Runterladen. Gegeben sehen)

ich es mache, von Ihnen ein bisschen anders, weil ich das Chart tatsächlich habe die Einrichtung " Cursor“, wie der Benutzer um die Maus bewegt, aber hoffentlich wird diese Ihnen genügend Informationen geben, damit Sie es an Ihre Bedürfnisse anpassen ...

Hier ist, wie ich die X-Achse coord für einen Kunden X-Koord berechnen:

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

Gegeben ein X-Wert, der von dem obigen met zurückgegeben wird hod, können wir den nächsten vorhergehenden Wert sehen:

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

Dann haben Sie ein Index, der Sie den Wert aus nachschlagen können _chart.Series[SERIES_INDEX].Points

Ich bin nicht sicher, ob dies mit der Art und Weise passt, dass Ihre Daten werden in den Diagrammen gespeichert, aber so mache ich es.

[EDIT] Hier ist die fehlende BinarySearch-Erweiterungs-Methode. Fügen Sie es einer statischen Klasse hinzu, auf die Sie zugreifen können. Ersetzen Sie die "Verträge" durch eigene Fehlerbehandlung, wenn Sie keine Code-Verträge verwenden.

/// <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 Vielen Dank für Ihre schnelle Antwort. Ich versuche, Ihre Methode zu implementieren, jedoch kann ich BinarySearch nicht in meinem chart.Series [inex] .Point verwenden. Es sagt mir, dass BinarySearch nicht in 'System.Windows.Forms.DataVisualization.Charting definiert ist.DataPointCollection " Nicht sicher, ob ich eine Verwendung oder etwas vermisse. Ich kann BinarySearch auf meinen Listen verwenden. – hansioux

+0

Oh Entschuldigung, ich habe vergessen, ich hatte eine Erweiterungsmethode für binäre Suche ein IList. Nur eine Sekunde, ich werde es hinzufügen. –

Verwandte Themen