2016-08-08 37 views
0

Ich habe ein Problem mit C# -Charting.Diagramm: Rot X Fehler beim Versuch, mehrere Serien in einem indizierten Diagramm anzuzeigen

Dies ist mit System.Windows.Forms.DataVisualization.Charting

Meine Serie sind so konfiguriert, als solche indiziert zu werden:

{ 
      Name = name, 
      Color = color, 
      IsVisibleInLegend = false, 
      IsXValueIndexed = true, 
      ChartType = 
        System.Windows.Forms.DataVisualization.Charting.SeriesChartType.FastLine 
    }; 

Ich habe 3-Serie in diesem Diagramm

Ich bin Hinzufügen von Daten zu der Serie, wenn sie über einen Event-Handler ankommt

for (int i = 0; i < samples; i++) 
{ 
    double time_point = DData[i * 4]  
    chart1.Series[0].Points[lastSample + i].XValue = time_point; 
    chart1.Series[0].Points[lastSample + i].YValues[0] = DData[i * 4 + 1]; 
    chart1.Series[1].Points[lastSample + i].XValue = time_point; 
    chart1.Series[1].Points[lastSample + i].YValues[0] = DData[i * 4 + 2]; 
    chart1.Series[2].Points[lastSample + i].XValue = time_point; 
    chart1.Series[2].Points[lastSample + i].YValues[0] = DData[i * 4 + 3]; 
} 
lastSample = (lastSample + samples) % maxPlotPoints; 
chart1.Invalidate(); 

Die Frage ist, wie folgt:

  • Wenn ich auf jede Serie drehen einzeln (über chart1.Series [0] .Enabled), sie alle
  • gut funktionieren, wenn ich auf mehr als 1 Serie zu einer Zeit drehen , ein großes rotes X erscheint anstelle von eh chart, und ich muss die Anwendung neu starten, um das Streaming von Charts fortzusetzen. Dies geschieht entweder sofort oder nach ein paar Sekunden.
  • Wenn ich time_point auf eine andere Zahl festgelegt, wie 0, dieses Problem nicht geschieht, und alle drei Diagramme können gleichzeitig

Weiter angezeigt werden, ich verstehe, dass dies geschieht, wenn jede Serie eine andere X hat -Wert für den gleichen Punkt []. Aber ich setze ausdrücklich alle 3 Reihen, um den gleichen genauen time_point zu verwenden

Meine folgende Annahme war, dass der Eventhandler das Profil ausführte, bevor das vorhergehende Gewinde beendet wurde.

So habe ich eine Sperre um die grafische Darstellung Anruf, es ist nicht

sind
private Object thisLock = new Object(); 
lock (thisLock) 
{ 

} 

meine Fragen geholfen haben:

  1. Weiß jemand, ob es einen anderen Grund, warum dies verursacht werden kann?

  2. Ist es überhaupt möglich, nur die X-Indizes der ersten Serie für das Diagramm zu verwenden, aber alle 3 Reihen gleichzeitig anzuzeigen?

+0

_Wenn ich time_point auf eine andere Nummer, wie 0_ Ist das "wie" oder "anders als 0"? Außerdem: Der angezeigte Code ändert nur DataPoints; es fügt sie nicht hinzu, richtig? – TaW

+0

Korrigieren. Ich habe alle Datenpunkte erstellt, damit das Diagramm die gleiche Länge behält, und es aktualisiert nur Punkte von links nach rechts (sieht wie ein EKG-Scan aus). Ich kann time_point auf jede feste Zahl setzen und es funktioniert, nur wenn time_point sich ständig ändert, stürzt es ab. Zum Beispiel, wenn ich time_point ++ nach chart1.Invalidate() stürze – Mich

+1

Hm, wäre ein Test zu sehen, ob es mit der IsXValueIndexed-Eigenschaft zu tun hat. Sie könnten es vor den Updates auf "false" setzen und danach auf "true" setzen. Übrigens: Sie müssen es nur für eine Serie einstellen. – TaW

Antwort

0

EDIT: Dieses Update hat nicht funktioniert, ist das Problem verschwunden, kam dann nach einer Weile zurück

Der Kommentar oben TaW hat mir geholfen, dieses Problem zu beheben.

Dies scheint wirklich ein Problem mit Microsoft-Charts I

zu sein ursprünglich obwohl es aufgrund Eventhandler mehrmals feuern, bevor es fertig ist, und ich entschieden, um eine Warteschlange zu verwenden, die mit einem Eventhandler und Aus der Warteschleife angenommene gefüllt werden würden auf einem separaten Thread.

Das Problem war immer noch da.

Die Lösung des Problems war einfach Set IsXValueIndexed zu falsch dann es auf wahr bevor das Diagramm

Zeichnung unten ist der Code

verwendet

Falls sich jemand fragt sich, was dies tut: Es zeigt 3 Werte gleichzeitig auf dem Diagramm mit zunehmender Zeit. Das Diagramm wird von links nach rechts aktualisiert, statt zu scrollen (glaube EKG-Gerät in einem Krankenhaus) Es gibt eine feste Gesamtzahl von Punkten, die auf gesetzt ist maxPlotPoints Der EventHandler empfängt einige Datenpaket (hier gemacht), die a enthält bestimmte Anzahl von Punkten, die = samplePoints. Es konstruiert eine Datapoints struct und fügt sie in eine Warteschlange

ein separater Thread Task ein Element aus Datapoints aus der Warteschlange entfernt und verwendet es einen 100-Punkte-Abschnitt von jedem der drei Serien zu bevölkern. Dieser Abschnitt wird dann auf die nächsten 100 Punkte erhöht, und so weiter.

Dies ist nützlich, wenn Sie wollen

Leider eine feste Anzahl von Punkten kontinuierlich Diagramm scheinen kann ich nicht so richtig oben von TaW die Antwort zu markieren, weil es in einem Kommentar ist. Aber ich würde gerne versuchen, wenn Sie erklären können, wie das geht. Danke

private struct DataPoint 
    { 
     public double timePoint; 
     public double X; 
     public double Y; 
     public double Z; 
    } 
    private struct DataPoints 
    { 
     public DataPoints(int samples) 
     { 
      dataPoints = new DataPoint[samples]; 
     } 
     public DataPoint[] dataPoints; 
    } 

    Queue queue = new Queue(); 
    int lastSample = 0; 
    static int maxPlotPoints = 1000; 
    static int samplePoints = 100; 

    public ChartForm(UdpMgrControl RefUdpMgr, byte GyroChartNum, string ConfigFile) 
    { 
     for (Row = 0; Row < 3; Row++) 
     { 
      var series1 = new System.Windows.Forms.DataVisualization.Charting.Series 
      { 
       Name = name, 
       Color = Color.Blue, 
       IsVisibleInLegend = false, 
       IsXValueIndexed = true, 
       ChartType = System.Windows.Forms.DataVisualization.Charting.SeriesChartType.FastLine 
      }; 

      //Fill in chart with blank points 
      for (int i = 0; i < maxPlotPoints; i++) 
      { 
       series1.Points.AddY(0); 
      } 

      chart1.Series.Add(series1); 
     } 

     chart1.Series[0].Enabled = true; 
     chart1.Series[1].Enabled = true; 
     chart1.Series[2].Enabled = true; 

     running = true; 
     Thread main_thread = new Thread(new ThreadStart(this.MainTask)); 

    } 

    private void OutputHandler(byte[] DData) 
    { 
     if (running) 
     { 
      DataPoints data_element = new DataPoints(samplePoints); 
      for (int i = 0; i < samplePoints; i++) 
      { 
       data_element.dataPoints[i].X = DData[i].X; 
       data_element.dataPoints[i].Y = DData[i].Y; 
       data_element.dataPoints[i].Z = DData[i].Z; 
       data_element.dataPoints[i].timePoint = DData[i].timePoint; 
      } 
      queue.Enqueue(data_element); 
     } 
    } 
    private void MainTask() 
    { 
     while (running) 
     { 
      try 
      { 
       if (queue.Count > 0) 
       { 
        chart1.Series[0].IsXValueIndexed = false; 
        chart1.Series[1].IsXValueIndexed = false; 
        chart1.Series[2].IsXValueIndexed = false; 

        DataPoints data_element = (DataPoints)queue.Dequeue(); 
        for (int i = 0; i < data_element.dataPoints.Length; i++) 
         { 
          chart1.Series[0].Points[lastSample + i].XValue = data_element.dataPoints[i].timePoint; 
          chart1.Series[0].Points[lastSample + i].YValues[0] = data_element.dataPoints[i].X; 

          chart1.Series[1].Points[lastSample + i].XValue = data_element.dataPoints[i].timePoint; 
          chart1.Series[1].Points[lastSample + i].YValues[0] = data_element.dataPoints[i].Y; 

          chart1.Series[2].Points[lastSample + i].XValue = data_element.dataPoints[i].timePoint; 
          chart1.Series[2].Points[lastSample + i].YValues[0] = data_element.dataPoints[i].Z; 
         } 

        //Adjust the next location to end of first 
        lastSample = (lastSample + samples) % maxPlotPoints; 

        chart1.Series[0].IsXValueIndexed = true; 
        chart1.Series[1].IsXValueIndexed = true; 
        chart1.Series[2].IsXValueIndexed = true; 

        GC_UpdateDataGrids(); 
        chart1.Invalidate(); 
       } 
       else 
       { 
        Thread.Sleep(10); 
       } 
      } 
      catch (Exception error) 
      { 
       LogErrors.AddErrorMsg(error.ToString()); 
      } 
     } 
    } 
+0

Oh, und ich habe ein zusätzliches Problem gefunden. Das bedingte Aktivieren und Deaktivieren der Serie führt ebenfalls zum Absturz. Also muss ich immer chart1.Series [0] .Enabled = true; chart1.Series [1] .Enabled = true; chart1.Series [2] .Enabled = true; – Mich