c# - 带有 zedgraphs 的多种形式。当下一个开始时,一个上的行继续

标签 c# multithreading visual-studio zedgraph

好吧,这可能有点难以解释。我有一种方法可以计算我想要绘制的 X 和 Y 值。此方法是纯后端方法,在从我的主 GUI 线程调用的后台工作程序中运行。

与我的主窗体分开,我有一个仅包含一个 zedgraph 和一个代码的窗体。我使用组合来显示从我的后台线程吐出的滚动 X、Y。这工作正常,这里一切顺利。

当我单击主 GUI 上的按钮时,后台工作程序关闭,zedgraph 停止更新。这是我的问题开始的地方

当我点击停止按钮时,图表需要保持不变。它做得很好......如果它是第一次运行。在所有 future 的图表上都会发生这种情况:(顶部图像是第一张图,第二张图像是第二张图。)

graph wit connected first and last point

第一个图表在不应该的时候不断更新。我如何防止这种情况发生?有没有办法“关闭”第一个 zedgraph 并阻止它监听新数据?

下面是我的 zedgraph 代码,我很确定问题出在此处,而不是我的主要 GUI 代码。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using ZedGraph;

namespace RTHERM
{
    public partial class Readout : Form
    {
        // Starting time in milliseconds
        public static float Time_old = 0.0f;
        public static float Tsurf_old;
        public static float Tmidr_old;
        public static float Tcent_old;
        public static float Tenvi_old;

        //  Every "redrawInterval" secods plot a new point (if one is available)
        public static int redrawInterval;
        public int plotRange = 15;      //   Plot will span "plotRange" minutes


        int tickStart = 0;

        public Readout()
        {
            InitializeComponent();
        }


        private void Form1_Load(object sender, EventArgs e)
        {
            //timer1.Equals(0);
            GUI gui = new GUI();
            GraphPane graph = zedGraph.GraphPane;
            graph.Title.Text = GUI.plotTitle;
            graph.XAxis.Title.Text = "Time [min]";
            graph.YAxis.Title.Text = "Temperature [F]";

            graph.Legend.Position = ZedGraph.LegendPos.BottomCenter;
            // Save 1200 points.  At 50 ms sample rate, this is one minute
            // The RollingPointPairList is an efficient storage class that always
            // keeps a rolling set of point data without needing to shift any data values
            RollingPointPairList surfList = new RollingPointPairList(1200);
            //surfList.Clear();
            RollingPointPairList midrList = new RollingPointPairList(1200);
            //midrList.Clear();
            RollingPointPairList centList = new RollingPointPairList(1200);
            //centList.Clear();
            RollingPointPairList furnList = new RollingPointPairList(1200);
            //furnList.Clear();
            // Initially, a curve is added with no data points (list is empty)
            // Color is blue, and there will be no symbols
            LineItem surf = graph.AddCurve("Surface", surfList, Color.DarkBlue, SymbolType.None);
            LineItem midr = graph.AddCurve("Mid-Radius", midrList, Color.DarkOliveGreen, SymbolType.None);
            LineItem cent = graph.AddCurve("Center", centList, Color.DarkOrange, SymbolType.None);
            LineItem furn = graph.AddCurve("Ambient", furnList, Color.Red, SymbolType.None);
            surf.Line.Width = 2;
            midr.Line.Width = 2;
            cent.Line.Width = 2;
            furn.Line.Width = 2;

            // Check for new data points
            timer1.Interval = redrawInterval;
            timer1.Enabled = true;
            //timer1.Start();

            // Just manually control the X axis range so it scrolls continuously
            // instead of discrete step-sized jumps
            graph.XAxis.Scale.Min = 0;
            graph.XAxis.Scale.Max = plotRange;
            graph.XAxis.Scale.MinorStep = 1;
            graph.XAxis.Scale.MajorStep = 5;

            // Scale the axes
            zedGraph.AxisChange();

            // Save the beginning time for reference
            tickStart = Environment.TickCount;
        }

        //  USING A TIMER OBJECT TO UPDATE EVERY FEW MILISECONDS
        private void timer1_Tick(object sender, EventArgs e)
        {
            // Only redraw if we have new information
            if (Transfer.TTIME != Time_old)
            {
                GraphPane graph = this.zedGraph.GraphPane;
                // Make sure that the curvelist has at least one curve
                if (zedGraph.GraphPane.CurveList.Count <= 0)
                    return;

                // Grab the three lineitems
                LineItem surf = this.zedGraph.GraphPane.CurveList[0] as LineItem;
                LineItem midr = this.zedGraph.GraphPane.CurveList[1] as LineItem;
                LineItem cent = this.zedGraph.GraphPane.CurveList[2] as LineItem;
                LineItem furn = this.zedGraph.GraphPane.CurveList[3] as LineItem;

                if (surf == null)
                    return;

                // Get the PointPairList
                IPointListEdit surfList = surf.Points as IPointListEdit;
                IPointListEdit midrList = midr.Points as IPointListEdit;
                IPointListEdit centList = cent.Points as IPointListEdit;
                IPointListEdit enviList = furn.Points as IPointListEdit;

                // If these are null, it means the reference at .Points does not
                // support IPointListEdit, so we won't be able to modify it
                if (surfList == null || midrList == null || centList == null || enviList == null)
                    return;

                // Time is measured in seconds
                double time = (Environment.TickCount - tickStart) / 1000.0;

                // ADDING THE NEW DATA POINTS
                // format is List.Add(X,Y)  Finally something that makes sense!
                surfList.Add(Transfer.TTIME, Transfer.TSURF);
                midrList.Add(Transfer.TTIME, Transfer.TMIDR);
                centList.Add(Transfer.TTIME, Transfer.TCENT);
                enviList.Add(Transfer.TTIME, Transfer.TENVI);

                // Keep the X scale at a rolling 10 minute interval, with one
                // major step between the max X value and the end of the axis
                if (GUI.isRunning)
                {
                    Scale xScale = zedGraph.GraphPane.XAxis.Scale;
                    if (Transfer.TTIME > xScale.Max - xScale.MajorStep)
                    {
                        xScale.Max = Transfer.TTIME + xScale.MajorStep;
                        xScale.Min = xScale.Max - plotRange;
                    }
                }
                // Make sure the Y axis is rescaled to accommodate actual data
                zedGraph.AxisChange();
                // Force a redraw
                zedGraph.Invalidate();
            }
            else return;
        }

        public void reset()
        {
            Time_old = 0.0f;
            Tsurf_old = 0.0f;
            Tmidr_old = 0.0f;
            Tcent_old = 0.0f;
            Tenvi_old = 0.0f;
        }
        private void Form1_Resize(object sender, EventArgs e)
        {
            if (GUI.isRunning)
            {
                SetSize();
            }
        }

        // Set the size and location of the ZedGraphControl
        private void SetSize()
        {
            // Control is always 10 pixels inset from the client rectangle of the form
            Rectangle formRect = this.ClientRectangle;
            formRect.Inflate(-10, -10);

            if (zedGraph.Size != formRect.Size)
            {
                zedGraph.Location = formRect.Location;
                zedGraph.Size = formRect.Size;
            }
        }

        private void saveGraph_Click(object sender, EventArgs e)
        {
            GUI.Pause();
            zedGraph.DoPrint();
            //SaveFileDialog saveDialog = new SaveFileDialog();
            //saveDialog.ShowDialog();
        }

        private void savePlotDialog_FileOk(object sender, CancelEventArgs e)
        {
            // Get file name.
            string name = savePlotDialog.FileName;
            zedGraph.MasterPane.GetImage().Save(name);
            GUI.Resume();
        }

        private bool zedGraphControl1_MouseMoveEvent(ZedGraphControl sender, MouseEventArgs e)
        {
            // Save the mouse location
            PointF mousePt = new PointF(e.X, e.Y);

            // Find the Chart rect that contains the current mouse location
            GraphPane pane = sender.MasterPane.FindChartRect(mousePt);

            // If pane is non-null, we have a valid location.  Otherwise, the mouse is not
            // within any chart rect.
            if (pane != null)
            {
                double x, y;
                // Convert the mouse location to X, and Y scale values
                pane.ReverseTransform(mousePt, out x, out y);
                // Format the status label text
                toolStripStatusXY.Text = "(" + x.ToString("f2") + ", " + y.ToString("f2") + ")";
            }
            else
                // If there is no valid data, then clear the status label text
                toolStripStatusXY.Text = string.Empty;

            // Return false to indicate we have not processed the MouseMoveEvent
            // ZedGraphControl should still go ahead and handle it
            return false;
        }

        private void Readout_FormClosed(object sender, FormClosedEventArgs e)
        {

        }

        private void Readout_FormClosing(object sender, FormClosingEventArgs e)
        {
            //e.Cancel = true;
            //WindowState = FormWindowState.Minimized;
        }
    }
}

最佳答案

最后一个点连接到图中的第一个点。我怀疑,因为您所有的 RollingPointPairList 都多次包含数据。使用 timer1_Tick 函数中的断点验证这一点。

private void Form1_Load 上,您将把完整列表添加到 LineItem

graph.CurveList.Clear();
LineItem surf = graph.AddCurve("Surface", surfList, Color.DarkBlue, SymbolType.None);
LineItem midr = graph.AddCurve("Mid-Radius", midrList, Color.DarkOliveGreen, SymbolType.None);
LineItem cent = graph.AddCurve("Center", centList, Color.DarkOrange, SymbolType.None);
LineItem furn = graph.AddCurve("Ambient", furnList, Color.Red, SymbolType.None);

关于c# - 带有 zedgraphs 的多种形式。当下一个开始时,一个上的行继续,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18037921/

相关文章:

c# - Context.User.Identity.Name 在 MVC 4 中返回 null

python - 从另一个线程或进程更新 Gtk.ProgressBar

visual-studio - 禁用特定项目的代码分析规则

visual-studio - Web 部署不再有效

c# - 从月份数组中获取一系列值

c# - 用于 C# 应用程序的图形拖放式设计器库?

c# - 如何在DataGridTextColumn中获取文本像素大小

java - 生产者/消费者线程不给出结果

c++ 11 - 将成员函数传递给线程给出 : no overloaded function takes 2 arguments

c++ - 更改 DEF 文件中的函数签名