Dessiner un graphe Sur un Contrôle Chart + dessiner dessus

Résolu
Karin.code Messages postés 183 Date d'inscription vendredi 2 septembre 2016 Statut Membre Dernière intervention 16 janvier 2018 - 5 mars 2017 à 11:16
Karin.code Messages postés 183 Date d'inscription vendredi 2 septembre 2016 Statut Membre Dernière intervention 16 janvier 2018 - 5 mars 2017 à 21:45
Bonjour,
Ce projet est en quelque sorte la suite de celui que Vb95 m'a aidée dessus (Merci Encore) :
http://codes-sources.commentcamarche.net/forum/affich-10073827-une-partie-du-dessin-ne-s-affiche-pas#top
comme l'indique le titre je veux créer un graphe des moments fléchissants et ajouter un dessin (Appuis), j'ai trouvé exactement ce que je veux ici dans le poste de Kikou93 (la réponse a été donnée par cs_Le Pivert) :
http://codes-sources.commentcamarche.net/forum/affich-10069537-vb-net-dessiner-dans-un-diagramme-d-un-controle-chart#10
j'ai un petit peu modifier le code pour qu'il me convient (c'est juste un exemple, il n'est pas fini), Voici le code :
Imports System.Windows.Forms.DataVisualization.Charting
Public Class Form1
Dim ChartArea1 As New ChartArea() ' Créer ChartArea (zone graphique)
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Chart2.ChartAreas.Add(ChartArea1) ' Ajouter le Chart Area à la Collection ChartAreas du Chart
With Me.Chart2
.ChartAreas(0).AxisY.IsReversed = True
.ChartAreas(0).AxisX.LabelStyle.Enabled = False 'Pour masquer les étiquettes de l'axe X
.ChartAreas(0).AxisY.LabelStyle.Enabled = False 'Pour masquer les étiquettes de l'axe Y
.ChartAreas(0).AxisX.MajorGrid.Enabled = False 'Pour masquer les quadrillages dans le sens X
.ChartAreas(0).AxisY.MajorGrid.Enabled = False 'Pour masquer les quadrillages dans le sens Y
.ChartAreas(0).AxisX.MajorTickMark.Enabled = False 'Pour masquer les graduations dans le sens X
.ChartAreas(0).AxisY.MajorTickMark.Enabled = False 'Pour masquer les graduations dans le sens Y
.ChartAreas(0).AxisY.Crossing = 0 'Pour masquer l'axe X
.ChartAreas(0).AxisX.IsMarksNextToAxis = False
.ChartAreas(0).AxisX.LineWidth = 0
.ChartAreas(0).AxisY.LineWidth = 0 'Pour masquer l'axe Y
.ChartAreas(0).AxisX.Minimum = 0
.ChartAreas(0).AxisX.ArrowStyle = DataVisualization.Charting.AxisArrowStyle.Triangle
.ChartAreas(0).AxisX.Interval = 2
.Legends(0).Enabled = False 'pour maquer la légend
.Width = 800 : .Height = 200 'Redimensionner le graphe
End With
Dim TableauXAppuis() As Integer = {2, 6, 10, 14}
Dim TableauXTravee() As Integer = {4, 8, 12, 16}
Dim TableauX3() As Integer = {6, 10, 14, 18}
Dim TableauYAppuis() As Integer = {-500, -400, -550, -300}
Dim TableauYTravee() As Integer = {200, 150, 100, 50}
Dim TableauY3() As Integer = {-400, -550, -300, -550}
Dim Series() As Series ' Créer deux data series (qui contiendront les DataPoint)
For i As Integer = 0 To 6
ReDim Preserve Series(i)
Series(i) = New Series
Series(i).BorderWidth = 1
Series(i).ChartType = SeriesChartType.Spline
Series(i).Color = Color.Red
Series(i).ChartArea = "ChartArea1"
Chart2.Series.Add(Series(i))
If i = 0 Then
With Series(i).Points
.AddXY(2, 0)
.AddXY(2, -500)
End With
ElseIf i = 1 Then
With Series(i).Points
.AddXY(2, 0)
.AddXY(18, 0)
End With
ElseIf i = 6 Then
With Series(i).Points
.AddXY(18, 0)
.AddXY(18, -550)
End With
Else
With Series(i).Points
.AddXY(TableauXAppuis(i - 2), TableauYAppuis(i - 2))
.AddXY(TableauXTravee(i - 2), TableauYTravee(i - 2))
.AddXY(TableauX3(i - 2), TableauY3(i - 2))
End With
End If
Next
End Sub
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
Dim X, Y As Integer
Dim listeX() As Integer = {2, 6, 10, 14, 18}
Dim G As Graphics
G = Chart2.CreateGraphics
For i As Integer = 0 To 4
Y = CInt((Chart2.ChartAreas(0).AxisY.ValueToPixelPosition(0)))
X = CInt((Chart2.ChartAreas(0).AxisX.ValueToPixelPosition(listeX(i))))
With G
Dim blackPen1 As New Pen(Color.Black, 1)
Dim curvePoints1 As Point() = {New Point(X, Y), New Point(X - 8, Y + 15), New Point(X + 8, Y + 15), New Point(X, Y)} 'le triangle 0
.DrawPolygon(blackPen1, curvePoints1) 'Dessiner le Triangle
.DrawLine(blackPen1, X - 12, Y + 15, X + 12, Y + 15) 'La premiere ligne d'appuis
.DrawLine(blackPen1, X - 12, Y + 18, X + 12, Y + 18) 'La 2eme ligne d'appuis
.DrawLine(blackPen1, X - 10, Y + 18, X - 8, Y + 21) 'Slache qui représente le sol
.DrawLine(blackPen1, X - 6, Y + 18, X - 4, Y + 21) 'Slache qui représente le sol
.DrawLine(blackPen1, X - 2, Y + 18, X, Y + 21) 'Slache qui représente le sol
.DrawLine(blackPen1, X + 2, Y + 18, X + 4, Y + 21) 'Slache qui représente le sol
.DrawLine(blackPen1, X + 6, Y + 18, X + 8, Y + 21) 'Slache qui représente le sol
.DrawLine(blackPen1, X + 10, Y + 18, X + 12, Y + 21) 'Slache qui représente le sol
End With
Next
End Sub
End Class

mais il y a un problème au lieu d'utiliser deux Boutons je veux utiliser un seul bouton, j'ai essayé de fusionner les deux codes dans un seul bouton, mais ça n'a pas fonctionné
j'ai aussi essayé ça
Button2.PerformClick()
mais aucun succès
une erreur s'affiche toujours dans
 Y = CInt((Chart2.ChartAreas(0).AxisY.ValueToPixelPosition(0)))

l'erreur en question : La référence d'objet n'est pas définie à une instance d'un objet.
Remarque : le contrôle Chart2 est déjà créé à partir de la boîte d'outils, il est vide sans ChartAreas et sans séries
quelqu'un pourrait m'expliquer pourquoi ça ne fonctionne pas, merci d'avance pour votre

2 réponses

vb95 Messages postés 3472 Date d'inscription samedi 11 janvier 2014 Statut Contributeur Dernière intervention 13 avril 2024 169
5 mars 2017 à 15:00
bonjour Karin.code
Plusieurs défauts dans ton code
1)
 Dim ChartArea1 As New ChartArea()   ' Créer ChartArea (zone graphique)

La variable est son type se ressemblent beaucoup trop
il est plus judicieux de faire
 Dim MonChartArea As New ChartArea()   ' Créer MonChartArea (zone graphique)


2)

With Me.Chart2
.ChartAreas(0).AxisY.IsReversed = True
' etc ......
End With

Quand tu appuie la première fois sur Button1 cela te crée ChartAeras(0)
Rappuies une seconde fois tu vas Créer ChartAeras(1) donc cause d'eereur dans ton code

3)

With Me.Chart2
.ChartAreas(0).AxisY.IsReversed = True
.ChartAreas(0).AxisX.LabelStyle.Enabled = False .ChartAreas(0).AxisY.LabelStyle.Enabled = False
.ChartAreas(0).AxisX.MajorGrid.Enabled = False
.ChartAreas(0).AxisY.MajorGrid.Enabled = False
.ChartAreas(0).AxisX.MajorTickMark.Enabled = False
.ChartAreas(0).AxisY.MajorTickMark.Enabled = False
.ChartAreas(0).AxisY.Crossing = 0.ChartAreas(0).AxisX.IsMarksNextToAxis = False
.ChartAreas(0).AxisX.LineWidth = 0
.ChartAreas(0).AxisY.LineWidth = 0
.ChartAreas(0).AxisX.Minimum = 0
.ChartAreas(0).AxisX.ArrowStyle = DataVisualization.Charting.AxisArrowStyle.Triangle
.ChartAreas(0).AxisX.Interval = 2
.Legends(0).Enabled = False
.Width = 800 : .Height = 200
End With


Tout ceci est factorisable : pourquoi tu répètes x fois .ChartAeras(0)

4)
Y = CInt((Chart2.ChartAreas(0).AxisY.ValueToPixelPosition(0)))

Chart2 existe ! OK
Mais ChartAeras(0) ? tu as vérifié ?

0
Karin.code Messages postés 183 Date d'inscription vendredi 2 septembre 2016 Statut Membre Dernière intervention 16 janvier 2018 2
5 mars 2017 à 15:31
Salut Vb95,
merci pour ta réponse
j'ai corrigé la première et la troisième erreur comme tu as suggéré
en ce qui concerne la deuxième erreur j'avais l'intention de désactiver le Bouton (Button1.Enabled = False) après avoir cliqué sur lui pour la première fois et le réactiver (Button1.Enabled = True) avec un autre Bouton qui contient le code qui permet d'effacer le graphe
concernant la quatrième erreur
je me trompe peut-être mais je crois que "ChartAeras(0)" est obligatoire pour dessiner le graphe, si il n'existe pas alors dès le début il y a une erreur
on l'utilise
Series(i).ChartArea = "MonChartArea1"
pour définir le ChartArea utilisé pour tracer la série de données
0
vb95 Messages postés 3472 Date d'inscription samedi 11 janvier 2014 Statut Contributeur Dernière intervention 13 avril 2024 169 > Karin.code Messages postés 183 Date d'inscription vendredi 2 septembre 2016 Statut Membre Dernière intervention 16 janvier 2018
5 mars 2017 à 16:22
Salut Karin.code

- Pour la seconde erreur
Dans le code qui te permettra d'effacer le graphe mets
 Chart2.ChartAreas.Clear() 

Cela videra ta collection ChartAeras
Ainsi lorsque tu réappuieras sur Button1 cela te recréera le ChartAeras(0)

Pour ta quatrième erreur
Y = CInt((Chart2.ChartAreas(0).AxisY.ValueToPixelPosition(0)))

Si Chart2 existe et ChartAeras(0) existe il n'y a plus que un seul problème :
ValueToPixelPosition(0)
existe-t-il ?

Autre chose :
Donne un nom à tes boutons : lorsque tu crées un bouton ( ou tout autre contrôle ) sur la Form une fenêtre Propriétés s'affiche
Si elle ne s'affiche pas tu cliques dans Affichage puis Fenêtre Propriétés ( ou directement F4 : c'est une touche Raccourci )
Tu peux alors définir le nom de ton contrôle, sa couleur, son texte ( si label ou button), etc....
Tout ce que tu peux définir ainsi n'a plus besoin d'être codé
C'est codé en interne dans le code de la Form
0
Karin.code Messages postés 183 Date d'inscription vendredi 2 septembre 2016 Statut Membre Dernière intervention 16 janvier 2018 2
5 mars 2017 à 16:52
Salut Vb95,
Quand j'utiluse
Chart2.ChartAreas.Clear()
il m'affiche l'erreur suivante :
Un élément de graphique portant le nom « ChartArea1 » est introuvable dans « ChartAreaCollection ».

peut-être parce que j'ai modifié le nom de ChartArea1 par MonChartArea1 ?

en fait j'utilise
Diagramme.ChartAreas.Remove(MonChartArea1)
et ça marche très bien (Diagramme est le nom de Chart2, j'ai modifié les noms comme tu l'as suggéré)
ça ne pose pas de problème car je n'ai l'intention d'utiliser qu'un seul ChartArea (MonChartArea1)
Si Chart2 existe et ChartAeras(0) existe il n'y a plus que un seul problème : ValueToPixelPosition(0) existe-t-il ? 

ça devrait exister non? car si il n'existe pas même si je mets le code qui me permet de dessiner les Appuis dans un autre Bouton ça va afficher une erreur
voir si le projet, peut-être que tu trouveras des erreurs que je n'ai pas mentionné :
http://www.cjoint.com/c/GCfp0eWfb8w
0
vb95 Messages postés 3472 Date d'inscription samedi 11 janvier 2014 Statut Contributeur Dernière intervention 13 avril 2024 169 > Karin.code Messages postés 183 Date d'inscription vendredi 2 septembre 2016 Statut Membre Dernière intervention 16 janvier 2018
5 mars 2017 à 19:04
Salut Karin.code

1)
Diagramme.ChartAreas.Remove(MonChartArea1)

peut être remplacé par
Diagramme.ChartAreas.Clear()


2) Tu vas devoir rester avec 2 boutons car j'ai trouver pourquoi cela coince
Avec le premier bouton tu dessines le diagramme
Avec le second tu dessines les appuis

Or
ValueToPixelPosition
dans
Y = CInt((Chart2.ChartAreas(0).AxisY.ValueToPixelPosition(0)))
n'existe q'une fois que le contrôle est dessiné soit lorsque la procédure DessinerDiagramme est finie
Si tu groupes les 2 boutons cela ne marche pas car ce paramètre est à Nothing soit rien !

3) je t'enverrais plus tard ton code optimisé
4) tu n'utilises pas Option Strict dans l'onglet Compiler du projet et tu as encore laissé Microsoft Visual Basic dans les références ! Je vais te donner la fessée lol !
0
Karin.code Messages postés 183 Date d'inscription vendredi 2 septembre 2016 Statut Membre Dernière intervention 16 janvier 2018 2
5 mars 2017 à 19:30
Salut vb95
dommage, merci pour ton aide
j'ai oublié d'ajouter Option Explicit On, Option Strict On et de décrocher Microsoft.VisualBasic, car je n'ai pas l'habitude et le faire
je te rappelle aussi que même toi tu oublies parfois de la faire lol
0
vb95 Messages postés 3472 Date d'inscription samedi 11 janvier 2014 Statut Contributeur Dernière intervention 13 avril 2024 169
Modifié par vb95 le 5/03/2017 à 21:14
Salut Karine.code
J'ai une bonne nouvelle : j'ai réussi avec un seul bouton
Je suis têtu comme une mule mais c'est top
L'instruction importante est
Diagramme.Refresh()
qui force le dessin à se rafraîchir avant de dessiner les appuis . Ainsi les
ValueToPixelPosition
sont créés et il n'y a plus d'erreur .

Un bouton Dessin et un bouton Effacement



Voici le code complet de la Form

Imports System.Windows.Forms.DataVisualization.Charting

Public Class Form1

Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load

End Sub

Private Sub ButtonDessin_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ButtonDessin.Click

DessinerDiagramme()
Diagramme.Refresh()
DessinerAppuis()

End Sub

Private Sub DessinerDiagramme()

With Diagramme
Diagramme.ChartAreas.Add(New ChartArea) ' Ajouter le Chart Area à la Collection ChartAreas du Chart
With .ChartAreas(0)
With .AxisX
.LabelStyle.Enabled = False 'Pour masquer les étiquettes de l'axe X
.MajorGrid.Enabled = False 'Pour masquer les quadrillages dans le sens X
.MajorTickMark.Enabled = False 'Pour masquer les graduations dans le sens X
.IsMarksNextToAxis = False
.LineWidth = 0
.Minimum = 0
.ArrowStyle = DataVisualization.Charting.AxisArrowStyle.Triangle
.Interval = 2
End With
With .AxisY
.IsReversed = True
.LabelStyle.Enabled = False 'Pour masquer les étiquettes de l'axe Y
.MajorGrid.Enabled = False 'Pour masquer les quadrillages dans le sens Y
.MajorTickMark.Enabled = False 'Pour masquer les graduations dans le sens Y
.Crossing = 0 'Pour masquer l'axe X
.LineWidth = 0 'Pour masquer l'axe Y
End With
End With
.Legends(0).Enabled = False 'pour maquer la légend
.Size = New Size(800, 200) 'Redimensionner le graphe
End With
Dim TableauXAppuis() As Integer = {2, 6, 10, 14}
Dim TableauXTravee() As Integer = {4, 8, 12, 16}
Dim TableauX3() As Integer = {6, 10, 14, 18}
Dim TableauYAppuis() As Integer = {-500, -400, -550, -300}
Dim TableauYTravee() As Integer = {200, 150, 100, 50}
Dim TableauY3() As Integer = {-400, -550, -300, -550}
Dim ListSeries As New List(Of Series) ' Créer deux data series (qui contiendront les DataPoint)
For i As Integer = 0 To 6
ListSeries.Add(New Series)
With ListSeries(i)
.BorderWidth = 1
.ChartType = SeriesChartType.Spline
.Color = Color.Red
.ChartArea = "ChartArea1"
End With
Diagramme.Series.Add(ListSeries(i))
With ListSeries(i).Points
Select Case i
Case 0
.AddXY(2, 0)
.AddXY(2, -500)
Case 1
.AddXY(2, 0)
.AddXY(18, 0)
Case 6
.AddXY(18, 0)
.AddXY(18, -550)
Case Else
.AddXY(TableauXAppuis(i - 2), TableauYAppuis(i - 2))
.AddXY(TableauXTravee(i - 2), TableauYTravee(i - 2))
.AddXY(TableauX3(i - 2), TableauY3(i - 2))
End Select
End With
Next
End Sub

Private Sub DessinerAppuis()

Dim X, Y As Integer
Dim listeX() As Integer = {2, 6, 10, 14, 18}
Dim G As Graphics
With Diagramme
G = .CreateGraphics
For i As Integer = 0 To 4
With .ChartAreas(0)
Y = CInt((.AxisY.ValueToPixelPosition(0)))
X = CInt((.AxisX.ValueToPixelPosition(listeX(i))))
End With
With G
'* Dessine les Appuis
.DrawPolygon(New Pen(Color.Black, 1), {New Point(X, Y), New Point(X - 8, Y + 15), New Point(X + 8, Y + 15), New Point(X, Y)}) 'le triangle 0) 'Dessiner le Triangle
.DrawLine(New Pen(Color.Black, 1), X - 12, Y + 15, X + 12, Y + 15) 'La premiere ligne d'appuis
.DrawLine(New Pen(Color.Black, 1), X - 12, Y + 18, X + 12, Y + 18) 'La 2eme ligne d'appuis
.DrawLine(New Pen(Color.Black, 1), X - 10, Y + 18, X - 8, Y + 21) 'Slache qui représente le sol
.DrawLine(New Pen(Color.Black, 1), X - 6, Y + 18, X - 4, Y + 21) 'Slache qui représente le sol
.DrawLine(New Pen(Color.Black, 1), X - 2, Y + 18, X, Y + 21) 'Slache qui représente le sol
.DrawLine(New Pen(Color.Black, 1), X + 2, Y + 18, X + 4, Y + 21) 'Slache qui représente le sol
.DrawLine(New Pen(Color.Black, 1), X + 6, Y + 18, X + 8, Y + 21) 'Slache qui représente le sol
.DrawLine(New Pen(Color.Black, 1), X + 10, Y + 18, X + 12, Y + 21) 'Slache qui représente le sol
End With
Next
End With

End Sub

Private Sub ButtonEffacement_Click(sender As Object, e As EventArgs) Handles ButtonEffacement.Click

Diagramme.ChartAreas.RemoveAt(0)
Diagramme.Invalidate()

End Sub

End Class

La théorie, c'est quand on sait tout et que rien ne fonctionne. La pratique, c'est quand tout fonctionne et que personne ne sait pourquoi. 
0
Karin.code Messages postés 183 Date d'inscription vendredi 2 septembre 2016 Statut Membre Dernière intervention 16 janvier 2018 2
5 mars 2017 à 21:45
Salut vb95
Wow, je dis bravo
ce n'est pas si mal que ça d'être têtu lol
Merci infiniment
A+
0
Rejoignez-nous