2012-04-16 19 views
6

Quiero hacer ZedGraph wtih siguiente tabla dinámica: enter image description here ¿Cómo hacer ZedGraph ejes inversa y el tiempo y el eje? GraciasZedGraph gráfica personalizada

UPD 1: tengo que tratar con el siguiente código:

GraphPane myPane = zg1.GraphPane; 
      myPane.YAxis.Type = AxisType.Date; 
      myPane.YAxis.Scale.MajorUnit = DateUnit.Minute; 
      myPane.YAxis.Scale.MinorUnit = DateUnit.Second; 
      myPane.XAxis.IsVisible = false; 
      myPane.X2Axis.IsVisible = true; 
      myPane.X2Axis.MajorGrid.IsVisible = true; 
      myPane.X2Axis.Scale.Min = 0; 
      myPane.X2Axis.Scale.Max = 600; 
      myPane.YAxis.Scale.Format = "HH:mm:ss"; 
      PointPairList list = new PointPairList(); 
      PointPairList list2 = new PointPairList(); 
      for (int i = 0; i < 36; i++) 
      { 
       double x = (double)i * 5.0; 
       double y = (double)new XDate(DateTime.Now.AddSeconds(i)); 
       list.Add(y, x); 
       //list2.Add(y2, x); 
       listBox1.Items.Add("x = " + x + " y = " + y); 
      } 

      // Generate a red curve with diamond symbols, and "Alpha" in the legend 
      LineItem myCurve = myPane.AddCurve("Alpha", 
       list, Color.Red, SymbolType.None); 
      // Fill the symbols with white 
      myCurve.Symbol.Fill = new Fill(Color.White); 
         myPane.Y2Axis.MajorGrid.IsVisible = true; 
      // Align the Y2 axis labels so they are flush to the axis 
      myPane.Y2Axis.Scale.Align = AlignP.Inside; 

      // Fill the axis background with a gradient 
      myPane.Chart.Fill = new Fill(Color.White, Color.LightGray, 45.0f); 
      zg1.IsShowPointValues = true; 
      zg1.AxisChange(); 
      // Make sure the Graph gets redrawn 
      zg1.Invalidate(); 

Pero tomar algo mal: enter image description here

UPD2:

tengo código para multihilo:

private TimerCallback ReadTimerCallback; 
     private LineItem myCurve; 
     private Random rnd = new Random(500); 
     public Form1() 
     { 
      InitializeComponent(); 
     } 

     private void button1_Click(object sender, EventArgs e) 
     { 
      GraphPane myPane = zg1.GraphPane; 

      myPane.XAxis.IsVisible = false; 

      myPane.X2Axis.IsVisible = true; 
      myPane.X2Axis.MajorGrid.IsVisible = true; 
      myPane.X2Axis.Scale.Min = 0; 
      myPane.X2Axis.Scale.Max = 600; 

      myPane.YAxis.IsVisible = false; 

      myPane.Y2Axis.IsVisible = true; 
      myPane.Y2Axis.Scale.MajorUnit = DateUnit.Minute; 
      myPane.Y2Axis.Scale.MinorUnit = DateUnit.Second; 
      myPane.Y2Axis.Scale.Format = "HH:mm:ss"; 
      myPane.Y2Axis.Type = AxisType.DateAsOrdinal; 

      // As we get more data we want to add it on to the end of the curve 
      // and we also want to get the scale so that we can shift it along 
      double? oringinalLastDate; 
      XDate firstDate; 
      if (myPane.CurveList.Count == 0) 
      { 
       myCurve = myPane.AddCurve("Alpha", 
              new PointPairList(), 
              Color.Red, 
              SymbolType.None); 
       firstDate = new XDate(DateTime.Now); 
       oringinalLastDate = null; 
      } 
      else 
      { 
       myCurve = (LineItem)myPane.CurveList[0]; 
       firstDate = myCurve.Points[myCurve.Points.Count - 1].Y; 
       oringinalLastDate = myPane.Y2Axis.Scale.Max; 
      } 

      /*for (int i = 0; i < 36; i++) 
      { 
       double x = i * 5.0; 
       firstDate.AddSeconds(i); 

       myCurve.AddPoint(x, firstDate); 

       //listBox1.Items.Add("x = " + x + " y = " + firstDate); 
      }*/ 

      myCurve.Symbol.Fill = new Fill(Color.White); 
      myCurve.IsX2Axis = true; 
      myCurve.IsY2Axis = true; 
      //myPane.Y2Axis.Scale.IsReverse = true; 

      myPane.Chart.Fill = new Fill(Color.White, Color.LightGray, 45.0f); 
      zg1.IsShowPointValues = true; 

      // Now make the minimum of the scale, the maximum that it was so 
      // the graph shifts 
      if (oringinalLastDate.HasValue) 
       myPane.Y2Axis.Scale.Min = oringinalLastDate.Value; 

      zg1.AxisChange(); 
      zg1.Invalidate(); 
      AutoResetEvent ReadautoEvent = new AutoResetEvent(false); 
      ReadTimerCallback = new TimerCallback(this.ShowData); 
      System.Threading.Timer timer = new System.Threading.Timer(ReadTimerCallback, ReadautoEvent, 100, 1000); 

     } 

     private void ShowData (object Object) 
     { 
      this.myCurve.AddPoint(rnd.Next(500, 600), new XDate(DateTime.Now)); 
     } 

UPD3: Quiero bajar eje Y, no escala de este eje. Y he actualizado tabla a sólo 1 minuto: enter image description here

Respuesta

3

Creo que quieres DateAsOrdinal (en lugar de la fecha), para darle una mejor representación de fecha (aunque quizás no si está satisfecho con él) y que hay que configurar los IsX2Axis y las propiedades IsY2Axis en la curva en verdadero.

Aquí hay una versión actualizada de su código que muestra lo que quiero decir: ¿es esto lo que necesita? (No será una línea ondulada como la que dibujaste dado los valores de los datos y la escala del eje x comienza en 0 no 100 como en tu dibujo, pero eso es porque tu código lo configuró explícitamente en 0, así que estoy asumiendo que eso es lo que querer).

Siempre agregará más datos cada vez que se invoca (supongo que lo está llamando desde su botón1) y cambiará el valor mínimo para el eje, por lo que solo muestra el dato más reciente: si no establece el valor Mín, verá una línea tambaleante, ya que muestra todos los datos.

GraphPane myPane = zg1.GraphPane;    

myPane.XAxis.IsVisible = false; 

myPane.X2Axis.IsVisible = true; 
myPane.X2Axis.MajorGrid.IsVisible = true; 
myPane.X2Axis.Scale.Min = 0; 
myPane.X2Axis.Scale.Max = 600; 

myPane.YAxis.IsVisible = false; 

myPane.Y2Axis.IsVisible = true; 
myPane.Y2Axis.Scale.MajorUnit = DateUnit.Minute; 
myPane.Y2Axis.Scale.MinorUnit = DateUnit.Second; 
myPane.Y2Axis.Scale.Format = "HH:mm:ss"; 
myPane.Y2Axis.Type = AxisType.DateAsOrdinal; 

// As we get more data we want to add it on to the end of the curve 
// and we also want to get the scale so that we can shift it along 
double? oringinalLastDate; 
XDate firstDate; 
LineItem myCurve; 
if(myPane.CurveList.Count == 0) 
{ 
    myCurve = myPane.AddCurve("Alpha", 
           new PointPairList(), 
           Color.Red, 
           SymbolType.None); 
    firstDate = new XDate(DateTime.Now); 
    oringinalLastDate = null; 
} 
else 
{ 
    myCurve = (LineItem)myPane.CurveList[0]; 
    firstDate = myCurve.Points[myCurve.Points.Count - 1].Y; 
    oringinalLastDate = myPane.Y2Axis.Scale.Max; 
}    

for (int i = 0; i < 36; i++) 
{ 
    double x = i * 5.0; 
    firstDate.AddSeconds(i); 

    myCurve.AddPoint(x, firstDate); 

    listBox1.Items.Add("x = " + x + " y = " + firstDate); 
} 

myCurve.Symbol.Fill = new Fill(Color.White); 
myCurve.IsX2Axis = true; 
myCurve.IsY2Axis = true; 

myPane.Chart.Fill = new Fill(Color.White, Color.LightGray, 45.0f); 
zg1.IsShowPointValues = true; 

// Now make the minimum of the scale, the maximum that it was so 
// the graph shifts 
if (oringinalLastDate.HasValue) 
    myPane.Y2Axis.Scale.Min = oringinalLastDate.Value; 

zg1.AxisChange();    
zg1.Invalidate(); 

actualización

Si desea actualizar el gráfico de una vez por segundo con un número aleatorio entre 500 y 600 esto debe hacerlo (después se añaden cada 3 puntos, la escala en el eje Y se mueve):

private int pointCount; 
private double? scaleMin = null; 
private static readonly Random rnd = new Random(); 

private void button1_Click(object sender, EventArgs e) 
{ 
    GraphPane myPane = zg1.GraphPane; 

    myPane.XAxis.IsVisible = false; 

    myPane.X2Axis.IsVisible = true; 
    myPane.X2Axis.MajorGrid.IsVisible = true; 
    myPane.X2Axis.Scale.Min = 0; 
    myPane.X2Axis.Scale.Max = 600; 

    myPane.YAxis.IsVisible = false; 

    myPane.Y2Axis.IsVisible = true; 
    myPane.Y2Axis.Scale.MajorUnit = DateUnit.Minute; 
    myPane.Y2Axis.Scale.MinorUnit = DateUnit.Second; 
    myPane.Y2Axis.Scale.Format = "HH:mm:ss"; 
    myPane.Y2Axis.Type = AxisType.DateAsOrdinal; 

    LineItem myCurve = myPane.AddCurve("Alpha", 
            new PointPairList(), 
            Color.Red, 
            SymbolType.None); 

    myCurve.Symbol.Fill = new Fill(Color.White); 
    myCurve.IsX2Axis = true; 
    myCurve.IsY2Axis = true; 

    myPane.Chart.Fill = new Fill(Color.White, Color.LightGray, 45.0f); 
    zg1.IsShowPointValues = true; 

    pointCount = 0; 

    var t = new System.Windows.Forms.Timer(); 
    t.Interval = 1000; 
    t.Tick += ShowData; 

    Thread.Sleep(100); 

    t.Start(); 
} 

private void ShowData(object sender, EventArgs e) 
{ 
    var t = (System.Windows.Forms.Timer) sender; 
    t.Enabled = false; 

    pointCount++; 

    int x = rnd.Next(500, 600); 
    var y = new XDate(DateTime.Now); 

    GraphPane myPane = zg1.GraphPane; 

    if (scaleMin == null) scaleMin = myPane.Y2Axis.Scale.Max; 

    LineItem myCurve = (LineItem)myPane.CurveList[0];    

    myCurve.AddPoint(x, y); 

    // After 3 points are added move the scale along 
    if (pointCount > 3) 
    { 
     myPane.Y2Axis.Scale.Min = scaleMin.Value; 
     scaleMin = myPane.Y2Axis.Scale.Max; 
    } 

    zg1.AxisChange(); 
    zg1.Invalidate(); 

    t.Enabled = true; 
} 
+0

Gracias kmp! Esto es lo que necesito, pero quiero hacer que los ejes del tiempo estén en movimiento, para visualizar datos en tiempo real. ¿Cómo hacer esto? – amaranth

+0

He actualizado la respuesta - con suerte lo he entendido - los datos se agregan cada vez que se llama el código ahora y se ajusta el punto mínimo del eje para que pueda ver los últimos 35 segundos de datos. – kmp

+0

1. Debo agregar datos nuevos con myCurve.AddPoint (x, firstDate) y establecer el mínimo de escala en myPane.Y2Axis.Scale.Min = oringinalLastDate.Value? 2. ¿Puedo agregar puntos a myCurve desde otro hilo? – amaranth

Cuestiones relacionadas