|
begin process at 2008 05 16 09:05:44
Derniers logiciels
|
Trouver une ressource
Vous ne trouvez pas de réponse à votre problème ? Alors posez la question dans le forum.
Souvenez-vous qu'il n'y a jamais de question bête, mais rester dans l'ignorance parce que l'on n'ose pas poser une question, ça c'est une erreur !
GRAPHIQUE FACILE A DESSINER : CAMEMBERT ET HISTOGRAMME
Information sur la source
Description
Ce code permet de dessiner des camemberts et des histogramme facilement sans aucune API! certe c'est un peu réinventer la roue mais si comme moi vous n'arrivez pas a faire marche les objets fait pour afficher des graphe vous serez content de le trouver. Son principe est simple : il dessine lui même le camembert ou l'histogramme à même la form.
Source
- Public Class Chart
- Inherits CollectionBase
- Implements IDisposable
- 'hérite de la classe CollectionBase pour être une liste de ainsi profiter de toutes les méthode
- 'de cette classe
-
- 'liste et énumerateur pour les couleur
- Dim LLCouleur As LinkedList(Of Color)
- Private couleur As LinkedList(Of Color).Enumerator
- 'autre variables
- Public ShowText As Boolean
- Public TextMode As TypeText
- Public GraphMode As TypeGraph = TypeGraph.Pie2D
- Public Font As Font
-
- 'Enum afin de définir le type d'affichage du texte : %, val, les deux, ...
- Public Enum TypeText
- Pourcent = 0
- Valeur = 1
- PourcentPuisValeur = 2
- ValeurPuisPourcent = 3
- Pourcent_SautLigne_Valeur = 4
- Valeur_SautLigne_Pourcent = 6
- End Enum
-
- 'type du graphique : histogramme (barres), camembert, d'autre aisément ajoutable
- Public Enum TypeGraph
- Pie2D = 0
- Hist2D = 1
- End Enum
-
- Public Sub New(ByVal FontA As Font)
- Font = FontA
- 'list des couleurs que l'on affichera
- LLCouleur = New LinkedList(Of Color)
- LLCouleur.AddLast(Color.Thistle)
- LLCouleur.AddLast(Color.Aqua)
- LLCouleur.AddLast(Color.Coral)
- LLCouleur.AddLast(Color.DeepSkyBlue)
- LLCouleur.AddLast(Color.DarkSalmon)
- LLCouleur.AddLast(Color.DarkOrchid)
- couleur = LLCouleur.GetEnumerator
- End Sub
-
- 'ajoute de nv item au graph en spécifiant la couleur
- Public Function Add(ByVal iValeur As Integer, ByVal Couleur As Color, Optional ByVal texte As String = "") As ChartItem
- Dim oCI As New ChartItem(iValeur, Couleur, texte)
- Me.List.Add(oCI)
- Return oCI
- End Function
-
- 'se déclanche quand on a finit de vider un graph de ces items
- Protected Overrides Sub OnClearComplete()
- MyBase.OnClearComplete()
- couleur = LLCouleur.GetEnumerator
- End Sub
-
- 'ajout de nv item sans spécifier la couleur
- Public Function Add(ByVal iValeur As Integer, Optional ByVal texte As String = "") As ChartItem
- 'si on est arriver a la fin de la liste des couleurs on revient au début
- ' plus détaillé : quand le curseur à été parcouru on crée un nouveau curseur et on le position sur la
- ' première couleur de la liste
- If Not (couleur.MoveNext) Then
- couleur = LLCouleur.GetEnumerator
- couleur.MoveNext()
- End If
- Return Me.Add(iValeur, couleur.Current, texte)
- End Function
-
- 'accesseur en lecture seul pour les items
- Default Public ReadOnly Property Item(ByVal iIndex As Integer) As ChartItem
- Get
- Return CType(Me.List.Item(iIndex), ChartItem)
- End Get
- End Property
-
- 'calcule le total de valeur pour les items
- 'on peut imaginer une évolution où l'utilisateur définirai lui même un max et si ce dernier est dépassé alors
- 'et alors seulement on prend le mac réél
- Public ReadOnly Property Total() As Integer
- Get
- Dim iTotal As Integer, iItem As ChartItem
- For Each iItem In Me.List
- iTotal += iItem.Valeur
- Next
- Return iTotal
- End Get
- End Property
-
- 'demande le dessin du graphique en fonction du type définit en paramètre
- Public Sub Draw(ByVal g As Graphics, ByVal oRect As Rectangle, ByVal type As TypeGraph)
- 'g.DrawRectangle(System.Drawing.Pens.Black, oRect)
- oRect.Height = oRect.Height - 2 * g.MeasureString("Test01", Me.Font).Height
- oRect.Y = oRect.Y + g.MeasureString("Test01", Me.Font).Height
- Select Case type
- Case TypeGraph.Hist2D
- DrawHist2D(g, oRect)
- Case TypeGraph.Pie2D
- 'on tranforme le rectangle en carré pour avoir un rond et non un oval
- If oRect.Height < oRect.Width Then
- oRect.X += (oRect.Width - oRect.Height) / 2
- oRect.Width = oRect.Height
- Else
- oRect.Y += (oRect.Height - oRect.Width) / 2
- oRect.Height = oRect.Width
- End If
- DrawPie2D(g, oRect)
- End Select
- End Sub
-
- 'demande le dessin du graphique en fonction du type définit avant
- Public Sub Draw(ByVal g As Graphics, ByVal oRect As Rectangle)
- On Error Resume Next
- 'on retrouve assez régulièrement des divisions par 0 dans les graphs si leurs tailles est petites
- 'on on passe en cas de problème
- Draw(g, oRect, Me.GraphMode)
- End Sub
-
- 'dessin l'histogramme
- Private Sub DrawHist2D(ByVal g As Graphics, ByVal oRect As Rectangle)
- Dim iItem As ChartItem
- Dim iTotal As Integer = Total
- Dim iMax As Integer = Integer.MinValue
- Dim iRec As Rectangle
- Dim iCpt As Integer = 0
- Dim iLarg As Integer
- Dim iUnite As Integer
- Dim iX As Integer
- Dim iPas As Integer = 0
- Dim iText As String = 0
- Dim iVal As String = 0
-
- For Each iItem In Me.List
- If iItem.Valeur > iMax Then iMax = iItem.Valeur
- iCpt = iCpt + 1
- Next
- iLarg = Math.Min(((oRect.Width - 20) / iCpt), 40)
- iPas = (oRect.Width - 20 - iLarg * iCpt) / iCpt
- iUnite = oRect.Height / iMax
- iX = oRect.X + 10 + iPas / 2
- iRec.Width = iLarg
- 'cadre
- 'ordonné
- g.DrawLine(Pens.Black, oRect.X, oRect.Y, oRect.X, oRect.Y + oRect.Height)
- 'abcisse
- g.DrawLine(Pens.Black, oRect.X + oRect.Width, oRect.Y + oRect.Height, oRect.X, oRect.Y + oRect.Height)
-
- For Each iItem In Me.List
- 'la barre
- iRec.X = iX
- iRec.Y = oRect.Y + (iMax - iItem.Valeur) * iUnite
- iRec.Height = oRect.Y + oRect.Height - iRec.Y 'iItem.Valeur * iUnite
- g.FillRectangle(iItem.Brush, iRec)
- g.DrawRectangle(Pens.Black, iRec)
-
- Dim sngAngle As Single = 360.0F * iItem.Valeur / iTotal
-
- 'le texte
- If ShowText Then
- iVal = getTextVal(iItem, iTotal, TypeText.Valeur)
- iText = iItem.texte
-
- g.DrawString(iVal, Me.Font, Brushes.Black, iRec.X + iRec.Width / 2 - g.MeasureString(iVal, Me.Font).Width / 2, iRec.Y + iRec.Height / 2 - g.MeasureString(iVal, Me.Font).Height / 2)
- g.DrawString(iText, Me.Font, Brushes.Black, iRec.X + iRec.Width / 2 - g.MeasureString(iText, Me.Font).Width / 2, iRec.Y + iRec.Height + g.MeasureString(iText, Me.Font).Height / 2)
- End If
- iX += iPas + iLarg
- Next
-
- End Sub
-
- 'dessin le camembert
- Private Sub DrawPie2D(ByVal g As Graphics, ByVal oRect As Rectangle)
- Dim iItem As ChartItem, sngCurrentStartAngle As Single
- Dim iTotal As Integer = Total
- For Each iItem In Me.List
- 'le camembert
- Dim sngAngle As Single = 360.0F * iItem.Valeur / iTotal
- g.FillPie(iItem.Brush, oRect, sngCurrentStartAngle, sngAngle)
- g.DrawPie(Pens.Black, oRect, sngCurrentStartAngle, sngAngle)
-
- 'le texte
- If ShowText Then
- Dim sText As String = ""
- sText = iItem.texte + " : " + getTextVal(iItem, iTotal)
-
- 'position du texte
- Dim sngX, sngY As Single, sngAngleRadian As Single
- sngAngleRadian = CType((sngCurrentStartAngle + sngAngle / 2) * Math.PI / 180, Single)
- sngX = CType(oRect.X + oRect.Width / 2, Single)
- sngX += CType((oRect.Width / 2) * Math.Cos(sngAngleRadian), Single)
- If Math.Cos(sngAngleRadian) < 0 Then
- sngX -= g.MeasureString(sText, Me.Font).Width
- End If
- sngY = CType(oRect.Y + oRect.Height / 2, Single)
- sngY += CType((oRect.Height / 2) * Math.Sin(sngAngleRadian), Single)
- If Math.Sin(sngAngleRadian) < 0 Then
- sngY -= g.MeasureString(sText, Me.Font).Height
- End If
-
- g.DrawString(sText, Me.Font, Brushes.Black, sngX, sngY)
- End If
-
- sngCurrentStartAngle += sngAngle
- Next
- End Sub
-
- 'un sort de garbage collector : libert la mémoire utiliser par lui et ses objets
- Public Sub Dispose() Implements IDisposable.Dispose
- Dim iItem As ChartItem
- For Each iItem In Me.List
- iItem.Dispose()
- Next
- Me.List.Clear()
- End Sub
-
- 'retourn le texte a affiché dans les graphique en fonction du type définit avant
- Private Function getTextVal(ByRef iItem As ChartItem, ByVal iTotal As Integer) As String
- Return getTextVal(iItem, iTotal, Me.TextMode)
- End Function
-
- 'retourn le texte a affiché dans les graphique en fonction du type passé en paramètre
- Private Function getTextVal(ByRef iItem As ChartItem, ByVal iTotal As Integer, ByRef leTextMode As TypeText) As String
- Select Case leTextMode
- Case TypeText.Pourcent
- Return (100 * iItem.Valeur / iTotal).ToString("#.#") & " %"
-
- Case TypeText.Valeur
- Return iItem.Valeur.ToString
-
- Case TypeText.PourcentPuisValeur
- Return (100 * iItem.Valeur / iTotal).ToString("#.#") & " %" + _
- " (" + iItem.Valeur.ToString + "/" + iTotal.ToString + ")"
-
- Case TypeText.Pourcent_SautLigne_Valeur
- Return (100 * iItem.Valeur / iTotal).ToString("#.#") & " %" + vbNewLine + _
- "(" + iItem.Valeur.ToString + "/" + iTotal.ToString + ")"
-
- Case TypeText.Valeur_SautLigne_Pourcent
- Return iItem.Valeur.ToString + vbNewLine + "(" + (100 * iItem.Valeur / iTotal).ToString("#.#") & " %" + ")"
- End Select
- 'case TypeText.ValeurPuisPourcent
- Return iItem.Valeur.ToString + " (" + (100 * iItem.Valeur / iTotal).ToString("#.#") & " %" + ")"
- End Function
- End Class
-
- Public Class ChartItem
- Implements IDisposable
- 'objet du graphique : ce sera une "part" du camembert, une barre de l'histogramme, ...
- Public Valeur As Integer
- Public texte As String
- Private _Couleur As Color
- Private _Brush As Brush
-
- Public Sub New()
- Couleur = Color.White 'couleur par défaut
- End Sub
-
- Public Sub New(ByVal iValeur As Integer, ByVal CouleurA As Color, ByVal newTexte As String)
- Me.New()
- Valeur = iValeur
- Couleur = CouleurA
- texte = newTexte
- End Sub
-
- Public Sub Dispose() Implements IDisposable.Dispose
- If Not _Brush Is Nothing Then _Brush.Dispose()
- End Sub
-
- Public Property Couleur() As Color
- Get
- Return _Couleur
- End Get
- Set(ByVal Value As Color)
- _Couleur = Value
- End Set
- End Property
-
- Public Property Brush() As Brush
- Get
- If _Brush Is Nothing Then
- Return New SolidBrush(Me.Couleur)
- End If
- Return _Brush
- End Get
- Set(ByVal Value As Brush)
- _Brush = Value
- End Set
- End Property
- End Class
Public Class Chart
Inherits CollectionBase
Implements IDisposable
'hérite de la classe CollectionBase pour être une liste de ainsi profiter de toutes les méthode
'de cette classe
'liste et énumerateur pour les couleur
Dim LLCouleur As LinkedList(Of Color)
Private couleur As LinkedList(Of Color).Enumerator
'autre variables
Public ShowText As Boolean
Public TextMode As TypeText
Public GraphMode As TypeGraph = TypeGraph.Pie2D
Public Font As Font
'Enum afin de définir le type d'affichage du texte : %, val, les deux, ...
Public Enum TypeText
Pourcent = 0
Valeur = 1
PourcentPuisValeur = 2
ValeurPuisPourcent = 3
Pourcent_SautLigne_Valeur = 4
Valeur_SautLigne_Pourcent = 6
End Enum
'type du graphique : histogramme (barres), camembert, d'autre aisément ajoutable
Public Enum TypeGraph
Pie2D = 0
Hist2D = 1
End Enum
Public Sub New(ByVal FontA As Font)
Font = FontA
'list des couleurs que l'on affichera
LLCouleur = New LinkedList(Of Color)
LLCouleur.AddLast(Color.Thistle)
LLCouleur.AddLast(Color.Aqua)
LLCouleur.AddLast(Color.Coral)
LLCouleur.AddLast(Color.DeepSkyBlue)
LLCouleur.AddLast(Color.DarkSalmon)
LLCouleur.AddLast(Color.DarkOrchid)
couleur = LLCouleur.GetEnumerator
End Sub
'ajoute de nv item au graph en spécifiant la couleur
Public Function Add(ByVal iValeur As Integer, ByVal Couleur As Color, Optional ByVal texte As String = "") As ChartItem
Dim oCI As New ChartItem(iValeur, Couleur, texte)
Me.List.Add(oCI)
Return oCI
End Function
'se déclanche quand on a finit de vider un graph de ces items
Protected Overrides Sub OnClearComplete()
MyBase.OnClearComplete()
couleur = LLCouleur.GetEnumerator
End Sub
'ajout de nv item sans spécifier la couleur
Public Function Add(ByVal iValeur As Integer, Optional ByVal texte As String = "") As ChartItem
'si on est arriver a la fin de la liste des couleurs on revient au début
' plus détaillé : quand le curseur à été parcouru on crée un nouveau curseur et on le position sur la
' première couleur de la liste
If Not (couleur.MoveNext) Then
couleur = LLCouleur.GetEnumerator
couleur.MoveNext()
End If
Return Me.Add(iValeur, couleur.Current, texte)
End Function
'accesseur en lecture seul pour les items
Default Public ReadOnly Property Item(ByVal iIndex As Integer) As ChartItem
Get
Return CType(Me.List.Item(iIndex), ChartItem)
End Get
End Property
'calcule le total de valeur pour les items
'on peut imaginer une évolution où l'utilisateur définirai lui même un max et si ce dernier est dépassé alors
'et alors seulement on prend le mac réél
Public ReadOnly Property Total() As Integer
Get
Dim iTotal As Integer, iItem As ChartItem
For Each iItem In Me.List
iTotal += iItem.Valeur
Next
Return iTotal
End Get
End Property
'demande le dessin du graphique en fonction du type définit en paramètre
Public Sub Draw(ByVal g As Graphics, ByVal oRect As Rectangle, ByVal type As TypeGraph)
'g.DrawRectangle(System.Drawing.Pens.Black, oRect)
oRect.Height = oRect.Height - 2 * g.MeasureString("Test01", Me.Font).Height
oRect.Y = oRect.Y + g.MeasureString("Test01", Me.Font).Height
Select Case type
Case TypeGraph.Hist2D
DrawHist2D(g, oRect)
Case TypeGraph.Pie2D
'on tranforme le rectangle en carré pour avoir un rond et non un oval
If oRect.Height < oRect.Width Then
oRect.X += (oRect.Width - oRect.Height) / 2
oRect.Width = oRect.Height
Else
oRect.Y += (oRect.Height - oRect.Width) / 2
oRect.Height = oRect.Width
End If
DrawPie2D(g, oRect)
End Select
End Sub
'demande le dessin du graphique en fonction du type définit avant
Public Sub Draw(ByVal g As Graphics, ByVal oRect As Rectangle)
On Error Resume Next
'on retrouve assez régulièrement des divisions par 0 dans les graphs si leurs tailles est petites
'on on passe en cas de problème
Draw(g, oRect, Me.GraphMode)
End Sub
'dessin l'histogramme
Private Sub DrawHist2D(ByVal g As Graphics, ByVal oRect As Rectangle)
Dim iItem As ChartItem
Dim iTotal As Integer = Total
Dim iMax As Integer = Integer.MinValue
Dim iRec As Rectangle
Dim iCpt As Integer = 0
Dim iLarg As Integer
Dim iUnite As Integer
Dim iX As Integer
Dim iPas As Integer = 0
Dim iText As String = 0
Dim iVal As String = 0
For Each iItem In Me.List
If iItem.Valeur > iMax Then iMax = iItem.Valeur
iCpt = iCpt + 1
Next
iLarg = Math.Min(((oRect.Width - 20) / iCpt), 40)
iPas = (oRect.Width - 20 - iLarg * iCpt) / iCpt
iUnite = oRect.Height / iMax
iX = oRect.X + 10 + iPas / 2
iRec.Width = iLarg
'cadre
'ordonné
g.DrawLine(Pens.Black, oRect.X, oRect.Y, oRect.X, oRect.Y + oRect.Height)
'abcisse
g.DrawLine(Pens.Black, oRect.X + oRect.Width, oRect.Y + oRect.Height, oRect.X, oRect.Y + oRect.Height)
For Each iItem In Me.List
'la barre
iRec.X = iX
iRec.Y = oRect.Y + (iMax - iItem.Valeur) * iUnite
iRec.Height = oRect.Y + oRect.Height - iRec.Y 'iItem.Valeur * iUnite
g.FillRectangle(iItem.Brush, iRec)
g.DrawRectangle(Pens.Black, iRec)
Dim sngAngle As Single = 360.0F * iItem.Valeur / iTotal
'le texte
If ShowText Then
iVal = getTextVal(iItem, iTotal, TypeText.Valeur)
iText = iItem.texte
g.DrawString(iVal, Me.Font, Brushes.Black, iRec.X + iRec.Width / 2 - g.MeasureString(iVal, Me.Font).Width / 2, iRec.Y + iRec.Height / 2 - g.MeasureString(iVal, Me.Font).Height / 2)
g.DrawString(iText, Me.Font, Brushes.Black, iRec.X + iRec.Width / 2 - g.MeasureString(iText, Me.Font).Width / 2, iRec.Y + iRec.Height + g.MeasureString(iText, Me.Font).Height / 2)
End If
iX += iPas + iLarg
Next
End Sub
'dessin le camembert
Private Sub DrawPie2D(ByVal g As Graphics, ByVal oRect As Rectangle)
Dim iItem As ChartItem, sngCurrentStartAngle As Single
Dim iTotal As Integer = Total
For Each iItem In Me.List
'le camembert
Dim sngAngle As Single = 360.0F * iItem.Valeur / iTotal
g.FillPie(iItem.Brush, oRect, sngCurrentStartAngle, sngAngle)
g.DrawPie(Pens.Black, oRect, sngCurrentStartAngle, sngAngle)
'le texte
If ShowText Then
Dim sText As String = ""
sText = iItem.texte + " : " + getTextVal(iItem, iTotal)
'position du texte
Dim sngX, sngY As Single, sngAngleRadian As Single
sngAngleRadian = CType((sngCurrentStartAngle + sngAngle / 2) * Math.PI / 180, Single)
sngX = CType(oRect.X + oRect.Width / 2, Single)
sngX += CType((oRect.Width / 2) * Math.Cos(sngAngleRadian), Single)
If Math.Cos(sngAngleRadian) < 0 Then
sngX -= g.MeasureString(sText, Me.Font).Width
End If
sngY = CType(oRect.Y + oRect.Height / 2, Single)
sngY += CType((oRect.Height / 2) * Math.Sin(sngAngleRadian), Single)
If Math.Sin(sngAngleRadian) < 0 Then
sngY -= g.MeasureString(sText, Me.Font).Height
End If
g.DrawString(sText, Me.Font, Brushes.Black, sngX, sngY)
End If
sngCurrentStartAngle += sngAngle
Next
End Sub
'un sort de garbage collector : libert la mémoire utiliser par lui et ses objets
Public Sub Dispose() Implements IDisposable.Dispose
Dim iItem As ChartItem
For Each iItem In Me.List
iItem.Dispose()
Next
Me.List.Clear()
End Sub
'retourn le texte a affiché dans les graphique en fonction du type définit avant
Private Function getTextVal(ByRef iItem As ChartItem, ByVal iTotal As Integer) As String
Return getTextVal(iItem, iTotal, Me.TextMode)
End Function
'retourn le texte a affiché dans les graphique en fonction du type passé en paramètre
Private Function getTextVal(ByRef iItem As ChartItem, ByVal iTotal As Integer, ByRef leTextMode As TypeText) As String
Select Case leTextMode
Case TypeText.Pourcent
Return (100 * iItem.Valeur / iTotal).ToString("#.#") & " %"
Case TypeText.Valeur
Return iItem.Valeur.ToString
Case TypeText.PourcentPuisValeur
Return (100 * iItem.Valeur / iTotal).ToString("#.#") & " %" + _
" (" + iItem.Valeur.ToString + "/" + iTotal.ToString + ")"
Case TypeText.Pourcent_SautLigne_Valeur
Return (100 * iItem.Valeur / iTotal).ToString("#.#") & " %" + vbNewLine + _
"(" + iItem.Valeur.ToString + "/" + iTotal.ToString + ")"
Case TypeText.Valeur_SautLigne_Pourcent
Return iItem.Valeur.ToString + vbNewLine + "(" + (100 * iItem.Valeur / iTotal).ToString("#.#") & " %" + ")"
End Select
'case TypeText.ValeurPuisPourcent
Return iItem.Valeur.ToString + " (" + (100 * iItem.Valeur / iTotal).ToString("#.#") & " %" + ")"
End Function
End Class
Public Class ChartItem
Implements IDisposable
'objet du graphique : ce sera une "part" du camembert, une barre de l'histogramme, ...
Public Valeur As Integer
Public texte As String
Private _Couleur As Color
Private _Brush As Brush
Public Sub New()
Couleur = Color.White 'couleur par défaut
End Sub
Public Sub New(ByVal iValeur As Integer, ByVal CouleurA As Color, ByVal newTexte As String)
Me.New()
Valeur = iValeur
Couleur = CouleurA
texte = newTexte
End Sub
Public Sub Dispose() Implements IDisposable.Dispose
If Not _Brush Is Nothing Then _Brush.Dispose()
End Sub
Public Property Couleur() As Color
Get
Return _Couleur
End Get
Set(ByVal Value As Color)
_Couleur = Value
End Set
End Property
Public Property Brush() As Brush
Get
If _Brush Is Nothing Then
Return New SolidBrush(Me.Couleur)
End If
Return _Brush
End Get
Set(ByVal Value As Brush)
_Brush = Value
End Set
End Property
End Class
Conclusion
Le code initial n'est pas de moi, je l'ai récupéré et j'ai ajouté la fonction d'histogramme, et la "génération" automatique de couleur.
Historique
- 13 avril 2006 14:50:27 :
- des commentaires d'ajoutés, et des façons d'afficher les valeurs aussi : pourcentage, valeur, les deux, ...
Sources de la même categorie
Commentaires
Discussions en rapport avec ce code source
|
Téléchargements
Logiciels à télécharger sur le même thème :
|
|