在C#中的特定点剪切图表

时间:2017-08-02 03:08:52

标签: c# charts

到目前为止,我的C#程序一直从COM门接收实时输入,并将其绘制在图表上,如下所示:

// DATA is the input from the COM gate, TIMESTAMP is the time the data is taken  
DataChart.Series["Data"].Points.AddXY(TIMESTAMP, DATA);
// Continue processing

我没有将数据保存到单独的数组或类中,因为它们相当大,导致我们的网站同名。
现在需要程序将两个时间点(称为StartTime和EndTime)之间的图表“切割”到另一个图表(称为CutChart)。由于我仍然不想长期保留它们,我试过这个:

foreach (Series series in DataChart.Series)
    foreach(DataPoint point in series.Points)
        if (point.XValue <= EndTime && point.XValue >= StartTime) 
            CutChart.Series[DataChart.Series.IndexOf(series)].Points.Add(point);

然而它不起作用(如在CutChart中,没有任何一点开始,因此在代码行运行时显示为空,仍然显示为空,没有记录错误或异常)。
奇怪的是,当我错误地在DataChart中添加点(Y轴上的TIMESTAMP而不是X)时,上面的代码行完美地工作。
我理解它的方式,绘制图形,C# Chart class必须保存每个点的XY坐标...某处。要生成一个新图形,它是两个时间点之间旧图形的一部分,只需将具有令人满意的X值的点添加到新图形中即可。除了我不知道那个“某个地方”在哪里 注意:我需要在新图表上绘制DataChart的“剪切”部分,因此只有zoom in还不够。

2 个答案:

答案 0 :(得分:0)

我已经成功测试了您的代码,因此问题很可能在其他地方。 我认为通过使用Datasource项目可以让您的生活更轻松,而不必自己操纵点和坐标。

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }

    private void Form1_Load(object sender, EventArgs e)
    {
        chart1.Series.Add("test");
        chart1.Series[0].ChartType = System.Windows.Forms.DataVisualization.Charting.SeriesChartType.Line;
        chart1.Series[0].Points.AddXY(1, 1);
        chart1.Series[0].Points.AddXY(2, 2);
        chart1.Series[0].Points.AddXY(3, 3);


        chart2.Series.Add("test2");
        chart2.Series[0].ChartType = System.Windows.Forms.DataVisualization.Charting.SeriesChartType.Line;
    }

    private void button1_Click(object sender, EventArgs e)
    {
        foreach (Series series in chart1.Series)
            foreach (DataPoint point in series.Points)
                if (point.XValue >= 2)
                    chart2.Series[chart1.Series.IndexOf(series)].Points.Add(point);
    }
}

编辑:使用数据源的意思是利用图表的绑定功能将数据与其表示分离,简而言之,不必每次都将所有数据点从一个图表复制到另一个图表。

例如:

        //this is just dummy data, see https://msdn.microsoft.com/en-us/library/system.windows.forms.datavisualization.charting.chart.datasource(v=vs.110).aspx
        List<Tuple<int, int>> data = new List<Tuple<int, int>>() { new Tuple<int, int>(1,1), new Tuple<int, int>(2,5) }; 

        //this code bind your data source to your chart
        chart1.DataSource = data;
        chart1.Series.Add("test");
        chart1.Series[0].ChartType = System.Windows.Forms.DataVisualization.Charting.SeriesChartType.Line;
        chart1.Series[0].XValueMember = "item1";
        chart1.Series[0].YValueMembers = "item2";
        chart1.DataBind();

        // now to create your "cut" chart you can simply query the data you want from the data source and use the same code as above to create another chart.
        var subdata = data.Where(x => x.Item1 > 1);

答案 1 :(得分:0)

你写了

  

奇怪的是,当我错误地在DataChart中添加点时(TIMESTAMP in   Y轴代替X),上面的代码行完美地工作。

这可能暗示问题出在数据类型上。

由于从DateTime变量输入了x值,因此可以得出结论,可以将它们与DateTime变量进行比较。

但内部所有值,x值和y值都存储为doubles

因此,您需要转换要与double进行比较时使用的任何日期:

var datetime1 = DateTime.Now;
var dDouble = datetime1.ToOADate();

还有来自双倍值的转换:

var datetime2 = DateTime.FromOADate(dDouble );

var datetime3 = DateTime.FromOADate(aDataPoint.XValue);

所以你的病情可以写成

if (point.XValue <= EndTime.ToOADate() && point.XValue >= StartTime.ToOADate()) 

但是转换只有一次更清晰,当然......:

double dStarttime = StartTime.ToOADate();
double dEndTime = EndTime.ToOADate();
..
..
if (point.XValue <= dEndTime  && point.XValue >= dStarttime ) 

Chart可能显示为空的其他原因是:

  • ChartArea。如果您在代码中创建图表,因为选择将其从工具箱中删除,它将没有ChartArea。
  • Points。无论你如何设置轴的样式,在出现任何东西之前仍然必须至少有一个虚拟点。