2017-05-10 1 views
0

Situation:Zoom/unzoom und Punkte Dezimierung

Ich habe ein Diagramm und drei Chartarea, die in der Ansicht, Zoom, Cursor durch das AxisViewChanged Verfahren ausgerichtet sind, die auf diese Weise handeln:

 if (e.Axis == ax1) 
     { 
      ax2.ScaleView.Size = ax1.ScaleView.Size; 
      ax2.ScaleView.Position = ax1.ScaleView.Position; 
      ax3.ScaleView.Size = ax1.ScaleView.Size; 
      ax3.ScaleView.Position = ax1.ScaleView.Position; 
      min = (int)ax1.ScaleView.ViewMinimum; 
      max = (int)ax1.ScaleView.ViewMaximum;   
     } 

     if (e.Axis == ax2) 
     { 
     .... 

Und es funktioniert in beiden Fällen sehr gut: wenn ich ein-/auszoomen oder scrollen.

Problem:

Das Problem ist, dass mein Graph Quelle durch eine Menge von Punkten gemacht wird, im schlimmsten Fall, dass wir über 3'600'000 Proben sprechen. Bei dieser Anzahl an Samples, wenn ich Punkte mit dem Cursor umherbewege und versuche, einen Tooltip mit den Werten zu zeigen, kollabiert die Interaktionsqualität und wird unbrauchbar (selbst wenn Fast Line gesetzt wurde). Also habe ich versucht, eine einfache Dezimierung Algorithmus zu implementieren, um reducethe Anzahl zeigten Punkte:

void draw_graph(int start, int end) 
    { 
     double fract_value = 0; 
     int int_value = 0; 
     int num_saples_selected = end - start; 
     if(num_saples_selected <= MAX_GRAPH_NUM_SAMPLES) 
      fill_graphs_point(0, end, 1); 
     else 
     { 
      fract_value = ((double)num_saples_selected)/((double)MAX_GRAPH_NUM_SAMPLES); 
      int_value = (int)fract_value; 
      if (fract_value > int_value)     
       int_value++;          
      fill_graphs_point(0, end, int_value); 
     } 
    } 

    void fill_graphs_point(int start, int end, int step) 
    { 
     int i = 0;   
     for (i = start; i < end; i=i+step) 
     { 
      dlChart.Series[SERIES_VOLTAGE].Points.AddXY(timestamps_array[i], voltage_array[i]);              
      dlChart.Series[SERIES_CURRENT].Points.AddXY(timestamps_array[i], current_array[i]);    
      dlChart.Series[SERIES_ENERGY].Points.AddXY(timestamps_array[i], energy_array[i]); 

     // I will use this to came back to real position of the initial array 
      decimation_positions.Add(i); 
     } 
    } 

Assuminig ich mit dieser Methode eine gute Idee hatte die Punkte Zahl zu reduzieren, ich weiß nicht, wo der Anruf an die setzen Funktion "draw_graph". Wenn ich es in die AxisViewChanged-Methode einfüge, wird es meine Methode auch aufrufen, wenn ich meinen Graphen (horizontal) scrolle und das ist nicht das, was ich will. Ich möchte meine Methode nur beim Zoomen und Unzoom aufrufen.

Erwartetes Verhalten: In der ersten Ansicht (ohne Zoom) muss der Graph eine "Idee" des Trends des Graphen zeigen. Dann für jede Auswahl/(Un) Zoom Ich möchte meine Funktion aufrufen, um zu überprüfen, ob die Anzahl der Punkte des ausgewählten Teils in meine Fenstergröße passt, die MAX_GRAPH_NUM_SAMPLES (= 10000) ist.

Hoffe jemand kann mir helfen. Welche Art von Vorschlag auch immer zu schätzen wissen wird. Danke im Voraus.

+1

Es gibt nie einen guten Grund, so viele Punkte in ein Diagramm zu entleeren, niemand hat einen so großen Monitor. Filtern Sie die Daten einfach * immer *, bevor Sie die Serie erstellen. –

+0

Danke Hans, auf diese Weise versuche ich die Punkte zu filtern um ihre Anzahl zu reduzieren. Vielleicht war ich nicht so klar: In der ersten Ansicht (ohne Zoom) muss die Grpah eine "Idee" für den Trend des Graphen zeigen. Dann für jede Auswahl/(Un) Zoom Ich möchte meine Funktion aufrufen, um zu überprüfen, ob die Anzahl der Punkte des ausgewählten Teils passt in meine Fenstergröße, die ist (MAX_GRAPH_NUM_SAMPLES = 10000) – GiPi

+0

Es gibt eine 'AxisViewChanged', die ich verwenden würde, zu bestimmen Wenn wir uns auf das Vergrößern oder Verkleinern vorbereiten müssen, indem Sie die Points-Sammlung in einen anderen Datensatz ändern. Aber es gibt andere UI-Lösungen, die weniger schwer zu programmieren sind. Sehen Sie [hier] (https://www.google.com/search?q=tsla+stock) für ein Beispiel, das Benutzer als akzeptabel empfinden. Die (deutschen) Tabs gehen von 1 Tag zu 5 Jahren und Max. – TaW

Antwort

0

Ich habe vergessen zu sagen, dass seltsamerweise das Problem erschien, wenn ich mehr als einmal gezoomt. Irgendwann startete auch der PC-Lüfter. Ich löste das Deaktivieren der Bibliothekszoom und implementiere selbst eine Art Zoom (ein bisschen einfacher). Die Lösung ist in dieser Methode und die Methode schreibe ich in der Frage:

private void dlChart_SelectionRangeChange(object sender, CursorEventArgs e) 
    { 
     double startSelection = e.NewSelectionStart; 
     double endSelection = e.NewSelectionEnd; 

     // Allow the selection to disappear 
     reset_selection(); 
     try 
     { 
      // before convert point from "showed point" to "real point" I check the limits 
      if (
       (startSelection >= 0) && (startSelection <= decimation_positions.Count()) && 
       (endSelection >= 0) && (endSelection <= decimation_positions.Count()) && 
       (endSelection != startSelection) 
      ) 
      { 
       // convert 
       startSelection = decimation_positions[(int)startSelection]; 
       endSelection = decimation_positions[(int)endSelection]; 
       // check for reverse zoom (from right to left) 
       if (startSelection > endSelection) 
       { 
        double tmp = startSelection; 
        startSelection = endSelection; 
        endSelection = tmp; 
       } 
       // clean the series 
       this.reset_series(); 
       // draw the selected range 
       draw_graph((int)startSelection, (int)endSelection); 
      } 
     }catch(ArgumentOutOfRangeException ex) 
     { 
      // todo 
     } 


     //System.Console.WriteLine("SelSTART = "+e.NewSelectionStart+" SelEND = "+e.NewSelectionEnd); 

    }