I'm trying to build a chart composed of up-to-100% stacked columns, each with 4 series and, once built, upon hovering upon the series, return all bound data (in this case, user names)
I'm very close to what i want, but the tooltip is showing only the sums, which is expected, but i dont know how to proceed. If there's another way that passes over the hover, like clicking and, in the click, I recognize the series and all those that are there, that would help immensely too
After looking it up, i built the chart this way: (right now its a code nightmare, but i will methodify everything properly later)
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim sql As New SqlCommand(my query, my connector)
connect()
Dim rs = sql.ExecuteReader
Dim dtTest1 As DataTable = New DataTable
If rs.Read Then
dtTest1.Load(rs)
End If
disconnect()
Dim arrayTempoCallback(dtTest1.Rows.Count) As Double
Dim arrayTempoInaptidao(dtTest1.Rows.Count) As Double
Dim arrayTempoParabens(dtTest1.Rows.Count) As Double
Dim arrayTempoRecusa(dtTest1.Rows.Count) As Double
Dim arrayTempoSemDados(dtTest1.Rows.Count) As Double
For Each item In dtTest1.Rows
arrayTempoCallback(dtTest1.Rows.IndexOf(item)) = item("TEMPO_CALLBACK")
arrayTempoInaptidao(dtTest1.Rows.IndexOf(item)) = item("TEMPO_INAPTIDAO")
arrayTempoParabens(dtTest1.Rows.IndexOf(item)) = item("TEMPO_PARABENS")
arrayTempoRecusa(dtTest1.Rows.IndexOf(item)) = item("TEMPO_RECUSA")
arrayTempoSemDados(dtTest1.Rows.IndexOf(item)) = item("TEMPO_SEMDADOS")
Next
Dim QuartisCallBack = Quartiles(arrayTempoCallback)
Dim QuartisTempoInaptidao = Quartiles(arrayTempoInaptidao)
Dim QuartisTempoParabens = Quartiles(arrayTempoParabens)
Dim QuartisTempoRecusa = Quartiles(arrayTempoRecusa)
Dim QuartisTempoSemDados = Quartiles(arrayTempoSemDados)
Dim tabelafinal As New DataTable
tabelafinal.Columns.Add("VALORES", GetType(String))
tabelafinal.Columns.Add("COLUNA", GetType(String))
tabelafinal.Columns.Add("COR", GetType(String))
Dim somaS As Integer = 0
Dim somaH As Integer = 0
Dim somaC As Integer = 0
Dim somaD As Integer = 0
For Each linha In dtTest1.Rows
If linha("TEMPO_INAPTIDAO") < QuartisTempoInaptidao.Item1 Then
somaS += 1
ElseIf linha("TEMPO_INAPTIDAO") >= QuartisTempoInaptidao.Item1 AndAlso linha("TEMPO_INAPTIDAO") < QuartisTempoInaptidao.Item2 Then
somaH += 1
ElseIf linha("TEMPO_INAPTIDAO") >= QuartisTempoInaptidao.Item2 AndAlso linha("TEMPO_INAPTIDAO") < QuartisTempoInaptidao.Item3 Then
somaC += 1
ElseIf linha("TEMPO_INAPTIDAO") >= QuartisTempoInaptidao.Item3 Then
somaD += 1
End If
Next
tabelafinal.Rows.Add(somaS, "TM_INAP", "D")
tabelafinal.Rows.Add(somaH, "TM_INAP", "C")
tabelafinal.Rows.Add(somaC, "TM_INAP", "H")
tabelafinal.Rows.Add(somaD, "TM_INAP", "S")
somaC = somaD = somaH = somaS = 0
For Each linha In dtTest1.Rows
If linha("TEMPO_PARABENS") < QuartisTempoParabens.Item1 Then
somaS += 1
ElseIf linha("TEMPO_PARABENS") >= QuartisTempoParabens.Item1 AndAlso linha("TEMPO_PARABENS") < QuartisTempoParabens.Item2 Then
somaH += 1
ElseIf linha("TEMPO_PARABENS") >= QuartisTempoParabens.Item2 AndAlso linha("TEMPO_PARABENS") < QuartisTempoParabens.Item3 Then
somaC += 1
ElseIf linha("TEMPO_PARABENS") >= QuartisTempoParabens.Item3 Then
somaD += 1
End If
Next
tabelafinal.Rows.Add(somaS, "TM_PARABENS", "S")
tabelafinal.Rows.Add(somaH, "TM_PARABENS", "H")
tabelafinal.Rows.Add(somaC, "TM_PARABENS", "C")
tabelafinal.Rows.Add(somaD, "TM_PARABENS", "D")
somaC = somaD = somaH = somaS = 0
For Each linha In dtTest1.Rows
If linha("TEMPO_RECUSA") < QuartisTempoRecusa.Item1 Then
somaS += 1
ElseIf linha("TEMPO_RECUSA") >= QuartisTempoRecusa.Item1 AndAlso linha("TEMPO_PARABENS") < QuartisTempoRecusa.Item2 Then
somaH += 1
ElseIf linha("TEMPO_RECUSA") >= QuartisTempoRecusa.Item2 AndAlso linha("TEMPO_PARABENS") < QuartisTempoRecusa.Item3 Then
somaC += 1
ElseIf linha("TEMPO_RECUSA") >= QuartisTempoRecusa.Item3 Then
somaD += 1
End If
Next
tabelafinal.Rows.Add(somaS, "TM_RECUSA", "S")
tabelafinal.Rows.Add(somaH, "TM_RECUSA", "H")
tabelafinal.Rows.Add(somaC, "TM_RECUSA", "C")
tabelafinal.Rows.Add(somaD, "TM_RECUSA", "D")
somaC = somaD = somaH = somaS = 0
For Each linha In dtTest1.Rows
If linha("TEMPO_SEMDADOS") < QuartisTempoSemDados.Item1 Then
somaS += 1
ElseIf linha("TEMPO_SEMDADOS") >= QuartisTempoSemDados.Item1 AndAlso linha("TEMPO_PARABENS") < QuartisTempoSemDados.Item2 Then
somaH += 1
ElseIf linha("TEMPO_SEMDADOS") >= QuartisTempoSemDados.Item2 AndAlso linha("TEMPO_PARABENS") < QuartisTempoSemDados.Item3 Then
somaC += 1
ElseIf linha("TEMPO_SEMDADOS") >= QuartisTempoSemDados.Item3 Then
somaD += 1
End If
Next
Dim somaFinalSemDadosS As Integer = If(somaS < 0, 0, somaS)
Dim somaFinalSemDadosH As Integer = If(somaH < 0, 0, somaH)
Dim somaFinalSemDadosC As Integer = If(somaC < 0, 0, somaC)
Dim somaFinalSemDadosD As Integer = If(somaD < 0, 0, somaD)
tabelafinal.Rows.Add(somaFinalSemDadosS, "TM_SEMDADOS", "S")
tabelafinal.Rows.Add(somaFinalSemDadosH, "TM_SEMDADOS", "H")
tabelafinal.Rows.Add(somaFinalSemDadosC, "TM_SEMDADOS", "C")
tabelafinal.Rows.Add(somaFinalSemDadosD, "TM_SEMDADOS", "D")
somaC = somaD = somaH = somaS = 0
For Each linha In dtTest1.Rows
If linha("TEMPO_CALLBACK") < QuartisCallBack.Item1 Then
somaS += 1
ElseIf linha("TEMPO_CALLBACK") >= QuartisCallBack.Item1 AndAlso linha("TEMPO_PARABENS") < QuartisCallBack.Item2 Then
somaH += 1
ElseIf linha("TEMPO_CALLBACK") >= QuartisCallBack.Item2 AndAlso linha("TEMPO_PARABENS") < QuartisCallBack.Item3 Then
somaC += 1
ElseIf linha("TEMPO_CALLBACK") >= QuartisCallBack.Item3 Then
somaD += 1
End If
Next
Dim somaFinalCallBackS As Integer = If(somaS < 0, 0, somaS)
Dim somaFinalCallBackH As Integer = If(somaH < 0, 0, somaH)
Dim somaFinalCallBackC As Integer = If(somaC < 0, 0, somaC)
Dim somaFinalCallBackD As Integer = If(somaD < 0, 0, somaD)
tabelafinal.Rows.Add(somaFinalCallBackS, "TEMPO_CALLBACK", "S")
tabelafinal.Rows.Add(somaFinalCallBackH, "TEMPO_CALLBACK", "H")
tabelafinal.Rows.Add(somaFinalCallBackC, "TEMPO_CALLBACK", "C")
tabelafinal.Rows.Add(somaFinalCallBackD, "TEMPO_CALLBACK", "D")
Dim dv As DataView = New DataView(tabelafinal)
Chart1.AlignDataPointsByAxisLabel()
Chart1.DataBindCrossTable(dv, "COR", "COLUNA", "VALORES", "")
For Each cs As Series In Chart1.Series
cs.ChartType = SeriesChartType.StackedColumn100
cs.ToolTip = "Pessoas = #VALY"
Next
End Sub
Friend Function Quartiles(ByVal afVal As Double()) As Tuple(Of Double, Double, Double)
Dim iSize As Integer = afVal.Length
System.Array.Sort(afVal)
Dim iMid As Integer = iSize / 2
Dim fQ1 As Double = 0
Dim fQ2 As Double = 0
Dim fQ3 As Double = 0
If iSize Mod 2 = 0 Then
fQ2 = (afVal(iMid - 1) + afVal(iMid)) / 2
Dim iMidMid As Integer = iMid / 2
If iMid Mod 2 = 0 Then
fQ1 = (afVal(iMidMid - 1) + afVal(iMidMid)) / 2
fQ3 = (afVal(iMid + iMidMid - 1) + afVal(iMid + iMidMid)) / 2
Else
fQ1 = afVal(iMidMid)
fQ3 = afVal(iMidMid + iMid)
End If
ElseIf iSize = 1 Then
fQ1 = afVal(0)
fQ2 = afVal(0)
fQ3 = afVal(0)
Else
fQ2 = afVal(iMid)
If (iSize - 1) Mod 4 = 0 Then
Dim n As Integer = (iSize - 1) / 4
fQ1 = (afVal(n - 1) * 0.25) + (afVal(n) * 0.75)
fQ3 = (afVal(3 * n) * 0.75) + (afVal(3 * n + 1) * 0.25)
ElseIf (iSize - 3) Mod 4 = 0 Then
Dim n As Integer = (iSize - 3) / 4
fQ1 = (afVal(n) * 0.75) + (afVal(n + 1) * 0.25)
fQ3 = (afVal(3 * n + 1) * 0.25) + (afVal(3 * n + 2) * 0.75)
End If
End If
Return New Tuple(Of Double, Double, Double)(fQ1, fQ2, fQ3)
End Function
End Class
If I understand correctly, you are trying to show a tooltip (when hovering the cursor over one colored 'block' in the chart) that shows information about the data that makes up the point.
The problem is that each 'block' is only a single X and Y value. For example: The DataPoint behind the tooltip that shows 'Pessoas = 392' is actually just a simple DataPoint (Series-S X=5 Y=392) with no additional information.
To show a tooltip the way you want each one will have to be pre-set, like this:
point.ToolTip = "User1 in the series\nUser2 in the series\n..."