TChart Series zur Laufzeit hinzufügen



  • hallo.
    seit einiger zeit beschäftige ich mich mit der tchart-komponente von bcb6 prof.
    ich muss mehrere kurven in einem diagramm darstellen und will erst zur laufzeit angeben, wieviele kurven es sein werden. kann mir jemand sagen, wie man zur laufzeit series zu einem chart hinzufügt, ohne dass man die series vorher deklariert haben muss?
    vielen dank, josocop



  • Deklariere ein (dynamisches) Array von TxyzSeries. Siehe FAQ unter "Komponenten".



  • VIelen Dank! 🙂



  • ich habe das gleiche Problem und habe es grad mal versucht. Der Thread in den FAQ lässt sich leider nicht so für die Chart übernehmen. Hier mal mein Code:

    void __fastcall TfrmMain::lviewDatasetSelectItem(TObject *Sender,
          TListItem *Item, bool Selected)
    {
    
       int index = Item->Selected;
       int count = VDataset[index].GetVFilenames().size(); //hier wird die ANzahl der Series festgelegt
       for (int i=0; i<count; i++) {
          seriesArray[i] = new TChartSeries(this); // der Fehler scheint hier zu liegen. Es wird eine C++ Exception ausgelöst
          seriesArray[i]->ParentChart = Chart1;
       }
    }
    

    Für die in einer Listview ausgewählten Einträge sollen entsprechend viele Series in einer Chart angelegt werden.
    In private der Form habe ich die Deklaration stehen:

    DynamicArray<TChartSeries*> seriesArray;
    


  • Hallo

    Es konkrerer Grund für den Fehler ist in deinem Auszug nicht zu finden. Aber in deinem Auszug ist z.B. nicht zu sehen, ob und wie du überhaupt deinem DynamicArray eine Größe, sprich eine Anzahl von Elementen, zuweist? Ich erinnere dich an deinen Letzten Thread...

    bis bald
    akari



  • Hallo,

    Hier braucht man kein dynamisches Array für die Serien. Das Chart verwaltet diese ja selbst.
    Was für eine Serie willst du überhaupt? TChartSeries ist ja nur eine BasisKlasse für die konkreten Serien.
    Du kannst es so machen (für eine TLineSeries).

    for (int i=0; i<count; i++) {
    	TLineSeries *LSer = new TLineSeries(Chart1);
    	LSer->ParentChart = Chart1;
    }
    

    Hier wird die neue Serie dem Chart auch gleich zugefügt.
    TChart hat eine Eigenschaft Series. Das ist ein Array auf alle Serien, die das Chart verwaltet.



  • Die Achsen werden entsprechend den Werten angepasst und es erscheint auch das Gitter. Nur der Graph ist nicht zu sehen. Muss ich evtl noch irgendwas enableln?



  • Stützpunkte einfügen?



  • Es funktioniert soweit. Nur kann ich das hier so nicht machen, da es sich ja hier um ein SelectItem-Event handelt und bei jedem Auswählen neue Charts angelegt werden. Wenn der gleiche Datensatz erneut ausgewählt wird, sollen nicht wieder neue Charts angelegt werden sondern in die vorhandenen geschrieben werden.

    void __fastcall TfrmMain::gridDatasetSelectCell(TObject *Sender, int ACol,
          int ARow, bool &CanSelect)
    {
       int index = ARow-1; //welcher Datensatz ausgewählt
       int count = frmNewDataset->GetVDataset()[index].GetVFilenames().size();
       gridData->RowCount = count;
    
       for (int i=0; i<count; i++) {
          gridData->Cells[0][i] = frmNewDataset->GetVDataset()[index].GetVFilenames()[i];
    
          TLineSeries* serImportedData = new TLineSeries(Chart1);
          serImportedData->ParentChart = Chart1;
    
          for (unsigned int j=0; j<frmNewDataset->GetVDataset()[index].VData[i].size(); j++)
             serImportedData->AddXY(frmNewDataset->GetVDataset()[index].VData[i][j].timestamp, frmNewDataset->GetVDataset()[index].VData[i][j].value, "", clBlue);
       }
    }
    


  • Wie meinst du das jetzt? In deinem Codebeispiel legst du kein neues Chart an, nur eine neue Serie.
    Willst du vielleicht nur keine neue Serie im Chart anlegen?



  • ja genau das mein ich 🙂
    Die Anzahl der Series wird durch die Variable count festgelegt. Tritt das Ereignis erneut ein sollen die Series nicht erneut angelegt werden.
    Oder man müsste den Speicherbereich wieder freigeben.



  • Du musst dir eben irgendwie merken welche Serie (Index) zu welchem Dataset gehört.
    Dann musst du nur noch nachschauen ob die Serie für den gewählten Datensatz schon existiert. Über Chart::Series[index] kannst du dann auf die entsprechende Serie zugreifen und damit machen was du willst.



  • sowas habe ich mir auch schon gedacht. Leider habe ich keine Idee wie ich das umsetzen könnte. Wähle ich das erste mal einen Datensatz aus werden ja entsprechend der Anzahl der Dateien Series angelegt. Nun müsste es da aeine Prüfung geben ob die Series schon existieren.



  • Du musst doch in SelectCell nur schauen, ob die Anzahl der Serien mit der Anzahl der Datensätze übereinstimmt. Dann bei bei Bedarf neue Serien zufügen oder alte löschen und dann alles neu beschreiben.
    Bei dir wäre es wohl aber einfacher alle vorhandenen Serien zu löschen und dann neue zu erstellen.
    Um mehr zu sagen fehlt mir hier etwas mehr Umfeld (also was dein programm konkret machen soll).



  • Wie kann man die Anzahl der Series bestimmen?



  • rudpower schrieb:

    Wie kann man die Anzahl der Series bestimmen?

    Komm schon, das schaffst du auch alleine. Einfach mal die TeeCharts Hilfe öffnen und ein bisschen suchen.



  • ja habs gefunden:
    Chart1->SeriesList->Count

    Ich denk hiermit bin ich auf den richtigen Weg:

    void __fastcall TfrmMain::gridDatasetSelectCell(TObject *Sender, int ACol,
          int ARow, bool &CanSelect)
    {
       int index = ARow-1; //welcher Datensatz ausgewählt
       int count = frmNewDataset->GetVDataset()[index].GetVFilenames().size(); //Anzahl der Dateien
       gridData->RowCount = count;
    
       for (int i=0; i<count; i++) {
          gridData->Cells[0][i] = ExtractFileName(frmNewDataset->GetVDataset()[index].GetVFilenames()[i]);
    
          if (Chart1->SeriesList->Count < count) {
             serImportedData = new TLineSeries(Chart1);
             serImportedData->ParentChart = Chart1;
          }
    
          unsigned int countData = frmNewDataset->GetVDataset()[index].VData[i].size();
          for (unsigned int j=0; j<countData; j++)
             serImportedData->AddXY(frmNewDataset->GetVDataset()[index].VData[i][j].timestamp, frmNewDataset->GetVDataset()[index].VData[i][j].value, "", clBlue);
       }
    
       Label1->Caption = Chart1->SeriesList->Count;
    }
    

    Nun muss ich noch irgendwie die eventuell zu viel angelegten Series löschen. Das müsste ich doch dann mit delete machen?



  • Du musst die Serie aus dem Chart entfernen (mit Chart1->RemoveSeries()) und dann löschen.


Anmelden zum Antworten