Překreslování grafu   zodpovězená otázka

VB.NET, Algoritmy, Grafika

Zdravím,

potýkám se s problémem při zobrazování grafu. Když mám aplikaci s jedním grafem (zobrazení jedné hodnoty) lze událostí paint zajistit jeho obnovování při změně na obrazovce. V jiné aplikaci zobrazuji tři hodnoty jako tři čáry drafu a obnovování událostí paint ne a ne fungovat. Zkratka kódu:

' při načtení formuláře(Form_Load)....
 TBitmap = New Bitmap(PictureBox1.Width, PictureBox1.Height)
        g = Graphics.FromImage(TBitmap)
        g.Clear(Color.Black)
.........
' zobrazení čáry grafu

g.draw.path(.....)

' zobrazení další čáry grafu

g1.draw.path(....)

'událost paint
  e.Graphics.DrawImage(TBitmap, 0, 0)

Tohle nechodí. Asi ta zkratka nebude moc srozumitelná, takže pokud bude potřeba pošlu ten kód celý.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Zkratka je opravdu hodně zkratkovitá, ale zeptal bych se alespoň na něco:

- máte g a TBitmap deklarováno jako globální proměnnou (abyste je viděl i v těch jiných částech programu)

- co je to g1 u té "další čáry grafu"?

g-čko je jasné, tam vykreslujete do obrázku (bitmapy) TBitmap, kterou pak v události Paint obnovujete na obrazovce, ale g1 kreslí kam? Logicky bych odhadoval, že by tam taky mělo být "g", ale z toho kousku programu to skutečně pouze hádám.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Díky za reakci,

přidávám celý kód na vykreslování několika grafů

  Private Sub Timer3_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer3.Tick        
        CG += 1                    
        
        g = PictureBox2.CreateGraphics               'graf teploty na kotli
        g.Clear(PictureBox2.BackColor)
        g.SmoothingMode = Drawing2D.SmoothingMode.AntiAlias 'vyhlazování křivky grafu
        y = (-1) * CInt((tepnakotli * 3))
        x = CG
        transX += -1                   
        g.TranslateTransform(transX, 330)
        If oldy = 0 Then
            oldx = x
            oldy = y
        End If
        plotX.AddLine(oldx, oldy, x, y)
        g.DrawPath(plotpenX, plotX)
        oldx = x
        oldy = y
        Dim gslou As Graphics                          'sloupec za grafem u stupnice  
        gslou = PictureBox2.CreateGraphics
        gslou.TranslateTransform(0, 330)
        gslou.DrawLine(sloupkot, 906, 0, 906, y)
       
        Dim g1 As Drawing.Graphics
        g1 = PictureBox2.CreateGraphics               'graf teploty v pokoji
        g1.SmoothingMode = Drawing2D.SmoothingMode.AntiAlias 'vyhlazování křivky grafu
        yf = -1 * CInt(tepvpok * 3)
        xe = CG
        transxe += -1                  
        If oldxe = 0 Then
            oldxe = xe
            oldyf = yf
        End If
        plotE.AddLine(oldxe, oldyf, xe, yf)
        g1.TranslateTransform(transxe, 330)
        g1.DrawPath(penpok, plotE)
        oldxe = xe
        oldyf = yf
        Dim sloupok As Graphics                          'sloupec za grafem u stupnice  
        sloupok = PictureBox2.CreateGraphics
        sloupok.TranslateTransform(0, 330)
        sloupok.DrawLine(slouppok, 904, 0, 904, yf)

        Dim g2 As Drawing.Graphics
        g2 = PictureBox2.CreateGraphics               'graf teploty venkovní
        yc = -1 * CInt(tepvenku * 3)
        xc = CG
        transxc += -1                
        If oldxc = 0 Then
            oldxc = xc
            oldyc = yc
        End If
        plotC.AddLine(oldxc, oldyc, xc, yc)
        g2.TranslateTransform(transxc, 330)
        g2.DrawPath(penven, plotC)
        oldxc = xc
        oldyc = yc
        Dim sloupven As Graphics                          'sloupec za grafem u stupnice  
        sloupven = PictureBox2.CreateGraphics
        sloupven.TranslateTransform(0, 330)
        sloupven.DrawLine(venslou, 902, 0, 902, yc)
        '  ***********************  horizont mřížka v grafu pětitupně ********************************
        Dim g3 As Graphics
        Dim i2 As Single
        g3 = PictureBox2.CreateGraphics
        mrizkot.DashStyle = Drawing2D.DashStyle.Dot
        For i2 = 15 To 390 Step 30
            g3.DrawLine(mrizkot, 0, i2, 906, i2)
        Next i2
        '  *********************** horizont mřížka v grafu desetistupně******************************
        Dim g4 As Graphics
        g4 = PictureBox2.CreateGraphics
        mrizka10.DashStyle = Drawing2D.DashStyle.Dot
        For i2 = 30 To 390 Step 30
            g4.DrawLine(mrizka10, 0, i2, 906, i2)
        Next i2
        ' ********************* *  SVISLÁ   mřížka v grafu *********************************
        Dim g5 As Graphics
        g5 = PictureBox2.CreateGraphics
        mrizka10.DashStyle = Drawing2D.DashStyle.Dot
        For i2 = 0 To 900 Step 60
            g5.DrawLine(mrizka10, i2, 0, i2, 900)
        Next i2
        

Je to tak, jak to používám. Jestli najdete co tam mam spatne uvítam radu. Případné dotazy rád zodpovím. Díky předem Jan

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Trochu jsem se na to koukal, a kreslí to spolehlivě. tedy tak, jak jsem si to upravil. je to totiž něco úplně jiného, než jste psal v dotaze.

Tam jste "graf" vykresloval do bitmapy a tu jste pak v události paint teprve kreslil do Pictureboxu. Takže netuším Vaše skutečné problémy.

Tak jak to máte (máte-li správná vstupní data a provedl-li jste si správné transformace), tak to kreslí do pictureboxu v taktu Timmeru3. Nevím, na jaký interval ho máte nastaven, ale bude se Vám to vykreslovat přesně v tomto intervalu (nebude-li moc krátký tak, aby to nestíhalo). Pokud ho budete mít ale třeba 5 s, musíte počítat s tím, že když okno třeba překryjete jiným a odkryjete, budete tam mít prázdno až do následujícího překreslovacího cyklu (třeba těch 5 s).

A tak, jak to máte navrženo, musíte počítat s tím, že Vám to bude v důsledku překreslování blikat a při rychlém opakování timeru se to nebude stačit vykreslovat celé.

nahlásit spamnahlásit spam 1 / 1 odpovědětodpovědět

Asi to píšu jako vožralej. To první taky platí. Picturebox se načte do bitmapy při otevření formuláře.Viz první kód. Proběhne timer to je ten druhý kód (interval 1 minuta, ) a když otevřu na obrazovku něco jiného např. kalkulačku smaže nakreslené grafy. To by měla ošetřit událost paint, která je tam taky, ale nechodí to.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Tak to už jsem z toho úplnej jelen.

"Picturebox se načte do bitmapy při otevření formuláře.Viz první kód"

Buď už nevidím, nebo si nerozumíme.

V tom prvním kódu nic nikam nenačítáte!:

' při načtení formuláře(Form_Load)....
 TBitmap = New Bitmap(PictureBox1.Width, PictureBox1.Height)
' právě jste založil novou bitmapu, která má stejné rozměry, jako PictureBox1
' nic víc, nic míň (bitmapa je prázdná a s pictureboxem mimo stejné rozměry nemá nic společného
        g = Graphics.FromImage(TBitmap)
' na obrázku jste si vytvořil "kreslicí tabuli", abyste naň mohl kreslit
        g.Clear(Color.Black)
' obrázek jste vyplnil černou barvou

Potom ale, z nepochopitelných důvodů, kreslíte přímo do Pictureboxu2:

Private Sub Timer3_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer3.Tick        
        CG += 1                    
        
        g = PictureBox2.CreateGraphics               'graf teploty na kotli
        g.Clear(PictureBox2.BackColor)
'...
'...
Dim g1 As Drawing.Graphics
        g1 = PictureBox2.CreateGraphics  
'...
'...

Vytvoříte si "tisíc" kreslicích tabulí na jednom a tom samém prvku ( PictureBox2! ), a kreslíte na něj.

Pak ale, z ničeho nic použijete

'událost paint
 e.Graphics.DrawImage(TBitmap, 0, 0)

, tedy, jestli předpokládám správně, jedná se o událost paint prvku PictureBox2.

Jinak řečeno, obsah PictureBoxu, který jste právě pracně pomaloval grafama, překreslíte obsahem prázdného (navíc černého) obrázku, protože do něj jste nic neuložil!

Jestli jsem tedy Váš kód pochopil správně, měl byste zkusit něco takového:

1) v události Form_load kód zachovat (pro jednoduchost g i TBitmap deklarovat jako globální proměnné)

2) v metodě Timer3_Tick nedeklarovat žádné galší kreslicí tabule (graphics), ale veškeré výstupy dělat výhradně na toto naše g (tj. nekreslit na PictureBox, ale do TBitmap)

3) jako poslední příkaz metody Timmer3_Tick (až máte vše vykreslené) zavolat metodu paint (Refresh-nout zobrazení)

4) V metodě paint controlu PictureBox2 ponechat to, co tam máte - tzn. vždy, když systém usoudí, že je nutné obsah PictureBoxu zaktualizovat a také vždy, když do grafů doplníte další změřený bod - se Vám na pictureBox vykreslí obrázek TBitmap, který v paměti průběžně doplňujete.

nahlásit spamnahlásit spam 1 / 1 odpovědětodpovědět

Díky to bude asi ono. Vyzkouším to.

Jan

nahlásit spamnahlásit spam 0 odpovědětodpovědět
                       
Nadpis:
Antispam: Komu se občas házejí perly?
Příspěvek bude publikován pod identitou   anonym.
  • Administrátoři si vyhrazují právo komentáře upravovat či mazat bez udání důvodu.
    Mazány budou zejména komentáře obsahující vulgarity nebo porušující pravidla publikování.
  • Pokud nejste zaregistrováni, Vaše IP adresa bude zveřejněna. Pokud s tímto nesouhlasíte, příspěvek neodesílejte.

přihlásit pomocí externího účtu

přihlásit pomocí jména a hesla

Uživatel:
Heslo:

zapomenuté heslo

 

založit nový uživatelský účet

zaregistrujte se

 
zavřít

Nahlásit spam

Opravdu chcete tento příspěvek nahlásit pro porušování pravidel fóra?

Nahlásit Zrušit

Chyba

zavřít

feedback