C#图表-多个曲线但颜色被覆盖

时间:2018-07-11 12:19:29

标签: c# winforms

所以我在图表中显示了多条曲线。但是,当我生成随机颜色时,所有其他曲线也将获得该颜色。

int fileIndex=0;
Random r = new Random();
foreach (var i in graphContainer)
{
    fileIndex++;
    var series = new Series
    {
        Name                = legendNames[fileIndex],
        Color               = Color.FromArgb(r.Next(0, 256), r.Next(0, 256), r.Next(0, 256)),
        IsVisibleInLegend   = true,
        IsXValueIndexed     = false,
        ChartType           = SeriesChartType.Line
    };
    foreach (var j in i)
    {
        series.Points.AddXY (j.Item2, j.Item1);
    }
    chart.Invalidate        ();
    chart.Series.Add        (series);
}

注意:除一条曲线外,所有曲线都具有相同的值,但是您可以理解。 enter image description here

为什么我的曲线颜色相同?

整个功能:

    private void generateWaveformsFromFileBtn_Click(object sender, EventArgs e)
    {
        int fileIndex                       = -1;
        string folder                       = Path.GetDirectoryName(Process.GetCurrentProcess().MainModule.FileName) + @"\WaveForms\";
        string filter                       = "*.csv";
        string[] filePath                   = Directory.GetFiles(folder, filter);
        List<string> legendNames            = new List<string>();
        List<Tuple<double, double>> graph   = new List<Tuple<double, double>>();
        List<List<Tuple<double, double>>> graphContainer = new List<List<Tuple<double, double>>>();
        chart.Series.Clear();
        foreach(var fileName in filePath) {
            legendNames.Add(Path.GetFileName(fileName));
            using (TextFieldParser csvParser = new TextFieldParser(fileName))
            {
                csvParser.SetDelimiters (new string[] { ";" });
                csvParser.ReadLine      ();
                while (!csvParser.EndOfData)
                {
                    string[] fields     = csvParser.ReadFields();
                    double current      = Double.Parse(fields[0]);
                    double inductance   = Double.Parse(fields[1]);
                    graph.Add           (new Tuple<double,double>(current, inductance));
                }
                graphContainer.Add(graph);
            }
        }
        Random r = new Random();
        foreach (var i in graphContainer)
        {
            fileIndex++;
            var series = new Series
            {
                Name                = legendNames[fileIndex],
                Color               = Color.FromArgb(r.Next(0, 256), r.Next(0, 256), r.Next(0, 256)),
                IsVisibleInLegend   = true,
                IsXValueIndexed     = false,
                ChartType           = SeriesChartType.Line
            };
            foreach (var j in i)
            {
                series.Points.AddXY (j.Item2, j.Item1);
            }
            chart.Invalidate        ();
            chart.Series.Add        (series);
        }
    }

建议:(?)

enter image description here

2 个答案:

答案 0 :(得分:0)

如用户@Taw所建议,我忘记在运行之间创建graph的新实例或将其清空。

graph = new List<Tuple<double, double>>(); // <-- solved it
while (!csvParser.EndOfData)
{
      string[] fields     = csvParser.ReadFields();
      ...
}

编辑:

请勿使用yourList.Clear(),在这里查看原因:https://stackoverflow.com/a/35848659/2902996

答案 1 :(得分:0)

您已经发布了一种解决方案:

在循环添加新数据之前,请确保已删除旧数据。您可以通过创建一个新实例来做到这一点:

graph = new List<Tuple<double, double>>();

这是一种有效的方法。

但出于完整性考虑,我们还要看看更直接的方法:

graph.Clear();

这将清除列表对象中的数据。但是您需要将图形添加到graphContainer列表中,如下所示:

graphContainer.Add(graph);

这意味着该对象被放入列表,该列表在下一个循环之前将被清除。这是一个常见的错误。解决方案很简单:不要将图形对象本身添加到graphContainer列表中,而是将其复制

graphContainer.Add(graph.ToList());

ToList()调用是创建List<T>副本的简单方法。


至于post you linked to:旧文章严格来说是关于运行时性能的。与创建列表的副本无关。

但即使在那儿,推荐的方法还是取决于您是否可以预测要放入每个列表中的元素数量。

如果您可以预测,而如果有点大,则可以说是数百个大型较小的元素,您应该告诉列表应保留的容量。

这避免了多重成长的烦恼。在Clear()之后,Capacity被保留,避免了新的分配。

您的元素(Tuples)很小,因此您不必担心列表的性能提高。.