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

Composants VCL Delphi Discussion :

[TChart] Scrolling horizontal des séries


Sujet :

Composants VCL Delphi

  1. #1
    Membre éclairé
    Inscrit en
    Juin 2005
    Messages
    644
    Détails du profil
    Informations professionnelles :
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2005
    Messages : 644
    Points : 754
    Points
    754
    Par défaut [TChart] Scrolling horizontal des séries
    j'ai un ( ou plusieurs ) composant(s) TChart avec un nombre relativement importants de series ( typiquement 20 )
    chaque serie contient le même nombre de points qui est compris entre 1000 et 10'000.
    en x : le temps, en Y les valeurs d'aquisitions, etat de relais, ...
    à une fréquence f comprise entre 20 et 100 Hz, on aquière un nouveau point pour chaque canal et on 'laisse tomber' le point le plus ancien : scrolling horizontal.
    Toutefois cela implique des ressources matérielle tres importantes. ( je ne sais pas comment une series S d'un Tchart T demande un repaint si on la change mais si elle le fait dans la boucle qui fait de scrolling cela devient épouventable!)

    Quelqu'un aurait-il un code optimisé pour réaliser un code équivalent à mais
    moins gourment en ressources!
    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
     
     
    procedure TForm1.Timer1Timer(Sender: TObject);  // 1kHz
       begin
    inc(n);
    if n mod X =0 then  // disiseur pour 20 a 100 Hz
       begin
        m:=0;
       for serie:=Serie_first to serie_last // ( # 20 series )
          begin
          for i:=0 to serie.count-2 do
             begin
             serie.xvalue[i]:=serie.xvalue[i+1];
             serie.yvalue[i]:=serie.yvalue[i+1];
             end;
          serie.xvalue[serie.count-1].xvalue:=serie.xvalue[serie.count-2].xvalue  + deltat;
          serie.Yvalue[serie.count-1].yvalue:= read_port(m);
          inc(m);
          end;
       end;
       end;
    Note : Peut-être le composant TChart n'est pas adapté et qu'un autre moyen est mieux ciblé.

  2. #2
    Expert éminent sénior
    Avatar de Cl@udius
    Homme Profil pro
    Développeur Web
    Inscrit en
    Février 2006
    Messages
    4 878
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Février 2006
    Messages : 4 878
    Points : 10 008
    Points
    10 008
    Par défaut
    Salut

    Visiblement tu dois avoir des appels répétés au repaint, notamment lorsque que tu décales tes valeurs (XValues[I] := XValues[I + 1]).

    Je me limiterais simplement à ajouter la nouvelle acquisition.
    Regarde cet exemple de scrolling avec un simple ajout de valeur. Il suffira d'adapter à tes besoins.

    Une LineSeries, X en TDateTime, Y en Integer, un Timer qui envoie une valeur aléatoire toutes les secondes:
    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
     
    procedure TForm1.Timer1Timer(Sender: TObject);
    begin
      // Ajout d'une valeur aléatoire pour l'exemple
      AddPoint(LineSeries1, Now, Random(100), clRed);
    end;
     
    procedure TForm1.AddPoint(ASeries: TLineSeries; const X, Y: Double;
      AColor: TColor);
    begin
      // Ajout du point à la série
      ASeries.AddXY(X, Y, '', AColor);
    end;
     
    procedure TForm1.LineSeriesAfterAdd(Sender: TChartSeries;
      ValueIndex: Integer);
    begin
      // Recalage de la plage des abscisses affichées
      with Sender.GetHorizAxis do
      begin
        Automatic := False;
        Minimum := 0;
        Maximum := Sender.XValues.MaxValue + DateTimeStep[dtOneSecond];
        Minimum := Maximum - DateTimeStep[dtOneMinute];
      end;
    end;
    @+ Claudius

  3. #3
    Membre averti
    Inscrit en
    Octobre 2005
    Messages
    338
    Détails du profil
    Informations forums :
    Inscription : Octobre 2005
    Messages : 338
    Points : 383
    Points
    383
    Par défaut
    bonjour

    à mon avis TChart est pas mal!

    Dans le principe il ne faut pas "déplacer" tous les points de chaque série à chaque acquisition, mais simplement comme le préconise Cl@udius ajouter une valeur XY pour chaque nouvelle acquisition, et lorsqu'un certain nombre de points est atteind supprimer le premier,
    code du genre (issu du tien) suivant non testé:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    procedure TForm1.Timer1Timer(Sender: TObject);  // 1kHz
    begin
      inc(n);
      if n mod X = 0 then begin  // disiseur pour 20 a 100 Hz  
        for serie := Serie_first to serie_last do begin  // ( # 20 series )
          serie.addXY( ValeurXàCalculer, read_port(m), LabelEnOption, CouleurEnOption);
          if serie.count >= NbMaxValeursàAfficher then serie.delete[0];
        end;  // for serie
      end;  // if n
    end;
    ne pas oublier de mettre les axes en automatic := true

    à plus

  4. #4
    Membre éclairé
    Inscrit en
    Juin 2005
    Messages
    644
    Détails du profil
    Informations professionnelles :
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2005
    Messages : 644
    Points : 754
    Points
    754
    Par défaut
    J'étais aussi arrivé à ce compromis mais il faut de plus pour chaque série ajouter seriexx.Delete(0) après seriexx.addxy(,) si non on arrive a saturer la liste et on tombe sur un erreur au bout d'un moment!
    Je me demandais tout de même si TChart est l'outil vraimant adapté pour ce type de présentation. Il est tout de même lourd avec émorméments de possibilités non utilisées ici ( zoom, 3d, print, ...)

  5. #5
    Expert éminent sénior
    Avatar de Cl@udius
    Homme Profil pro
    Développeur Web
    Inscrit en
    Février 2006
    Messages
    4 878
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Février 2006
    Messages : 4 878
    Points : 10 008
    Points
    10 008
    Par défaut
    Re,
    Citation Envoyé par j.p.mignot Voir le message
    ... si non on arrive a saturer la liste et on tombe sur un erreur au bout d'un moment!
    Certes, mais est-il vraiment nécessaire d'afficher 20 séries possédant chacune jusqu'à 10.000 valeurs.
    J'imagine difficilement que ceci soit très lisible donc interprétable à l'écran.

    @+

  6. #6
    Membre éclairé
    Inscrit en
    Juin 2005
    Messages
    644
    Détails du profil
    Informations professionnelles :
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2005
    Messages : 644
    Points : 754
    Points
    754
    Par défaut
    Il est question d'avoir un suivit visuel sur une machine de producion et de pouvoir analyser, en cas de rejet de pièces, les signaux.
    le nombre de points se justifie en 1er lieu pour pouvoir garentir que les traces respectent le timing et la chronologie: si non sur le même point de digit on voit 2 signaux changer d'état sans savoir lequel et postérieur.
    Bien sur on pourrait stocker 'haute résolution et présenter 'low résolution'.
    Cela complique aussi le traitement si, en cas de rejet, on souhaite zoomer pour détails locaux.
    En conséquence, si les outils le permettent sans side effect sur l'acquisition RT, il est plus simple de garder directement les data dans les series elles-mêmes.
    De toutes façons, même sans cette résolution 'élevée', il faut supprimer des points car les machines sont sensées tourner des semaines non-stop 24h/24 si le process n'a pas de défaillance.

  7. #7
    Membre averti
    Inscrit en
    Octobre 2005
    Messages
    338
    Détails du profil
    Informations forums :
    Inscription : Octobre 2005
    Messages : 338
    Points : 383
    Points
    383
    Par défaut
    Citation Envoyé par banban54 Voir le message
    et lorsqu'un certain nombre de points est atteind supprimer le premier,
    Citation Envoyé par banban54 Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
          if serie.count >= NbMaxValeursàAfficher then serie.delete[0];
    à mon avis Tchart est un moyen de visualisation, mais pas un moyen de stockage des données.

    à plus

  8. #8
    Expert éminent sénior
    Avatar de Cl@udius
    Homme Profil pro
    Développeur Web
    Inscrit en
    Février 2006
    Messages
    4 878
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Février 2006
    Messages : 4 878
    Points : 10 008
    Points
    10 008
    Par défaut
    OK, tout comme Banban, j'arrive à ce procédé:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    procedure TForm1.AddPoint(ASeries: TLineSeries; const X, Y: Double;
      AColor: TColor);
    const
      MAX_VALUE_COUNT = 1000; // A définir
    begin
      // Ajout du point à la série
      with ASeries do
      begin
        AddXY(X, Y, '', AColor);
        if Count > MAX_VALUE_COUNT then
          Delete(0);
      end;
    end;
    @+ Claudius

  9. #9
    Membre éclairé
    Inscrit en
    Juin 2005
    Messages
    644
    Détails du profil
    Informations professionnelles :
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2005
    Messages : 644
    Points : 754
    Points
    754
    Par défaut
    Ok j'arrive à cette solution si ce n'est que je n'utilise pas
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    if Count > MAX_VALUE_COUNT then
          Delete(0);
    mais directement
    car mes series sont initialisées avec le bon nombre de points.

    Reste que le système est lent.

    Existe-t-il un moyen de locker le repaint lors de la manitulation des n series (c.a.d lors du addxx et delete[0]) et de ne faire qu'un seul repaint du chart lorsque tout est prêt?

    J'ai essayé ( peut-être incorrectement ) et sans succès d'utiliser
    a- la propriété AutoRepaint {false faire les modif puis true }
    b- de locker la fenêtre via
    { LockWindowUpdate(Form1.Handle ); faire modif LockWindowUpdate(0); }

    Peut-être doit-on travailler sur une propriété des séries du chart et appeler soit même chart.repaint?

    merci pour vos suggestions

Discussions similaires

  1. Changer l'ordre des séries d'un TChart
    Par j.p.mignot dans le forum Composants VCL
    Réponses: 2
    Dernier message: 21/12/2010, 13h52
  2. scroll horizontal largeur maximale ?
    Par moque dans le forum Balisage (X)HTML et validation W3C
    Réponses: 4
    Dernier message: 17/01/2006, 14h32
  3. synchroniser le scroll horizontal d'un Tmemo avec un Tedit
    Par bambino3996 dans le forum Composants VCL
    Réponses: 2
    Dernier message: 09/08/2005, 12h06
  4. [TChart] Comment empiler plusieurs séries ?
    Par coucoucmoi dans le forum Composants VCL
    Réponses: 11
    Dernier message: 26/07/2005, 10h44

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