Tento příspěvek je překladem
originálního tutoriálu pro zobrazení dynamický dat. Nejedná se o doslovný překlad.
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;
}
}
}
}