Descrizione :
Esempio pratico di associazione dati e loro rappresentazione con il controllo Chart.
+ Articolo :
Anzitutto, dal momento che di "controlli chart" in giro ce ne sono davvero tanti, voglio precisare che l'argomento in esame riguarda esclusivamente il controllo incluso in Visual Studio ( in questo caso : 2010 ), e per l'esattezza quello in Forms :
System.Windows.Forms.DataVisualization.Charting.Chart().
Ho creato questo articolo per un duplice scopo :
1. Mostrare una tecnica valida per collegare un Chart con le sue varie Serie, ad una unica fonte dati, come un DataTable.
2. Illustrare 4 diversi modi per evidenziare ciascun dato, una volta che è rappresentato graficamente nel Chart.
Oltre a questo, si noterà come diversi controlli, come le ComboBox per la scelta di ciascun Punto-Dati, vengano automaticamente messe in relazione all'atto della loro associazione con una fonte dati comune.
Per replicare l'articolo occorre una semplice Form "FormMain", con i seguenti controlli essenziali :
Chart --> Chart1
ComboBox --> cmb_x
ComboBox --> cmb_serie2
ComboBox --> cmb_serie3
Le Label sono a scopo descrittivo.
Un'immagine rende bene l'idea della struttura desiderata e del funzionamento ottenuto :
--> Codice completo FormMain :
Note :
--> Il Chart, le Serie e anche le ComboBox puntano al medesimo DataTable, chiaramente ciascuno al suo o suoi campi di pertinenza.
--> Serie1 : evidenzia il dato al passaggio del Mouse come semplice ToolTip.
--> Serie2 : evidenzia il dato ( scelto in cmb_serie2 ) con una Label. A mio avviso la scelta più completa e flessibile.
--> Serie3 : evidenzia il dato ( scelto in cmb_serie3 ) con una bitmap caricata da disco. In questo caso sarà necessario predisporre un'immagine che abbia al suo centro il Marker, e uno o più indicatori esterni. La figura seguente mostra come ho creato la mia "arrow.bmp" in 3 semplici passi, aiutandomi semplicemente con le Forme di Word 2007 :
--> Serie4 : evidenzia il dato al passaggio del Mouse con una Label. Comportamento molto simile al ToolTip della Serie1, ma molto più flessibile nella gestione.
--> Come già accennato, una selezione su ciascuna delle 3 ComboBox si propaga alle altre in automatico e senza che sia necessario estendere gli Handles nelle routine di evento, o scrivere alcun codice aggiuntivo, perchè ciò accade solo grazie alle associazioni fatte in precedenza con i Campi del DataTable.
+ Fine Articolo.
Esempio pratico di associazione dati e loro rappresentazione con il controllo Chart.
+ Articolo :
Anzitutto, dal momento che di "controlli chart" in giro ce ne sono davvero tanti, voglio precisare che l'argomento in esame riguarda esclusivamente il controllo incluso in Visual Studio ( in questo caso : 2010 ), e per l'esattezza quello in Forms :
System.Windows.Forms.DataVisualization.Charting.Chart().
Ho creato questo articolo per un duplice scopo :
1. Mostrare una tecnica valida per collegare un Chart con le sue varie Serie, ad una unica fonte dati, come un DataTable.
2. Illustrare 4 diversi modi per evidenziare ciascun dato, una volta che è rappresentato graficamente nel Chart.
Oltre a questo, si noterà come diversi controlli, come le ComboBox per la scelta di ciascun Punto-Dati, vengano automaticamente messe in relazione all'atto della loro associazione con una fonte dati comune.
Per replicare l'articolo occorre una semplice Form "FormMain", con i seguenti controlli essenziali :
Chart --> Chart1
ComboBox --> cmb_x
ComboBox --> cmb_serie2
ComboBox --> cmb_serie3
Le Label sono a scopo descrittivo.
Un'immagine rende bene l'idea della struttura desiderata e del funzionamento ottenuto :
--> Codice completo FormMain :
Public Class FormMain Private fontLab As New Font(FontFamily.GenericSansSerif, 14, FontStyle.Regular) Private DT As New DataTable("TabellaDati") Private percorsoBmp As String = Application.StartupPath & "\" Private nomeBmp As String = "arrow.bmp" Private Function RandomInteger(ByVal min As Integer, ByVal max As Integer, ByVal seed As Integer) As Integer Return (New Random(seed)).Next(min, max) End Function Private Sub FormMain_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load 'Formattazione DataTable Tabella Dati per contenere due serie 'Asse X comune alle Serie Dati DT.Columns.Add("X", GetType(System.Int32)) DT.PrimaryKey = {DT.Columns("X")} 'Asse Y Serie1 DT.Columns.Add("YSerie1", GetType(System.Single)) 'Asse Y Serie2 DT.Columns.Add("YSerie2", GetType(System.Int32)) 'Asse Y Serie3 DT.Columns.Add("YSerie3", GetType(System.Int32)) 'Asse Y Serie4 DT.Columns.Add("YSerie4", GetType(System.Int32)) 'Creazione Dati ( Pseudo-Random ) For i As Integer = 1 To 20 DT.Rows.Add({i, RandomInteger(10, 25, i ^ 2) * 1.2, _ RandomInteger(25, 50, i ^ 3), _ RandomInteger(50, 75, i ^ 4), _ RandomInteger(75, 100, i ^ 5)}) Next 'Creazione Serie Chart1.Series.Clear() Chart1.DataSource = DT 'Serie1 Dim serie1 As New DataVisualization.Charting.Series("Serie1") With serie1 .ChartType = DataVisualization.Charting.SeriesChartType.Column .Color = Color.Goldenrod .BorderWidth = 1 .BorderColor = Color.Black .XValueMember = DT.Columns("X").ToString .YValueMembers = DT.Columns("YSerie1").ToString End With Chart1.Series.Add(serie1) serie1.ToolTip = serie1.Name & " [ #VALX{F0} | #VALY{F2} ]" 'Serie2 Dim serie2 As New DataVisualization.Charting.Series("Serie2") With serie2 .ChartType = DataVisualization.Charting.SeriesChartType.Line .Color = Color.Red .BorderWidth = 2 .MarkerSize = 12 .MarkerBorderColor = Color.Black .MarkerBorderWidth = 2 .MarkerStyle = DataVisualization.Charting.MarkerStyle.Diamond .XValueMember = DT.Columns("X").ToString .YValueMembers = DT.Columns("YSerie2").ToString End With Chart1.Series.Add(serie2) 'Serie3 Dim serie3 As New DataVisualization.Charting.Series("Serie3") With serie3 .ChartType = DataVisualization.Charting.SeriesChartType.Line .Color = Color.SlateBlue .BorderWidth = 2 .MarkerSize = 10 .MarkerBorderColor = Color.Blue .MarkerBorderWidth = 2 .MarkerStyle = DataVisualization.Charting.MarkerStyle.Circle .XValueMember = DT.Columns("X").ToString .YValueMembers = DT.Columns("YSerie3").ToString End With Chart1.Series.Add(serie3) 'Serie4 Dim serie4 As New DataVisualization.Charting.Series("Serie4") With serie4 .ChartType = DataVisualization.Charting.SeriesChartType.Line .Color = Color.Green .BorderWidth = 2 .MarkerSize = 8 .MarkerBorderColor = Color.DarkGreen .MarkerBorderWidth = 2 .MarkerStyle = DataVisualization.Charting.MarkerStyle.Square .XValueMember = DT.Columns("X").ToString .YValueMembers = DT.Columns("YSerie4").ToString End With Chart1.Series.Add(serie4) With cmb_x .DropDownStyle = ComboBoxStyle.DropDownList .DataSource = DT .ValueMember = DT.Columns("X").ToString .DisplayMember = DT.Columns("X").ToString End With With cmb_serie2 .DropDownStyle = ComboBoxStyle.DropDownList .DataSource = DT .ValueMember = DT.Columns("X").ToString .DisplayMember = DT.Columns("YSerie2").ToString End With With cmb_serie3 .DropDownStyle = ComboBoxStyle.DropDownList .DataSource = DT .ValueMember = DT.Columns("X").ToString .DisplayMember = DT.Columns("YSerie3").ToString End With End Sub Private Sub cmb_serie2_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmb_serie2.SelectedIndexChanged With Chart1.Series("Serie2") If .Points.Count = 0 Then Exit Sub For i As Integer = 0 To .Points.Count - 1 .Points(i).Label = String.Empty .Points(i).MarkerStyle = DataVisualization.Charting.MarkerStyle.Diamond Next End With With Chart1.Series("Serie2").Points(cmb_serie2.SelectedIndex) .Font = fontLab .Label = "Serie2 - " & "X = " & cmb_serie2.SelectedValue & " | Y = " & cmb_serie2.Text .LabelBackColor = Color.Gold .LabelBorderColor = Color.Black .LabelBorderWidth = 1 .LabelForeColor = Color.Black .MarkerStyle = DataVisualization.Charting.MarkerStyle.Star10 End With End Sub Private Sub cmb_serie3_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmb_serie3.SelectedIndexChanged With Chart1.Series("Serie3") If .Points.Count = 0 Then Exit Sub For i As Integer = 0 To .Points.Count - 1 .Points(i).MarkerImage = String.Empty Next End With With Chart1.Series("Serie3").Points(cmb_serie3.SelectedIndex) .MarkerImage = percorsoBmp & nomeBmp .MarkerImageTransparentColor = Color.White End With End Sub Private Sub Chart1_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Chart1.MouseMove Dim HTR As DataVisualization.Charting.HitTestResult = Chart1.HitTest(e.X, e.Y) 'Controllo sul fatto che sia un DataPoint valido If Not HTR.ChartElementType = DataVisualization.Charting.ChartElementType.DataPoint Then Exit Sub 'Controllo sul fatto che sia la Serie desiderata ( Serie4 ) If Not HTR.Series.Name = "Serie4" Then Exit Sub With Chart1.Series("Serie4") For i As Integer = 0 To .Points.Count - 1 .Points(i).Label = String.Empty .Points(i).MarkerStyle = DataVisualization.Charting.MarkerStyle.Square Next End With With Chart1.Series("Serie4").Points(HTR.PointIndex) .Font = fontLab .Label = "Serie4 - " & "X = " & .XValue & " | Y = " & .YValues(0) .LabelBackColor = Color.YellowGreen .LabelBorderColor = Color.Black .LabelBorderWidth = 1 .LabelForeColor = Color.Black .MarkerStyle = DataVisualization.Charting.MarkerStyle.Star10 End With End Sub End Class
Note :
--> Il Chart, le Serie e anche le ComboBox puntano al medesimo DataTable, chiaramente ciascuno al suo o suoi campi di pertinenza.
--> Serie1 : evidenzia il dato al passaggio del Mouse come semplice ToolTip.
--> Serie2 : evidenzia il dato ( scelto in cmb_serie2 ) con una Label. A mio avviso la scelta più completa e flessibile.
--> Serie3 : evidenzia il dato ( scelto in cmb_serie3 ) con una bitmap caricata da disco. In questo caso sarà necessario predisporre un'immagine che abbia al suo centro il Marker, e uno o più indicatori esterni. La figura seguente mostra come ho creato la mia "arrow.bmp" in 3 semplici passi, aiutandomi semplicemente con le Forme di Word 2007 :
--> Serie4 : evidenzia il dato al passaggio del Mouse con una Label. Comportamento molto simile al ToolTip della Serie1, ma molto più flessibile nella gestione.
--> Come già accennato, una selezione su ciascuna delle 3 ComboBox si propaga alle altre in automatico e senza che sia necessario estendere gli Handles nelle routine di evento, o scrivere alcun codice aggiuntivo, perchè ciò accade solo grazie alle associazioni fatte in precedenza con i Campi del DataTable.
+ Fine Articolo.