我有一个C#图表问题。
这是使用System.Windows.Forms.DataVisualization.Charting
我的系列配置为索引:
{
Name = name,
Color = color,
IsVisibleInLegend = false,
IsXValueIndexed = true,
ChartType =
System.Windows.Forms.DataVisualization.Charting.SeriesChartType.FastLine
};
我在此图表中有3个系列
我通过事件处理程序
向系列添加数据for (int i = 0; i < samples; i++)
{
double time_point = DData[i * 4]
chart1.Series[0].Points[lastSample + i].XValue = time_point;
chart1.Series[0].Points[lastSample + i].YValues[0] = DData[i * 4 + 1];
chart1.Series[1].Points[lastSample + i].XValue = time_point;
chart1.Series[1].Points[lastSample + i].YValues[0] = DData[i * 4 + 2];
chart1.Series[2].Points[lastSample + i].XValue = time_point;
chart1.Series[2].Points[lastSample + i].YValues[0] = DData[i * 4 + 3];
}
lastSample = (lastSample + samples) % maxPlotPoints;
chart1.Invalidate();
问题如下:
接下来,我理解当每个系列对于相同的Point []位置具有不同的X值时会发生这种情况。但我明确地将所有3个系列设置为使用相同的time_point
我的下一个假设是事件处理程序在前一个线程完成之前执行了脚步。
所以我在图表调用周围添加了一个锁,它没有帮助
private Object thisLock = new Object();
lock (thisLock)
{
}
我的问题是:
有没有人知道是否还有其他原因造成这种情况?
是否可以仅使用图表第一个系列的X索引,但同时显示所有3个系列?
答案 0 :(得分:0)
TaW上面的评论帮助我解决了这个问题。
这似乎是微软图表的问题
我最初虽然它是由于EventHandler在它完成之前多次触发,但我选择使用一个Queh,它将填充一个EventHandler并在一个单独的线程上出列。
问题仍然存在。
问题的解决方案是简单地将IsXValueIndexed设置为 false 然后在绘制图表之前将其设置为 true
以下是使用的代码
如果有人想知道这是做什么的: 它随着时间的增加在图表上同时绘制3个值。 图表从左到右更新而不是滚动(想想医院中的EKG机器) 有一个固定的总点数设置为 maxPlotPoints EventHandler接收一些包含一定数量点= samplePoints 的数据包(此处构成)。 它构造一个 DataPoints 结构并将其添加到队列
一个单独的线程 MainTask 将一个元素从DataPoints中取出,并使用它来填充三个系列中每个元素的100个点。然后该部分增加到下一个100点,依此类推。
如果您想连续绘制固定数量的点数
,这非常有用不幸的是,我似乎无法将TaW上面的答案标记为正确,因为它在评论中。但如果您能解释如何做到这一点,我会很乐意尝试。感谢
private struct DataPoint
{
public double timePoint;
public double X;
public double Y;
public double Z;
}
private struct DataPoints
{
public DataPoints(int samples)
{
dataPoints = new DataPoint[samples];
}
public DataPoint[] dataPoints;
}
Queue queue = new Queue();
int lastSample = 0;
static int maxPlotPoints = 1000;
static int samplePoints = 100;
public ChartForm(UdpMgrControl RefUdpMgr, byte GyroChartNum, string ConfigFile)
{
for ( Row = 0; Row < 3; Row++)
{
var series1 = new System.Windows.Forms.DataVisualization.Charting.Series
{
Name = name,
Color = Color.Blue,
IsVisibleInLegend = false,
IsXValueIndexed = true,
ChartType = System.Windows.Forms.DataVisualization.Charting.SeriesChartType.FastLine
};
//Fill in chart with blank points
for (int i = 0; i < maxPlotPoints; i++)
{
series1.Points.AddY(0);
}
chart1.Series.Add(series1);
}
chart1.Series[0].Enabled = true;
chart1.Series[1].Enabled = true;
chart1.Series[2].Enabled = true;
running = true;
Thread main_thread = new Thread(new ThreadStart(this.MainTask));
}
private void OutputHandler(byte[] DData)
{
if (running)
{
DataPoints data_element = new DataPoints(samplePoints);
for (int i = 0; i < samplePoints; i++)
{
data_element.dataPoints[i].X = DData[i].X;
data_element.dataPoints[i].Y = DData[i].Y;
data_element.dataPoints[i].Z = DData[i].Z;
data_element.dataPoints[i].timePoint = DData[i].timePoint;
}
queue.Enqueue(data_element);
}
}
private void MainTask()
{
while (running)
{
try
{
if (queue.Count > 0)
{
chart1.Series[0].IsXValueIndexed = false;
chart1.Series[1].IsXValueIndexed = false;
chart1.Series[2].IsXValueIndexed = false;
DataPoints data_element = (DataPoints)queue.Dequeue();
for (int i = 0; i < data_element.dataPoints.Length; i++)
{
chart1.Series[0].Points[lastSample + i].XValue = data_element.dataPoints[i].timePoint;
chart1.Series[0].Points[lastSample + i].YValues[0] = data_element.dataPoints[i].X;
chart1.Series[1].Points[lastSample + i].XValue = data_element.dataPoints[i].timePoint;
chart1.Series[1].Points[lastSample + i].YValues[0] = data_element.dataPoints[i].Y;
chart1.Series[2].Points[lastSample + i].XValue = data_element.dataPoints[i].timePoint;
chart1.Series[2].Points[lastSample + i].YValues[0] = data_element.dataPoints[i].Z;
}
//Adjust the next location to end of first
lastSample = (lastSample + samples) % maxPlotPoints;
chart1.Series[0].IsXValueIndexed = true;
chart1.Series[1].IsXValueIndexed = true;
chart1.Series[2].IsXValueIndexed = true;
GC_UpdateDataGrids();
chart1.Invalidate();
}
else
{
Thread.Sleep(10);
}
}
catch (Exception error)
{
LogErrors.AddErrorMsg(error.ToString());
}
}
}