窗体图表控件中的堆叠图例项
本文关键字:控件 窗体 | 更新日期: 2023-09-27 18:18:02
我遇到了一个问题,我试图将多个图例项添加到图表控件。我想要的传说,以垂直向下的图表的左侧与右侧的图表区域对齐,但我似乎只能得到传说并排。
图表的性质意味着有类别,每个类别都有部分,每个部分都有一组数据,这些数据被绘制在一个单独的序列上。不同的类别可能包含相同的部分,但它们被绘制为不同的系列。这就是为什么有多个图例项目,每个都有一个不同的标题。
是否有一种方法,我可以在彼此的顶部对齐的传说或替代,我可以把所有系列的传说项目分组到有不同的类别,其中每个项目有一个标题的传说?
当前代码如下:
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;
}
根据图例项的已知最大尺寸重新绘制整个图表区域,设法解决了这个问题(见下面的代码)。我还将图例项设置为
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;
}