Czasem prosty wykres to za mało aby analizować dane. Kiedy danych jest bardzo dużo musimy udostępnić użytkownikowi możliwość zbliżenia na interesujący go odcinek czasu. Zobaczmy jak to wygląda. Mamy odcinek czasu z notowania waluty euro-usd, kiedy chce wyświetlić wykres tego notowania wszystko jest mało czytelne:
Tutaj jest i tak nieźle ponieważ wykres sam określa minimalne i maksymalne wartości, wasz wykres prawdopodobnie będzie miał minimum w 0 co jeszcze bardziej uniemożliwi jego skuteczną interpretacje. Jak ustawić automatyczne minima i maksima pokaże w tym tutorialu. Zaczynamy od utworzenia nowego projektu. Do projektu dodałem następujące elementy:
| Rodzaj elementu | Nazwa elementu | ustawienia |
|---|---|---|
| Form | Form1 | Name: Form1 Text: Sterowanie wykresem Size: 857; 523 |
| Chart | Wykres | Name: Wykres Anchor: Top, Bottom, Left, Right Size: 817; 338 Location: 12; 37 Dodałem jedną serię danych. |
| Button | WczytajDane | Text: Wczytaj dane Location: 12; 8 Name: WczytajDane |
| Button | lewy1 | Text: << Location: 8; 383 Size: 19; 43 Name: lewy1 Anchor: Bottom, Left |
| Button | lewy2 | Text: << Location: 8; 436 Size: 19; 43 Name: lewy2 Anchor: Bottom, Left |
| Button | prawy1 | Text: >> Location: 810; 383 Size: 19; 43 Name: prawy1 Anchor: Bottom, Right |
| Button | prawy2 | Text: >> Location: 810; 436 Size: 19; 43 Name: prawy2 Anchor: Bottom, Right |
| TrackBar1 | TrackBar1 | Location: 33; 381 Size: 771; 45 RightToLeft: No Anchor: Bottom, Left, Right BackColor: White Name: TrackBar1 |
| TrackBar2 | TrackBar2 | Location: 33; 432 Size: 771; 45 RightToLeft: No Anchor: Bottom, Left, Right BackColor: White Name: TrackBar2 |
| OpenFileDialod | OpenFileDialod1 | Name: OpenFileDialod1 |
Po ustawieniu tych obiektów powinniśmy otrzymać konstrukcję taką jak na obrazku poniżej:
Ja osobiście lubię gdy mój wykres ma specyficzny wygląd jest wtedy według mnie bardziej czytelny, ale wam zostawiam dowolność. Następnym etapem będzie wczytanie danych. Ja lubię gdy dane wczytywane są ze zwykłego pliku *.txt jeśli komuś to nie odpowiada może użyć bazy danych albo przenosić pliki z excela. Wszystkie te możliwości były opisywane na blogu, jeśli ktoś nie wie co i jak niech napisze w komentarzach. Tworzymy uchwyt do naszego przycisku (klikamy go dwukrotnie). Na starcie będziemy potrzebować zmiennej i listy typu double. Kod z opisem prezentuje poniżej:
Dim kontroler As Boolean = True ' służy do sprawdzania czy lista jest pusta
Dim dane As New List(Of Double)
Private Sub WczytajDane_Click(sender As Object, e As EventArgs) Handles WczytajDane.Click
'filtr danych
OpenFileDialog1.Filter = "csv files|;*.csv;*.txt"
OpenFileDialog1.Title = "Select a csv file"
OpenFileDialog1.FileName = ""
Try
With OpenFileDialog1
If .ShowDialog() = DialogResult.OK Then
'' kontroler posłuży nam do zaznaczania czy dane są wczytanie czy też nie,
'' daje to możliwość załadowania innych danych jeśli te nam już nie będą potrzebna.
If kontroler = False Then
dane.Clear() 'czyści tablice
TworzTabele(.FileName) 'Ładuje dane do listy (nie gotowa na tym etapie)
TrackBar2.Value = 0
TrackBar1.Value = 0
tworz_wykres(TrackBar1.Value, TrackBar2.Value) ' funkcja ładująca dane do wykresu (nie gotowa na tym etapie)
Else
TworzTabele(.FileName) 'Ładuje dane do listy (nie gotowa na tym etapie)
tworz_wykres(0, 0) ' funkcja ładująca dane do wykresu (nie gotowa na tym etapie)
kontroler = False
TrackBar1.Enabled = True
TrackBar2.Enabled = True
End If
End If
End With
Catch ex As Exception
End Try
End Sub
Zajmiemy się teraz funkcją która załaduje nam dane z pliku *.txt do listy o nazwie „dane”. Dodamy możliwość wstawienia separatora, da nam to możliwość importowania list z plików *.CSV . Kod do ładowania danych wygląda następująco:
Public Sub TworzTabele(ByVal sciezkaDoPliku As String)
Dim i As Integer
Dim wartosc As String() 'przechowuje dane z pliku
Dim f As IO.File = Nothing
Dim rodzajkodu As New IO.StreamReader(sciezkaDoPliku, System.Text.Encoding.UTF8)
Try
Dim k As String
k = InputBox("Wprowadź znak separatora. (pozostawienie pustego pola oznacza użycie tabulatora)", "")
If k = "" Then
wartosc = rodzajkodu.ReadLine().Split(ControlChars.Tab)
Else
wartosc = rodzajkodu.ReadLine().Split(k)
End If
For i = 0 To wartosc.Length() - 1
dane.Add(wartosc(i))
Next
While rodzajkodu.Peek() <> -1
wartosc = rodzajkodu.ReadLine().Split()
For i = 0 To wartosc.Length() - 1
dane.Add(wartosc(i)) 'Ładuje elementy pliku do list dane
Next
End While
Catch ex As Exception
MsgBox("Error: " & ex.Message)
Finally
rodzajkodu.Close()
End Try
'ustawia przedział TrackBarów
TrackBar1.Maximum = dane.Count - 2
TrackBar2.Maximum = dane.Count - 2
End Sub
Po załadowaniu danych wystarczy teraz tylko wyświetlić w naszym wykresie. Jak widzicie posłuży nam do tego metoda tworz_wykres. Najpierw musimy importować wymaganą bibliotekę, nad „Public Class” dodajemy linijkę:
Imports System.Windows.Forms.DataVisualization.Charting Public Class Form1
Kod metody tworz_wykres:
Private Sub tworz_wykres(ByVal wartosc As Integer, ByVal wartosc2 As Integer)
' Określamy minimum i maximum osi y aby nasze dane calościowo mieściły się na wykresie
Dim minimum As New Double
Dim maximum As New Double
'wstępne ustawienie minimum i maximum
minimum = dane(wartosc)
maximum = dane(wartosc)
'pętle szukające minimalnych/maxymalnych wartości
For i As Integer = wartosc + 1 To dane.Count - 1 - wartosc2
If dane(i) < minimum Then
minimum = dane(i)
End If
Next
For i As Integer = wartosc + 1 To dane.Count - 1 - wartosc2
If dane(i) > maximum Then
maximum = dane(i)
End If
Next
'ustawienie wartości
Wykres.ChartAreas(0).AxisY.Minimum = Val(minimum)
Wykres.ChartAreas(0).AxisY.Maximum = Val(maximum)
'gdy zbliżymu wykres do 20 danych pojawią się znaczniki informujące o wartościach danych
If (dane.Count - 3) - wartosc - wartosc2 <= 20 Then
Wykres.Series(0).IsValueShownAsLabel = True
Wykres.Series(0).LabelFormat = "N4"
Wykres.Series(0).MarkerStyle = MarkerStyle.Square
Wykres.Series(0).MarkerSize = 5
Else
Wykres.Series(0).IsValueShownAsLabel = False
Wykres.Series(0).MarkerStyle = MarkerStyle.None
End If
'tutaj możemy ustawić właściwości naszego wykresu takie jak rodzaj, nazwę itp
Wykres.Series(0).ChartType = DataVisualization.Charting.SeriesChartType.Line
Wykres.Series(0).Points.Clear()
Wykres.Series(0).Name = "yt"
Wykres.Series(0).BorderWidth = 2
'ładuje dane do wykresu
For Count As Integer = wartosc To dane.Count - 2 - wartosc2
Wykres.Series(0).Points.AddXY(Count, dane(Count))
Next
End Sub
Wygląda to nieźle według mnie, po załadowaniu znacznej ilości danych mój wykres wygląda tak:
Widzimy ładnie zachowane minima i maxima które pozwalają wypełnić całą przestrzeń wykresu. Jak to bez tych opcji wygląda:
Chyba trochę słabo. Najbardziej widoczne jest to wtedy gdy nasze dane są bardzo małe jak np. dane z rynku FOREX. Wystarczy teraz tylko dodać funkcjonalność Trackbarów i przycisków:
Private Sub TrackBar1_ValueChanged(sender As Object, e As EventArgs) Handles TrackBar1.ValueChanged
If (TrackBar1.Value + TrackBar2.Value) < dane.Count - 2 Then
tworz_wykres(TrackBar1.Value, TrackBar2.Value)
End If
End Sub
Private Sub TrackBar2_ValueChanged(sender As Object, e As EventArgs) Handles TrackBar2.ValueChanged
If (TrackBar1.Value + TrackBar2.Value) < dane.Count - 2 Then
tworz_wykres(TrackBar1.Value, TrackBar2.Value)
End If
End Sub
Private Sub lewy1_Click(sender As Object, e As EventArgs) Handles lewy1.Click
If (TrackBar1.Value + TrackBar2.Value) < dane.Count - 2 Then
If Not TrackBar1.Value = 0 Then
TrackBar1.Value -= 1
End If
Else
End If
End Sub
Private Sub prawy1_Click(sender As Object, e As EventArgs) Handles prawy1.Click
If (TrackBar1.Value + TrackBar2.Value) < dane.Count - 2 Then
If Not TrackBar1.Value = dane.Count - 2 Then
TrackBar1.Value += 1
End If
Else
End If
End Sub
Private Sub Lewy2_Click(sender As Object, e As EventArgs) Handles Lewy2.Click
If (TrackBar1.Value + TrackBar2.Value) < dane.Count - 2 Then
If Not TrackBar2.Value = dane.Count - 2 Then
TrackBar2.Value += 1
End If
Else
End If
End Sub
Private Sub prawy2_Click(sender As Object, e As EventArgs) Handles prawy2.Click
If (TrackBar1.Value + TrackBar2.Value) < dane.Count - 2 Then
If Not TrackBar2.Value = 0 Then
TrackBar2.Value -= 1
End If
Else
End If
End Sub
Po zbliżeniu nasz wykres będzie wyglądał tak:
No i ładnie. Jak zawsze dorzucam pliki do pobrania:
Projekt: Zblizanie_Wykresu
Dane wykorzystane w tutorialu: nowa
Jeśli ktoś jest zainteresowany tylko programem to proszę: Wykres interaktywny
Film prezentujący program :






