问题描述
好的,这可能很难解释.我有一种方法可以计算要绘制的X和Y值.此方法纯属后端,可在从主GUI线程调用的backgroundworker中运行.
Ok, this could be a little tough to explain. I have a method that computes X and Y values that I want to plot. This method is purely backend and runs inside a backgroundworker called from my main GUI thread.
与我的主表单分开,我有一个仅包含zedgraph和代码的表单.我使用组合显示从后台线程吐出的滚动X,Y.一切正常,在这里一切都很好.
Separate from my main form I have a form that contains only a zedgraph and a ticker. I use the combination to display the rolling X,Y spit out from my background thread. This works fine, everything goes great here.
当我单击主GUI上的按钮时,背景工作人员将关闭,并且zedgraph停止更新.这是我的问题开始的地方
When I click a button on my main GUI the backgroundworker is closed, and zedgraph stops updating. Here's where my problem starts
当我单击停止按钮时,图形需要保持向上.它做得很好……如果这是它第一次运行.在所有将来的图形上都会发生这种情况:(顶部图像是第一个图形,第二个图像是第二个图形.)
When I click the stop button the graph needs to stay up. It does this just fine... iff it's the very first time it was run. On all future graphs this happens: (Top image is the first graph, second image is the second graph.)
第一个图在不应该更新时会不断更新.如何避免这种情况发生?有没有办法关闭"第一个zedgraph并阻止其监听新数据?
The first graph keeps updating when it isn't supposed to. How do I keep this from happening? Is there a way to "shut down" the first zedgraph and keep it from listening for new data?
下面是我的zedgraph代码,我很确定问题出在这里,而不是我的主要GUI代码.
Below is my zedgraph code, I'm pretty sure the problem is in here somewhere and not my main GUI code.
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
函数中使用断点来验证这一点.
The last point is connected to the first point in the graph. I suspect, because all your RollingPointPairList
contains the data multiple times. Verify this using a breakpoint in your timer1_Tick
function.
在private void Form1_Load
上,您会将完整列表添加到LineItem
.
On private void Form1_Load
you will add the complete list to the 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);
这篇关于带zedgraphs的多种形式.下一条开始时,一条线继续的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!