Page 1 sur 1

Statistic_Gadget()

Publié : mar. 07/juin/2011 21:22
par G-Rom
je me suis amusé à codé un gadget qui représente un graphique :

Image

Avant que le code parte au oubliettes , le voici :

Code : Tout sélectionner

Structure statistic_cell
  List timeHeight.i()
  color.i
EndStructure

Structure statistic_gadget
  xPos.i
  yPos.i
  width.i
  height.i
  imageId.i
  pbGadgetId.i
  min.i
  max.i
  steps.i
  title.s
  Map information.statistic_cell()
EndStructure

; -------------------------------------------------------------------------------------------------
;
; MERCI A LSI POUR CES 2 PROCEDURES
;
; -------------------------------------------------------------------------------------------------

ProcedureDLL.l ColorBlending(Couleur1.l, Couleur2.l, Echelle.f) ; Mélanger 2 couleurs
  Protected Rouge, Vert, Bleu, Rouge2, Vert2, Bleu2
 
  Rouge = Couleur1 & $FF
  Vert = Couleur1 >> 8 & $FF
  Bleu = Couleur1 >> 16
  Rouge2 = Couleur2 & $FF
  Vert2 = Couleur2 >> 8 & $FF
  Bleu2 = Couleur2 >> 16
 
  Rouge = Rouge * Echelle + Rouge2 * (1-Echelle)
  Vert = Vert * Echelle + Vert2 * (1-Echelle)
  Bleu = Bleu * Echelle + Bleu2 * (1-Echelle)
 
  ProcedureReturn (Rouge | Vert <<8 | Bleu << 16)
EndProcedure

; -------------------------------------------------------------------------------------------------
;
; -------------------------------------------------------------------------------------------------

Procedure LineAA(X, Y, Width, Hight, Color, Thickness = 1)
  Protected SensX, SensY, n, nn, Epaisseur.f, x2.f, y2.f, Couleur_Fond.l, Application.f, Distance.f
  ; On mets la droite toujours dans le même sens pour l'analyse
  ; La sauvegarde du sens permettra de dessiner la droite ensuite dans le bon sens
  If Width >= 0
    SensX = 1
  Else
    SensX = -1
    Width = - Width
  EndIf
  If Hight >= 0
    SensY = 1
  Else
    SensY = -1
    Hight = - Hight
  EndIf
 
 
  ; Demi épaisseur de la ligne
  Epaisseur.f = Thickness / 2
 
  ; calcul pour le changement de repère qui permet de connaitre l'épaisseur du trait et de gérer l'AA
  Distance.f = Sqr(Width * Width + Hight * Hight)
  CosAngle.f = Width / Distance
  SinAngle.f = -Sin(ACos(CosAngle))
 
  ; Dessin de la ligne
  For n = -Thickness To Width + Thickness
    For nn = -Thickness To Hight + Thickness
     
      ; changement de base
      ; les y représentent l'épaisseur de la ligne
      x2 = n * CosAngle - nn * SinAngle
      y2 = Abs(n * SinAngle + nn * CosAngle)
     
      If y2 <= Epaisseur + 0.5
        Application =  0.5 + Epaisseur - y2
        If Application > 1
          Application = 1
        EndIf
        If x2 > -1 And x2 < Distance + 1
          If x2 < 0
            Application * (1 + x2)
          ElseIf x2 > Distance
            Application * (1 - x2 + Distance)
          EndIf
        Else
          Application = 0
        EndIf
        If Application > 0
          If Application < 1
            Couleur_Fond = Point(X + n * SensX, Y + nn * SensY)
            Plot(X + n * SensX, Y + nn * SensY, ColorBlending(Color, Couleur_Fond, Application))
          Else
            Plot(X + n * SensX, Y + nn * SensY, Color)
          EndIf
        EndIf
      EndIf
     
    Next
  Next
 
EndProcedure

; -------------------------------------------------------------------------------------------------
;
; -------------------------------------------------------------------------------------------------

Procedure _drawbackground_(*g.statistic_gadget)
  StartDrawing(ImageOutput(*g\imageId))
  
    DrawingMode(#PB_2DDrawing_Default)
  
    DrawingMode(#PB_2DDrawing_Gradient)  
    BackColor($CACACA)
    FrontColor($FFFFFF)
    LinearGradient(0, 0, 0, *g\height) 
    Box(0,0,*g\width , *g\height,$FFFFFF)
    
    BackColor($FFFFFF)
    FrontColor($CACACA)
    LinearGradient(0, 0, 0, *g\height) 
    Box(64,32,*g\width-96 , *g\height-64,$FFFFFF)
    If *g\title<>""
      DrawingMode(#PB_2DDrawing_Transparent)
      DrawText(*g\width/2 - TextWidth(*g\title)/2 ,4,*g\title,$5A5A5A)
    EndIf 
    DrawingMode(#PB_2DDrawing_Default)
    DrawingMode(#PB_2DDrawing_Transparent)
    byStep.f        =  (*g\max - *g\min) / *g\steps
    gfxHeight.f     = *g\height-64
    gfxHeightStep.f = gfxHeight / byStep
    For i = 0 To byStep
      number = *g\min + (i * *g\steps)
      hLine.i = ((32+gfxHeight) - (gfxHeightStep*i))
;       LineXY(64,hLine,68,hLine,0)
      LineXY(64,hLine,*g\width-32,hLine,$BCBCBC)
      DrawText(5,hLine-10,Str(number),$5A5A5A)
    Next 
    LineXY(64,32+gfxHeight,64+5*Cos(-45*#PI/180),(32+gfxHeight)+5*Sin(-45*#PI/180),$5A5A5A)
    DrawingMode(#PB_2DDrawing_Default)
    LineXY(64,32+gfxHeight,64,0,$9A9A9A)
    LineXY(64,32+gfxHeight,64+*g\width,32+gfxHeight,$9A9A9A)
  StopDrawing()
EndProcedure

; -------------------------------------------------------------------------------------------------
;
; -------------------------------------------------------------------------------------------------

Procedure _update_(*g.statistic_gadget)

  _drawbackground_(*g)

  StartDrawing(ImageOutput(*g\imageId))   
  
  ResetMap(*g\information())
  While NextMapElement(*g\information())
    
    key$           = MapKey(*g\information())
    index.i        = 0
    number         = ListSize(*g\information(key$)\timeHeight())-1
    gfxWidthStep.f = (*g\width-96) / number
    gfxHeight.f    = *g\height-32
    YY.f           = -1

    ForEach *g\information(key$)\timeHeight()
      xx.f = index * gfxWidthStep
      index + 1
;       LineXY(64+xx,gfxHeight,64+xx,gfxHeight-5,$9A9A9A)
      LineXY(64+xx,32,64+xx,gfxHeight,$9A9A9A)
      
      If NextElement(*g\information(key$)\timeHeight())<>0
        YY.f = *g\information(key$)\timeHeight()
        PreviousElement(*g\information(key$)\timeHeight())
      Else
        YY=-1
        Break 1
      EndIf 
      
      If YY<>-1
        pixelY_A.f = (*g\height-64) - ((*g\information(key$)\timeHeight() * (*g\height-64) / *g\max)-32)
        pixelY_B.f = (*g\height-64) - ((YY * (*g\height-64) / *g\max)-32)
;         LineXY(64+xx,pixelY_A,64+xx+gfxWidthStep,pixelY_B,*g\information(key$)\color)
        LineAA(64+xx,pixelY_A,gfxWidthStep,pixelY_B-pixelY_A,*g\information(key$)\color,2)
;         Circle(64+xx,pixelY_A,3,*g\information(key$)\color)
      EndIf 
      
    Next 
    
    
  Wend 
  
  StopDrawing()

  SetGadgetState(*g\pbGadgetId,ImageID(*g\imageId))
EndProcedure

; -------------------------------------------------------------------------------------------------
;
; -------------------------------------------------------------------------------------------------

Procedure StatisticGadget(x.i, y.i, width.i, height.i, min.i , max.i, steps.i, title.s="")
  *buffer.statistic_gadget = AllocateMemory(SizeOf(statistic_gadget))
  InitializeStructure(*buffer,statistic_gadget)
  
  ; ------------------------------------------------------------------
  
  *buffer\xPos    = x
  *buffer\yPos    = y
  *buffer\width   = width
  *buffer\height  = height
  *buffer\min     = min
  *buffer\max     = max
  *buffer\steps   = steps
  
  
  ; ------------------------------------------------------------------
  
  *buffer\title = title
  *buffer\imageId    = CreateImage(#PB_Any,*buffer\width , *buffer\height)
  *buffer\pbGadgetId = ImageGadget(#PB_Any,*buffer\xPos, *buffer\yPos, *buffer\width , *buffer\height,ImageID(*buffer\imageId),#PB_Image_Border) 
  
  ; ------------------------------------------------------------------
  
  ProcedureReturn *buffer
EndProcedure

; -------------------------------------------------------------------------------------------------
;
; -------------------------------------------------------------------------------------------------

Procedure AddStatisticGadgetElement(*g.statistic_gadget, name.s, color.i)
  *g\information(name)\color = color
EndProcedure

; -------------------------------------------------------------------------------------------------
;
; -------------------------------------------------------------------------------------------------

Procedure SetStatisticGadgetElementHeight(*g.statistic_gadget, name.s, value.i)
  AddElement(*g\information(name)\timeHeight())
  *g\information(name)\timeHeight() = value
EndProcedure

; -------------------------------------------------------------------------------------------------
;
; -------------------------------------------------------------------------------------------------

Procedure StatisticGadgetUpdate(*g.statistic_gadget)
  *g\width  = GadgetWidth(*g\pbGadgetId)
  *g\height = GadgetHeight(*g\pbGadgetId)
  ResizeImage(*g\imageId,*g\width, *g\height)
   _update_(*g)
EndProcedure

; -------------------------------------------------------------------------------------------------
;
; -------------------------------------------------------------------------------------------------

Procedure StatisticGadgetID(*g.statistic_gadget)
  ProcedureReturn *g\pbGadgetId
EndProcedure

; -------------------------------------------------------------------------------------------------
;
; -------------------------------------------------------------------------------------------------



;-TEST
OpenWindow(0,0,0,800,600,"")
TextGadget(#PB_Any,10,10,250,32,"Salaire en vert , Depense en rouge")
;Creation du graphique
;StatisticGadget(x , y , width , height, valeur mini , valeur maxi , pas valeur , titre du graphique) 
Graphique = StatisticGadget(10,64,640,480,100,2500,100,"Salaire & Dépenses")

AddStatisticGadgetElement(Graphique,"SALAIRE",RGB(0,255,0))
AddStatisticGadgetElement(Graphique,"DEPENSE",RGB(255,0,0))


; -------------------------------------------------

; Remplissage aléatoire de données

Dim SalaireMois(12)
Dim DepenseMois(12)

For i = 1 To 12
  SalaireMois(i) = 1800 + Random(400)
  DepenseMois(i) = 300+Random(800)
Next 

; -------------------------------------------------

; Remplissage du graphique

For i = 1 To 12
  SetStatisticGadgetElementHeight(Graphique,"SALAIRE",SalaireMois(i))
  SetStatisticGadgetElementHeight(Graphique,"DEPENSE",DepenseMois(i))
Next 

StatisticGadgetUpdate(Graphique)

; -------------------------------------------------


Repeat
  event = WindowEvent()
Until event = #PB_Event_CloseWindow

Re: Statistic_Gadget()

Publié : mar. 07/juin/2011 21:26
par venom
8) Sympa ce code
Merci G-Rom





@++

Re: Statistic_Gadget()

Publié : mar. 07/juin/2011 22:27
par Chris
C'est vrai qu'il est sympa son code.

Mais bon, je peux pas lui dire, il m'a foutu dans sa liste de boulets ignorés. :mrgreen:

Re: Statistic_Gadget()

Publié : mar. 07/juin/2011 22:27
par nico
Joli code :)

Re: Statistic_Gadget()

Publié : mar. 07/juin/2011 22:58
par Jacobus
En effet bel effet ce gadget! En plus ça simplifie grandement la réalisation de graph de stats, intéressant et utile.

Re: Statistic_Gadget()

Publié : jeu. 09/juin/2011 8:06
par Kwai chang caine
Splendide..... 8O
T'es vraiment un CAID du graphisme 8) , on dirait un vrai :D

C'est vrai qu'avec des codes comme ça, j'en arrive a regretter de ne pas avoir aimé faire du graphisme :oops:
Le graphisme, pas que pour les jeux, au service de l'utilitaire...voila une super idée qui réconcilie tout le monde :mrgreen:

Merci beaucoup de ce joli code, qui pourra être super utile dans mes utilitaires 8)

Re: Statistic_Gadget()

Publié : jeu. 09/juin/2011 9:17
par Fred
Sympa !

Re: Statistic_Gadget()

Publié : jeu. 09/juin/2011 12:26
par kernadec
bonjour G-rom
merci pour le partage.
chez moi le gadget au départ faisais un flash noir, avant de se dessiner.
alors pour remédier à cela, j'ai mis la fenêtre en #PB_Window_Invisible

Cordialement

Re: Statistic_Gadget()

Publié : jeu. 09/juin/2011 15:43
par Ar-S
Cool merci, ça me sera utile pour comparer l'évolution de mes 2 (maigres) CA en fin d'année..

Re: Statistic_Gadget()

Publié : jeu. 09/juin/2011 16:57
par graph100
moi je saute sur la procedure pour dessiner des lignes épaisses ;)

Re: Statistic_Gadget()

Publié : ven. 09/août/2013 20:14
par MetalOS
Histoire de déterrer le sujet voici un autre belle exemple de graphique fait avec PB. Trouvé sur le Forum Allemand.

http://forums.purebasic.com/german/view ... =8&t=24631

Image