Prosty dynamiczny wykres

0

Witam,
Chciałbym napisać program który pozwoli mi na narysowanie wykresu który jako wartości będzie pobierał dane z pliku i za każdym razem kiedy do pliku zostanie dopisana nowa wartość będzie ona dodawana do wykresu.

Jak na razie udało mi się zrobić program, który rysuje wykres z danych w pliku jednak nie rozbudowuje go o nowo dodane wartości.
Jak mogę tego dokonać?

oto kod mojego programu

namespace WindowsFormsApplication2
{
    
    public partial class Form1 : Form
    {
        string line;
        int counter = 0;
        System.IO.StreamReader file = new System.IO.StreamReader(@"C:\Documents and Settings\mgorynski\Pulpit\Adaptor Service Ver6.0\BasicClientsExe\BasicClientExeZapis\out.txt");

        public Form1()
        {
            InitializeComponent();
            

        }

        void rysuj()
        {
            while ((line = file.ReadLine()) != null)
            {
                this.chart1.Series["Dane"].Points.AddXY(counter, line);
                counter++;
            }
        }

        private void chart1_Click(object sender, EventArgs e)
        {            
        }
        private void button1_Click(object sender, EventArgs e)
        {
            rysuj();      
        }
    }
} 
1

Możesz co jakiś czas sprawdzać, czy data ostatniej modyfikacji pliku jest większa od tej kiedy ostatnio plik odczytywałeś. Jeżeli tak to wyczyść wykres i narysuj go od nowa, następnie zaktualizuj datę ostatniego odczytania pliku.

EDIT:
http://msdn.microsoft.com/en-us/library/system.io.filesystemwatcher.changed(v=vs.110).aspx
Lepiej zastosuj takie coś. System sam powie Ci kiedy plik się zmieni, wtedy wyczyść wykres i załaduj dane od nowa.

Chyba że masz pomysł na jakiś wykrywacz tego co się zmieniło, może wtedy nie będziesz musiał czyścić całego wykresu a tylko nałożyć zmiany, zależy od tego w jaki sposób te dane będą się zmieniać, bo jeżeli dochodzić będą tylko nowe punkty, to da się to łatwo zrobić (np, zapisać sobie ile linii było ostatnio, a ile jest teraz i te nowe dorysować)

0

Dane, będą dopisywane tylko na końcu pliku, każda liczba jest w oddzielnym wierszu. Miałem jednak niewiele do czynienia z c# i nie bardzo wiem jak sobie z tym poradzić

0

Najpierw weź ten przykład który jest na stronie którą podałem, skompiluj i zobacz jak działa. Jak już to ogarniesz, to minimalna znajomość angielskiego powinna wystarczyć, do tego żeby zastosować to u siebie. Zrób wersję z czyszczeniem całego wykresu i rysowaniem go od nowa. Jak to będzie działać, zobaczysz czy są potrzebne dalsze poprawki.

0

dzięki, udało mi się to zrobić, jednak mam kolejny problem, funkcja rysuj() uruchamia się po kliknięciu buttona tylko raz a chciałbym żeby wykonywała się wiele razy np co sekundę, próbowałem zamknąć ją w pętli while i użyć Thread.Sleep jednak to nie pomogło. W jaki sposób można coś takiego zrealizować?

 

namespace WindowsFormsApplication2
{
    
    public partial class Form1 : Form
    {
        
        int ileLini = File.ReadAllLines(@"C:\out.txt").Length;
        int ileLini2;

        public Form1()
        {
            InitializeComponent();           
        }

        int counter = 1;
        string [] line = File.ReadAllLines(@"C:\out.txt");

        void rysuj()
        {
            for (int i = counter;  i < ileLini; i++)
            {
                counter = i;
                this.chart1.Series["Dane"].Points.AddXY(counter, line[i]);
                ileLini2 = File.ReadAllLines(@"C:\out.txt").Length;
                if (ileLini2 > ileLini)
                {
                    ileLini = ileLini2;
                    line = File.ReadAllLines(@"C:\out.txt");
                }

            }
        }



        private void chart1_Click(object sender, EventArgs e)
        {
            
        }

        private void button1_Click(object sender, EventArgs e)
        {

                rysuj();
            
        }

        private void button2_Click(object sender, EventArgs e)
        {
        }
    }
}

0

Dobra poprawka, ale to jest ta mniej ważna część. W pierwszym swoim poście podałem link do FileSystemWatcher. Co on robi? Jak sama nazwa wskazuje, obserwuje plik. To znaczy, że jeżeli plik się zmieni, to program się o tym dowie i wywoła funkcję OnChanged. Żeby to się jednak stało najpierw musisz stworzyć obiekt tego watchera. Stwórz sobie nową funkcję

private void runWatcher(string fileName)
{
    FileSystemWatcher watcher = new FileSystemWatcher();
    watcher.Path = fileName;
    watcher.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite | NotifyFilters.FileName | NotifyFilters.DirectoryName; //nie wiem do końca jak to działa ale powinno być ok :P
//Prawodpodobnie FileName i DirectoryName mozesz usunac
    watcher.Filter = "*.txt"; //To CHYBA też
   
    // event handler.
    watcher.Changed += new FileSystemEventHandler(OnChanged);
    watcher.EnableRaisingEvents = true;
}

private static void OnChanged(object source, FileSystemEventArgs e)
{
    rysuj();
}

Do tego funkcję runWatcher odpal w swojej funkcji Form1.
Nie mam tego teraz jak sprawdzić, napisałem komentarze tam gdzie mam wątpliwości.

0

jednak wolałbym zostać przy swojej metodzie bo działa poprawnie, jednak nie wiem jak zrealizować to żeby uruchamiała się wiele razy w pętli, z tego co wiem to powinienem zastosować wątki jednak nie bardzo wiem jak to zrobić

0

Spróbuj z kontrolką Timer. We właściwości interval podajesz co ile milisekund ma się wykonać zdarzenie Tick (chyba tak się to nazywało).

1 użytkowników online, w tym zalogowanych: 0, gości: 1