【问题标题】:C# Chart - multiple curves but color gets overwrittenC# Chart - 多条曲线但颜色被覆盖
【发布时间】:2018-12-19 11:38:50
【问题描述】:

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

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);
}

注意:除一条之外的所有曲线都具有相同的值,但您明白了。

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

整个函数:

    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);
        }
    }

建议:(?)

【问题讨论】:

  • 只有1个“i”,它有所有的点吗?您是否使用相同的数据来确定您的图例?
  • graphcontainer 似乎是元组列表的列表 和 IsVisibleInLegend 在系列构造函数中的 true 表明这是我们在右上角实际看到的四种不同图例颜色的来源角落。奇怪的。加入系列后,你会对传说做些什么吗?
  • @dlatikay 正确,graphContainer 的类型为 List&lt;List&lt;Tuple&lt;double,double&gt;&gt;&gt;。不,在这点到图表之后,我没有做任何其他事情。这就是显示曲线的内容。
  • @Mike_G 不,iList&lt;Tuple&lt;double,double&gt;&gt;,在 graphContainer 中,我存储了包含图形信息的所有不同文档。
  • @dlatikay 为了清楚起见,我包含了整个函数。

标签: c# winforms


【解决方案1】:

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

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

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

这是一种有效的方法。

但为了完整起见,让我们也看看更直接的方法:

graph.Clear();

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

graphContainer.Add(graph);

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

graphContainer.Add(graph.ToList());

ToList() 调用是创建List&lt;T&gt; 副本的简单方法。


至于post you linked to:旧帖子完全是关于运行时性能的。而不是创建列表的副本。

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

如果你可以预测它并且如果它有点大,比如说超过几百个大几千个小的元素,你应该告诉列表它应该保留哪些容量。

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

您的元素(元组)很小,因此您可能不需要担心列表的性能增长..

【讨论】:

    【解决方案2】:

    按照用户@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

    【讨论】:

    • 不,这个imo是个误会。您可以并且也许应该使用graph.Clear()graphContainer.Add(graph.ToList()); 的组合,这肯定是一个非常好的方法。 - 旧帖子只是关于运行时性能,没有考虑将各种列表数据保存在内存中。- 话虽如此,初始化列表时您期望多少数据条目可能并不重要。但既然你想把它们放在图表中,它们无论如何都应该太大了..
    • 毕竟我已经添加了一个答案,因为你的所有方面都没有完全正确..
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-02-26
    • 2014-02-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-22
    • 2014-08-02
    相关资源
    最近更新 更多