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 :

Conseil: Quel composant pour générer une Heatmap (matrice thermique)


Sujet :

C++Builder

  1. #1
    Membre actif
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    385
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 385
    Points : 288
    Points
    288
    Par défaut Conseil: Quel composant pour générer une Heatmap (matrice thermique)
    Bonjour,

    Je vous donne un exemple d'une Heatmap
    elle se présente sous forme de Matrice[n,m];
    on associe à chaque cellule Matrice[i,j] une intensité de couleur selon la valeur contenu dans cette cellule.

    D'après vous quel composant je pourrais utiliser pour générer une figure comme celle-ci en BCB.

    Merci pour votre aide.

    http://kb.fusioncharts.com/images/Sa...ap%20chart.JPG

    « Aucun homme ne peut rien vous révéler sinon ce qui repose déjà à demi endormi dans l'aube de votre connaissance»

    « No man can reveal to you aught but that which already lies half asleep in the dawning of your knowledge »_(¯`·.__-Alg3ri4nH4ck3r-__.·´¯)_

  2. #2
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 453
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 453
    Points : 24 864
    Points
    24 864
    Par défaut
    Si c'est pour imprimer, j'ignore si TeeChart est aussi puissant, c'est possible en jouant sur les Series en bidouillant un peu tes matrices, c'est toi à la main qui fera le dispatch de couleur

    Si c'est pour de l'affichage, avec quelques sacrifices, une TStringGrid (ou même TDrawGrid) pourra faire l'affaire, idem, tu devras gérer le dispatch de couleur
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  3. #3
    Membre actif
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    385
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 385
    Points : 288
    Points
    288
    Par défaut
    merci pour ta réponse

    j'ai pensé à TDrawGrid mais en fait j'ai des matrice de taille énorme (> 1000) donc point de vue visibilité avec TDrawGrid sa sera limite.
    « Aucun homme ne peut rien vous révéler sinon ce qui repose déjà à demi endormi dans l'aube de votre connaissance»

    « No man can reveal to you aught but that which already lies half asleep in the dawning of your knowledge »_(¯`·.__-Alg3ri4nH4ck3r-__.·´¯)_

  4. #4
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 453
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 453
    Points : 24 864
    Points
    24 864
    Par défaut
    La DrawGrid gère le défilement, tu pourras ajouter une ScrollBar V et H pour améliorer le confort de l'utilisation

    1000 Cellules = Enorme ?
    Donc 1000 Cellules, ce n'est que 40 x 25, sur un écran en 1024 x 768, cela fait 25 x 30 pixel pour chaque cellule ce qui n'est pas éloigné de ton image, bon il faut retirer la légende, on doit pouvoir sortir un 20 x 20, cela reste lisible

    Si c'est 1000 Lignes x n colonne, oui là c'est difficile, d'où le Scroll comme si tu avais plusieurs pages de graphique
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  5. #5
    Membre actif
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    385
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 385
    Points : 288
    Points
    288
    Par défaut

    Oui je veux dire plus de 1000 lignes x 1000 colonnes
    et en plus sa devrait être visible sans scroll car je dois l'exporter en image

    Citation Envoyé par ShaiLeTroll Voir le message
    La DrawGrid gère le défilement, tu pourras ajouter
    une ScrollBar V et H pour améliorer le confort de l'utilisation

    1000 Cellules = Enorme ?
    Donc 1000 Cellules, ce n'est que 40 x 25, sur un écran en 1024 x 768, cela fait 25 x 30 pixel pour chaque cellule ce qui n'est pas éloigné de ton image, bon il faut retirer la légende, on doit pouvoir sortir un 20 x 20, cela reste lisible

    Si c'est 1000 Lignes x n colonne, oui là c'est difficile, d'où le Scroll comme si tu avais plusieurs pages de graphique
    « Aucun homme ne peut rien vous révéler sinon ce qui repose déjà à demi endormi dans l'aube de votre connaissance»

    « No man can reveal to you aught but that which already lies half asleep in the dawning of your knowledge »_(¯`·.__-Alg3ri4nH4ck3r-__.·´¯)_

  6. #6
    Membre averti

    Profil pro
    Inscrit en
    Janvier 2003
    Messages
    288
    Détails du profil
    Informations personnelles :
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations forums :
    Inscription : Janvier 2003
    Messages : 288
    Points : 334
    Points
    334
    Par défaut
    Dans ce cas si j'étais toi je ne m'embêterais pas et je dessinerais tout dans un TPaintBox et tu dessine toi-même dans le Paint.
    L'objet à dessiner serait une image. 1000x1000 pour une image cela ne pose pas de problème de perf, et tu peux rafraichir des parties seulement de l'image.
    Quand je dessine directement sur l'écran je ne passe pas par TPicture, ni TBitmap, je passe directement par un DIB.

  7. #7
    Membre actif
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    385
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 385
    Points : 288
    Points
    288
    Par défaut
    Merci Yarp pour la proposition.

    Sinon si je reviens à TDrawGrid , j'ai fais ce que m'a proposé ShaiLeTroll,
    sa génère une matrice de couleur, par contre quand je fais passer le pointeur de la souris sur une cell(i,j) sa couleur devient blanche, le même phénomène arrive quand je minimise/maximise ou cache la fenêtre principale

    Je suis dans la totale confusion.

    Une idée??

    merci par avance
    « Aucun homme ne peut rien vous révéler sinon ce qui repose déjà à demi endormi dans l'aube de votre connaissance»

    « No man can reveal to you aught but that which already lies half asleep in the dawning of your knowledge »_(¯`·.__-Alg3ri4nH4ck3r-__.·´¯)_

  8. #8
    Membre averti

    Profil pro
    Inscrit en
    Janvier 2003
    Messages
    288
    Détails du profil
    Informations personnelles :
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations forums :
    Inscription : Janvier 2003
    Messages : 288
    Points : 334
    Points
    334
    Par défaut
    Désolé je n'ai pas de CBuilder sous la main. Je pense que c'est une option du composant sur le MouseOver. Tu aura le même problème avec le select.
    Avec le DrawGrid il estmiuex d'overrider le OnDrawCell et dessiner la cellule soi-même.
    Vu que la couleur de chaque cellule est uniforme ce n'est pas compliqué (TCanvas->FillRect).
    Pour le focus si l'événement est de type gdSelect (gdFocus ?) tu dessine un rectangle autour de le cellule (TCanvas->FrameRect).

  9. #9
    Membre actif
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    385
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 385
    Points : 288
    Points
    288
    Par défaut
    oui exactement,
    un aperçu de ce que j'ai fais !
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    for(int i=0;i<N;i++){
    for(int j=0;j<M;j++){
    TRect DestRect;
    DestRect=DrawGrid1->CellRect(j+1,i+1);//matrice(i,j)
    DrawGrid1->Canvas->Brush->Color =scalcolor* MAtrice[i,j];
    DrawGrid1->Canvas->FillRect(DestRect);
                                    }//for j
                                            }//for i
    Même problème quand je sélectionne une case (par click): elle devient blanche
    pareil quand je réduit la fenêtre dans la barre des tache puis je la maximise.
    « Aucun homme ne peut rien vous révéler sinon ce qui repose déjà à demi endormi dans l'aube de votre connaissance»

    « No man can reveal to you aught but that which already lies half asleep in the dawning of your knowledge »_(¯`·.__-Alg3ri4nH4ck3r-__.·´¯)_

  10. #10
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 453
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 453
    Points : 24 864
    Points
    24 864
    Par défaut
    une boucle ???
    Il est clair que tu n'as pas codé l'affichage correctement !

    TDrawGrid doit être dessiner dans un gestionnaire d'évènement de OnDrawCell
    Je te conseille la lecture de Grilles de dessin et Un démineur dans une TDrawGrid.
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  11. #11
    Membre actif
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    385
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 385
    Points : 288
    Points
    288
    Par défaut
    je crois que je suis en mode saturé.
    l’évènement OnDrawCell c'est moi qui devrais l'invoquer quelque part dans le code, car je dois parcourir ma matrice et transformer son contenu en une couleur dans le DrawGrid1.

    ????
    « Aucun homme ne peut rien vous révéler sinon ce qui repose déjà à demi endormi dans l'aube de votre connaissance»

    « No man can reveal to you aught but that which already lies half asleep in the dawning of your knowledge »_(¯`·.__-Alg3ri4nH4ck3r-__.·´¯)_

  12. #12
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 453
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 453
    Points : 24 864
    Points
    24 864
    Par défaut
    As-tu comme je te l'ai conseillé lu le tutoriel C++Builder : Un démineur dans une TDrawGrid.

    Je suis plus habitué à la TStringGrid que la TDrawGrid mais pas chance cela fonctionne exactement de la même façon, la seule différence c'est que la TDrawGrid ne gère au contenu mais juste du dessin, alors que la TStringGrid gère un tableau de chaine et d'objet, évidemment bien trop lourd pour 1 millions de cellule

    Tu affectes ColCount et RowCount selon la taille de ta matrice (pense aussi au FixedRow...)

    Ensuite, tout seul la TDrawGrid va appeler DrawCell qui va appeler ton gestionnaire pour OnDrawCell dont le prototype est TDrawCellEvent

    Le Dessin n'est fait QUE pour les parties visibles, lors d'un Scroll cela va appeler de nouveau DrawCell pour les nouvelles parties visibles (c'est le blanc que tu voyais)
    Donc sur ton million de cellule, seul un millier seront dessinés à un instant T, c'est un évident un gain de performance
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  13. #13
    Membre averti

    Profil pro
    Inscrit en
    Janvier 2003
    Messages
    288
    Détails du profil
    Informations personnelles :
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations forums :
    Inscription : Janvier 2003
    Messages : 288
    Points : 334
    Points
    334
    Par défaut
    Rien à ajouter à ce qu'à écrit ShaiLeTroll, sinon un exemple de OnDrawCell.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    void __fastcall frmMain::DrawGrid1DrawCell(TObject *Sender, int ACol, int ARow,
       TRect &Rect, TDgDrawState State)
    {
       // Ou TRect est le rectangle de la cellule qui est redessinée
       // ACol et ARow les indices de la colonne courant (Attention ACol et Arow peuvent être < 0 !!!)
     
       DrawGrid1->Canvas->Brush->Color = scalcolor* MAtrice[ACol,ARow];
       DrawGrid1->Canvas->FillRect(Rect);
    }

  14. #14
    Membre chevronné

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

    Informations forums :
    Inscription : Juin 2002
    Messages : 1 374
    Points : 1 759
    Points
    1 759
    Par défaut
    Salut !

    Ne pas oublier qu'on dispose d'un outil de développement qui permet de concevoir des classes.
    Ici, on pouvait très facilement dériver de TCustomControl pour modéliser une classe HeatMap.
    Le graphisme est alors réalisé à l'aide des primitives de TCanvas sans que ce soit plus compliqué que ce qui nous est montré dans la OnDrawCell.
    Voici ma propre classe :

    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
    class jHeatMap : public TCustomControl
    {
    private :
    //=======
    Byte *FMatrix;
    Graphics::TBitmap *Bitmap;
     
    TPanel *HPanel;
    TPanel *Panel;
    TScrollBar *HScroll;
    TScrollBar *VScroll;
     
    TColor Palette[256];
     
    UINT FCellWidth;
    UINT FCellHeight;
     
    protected :
    //=========
    TPoint TopLeft;
    UINT MaxRow;
    UINT MaxCol;
     
    void __fastcall Init(UINT AMaxCol, UINT AMaxRow);
    void __fastcall VertScrolling(TObject *Sender);
    void __fastcall HorzScrolling(TObject *Sender);
     
    BYTE __fastcall GetMatrix(UINT Col, UINT Row);
    void __fastcall SetMatrix(UINT Col, UINT Row, BYTE Value);
     
    void __fastcall SetCellWidth(UINT Value);
    void __fastcall SetCellHeight(UINT Value);
     
    public :
    //======
    __fastcall jHeatMap(TComponent *AOwner);
    __fastcall jHeatMap(TComponent *AOwner, UINT AMaxCol, UINT AMaxRow);
    __fastcall ~jHeatMap();
    void __fastcall Paint();
     
    __property BYTE Matrix[UINT Col][UINT Row] = {read=GetMatrix, write = SetMatrix};
    __property UINT CellWidth = {read=FCellWidth, write = SetCellWidth};
    __property UINT CellHeight = {read=FCellHeight, write = SetCellHeight};
     
    };
    A ce stade ce n'est que de la poésie informatique... avec BCB3 Pro !

    La propriété Matrix sert à exploiter le tableau FMatrix (1D) comme un tableau 2D.

    Voici la méthode Paint :

    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
    void __fastcall jHeatMap::Paint()
    {
    if(Bitmap != NULL)
        {
        int we = VScroll->Left;
        int he = HPanel->Top;
        if(Bitmap->Width != we) Bitmap->Width = we;
        if(Bitmap->Height != he) Bitmap->Height = he;
     
        TCanvas *C = Bitmap->Canvas;
        C->Brush->Style = bsSolid;
        C->Brush->Color = clWhite;
        C->FillRect( Rect(0,0,we,he) );
     
        int xe;
        int ye=0;
        UINT col;
        UINT row = TopLeft.y;
     
        while(ye < he)
            {
            xe = 0;
            col = TopLeft.x;
            while(xe  < we)
                {
                if((col < MaxCol) && (row < MaxRow))
                    {
                    C->Brush->Color = Palette[ Matrix[col][row] ];
                    C->FillRect(Rect(xe,ye, xe+CellWidth, ye+CellHeight));
                    }
                xe = xe + CellWidth;
                col++;
                }
            ye = ye + CellHeight;
            row++;
            }
     
        Canvas->Draw(0,0, Bitmap);
        }
    }
    A noter que la palette est initialisée (depuis le constructeur de cette classe) comme suit :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    for(int i=0; i < 256; i++)
        {
        // du vert (min) au rouge (max)
        // il y a d'autres algos tout aussi simplistes
        Palette[ i ] = (TColor)RGB(i, 255-i, 0);
        }
    A plus !

Discussions similaires

  1. [Lazarus] Quel composant pour afficher une page web ?
    Par winow dans le forum Lazarus
    Réponses: 15
    Dernier message: 01/09/2013, 10h41
  2. Quel composant pour ouvrir une photo
    Par darkman13130 dans le forum C++Builder
    Réponses: 2
    Dernier message: 05/02/2009, 17h13
  3. [Conseil]quel composant pour un tableau
    Par Sniper37 dans le forum JSF
    Réponses: 2
    Dernier message: 06/03/2007, 13h26
  4. Quel composant pour développer une application de planning ?
    Par Wilco dans le forum Composants VCL
    Réponses: 7
    Dernier message: 19/02/2006, 13h12

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