Пользовательский график ZedGraph

Я хочу сделать wtih 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 ответов


Я думаю, вы хотите 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();

обновление

Если вы хотите обновить график после во-вторых, со случайным числом от 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;
}