IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C++Builder Discussion :

Problème d'affichage de graphes !


Sujet :

C++Builder

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    508
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Haute Vienne (Limousin)

    Informations forums :
    Inscription : Avril 2008
    Messages : 508
    Points : 100
    Points
    100
    Par défaut Problème d'affichage de graphes !
    Bonjour,

    j'ai une application dans laquelle j'ai des graphes à l'intérieur d'un tabcontrol.
    Des données arrivent sur le port USB et j'affiche celles ci dans mes graphes.
    Les données peuvent venir de source différente (numéro de série différent) donc j'affiche ces données dans un graphe d'un onglet différent dans le tabcontrol.
    Ceci fonctionne bien mais j'aimerai que les onglets ne changent pas automatiquement : c'est à dire que lorsque l'utilisateur visualise les données d'une source dans un onglet, qu'il reste sur le même onglet.
    J'ai plus ou moins réussi à palier ce problème (je reste sur le même onglet) mais les données des graphes se mélangent !!!

    je vous met le bout de code correspondant pour que vous compreniez mieux mon soucis.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
     
    int index = FormClient->JvgTabControlFlotteurs->Tabs->IndexOf( NomSerie );
    	if(index == -1)
    	{
    		Step_x = 1;
    		FormClient->JvgTabControlFlotteurs->Tabs->Add( NomSerie );
    		n = FormClient->JvgTabControlFlotteurs->Tabs->Count-1;
     
     
    		// La série de ChartPH
    		Serie = new TFastLineSeries(FormClient);
    		FormClient->ChartPH->Axes->Left->Automatic = true;
    		FormClient->ChartPH->Axes->Bottom->Automatic = true;
    		FormClient->ChartPH->Legend->Visible = false;
    		Serie->LinePen->Width = 2;
    		Serie->Color = clBlue;
    		FormClient->ChartPH->AddSeries(Serie);
    		Serie->AddXY(Step_x, Y1, "", clBlue);
    		FormClient->EditPH->Text = FormatFloat("0.00", (Serie->YValues->Last()));
    		FormClient->EditMoyPH->Text = FormatFloat("0.00",((Serie->YValues->Total)/(Serie->YValues->Count)));
    		//FormClient->ChartPH->Refresh();
    		//Serie->Active = true;
     
    		// La série de ChartConductivite
    		Serie = new TFastLineSeries(FormClient);
    		FormClient->ChartConductivite->Axes->Left->Automatic = true;
    		FormClient->ChartConductivite->Axes->Bottom->Automatic = true;
    		FormClient->ChartConductivite->Legend->Visible = false;
    		Serie->LinePen->Width = 2;
    		Serie->Color = clGreen;
    		FormClient->ChartConductivite->AddSeries(Serie);
    		Serie->AddXY(Step_x, Y2, "", clGreen);
    		FormClient->EditConductivite->Text = FormatFloat("0.00", (Serie->YValues->Last()));
    		FormClient->EditMoyConductivite->Text = FormatFloat("0.00",((Serie->YValues->Total)/(Serie->YValues->Count)));
    		//FormClient->ChartConductivite->Refresh();
    		//Serie->Active = true;
     
    		// La série de ChartTemperature
    		Serie = new TFastLineSeries(FormClient);
    		FormClient->ChartTemperature->Axes->Left->Automatic = true;
    		FormClient->ChartTemperature->Axes->Bottom->Automatic = true;
    		FormClient->ChartTemperature->Legend->Visible = false;
    		Serie->LinePen->Width = 2;
    		Serie->Color = clRed;
    		FormClient->ChartTemperature->AddSeries(Serie);
    		Serie->AddXY(Step_x, Y3, "", clRed);
    		FormClient->EditTemperature->Text = FormatFloat("0.0", (Serie->YValues->Last()));
    		FormClient->EditMoyTemperature->Text = FormatFloat("0.0",((Serie->YValues->Total)/(Serie->YValues->Count)));
    		//FormClient->ChartTemperature->Refresh();
    		//Serie->Active = true;
     
     
     
    		FormClient->JvgTabControlFlotteurs->TabIndex = n;
     
    		Tableau[n].EditHeure = Heure.sprintf("%02d h %02d min", Time->tm_hour, Time->tm_min);
    		FormClient->EditHeure->Text = Tableau[n].EditHeure;
     
    		Tableau[n].EditDate = laDate.sprintf("%02d.%02d.%02d", Time->tm_mday, (Time->tm_mon+1) ,(Time->tm_year+1900));
    		FormClient->EditDate->Text = Tableau[n].EditDate;
     
    		FormClient->EditNom->Text = Tableau[n].EditNom;
     
     
     
    	}
    	else
    	{
    		Tableau[n].Tab = FormClient->JvgTabControlFlotteurs->TabIndex;
     
     
    		FormClient->JvgTabControlFlotteurs->TabIndex = index;
     
     
    		Step_x++;
    		// La série de ChartPH
    		Serie = (TFastLineSeries *)FormClient->ChartPH->Series[ index ];
    		Tableau[index].Serie = Serie;
    		Serie->AddXY(Step_x, Y1, "", clBlue);
    		FormClient->EditPH->Text = FormatFloat("0.00", (Serie->YValues->Last()));
    		FormClient->EditMoyPH->Text = FormatFloat("0.00",((Serie->YValues->Total)/(Serie->YValues->Count)));
    		//FormClient->ChartPH->Refresh();
    		Serie->Active = true;
     
     
    		// La série de ChartConductivite
    		Serie = (TFastLineSeries *)FormClient->ChartConductivite->Series[ index ];
    		Serie->AddXY(Step_x, Y2, "", clGreen);
    		FormClient->EditConductivite->Text = FormatFloat("0.00", (Serie->YValues->Last()));
    		FormClient->EditMoyConductivite->Text = FormatFloat("0.00",((Serie->YValues->Total)/(Serie->YValues->Count)));
    		//FormClient->ChartConductivite->Refresh();
    		Serie->Active = true;
     
    		// La série de ChartTemperature
    		Serie = (TFastLineSeries *)FormClient->ChartTemperature->Series[ index ];
    		Serie->AddXY(Step_x, Y3, "", clRed);
    		FormClient->EditTemperature->Text = FormatFloat("0.0", (Serie->YValues->Last()));
    		FormClient->EditMoyTemperature->Text = FormatFloat("0.0",((Serie->YValues->Total)/(Serie->YValues->Count)));
    		//FormClient->ChartTemperature->Refresh();
    		Serie->Active = true;
     
    		Tableau[n].EditHeure = Heure.sprintf("%02d h %02d min", Time->tm_hour, Time->tm_min);
    		FormClient->EditHeure->Text = Tableau[index].EditHeure;
     
    		Tableau[n].EditDate = laDate.sprintf("%02d.%02d.%02d", Time->tm_mday, (Time->tm_mon+1) ,(Time->tm_year+1900));
    		FormClient->EditDate->Text = Tableau[n].EditDate;
     
    		FormClient->EditNom->Text = Tableau[n].EditNom;
     
    		FormClient->JvgTabControlFlotteurs->TabIndex = Tableau[n].Tab;
     
    		//Serie->Active = true;
    		//Serie->RefreshSeries();
     
    	}
    Merci d'avance pour votre aide !

  2. #2
    Membre régulier
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    508
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Haute Vienne (Limousin)

    Informations forums :
    Inscription : Avril 2008
    Messages : 508
    Points : 100
    Points
    100
    Par défaut
    Bonjour,

    personne n'a l'air intéressé par mon problème !

    Please help me !


  3. #3
    Membre chevronné

    Profil pro
    Inscrit en
    Juin 2002
    Messages
    1 390
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 1 390
    Points : 1 777
    Points
    1 777
    Par défaut
    Salut !

    Une simple question : les trois courbes (PH, C et T°) sont-elles étroitement dépendantes (au niveau du phénomène mesuré) ?
    Si c'est le cas on a intérêt à objétiser pour retrouver facilement les trois courbes (pour un phénomène donné) !

    A plus !

  4. #4
    Membre régulier
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    508
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Haute Vienne (Limousin)

    Informations forums :
    Inscription : Avril 2008
    Messages : 508
    Points : 100
    Points
    100
    Par défaut
    Bonjour,

    ces 3 courbes (3 charts, 1 série par chart) sont liées dans le fait que lorsque les informations d'un matériel arrivent sur le port USB : une trame comprenant les infos de PH, température, ...
    Puis, une deuxième trame arrivent sur le port USB mais avec un numéro de série différent donc nouvel onglet dans le tabcontrol avec infos de PH,température, ...
    Nouvelle trame du premier matériel (numéro de série déjà connu : onglet 1), ca bascule sur le premier onglet et ainsi de suite.

    Ce que je voudrais, c'est que ca évite de basculer les onglets : quand je visualise les données dans un des onglets (donc d'un numéro de série), je voudrai rester sur celui ci et cela sans que les données des autres numéro de série se mélangent dans mes graphes (mélange dans le même graphe des infos de température de 2 numéros de série différent : ce que je ne souhaite pas).

  5. #5
    Membre chevronné

    Profil pro
    Inscrit en
    Juin 2002
    Messages
    1 390
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 1 390
    Points : 1 777
    Points
    1 777
    Par défaut
    Salut !

    Il y a quelques mois j'ai participé à une discussion sur ce forum, au sujet d'un problème similaire (Tabs + TChart + séries).

    Tu dois avoir un problème d'indexation : deux niveaux d'indexation qui ne doivent jamais interférer et qui dans ton cas ...

    Sinon ... voici comment je ferais (plus exactement, comment je viens de tester) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
     
    class jMesures : public TComponent
    {
    protected :
        void __fastcall SetActive(bool Value);
    public :
    int x;
    TLineSeries *Capteurs[3];
        __fastcall jMesures(TComponent *AOwner,int Ph, int C, int T);
        __fastcall ~jMesures();
     
        void __fastcall AddValue(int Capteur, int Value);
        void __fastcall AddValues(int Ph, int C, int T);
     
    __property bool Active={write=SetActive};
     
    };

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
     
    TColor Colors[] = {clBlue, clRed, clYellow, clGreen};
     
    __fastcall jMesures::jMesures(TComponent *AOwner, int Ph, int C, int T)
        : TComponent(AOwner)
    {
    Capteurs[0] = new TLineSeries(this);
    Capteurs[0]->Stairs = true;
    Form1->ChartPh->AddSeries(Capteurs[0]);
    Capteurs[0]->AddXY(x, Ph, "", Colors[ 0 ]);
     
    Capteurs[1] = new TLineSeries(this);
    Capteurs[1]->Stairs = true;
    Form1->ChartC->AddSeries(Capteurs[1]);
    Capteurs[1]->AddXY(x, Ph, "", Colors[ 1 ]);
     
    Capteurs[2] = new TLineSeries(this);
    Capteurs[2]->Stairs = true;
    Form1->ChartT->AddSeries(Capteurs[2]);
    Capteurs[2]->AddXY(x, Ph, "", Colors[ 2 ]);
     
    Active = false; // << voir le setter de la propriété Active
    }
    //--
    __fastcall jMesures::~jMesures()
    {
    }
    //-- le setter de la propriété Active
    void __fastcall jMesures::SetActive(bool Value)
    {
    for(int j = 0; j < 3; j++) Capteurs[j]->Active = Value;
    }
    //-- A ce stade je n'ai pas testé...
    void __fastcall jMesures::AddValue(int Capteur, int Value)
    {
    Capteurs[Capteur]->AddXY(x, Value, "", Colors[ Capteur ]);
    }
    //-- Ce qui a été testé
    void __fastcall jMesures::AddValues(int Ph, int C, int T)
    {
    Capteurs[0]->AddXY(x, Ph, "", Colors[0]);
    Capteurs[1]->AddXY(x, C, "",  Colors[1]);
    Capteurs[2]->AddXY(x, T, "",  Colors[2]);
    x++;
    }

    Voici comment j'ai exploité :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
     
    class TForm1 : public TForm
    {
    __published:	// Composants gérés par l'EDI
        // mon tabcontrol
        TTabControl *TabControl1;
     
        // mes charts
        TChart *ChartPh;
        TChart *ChartC;
        TChart *ChartT;
     
        // 4 boutons pour donner vie
        TSpeedButton *Cap1;
        TSpeedButton *Cap2;
        TSpeedButton *Cap3;
        TSpeedButton *Cap4;
     
        // pour sélectionner un tab et les séries, il faut gérer avant et après
        void __fastcall TabControl1Changing(TObject *Sender, bool &AllowChange);
        void __fastcall TabControl1Change(TObject *Sender);
     
        // va donner vie pour le test
        void __fastcall Cap1Click(TObject *Sender);
     
    private:	// Déclarations de l'utilisateur
    public:		// Déclarations de l'utilisateur
        __fastcall TForm1(TComponent* Owner);
     
        // une méthode pour donner vie
        void __fastcall ToTabControl(AnsiString NomSerie, int Ph, int C, int T);

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
     
    __fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
    {
    }
    //---- partagée par les 4 Speedbuttons 
    void __fastcall TForm1::Cap1Click(TObject *Sender)
    {
    // Un nom de série + 3 valeurs aléatoires (Ph, C et T)
    ToTabControl(((TSpeedButton*)Sender)->Caption,
                     random(100), // REM : #include <stdlib.h> // pour random
                     random(100),
                     random(100));
    }
    //----
    void __fastcall TForm1::ToTabControl(AnsiString NomSerie, int Ph, int C, int T)
    {
    int index = TabControl1->Tabs->IndexOf(NomSerie);
    if(index == -1)
        {
        // La série n'existe pas donc on la crée
        TabControl1->Tabs->AddObject(NomSerie, new jMesures(this, Ph, C, T));
        // si c'est la première, on active
        if(TabControl1->Tabs->Count == 1)
            {
            ((jMesures*)TabControl1->Tabs->Objects[0])->Active = true;
            }
        }
    else
        {
        // donc ici on passe les trois mesures à la série cible
        ((jMesures*)TabControl1->Tabs->Objects[index])->AddValues(Ph, C, T);
        }
    }
    //----
    void __fastcall TForm1::TabControl1Changing(TObject *Sender,
          bool &AllowChange)
    {
    // on gère avant le changement de tab
    int n = TabControl1->TabIndex;
    if(n != -1) ((jMesures*)TabControl1->Tabs->Objects[n])->Active = false;
    }
    //----
    void __fastcall TForm1::TabControl1Change(TObject *Sender)
    {
    // on gère après le changement de tab
    int n = TabControl1->TabIndex;
    if(n != -1) ((jMesures*)TabControl1->Tabs->Objects[n])->Active = true;
    }
    //----
    Sans doute qu'il y a deux ou trois petites choses à régler ...
    TChart n'est pas un composant que j'utilise tous les jours ... donc ... !
    Mais à ce stade, ça fonctionne bien !

    A plus !

  6. #6
    Membre régulier
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    508
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Haute Vienne (Limousin)

    Informations forums :
    Inscription : Avril 2008
    Messages : 508
    Points : 100
    Points
    100
    Par défaut
    ok, merci henderson !

    Je ne comprend pas d'où viennent tes fichiers (ton code), comment les as tu créés ?

    Tu as créé un composant ?
    Peux tu m'expliquer ta démarche plus en détails s'il te plait ?

    Merci d'avance !

  7. #7
    Membre chevronné

    Profil pro
    Inscrit en
    Juin 2002
    Messages
    1 390
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 1 390
    Points : 1 777
    Points
    1 777
    Par défaut
    Salut !

    En fait je suis parti d'un nouveau projet ... juste pour tester (en pensant que tu ferais le même test ) !

    Ce qui est important pour toi, c'est de copier/coller tout ce qui concerne la classe jMesures :
    - la déclaration de classe dans le .h de ta form (celle qui détient les trois TChart)
    - la déclaration des méthodes dans le .cpp (idem pour la form)
    Cette classe crée 3 séries qu'elle mémorise et qui sont ajoutées au Chart qui leur est dédié.
    Elle sait aussi ajouter 1 valeur à ses trois séries.
    Note que sa propriété Active est en "écriture seule" et qu'elle fonctionne à l'aide d'un setter (une méthode) qui vient fixer la propriété Active des trois séries.

    Pour le tabcontrol, j'exploite deux événementielles qui surviennent l'une après l'autre, au moment d'un changement de tab :
    - OnChanging << pour désactiver les séries en cours d'affichage (ancien tab)
    - OnChange << pour activer les séries à afficher (nouveau tab)
    C'est à ce niveau là qu'il y a sans doute un problème chez toi !

    La méthode ToTabControl doit être déclarée dans la partie public de ta form (tel que je l'ai fait).
    Elle est donc développée (à copier/coller comme telle dans l'unité (.cpp) de cette form (attention à "TForm1::")
    Cette méthode sert à gérer les mesures.
    - si la référence n'existe pas alors on crée un objet qui sera associé à la chaîne (ce à quoi sert Tabs->AddObject).
    - si la référence existe alors on se contente d'ajouter les valeurs aux séries via l'objet associé à la chaîne.

    La classe jMesures représente du développement supplémentaire mais qui, de mon point de vue, simplifie le code en aval !

    A plus !

  8. #8
    Membre régulier
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    508
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Haute Vienne (Limousin)

    Informations forums :
    Inscription : Avril 2008
    Messages : 508
    Points : 100
    Points
    100
    Par défaut
    ok, merci henderson, c'est un peu plus clair pour moi !

    Par contre le bout de code que j'ai posté est contenu dans un thread donc je dois mettre ce qui concerne la classe jMesures dans le .h de mon thread ? et les méthodes dans le .cpp de mon thread ?


    A bientôt !

  9. #9
    Membre chevronné

    Profil pro
    Inscrit en
    Juin 2002
    Messages
    1 390
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 1 390
    Points : 1 777
    Points
    1 777
    Par défaut
    Salut !

    A première vue dans FormClient (qui détient le tabcontrol et les 3 charts) !

    A plus !

  10. #10
    Membre régulier
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    508
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Haute Vienne (Limousin)

    Informations forums :
    Inscription : Avril 2008
    Messages : 508
    Points : 100
    Points
    100
    Par défaut
    Bonjour,

    tout d'abord merci henderson pour ton aide.
    pour les graphes ça roule, j'ai fait quelques modifs pour que ça fonctionne comme je le souhaitais.
    Par contre, j'ai des labels sur ma form qui, comme les series, changent de contenu par rapport à l'onglet du tabcontrol que l'on choisi.
    Je pense que je dois faire un truc similaire que pour les series mais sans succès.

    Comment faire pour que le contenu d'un label change en fonction de l'onglet choisi ?

    A bientôt !

  11. #11
    Membre chevronné

    Profil pro
    Inscrit en
    Juin 2002
    Messages
    1 390
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 1 390
    Points : 1 777
    Points
    1 777
    Par défaut
    Salut !

    Dans tous les cas on peut rajouter des propriétés dans la classe jMesures, en les déclarant au plus simple !
    Par contre tout dépend si on développe une classe jMesure excessivement réactive (sachant par elle-même faire tout ce qu'il y a à faire).
    Par rapport à ce que j'ai donné, on peut modifier ainsi, en considérant qu'ici, je ne rajoute qu'une propriété du type AnsiString (Text) qui va servir à stocker et rafraîchir le texte dans un TLabel (Label1) placé sur la form.

    Coté .h :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
     
    class jMesures : public TComponent
    {
    protected :
        void __fastcall SetActive(bool Value);
    public :
    AnsiString Text; // << une propriété toute simple
    int x;
    TLineSeries *Capteurs[3];
        __fastcall jMesures(TComponent *AOwner,int Ph, int C, int T, AnsiString AText);
        __fastcall ~jMesures();
     
        void __fastcall AddValues(int Ph, int C, int T, AnsiString AText);
     
    __property bool Active={write=SetActive};
     
    };
    Coté .cpp :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
     
    TColor Colors[] = {clBlue, clRed, clYellow, clGreen};
     
    __fastcall jMesures::jMesures(TComponent *AOwner, int Ph, int C, int T, AnsiString AText)
        : TComponent(AOwner)
    {
    Capteurs[0] = new TLineSeries(this);
    Capteurs[0]->Stairs = true;
    Form1->ChartPh->AddSeries(Capteurs[0]);
    Capteurs[0]->AddXY(x, Ph, "", Colors[ 0 ]);
     
    Capteurs[1] = new TLineSeries(this);
    Capteurs[1]->Stairs = true;
    Form1->ChartC->AddSeries(Capteurs[1]);
    Capteurs[1]->AddXY(x, Ph, "", Colors[ 1 ]);
     
    Capteurs[2] = new TLineSeries(this);
    Capteurs[2]->Stairs = true;
    Form1->ChartT->AddSeries(Capteurs[2]);
    Capteurs[2]->AddXY(x, Ph, "", Colors[ 2 ]);
     
    // << on mémorise >>
    Text = AText; 
     
    Active = false;
    }
    //--
    __fastcall jMesures::~jMesures()
    {
    }
    //--
    void __fastcall jMesures::SetActive(bool Value)
    {
    for(int j = 0; j < 3; j++)
        {
        Capteurs[j]->Active = Value;
        }
    // << on rafraîchit s'il y a lieu >>
    if(Value == true) ((TForm1*)Owner)->Label1->Caption = Text;
    }
    //--
    void __fastcall jMesures::AddValues(int Ph, int C, int T, AnsiString AText)
    {
    Text = AText;
    Capteurs[0]->AddXY(x, Ph, "", Colors[ 0 ]);
    Capteurs[1]->AddXY(x, C, "", Colors[ 1 ]);
    Capteurs[2]->AddXY(x, T, "", Colors[ 2 ]);
    x++;
    // << on rafraîchit s'il y a lieu >>
    if(Capteurs[0]->Active == true) ((TForm1*)Owner)->Label1->Caption = AText;
    }
    //--
    Voici ce qui se passe dans la méthode ToTabControl de la form :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
     
    void __fastcall TForm1::ToTabControl(AnsiString NomSerie, int Ph, int C, int T)
    {
    int index = TabControl1->Tabs->IndexOf(NomSerie);
    if(index == -1)
        {
        // La série n'existe pas donc on la crée
        TabControl1->Tabs->AddObject(NomSerie, new jMesures(this, Ph, C, T, 
                                     IntToStr(GetTickCount()))); // << mon texte
        // et si c'est la première, on active
        if(TabControl1->Tabs->Count == 1)
            {
            ((jMesures*)TabControl1->Tabs->Objects[0])->Active = true;
            }
        }
    else
        {
        // donc ici on passe les trois mesures à la série cible
        ((jMesures*)TabControl1->Tabs->Objects[index])->AddValues(Ph, C, T, 
                                     IntToStr(GetTickCount())); // << mon texte
        }
    }
    J'espère quand avoir bien compris le truc !
    Il faudrait juste savoir si on traite effectivement du texte ou un autre type de contenu (a toi de voir).

    Par ailleurs, s'il s'agit d'afficher des signaux sans tenir d'une historique, il est possible également de développer une classe dédiée, en dérivant de TCustomForm (ou ... TForm), sans aucun TChart et avec une simple TListBox à la place du TabControl !!!
    On pourrait même obtenir quelque chose de plus lisible pour l'utilisateur, compte tenu que les courbes semblent concerner un même objet (une même soupe ...) en les alignant verticalement dans un même référentiel en x !
    En matière de graphisme, ça ne demanderait que très peu de choses : un simple Bitmap et son Canvas, le bitmap étant dessiné directement sur la form !
    Grosso modo, ça simplifierait certains mécanismes !
    Mais bon ... chacun fait comme il veut (ou comme il doit, par exemple, dans un contexte imposé) donc ... je n'insisterai pas sur cette façon de faire !

    A plus !

  12. #12
    Membre régulier
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    508
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Haute Vienne (Limousin)

    Informations forums :
    Inscription : Avril 2008
    Messages : 508
    Points : 100
    Points
    100
    Par défaut
    Bonjour,

    ok merci henderson !

    En fait, les Labels et Edits que j'ai sur ma Form me servaient entre autre à afficher la dernière valeur mesurée du graphe avec l'un et afficher la moyenne des valeurs avec un autre.

    Je faisais comme ceci avant (exemple avec ph):

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    FormClient->EditPH->Text = FormatFloat("0.00", (Serie->YValues->Last())); // Affichage de la dernière mesurée
    FormClient->EditMoyPH->Text = FormatFloat("0.00",((Serie->YValues->Total)/(Serie->YValues->Count))); // Affichage de la Moyenne
    Mais cette méthode fonctionne pas !!!


    A bientôt !

  13. #13
    Membre chevronné

    Profil pro
    Inscrit en
    Juin 2002
    Messages
    1 390
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 1 390
    Points : 1 777
    Points
    1 777
    Par défaut
    Salut !

    Dans ce qui suit, on part du principe qu'un seul TLabel est suffisant pour afficher l'ensemble :
    - les intitulés des captures
    - les dernières valeurs entrées
    - les moyennes

    Il aura suffit pour cela, de rajouter quelques tableaux dans la classe jMesure ainsi que quelques méthodes.
    On calcule donc discrètement à chaque capture et on affiche ... au bon moment.
    J'ai tenté de simplifier le code ... mais comme TChart (et tout ce qui va avec) n'est pas l'une de mes classes préférées ... j'ose espérer que les experts en la matière trouveront certainement mieux !

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
     
    class jMesures : public TComponent
    {
    private :
    int x;
    TLineSeries *Capteurs[3];
    int Count;
    int Total[3];
    int Last[3];
    double Moy[3];
     
    protected :
     
        TLineSeries*  __fastcall NewSerie(int N);
        void __fastcall SetActive(bool Value);
        void __fastcall ToStats(int N, int Y);
        void __fastcall ShowStats();
     
    public :
     
        __fastcall jMesures(TComponent *AOwner,int Ph, int C, int T);
        __fastcall ~jMesures();
     
        void __fastcall AddValues(int Ph, int C, int T);
     
    __property bool Active={write=SetActive};
     
    };

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
     
    TColor Colors[] = {clBlue, clRed, clYellow, clGreen};
     
    __fastcall jMesures::jMesures(TComponent *AOwner, int Ph, int C, int T)
        : TComponent(AOwner)
    {
    Form1->ChartPh->AddSeries(NewSerie(0));
    Form1->ChartC->AddSeries(NewSerie(1));
    Form1->ChartT->AddSeries(NewSerie(2));
    x=0;
    Count=1;
     
    ToStats(0, Ph);
    ToStats(1, C);
    ToStats(2, T);
     
    x++;
    Active = false;
    }
    //--
    __fastcall jMesures::~jMesures()
    {
    }
    //--
    TLineSeries* __fastcall jMesures::NewSerie(int N)
    {
    Capteurs[N] = new TLineSeries(this);
    Capteurs[N]->Stairs = false;
    return Capteurs[N];
    }
    void __fastcall jMesures::SetActive(bool Value)
    {
    for(int j = 0; j < 3; j++)
        {
        Capteurs[j]->Active = Value;
        }
    if(Value) ShowStats();
    }
    //--
    void __fastcall jMesures::AddValues(int Ph, int C, int T)
    {
    Count++;
     
    ToStats(0, Ph);
    ToStats(1, C);
    ToStats(2, T);
     
    x++;
     
    if(Capteurs[0]->Active) ShowStats();
    }
    //--
    void __fastcall jMesures::ToStats(int N, int Y)
    {
    Capteurs[N]->AddXY(x, Y, "", Colors[ N ]);
    Last[N] = Y;
    Total[N] = Total[N] + Y;
    double c = Count;
    double d = Total[N];
    Moy[N] = d / c;
    }
    //-- REM : Label1->Font->Name = "Courrier New"
    void __fastcall jMesures::ShowStats()
    {
    TLabel *Label = ((TForm1*)Owner)->Label1;
    Label->Caption = "Ph : " + IntToStr(Last[0]) + " / " + FormatFloat("0.00", Moy[0]) +
                     "\nC  : " + IntToStr(Last[1]) + " / " + FormatFloat("0.00", Moy[1]) +
                     "\nT° : " + IntToStr(Last[2]) + " / " + FormatFloat("0.00", Moy[2]);
    }

    Les méthodes de la form restent inchangées :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
     
    void __fastcall TForm1::ToTabControl(AnsiString NomSerie, int Ph, int C, int T)
    {
    int index = TabControl1->Tabs->IndexOf(NomSerie);
    if(index == -1)
        {
        TabControl1->Tabs->AddObject(NomSerie, new jMesures(this, Ph, C, T));
        if(TabControl1->Tabs->Count == 1) ((jMesures*)TabControl1->Tabs->Objects[0])->Active = true;
        }
    else
        {
        ((jMesures*)TabControl1->Tabs->Objects[index])->AddValues(Ph, C, T);
        }
    }
    //--
    void __fastcall TForm1::TabControl1Changing(TObject *Sender,
          bool &AllowChange)
    {
    int n = TabControl1->TabIndex;
    if(n != -1) ((jMesures*)TabControl1->Tabs->Objects[n])->Active = false;
    }
    //--
     
    void __fastcall TForm1::TabControl1Change(TObject *Sender)
    {
    int n = TabControl1->TabIndex;
    if(n != -1) ((jMesures*)TabControl1->Tabs->Objects[n])->Active = true;
    }
    //--
    A plus !

  14. #14
    Membre régulier
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    508
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Haute Vienne (Limousin)

    Informations forums :
    Inscription : Avril 2008
    Messages : 508
    Points : 100
    Points
    100
    Par défaut
    Bonjour et encore merci henderson !

    J'ai un autre soucis avec 2 edits : un Edit qui affiche la date de la dernière prise de mesure (JJ.MM.AA) et un autre Edit qui affiche l'heure de la dernière prise de mesure (HH h MM min).

    Encore une fois ces Edits doivent être liés par rapport à un onglet (un matériel).

    J'ai fais comme ceci mais sans succès :

    - dans le SetActive :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    ((TFormClient*)Owner)->EditDate->Text = TextDate.sprintf("%02d.%02d.%02d", Time->tm_mday, (Time->tm_mon+1) ,(Time->tm_year+1900));
    ((TFormClient*)Owner)->EditHeure->Text = TextHeure.sprintf("%02d h %02d min", Time->tm_hour, Time->tm_min);
    - dans le AddValues (la même chose) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    ((TFormClient*)Owner)->EditDate->Text = TextDate.sprintf("%02d.%02d.%02d", Time->tm_mday, (Time->tm_mon+1) ,(Time->tm_year+1900));
    ((TFormClient*)Owner)->EditHeure->Text = TextHeure.sprintf("%02d h %02d min", Time->tm_hour, Time->tm_min);
    Je n'arrive pas à faire assigner ces infos à un onglet.

    Merci d'avance et à bientôt !

  15. #15
    Membre chevronné

    Profil pro
    Inscrit en
    Juin 2002
    Messages
    1 390
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 1 390
    Points : 1 777
    Points
    1 777
    Par défaut
    Salut !

    Dans ce cas tu rajoutes une nouvelle propriété, dans la classe jMesures :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    TDateTime DateTime;
    Dans le méthode ToStats de jMesure :

    Dans la méthode ShowStats de jMesure (selon ta façon de faire):

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    ((...*)Owner)->DateLabel->Caption = DateTime.DateString();
    ((...*)Owner)->TimeLabel->Caption = DateTime.TimeString();
    Par contre, de mon coté je fais :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    TLabel *Label = ((TForm1*)Owner)->Label1;
    Label->Caption = DateTime.DateString() +
                     "\n" + DateTime.TimeString() +
                     "\nPh : " + IntToStr(Last[0]) + " / " + FormatFloat("0.00", Moy[0]) +
                     "\nC  : " + IntToStr(Last[1]) + " / " + FormatFloat("0.00", Moy[1]) +
                     "\nT° : " + IntToStr(Last[2]) + " / " + FormatFloat("0.00", Moy[2]);
    Si le timing devait être le plus précis possible, dans ce cas il serait plus logique de faire un Now() au moment de la réception des mesures.
    Mais peut-être qu'ici, ça n'a pas d'importance ... (???)

    A plus !

  16. #16
    Membre régulier
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    508
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Haute Vienne (Limousin)

    Informations forums :
    Inscription : Avril 2008
    Messages : 508
    Points : 100
    Points
    100
    Par défaut
    OK, ca fonctionne, merci henderson !

    J'utilisais struct tm *Time; ... .
    Je ne connaissais pas TDateTime et maintenant la date s'affiche au format YYYY.MM.DD et l'heure 130045.

    Comment mettre la date au format DD.MM.YYYY et l'heure au format 13 h 00 min ?
    J'ai cherché dans la FAQ mais je n'est pas trouvé comment faire.

    A bientôt !

  17. #17
    Membre expérimenté
    Avatar de sat83
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2004
    Messages
    1 040
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mars 2004
    Messages : 1 040
    Points : 1 307
    Points
    1 307
    Par défaut
    La fonction FormatDateTime?

    Pour un format date:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    TDateTime datetime ;
    AnsiString dateStr = FormatDateTime("DD/MM/YYYY", datetime) ;
    Pour un format time:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    TDateTime datetime ;
    AnsiString dateStr = FormatDateTime("HH:NN", datetime) ;

Discussions similaires

  1. [JpGraph] Problème d'affichage des graph
    Par D1@blo dans le forum Bibliothèques et frameworks
    Réponses: 1
    Dernier message: 15/03/2013, 16h31
  2. [JpGraph] probléme d'affichage des graphes
    Par farhaenis dans le forum Bibliothèques et frameworks
    Réponses: 0
    Dernier message: 06/07/2011, 12h30
  3. [JpGraph] JPGraphe:Probléme d'affichage de graphe et export pdf
    Par farhaenis dans le forum Bibliothèques et frameworks
    Réponses: 0
    Dernier message: 06/07/2011, 10h44
  4. [1.x] Probléme d'affichage de graphe et export pdf
    Par farhaenis dans le forum Symfony
    Réponses: 0
    Dernier message: 05/07/2011, 11h58
  5. Problème d'affichage des graphes avec Tomcat
    Par _Janu_ dans le forum BIRT
    Réponses: 11
    Dernier message: 20/09/2006, 15h30

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo