2012-04-16 4 views
6

동적 인 차트를 사용하여 ZedGraph를 만들고 싶습니다 : enter image description here ZedGraph 축을 역방향 및 시간 축으로 만드는 방법은 무엇입니까? 감사합니다ZedGraph 커스텀 그래프

UPD 1 : 나는 다음 코드를 시도해야 :

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(); 

하지만 뭔가 잘못 걸릴 :

내가 코드를 가지고 : enter image description here

UPD2을 멀티 스레딩 :

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 : 이 축의 축척을 조정하지 않고 Y 축 아래로 이동하려고합니다. 내가 업데이트 한 차트 1 분 : enter image description here

답변

3

난 당신이 DateAsOrdinal을 할 생각은 (대신 날짜), 더 나은 날짜 표현을 제공하는 (당신이 그것을 만족 아닐 경우하지만) 당신은 IsX2Axis를 설정해야 곡선의 IsY2Axis 속성이 true로 설정됩니다.

다음은 내가 원하는 것을 보여주는 코드의 업데이트 된 버전입니다. 필요한 것이 무엇입니까? (데이터 값이 주어지면 그려지는 물결 모양의 선이 아니며 x 축척은 도면에서와 같이 0이 아닌 100에서 시작하지만 코드는 명시 적으로 0으로 설정 되었기 때문에 그 점을 가정합니다. 필요).

호출 할 때마다 더 많은 데이터가 추가됩니다 (사용자가 button1에서 호출한다고 가정 할 때). 축의 최소값을 따라 이동하므로 가장 최근 데이터 비트 만 표시합니다. 최소값을 설정하지 않으면 모든 데이터가 표시 될 때 흔들린 선이 표시됩니다.

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(); 

업데이트

에서는 y 축이 그것을해야 500과 600 사이의 임의의 숫자 (각 3 점을 추가 한 후, 규모에 한 번 두 번째 차트를 업데이트하려면 이동) :

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

감사합니다. 이것이 내가 원하는 것이지만, 실시간 데이터를 시각화하기 위해 시간 축을 만들고 싶습니다. 이걸 만드는 방법? – amaranth

+0

답변을 업데이트했습니다. 코드를 호출 할 때마다 데이터가 추가되고 최소 축 점이 조정되므로 마지막 35 초의 데이터가 표시됩니다. – kmp

+0

1. myCurve.AddPoint (x, firstDate)와 함께 새 데이터를 추가하고 myPane.Y2Axis.Scale.Min = oringinalLastDate.Value로 최소 배율을 설정해야합니까? 2. 다른 스레드에서 myCurve에 포인트를 추가 할 수 있습니까? – amaranth