ZedGraphControl může zobrazovat statická nebo dynamická data. Pokud chcete dynamicky zobrazovat data, pokaždé, když chcete přidat grafu nová data, musíte provést následující:
- V kolekci GraphPane.CurveList najít křivku (tedy objekt typu CurveItem), do které chcete přidat data.
- Přistoupit k PointPairList (nebo jinému objektu, který implementuje rozhraní IPointListEdit) příslůšné křivky a přidat nová data.
- Zavolat metodu ZedGraphControl.AxisChange(), aby se přepočítaly rozsahy os.
- Zavolat metodu Form.Invalidate() pro update grafu.
Následující příklad obsahuje veškerý kód, kromě kódu vygenerovaného automaticky Visual Studiem. Obsahuje dvě hlavní metody:
- Form_Load(), která provede inicializaci grafu s jednou křivkou, která zatím neobsahuje žádné body.
- Timer_Tick(), která obsluhuje událost tiknutí časovače (timer), a přidá nová data
Graf zobrazuje základní sinusovou křivku, na kterou je každých 50 milisekund přidán nový bod. Po spuštění aplikace počkejte 25 vteřin, abyste viděli posunující se dynamická data.
V kódu je použita kolekce RollingPointPairList, která je speciální implementací IPointListEdit rozhraní. Tato kolekce udržuje stále stejný počet bodů tím, že stará data přemazává novými.
Metoda Timer_Tick() nejdříve najde naši křivku. V tomto případě zde je pouze jedna, proto jednoduše vezmeme první křivku s indexem nula (GraphPane.CurveList[0]). Potom vezmeme referenci na CurveItem.Points a přetypujeme na typ IPointListEdit. Pokud je výsledkem přetypování null, víme, že třída s daty neimplementuje rozhraní IPointListEdit, takže ji nemůžeme použít.
Ve chvíli, kdy přidáme nový bod, zařídíme, aby osa X měla vždy rozsah 30 vteřin. Minimum, maximum a velikost kroku nastavujeme ručně, takže se rozsah pohybuje s každým přidaným bodem. Stále voláme metodu AxisChange(), abychom přizpůsobyli osu Y hodnotám (AxisChange() zaručí, že se hodnoty "vlezou" na osu - tedy že budou ve viditelném rozsahu ). Invalidate() voláme, abychom se přesvědčili, že se graf překreslí.
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; using ZedGraph; namespace DynamicData { public partial class Form1 : Form { // počáteční čas v milisekundách int tickStart = 0; public Form1() { InitializeComponent(); } private void Form1_Load( object sender, EventArgs e ) { GraphPane myPane = zedGraphControl1.GraphPane; myPane.Title.Text = "Test dynamických dat s komponentou ZedGraph\n" + "(Graf začne skrolovat po 25 vteřinách)"; myPane.XAxis.Title.Text = "Čas (s)"; myPane.YAxis.Title.Text = "Napětí (V)"; // Uloží 1200 bodů. Každý po 50 ms, což dává jednu minutu. // RollingPointPairList je efektivní třída pro ukládání dat grafu, // která udržuje sadu rolujících dat, takže není potřeba přesunovat žádné hodnoty RollingPointPairList list = new RollingPointPairList( 1200 ); // Při inicializaci je přidána jedna křivka bez žádných dat // Barva křivky je modrá a body nemají žádný symbol LineItem curve = myPane.AddCurve( "Napětí", list, Color.Blue, SymbolType.None ); // Jeden vzorek po 50 ms timer1.Interval = 50; timer1.Enabled = true; timer1.Start(); // Ručně nastavíme rozsah osy X, takže může průběžně skrolovat, // namísto diskrétních krokových skoků myPane.XAxis.Scale.Min = 0; myPane.XAxis.Scale.Max = 30; myPane.XAxis.Scale.MinorStep = 1; myPane.XAxis.Scale.MajorStep = 5; // Přepočítáme osy zedGraphControl1.AxisChange(); // Uložíme si počáteční čas tickStart = Environment.TickCount; } private void timer1_Tick( object sender, EventArgs e ) { // Ujistíme se, že v seznamu křivek máme alespoň jednu if ( zedGraphControl1.GraphPane.CurveList.Count <= 0 ) return; // Vezmeme první křivku v seznamu LineItem curve = zedGraphControl1.GraphPane.CurveList[0] as LineItem; if ( curve == null ) return; // Vezmeme PointPairList IPointListEdit list = curve.Points as IPointListEdit; // Pokud je list null, znamená to, že reference na curve.Points // nepodporuje
IPointListEdit, takže jej nebudeme moct modifikovat
if ( list == null ) return; // Čas měříme ve vteřinách double time = (Environment.TickCount - tickStart) / 1000.0; // 3 vteřiny na jeden cyklus list.Add( time, Math.Sin( 2.0 * Math.PI * time / 3.0 ) ); // Rozsah osy X roluje v intervalu 30 vteřin // s jedním hlavním krokem mezi hodnoutou max osy X a koncem osy Scale xScale = zedGraphControl1.GraphPane.XAxis.Scale; if ( time > xScale.Max - xScale.MajorStep ) { xScale.Max = time + xScale.MajorStep; xScale.Min = xScale.Max - 30.0; } // Zde přepočítáme rozsah osy Y podle zobrazených dat zedGraphControl1.AxisChange(); // Žádost o překreslení zedGraphControl1.Invalidate(); } private void Form1_Resize( object sender, EventArgs e ) { SetSize(); } // Nastavíme velikost a umístění ZedGraphControlu private void SetSize() { // Control je vždy 10 pixelů od klienteského obdelníku formu Rectangle formRect = this.ClientRectangle; formRect.Inflate( -10, -10 ); if ( zedGraphControl1.Size != formRect.Size ) { zedGraphControl1.Location = formRect.Location; zedGraphControl1.Size = formRect.Size; } } }
}
Žádné komentáře:
Okomentovat