【问题标题】:Stacked legend items in windows forms charting controlsWindows 窗体图表控件中的堆叠图例项
【发布时间】:2014-08-14 10:14:11
【问题描述】:

我在尝试将多个图例项添加到图表控件时遇到问题。我希望图例在图表左侧与右侧图表区域垂直对齐,但是我似乎只能并排获得图例。

图表的性质意味着有类别,每个类别都有部分,每个部分都有一组数据,这些数据绘制在一个单独的系列上。不同的类别可能包含相同的部分,但它们被绘制为不同的系列。这就是为什么有多个图例项目,每个项目都有不同的标题。

有没有一种方法可以让我将图例相互对齐,或者我可以将所有系列图例项目分组到不同的类别中,其中每个项目在图例中都有一个标题?

目前的代码如下:

    private Chart PointChartFromDataColumn(string name, DataTable tbl, string xid, string yid, List<string> catagories)
    {
        Chart c = null;

        //Check the existance of the columns and that there are series to add
        if (tbl.Columns.Contains(xid) && tbl.Columns.Contains(yid))
        {
            //Define new chart
            c = new Chart();

            //Set the name
            c.Name = name;

            //Clear chart areas, series and legends
            c.ChartAreas.Clear();
            c.Series.Clear();
            c.Legends.Clear();

            //Create the chart area
            ChartArea area = new ChartArea();
            area.Name = "default";
            c.ChartAreas.Add(area);

            //Create the custom legend for all plants
            foreach (string s in catagories)
            {
                //Create the custom legend item and add
                Legend lg = new Legend();
                lg.Name = s;
                lg.IsEquallySpacedItems = true;

                lg.LegendStyle = LegendStyle.Column;
                lg.Docking = Docking.Left;


                lg.TitleAlignment = StringAlignment.Near;
                lg.TableStyle = LegendTableStyle.Auto;
                lg.Title = s;
                lg.BackColor = Color.White;
                lg.TitleFont = new Font("Verdana", 12, FontStyle.Italic);
                lg.TitleSeparator = LegendSeparatorStyle.Line;
                lg.TitleSeparatorColor = Color.Black;
                lg.TitleForeColor = Color.DarkGray;
                lg.BorderColor = Color.Black;
                lg.BorderWidth = 1;
                lg.BorderDashStyle = ChartDashStyle.Solid;

                c.Legends.Add(lg);
            }

            string seriesname;
            double dbl = 0;
            DateTime time;

            //For every row in the table
            foreach (DataRow row in tbl.Rows)
            {
                //try and parse x and why values
                if (double.TryParse(row[yid].ToString(), out dbl) && DateTime.TryParse(row[xid].ToString(), out time))
                {
                    seriesname = row["Catagory"].ToString() + "-" + row["PartNo"].ToString();

                    //If the series does not exist then create it and add the legend item
                    if (c.Series.IndexOf(seriesname) == -1)
                    {
                        Series s = CreateSeries(seriesname, area.Name);
                        c.Series.Add(s);
                        c.Legends[row["Catagory"].ToString()].CustomItems.Add(s.Color, row["PartNo"].ToString());
                    }

                    //Add the point to the chart series
                    c.Series[seriesname].Points.AddXY(time, dbl);
                }
            }
        }

        return c;
    }

【问题讨论】:

    标签: c# charts data-visualization


    【解决方案1】:

    通过根据图例项的已知最大大小重新绘制整个图表区域,设法解决了该问题(参见下面的代码)。我还将图例项设置为

    lg.LegendStyle = LegendStyle.Column;
    lg.Docking = Docking.Top;
    

    这意味着停靠功能将它们垂直堆叠。每次图表调整大小时都会调用此函数,并相应地重新绘制。

        /// <summary>
        /// Re-draw chart area
        /// </summary>
        /// <param name="c">Size of the chart</param>
        /// <param name="index">Index of chart area</param>
        private void ReDrawChartArea(Chart c, int index)
        {       
            //Set known max legend size (can't calculate programmatically as charts are stupid)
            float legendmaxsize = 140;
    
            //Calculate the percentage of the total size
            float maxpercentage = (legendmaxsize / (float)c.Width) * 100;
    
            //Get the chart area
            ChartArea area = c.ChartAreas[index];
    
            //Disable auto size
            area.Position.Auto = false;
    
            //Set the height as full and width as the remaining percentage
            area.Position.Height = 100;
            area.Position.Width = 100F - maxpercentage;
    
            //Set the area as top and start position as end of legend
            area.Position.Y = 0;
            area.Position.X = maxpercentage;        
        }
    

    【讨论】:

      猜你喜欢
      • 2010-10-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-05-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多