ZedGraph自定义图表

时间:2012-04-16 09:55:17

标签: c# charts customization zedgraph

我想用动态图表制作ZedGraph: enter image description here 如何使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

1 个答案:

答案 0 :(得分:3)

我认为您需要DateAsOrdinal(而不是Date),以便为您提供更好的日期表示(如果您对此感到满意,可能不会),并且您需要将曲线上的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();

<强>更新

如果您希望每秒更新一次图表,并且随机数在500到600之间,则应该这样做(在每增加3个点之后,y轴上的比例移动):

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;
}