Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/315.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何将带有图例键的数据表添加到C#中的MS图表?_C#_Excel_Charts_Legend_Legend Properties - Fatal编程技术网

如何将带有图例键的数据表添加到C#中的MS图表?

如何将带有图例键的数据表添加到C#中的MS图表?,c#,excel,charts,legend,legend-properties,C#,Excel,Charts,Legend,Legend Properties,有两个列表称为listversion和MIN\u list。使用这些列表的值,我创建了一个折线图。一切正常。但我想知道是否有可能像MS Excel那样在图表中添加带有图例键的数据表 chart.Series.Clear(); chart.ChartAreas[0].AxisX.Title = "Version"; chart.ChartAreas[0].AxisX.TitleFont = new System.Drawing.Font("Arial", 12, FontStyle.Regular

有两个列表称为listversionMIN\u list。使用这些列表的值,我创建了一个折线图。一切正常。但我想知道是否有可能像MS Excel那样在图表中添加带有图例键的数据表

chart.Series.Clear();
chart.ChartAreas[0].AxisX.Title = "Version";
chart.ChartAreas[0].AxisX.TitleFont = new System.Drawing.Font("Arial", 12, FontStyle.Regular);

chart.ChartAreas[0].AxisY.Title = "Time";
chart.ChartAreas[0].AxisY.TitleFont = new System.Drawing.Font("Arial", 12, FontStyle.Regular);

Series MIN = chart.Series.Add("Minimum");
MIN.Points.DataBindXY(listVersion, MIN_list[j]);
MIN.ChartType = SeriesChartType.Line;
MIN.Color = Color.Red;
MIN.BorderWidth = 3;
我期待着这样的事情

如果可能的话,我怎么做

谢谢。

是的,您可以这样做:

以下是我采取的步骤:

首先,我们禁用原始的
图例
,因为它无法按我们需要的方式进行操作

chart1.Legends[0].Enabled = false;
现在,我们创建一个新的和它的快捷方式引用:

chart1.Legends.Add(new Legend("customLegend"));
Legend L = chart1.Legends[1];
接下来我们做一些定位:

L.DockedToChartArea = chart1.ChartAreas[0].Name;  // the ca it refers to 
L.Docking = Docking.Bottom;
L.IsDockedInsideChartArea = false;
L.Alignment = StringAlignment.Center; 
现在我们要为标题填写一行,每个系列填写一行

我对两者都使用了一个公共函数,并传入一个标志,以指示是应该填充标题(x值)还是单元格数据(y值)。以下是我如何调用该函数:

addValuesToLegend(L, chart1.Series[0], false);
foreach (Series s in chart1.Series) addValuesToLegend(L, s, true);
请注意,要使其发挥作用,我们需要在
系列中做一些准备:

  • 我们需要显式地设置
    系列。颜色
    ,否则我们无法引用它们
  • 我在每个系列的
    标记中添加了一个格式字符串;但也许你能找到一个更好的解决方案,避免硬编码标题格式
下面是完成所有填充和一些造型的函数:

void addValuesToLegend(Legend L, Series S, bool addYValues)
{
    // create a new row for the legend
    LegendItem newItem = new LegendItem();
    // if the series has a markerstyle we show it:
    newItem.MarkerStyle = S.MarkerStyle ;
    newItem.MarkerColor = S.Color; 
    newItem.MarkerSize *= 2;   // bump up the size
    if (S.MarkerStyle == MarkerStyle.None)
    {
        // no markerstyle so we just show a colored rectangle
        // you could add code to show a line for other chart types..
        newItem.ImageStyle = LegendImageStyle.Rectangle;
        newItem.BorderColor = Color.Transparent;
        newItem.Color = S.Color;
    }
    else newItem.ImageStyle =  LegendImageStyle.Marker;

    // the rowheader shows the marker or the series color
    newItem.Cells.Add(LegendCellType.SeriesSymbol, "", ContentAlignment.MiddleCenter);
    // add series name
    newItem.Cells.Add(LegendCellType.Text, addYValues ? S.Name : "",
                      ContentAlignment.MiddleLeft);
    // combine the 1st two cells:
    newItem.Cells[1].CellSpan = 2;

    // we hide the first cell of the header row
    if (!addYValues)
    {
        newItem.ImageStyle = LegendImageStyle.Line;
        newItem.Color = Color.Transparent;
        newItem.Cells[0].Tag = "*";  // we mark the 1st cell for not painting it
    }
    // now we loop over the points:
    foreach (DataPoint dp in S.Points)
    {
        // we format the y-value
        string t = dp.YValues[0].ToString(S.Tag.ToString());
        // or maybe the x-value. it is a datatime so we need to convert it!
        // note the escaping to work around my european locale!
        if (!addYValues) t = DateTime.FromOADate(dp.XValue).ToString("M\\/d\\/yyyy");
        newItem.Cells.Add(LegendCellType.Text, t, ContentAlignment.MiddleCenter);
    }
    // we can create some white space around the data:
    foreach (var cell in newItem.Cells)  cell.Margins = new Margins(25, 20, 25, 20);
    // finally add the row of cells:
    L.CustomItems.Add(newItem);
}
要在图例表的单元格周围绘制边框,我们需要对
PrePaint
事件进行编码:

private void chart1_PrePaint(object sender, ChartPaintEventArgs e)
{
    LegendCell cell = e.ChartElement as LegendCell;
    if (cell != null && cell.Tag == null) 
    {
        RectangleF r = e.ChartGraphics.GetAbsoluteRectangle(e.Position.ToRectangleF());
        e.ChartGraphics.Graphics.DrawRectangle(Pens.DimGray,Rectangle.Round(r));
        // Let's hide the left border when there is a cell span!
        if (cell.CellSpan != 1) 
                e.ChartGraphics.Graphics.DrawLine(Pens.White, 
                                r.Left, r.Top+1, r.Left, r.Bottom-1);
    }
}
您可以添加更多样式,尽管我不确定您是否能够完美匹配示例。

是的,您可以这样做:

以下是我采取的步骤:

首先,我们禁用原始的
图例
,因为它无法按我们需要的方式进行操作

chart1.Legends[0].Enabled = false;
现在,我们创建一个新的和它的快捷方式引用:

chart1.Legends.Add(new Legend("customLegend"));
Legend L = chart1.Legends[1];
接下来我们做一些定位:

L.DockedToChartArea = chart1.ChartAreas[0].Name;  // the ca it refers to 
L.Docking = Docking.Bottom;
L.IsDockedInsideChartArea = false;
L.Alignment = StringAlignment.Center; 
现在我们要为标题填写一行,每个系列填写一行

我对两者都使用了一个公共函数,并传入一个标志,以指示是应该填充标题(x值)还是单元格数据(y值)。以下是我如何调用该函数:

addValuesToLegend(L, chart1.Series[0], false);
foreach (Series s in chart1.Series) addValuesToLegend(L, s, true);
请注意,要使其发挥作用,我们需要在
系列中做一些准备:

  • 我们需要显式地设置
    系列。颜色
    ,否则我们无法引用它们
  • 我在每个系列的
    标记中添加了一个格式字符串;但也许你能找到一个更好的解决方案,避免硬编码标题格式
下面是完成所有填充和一些造型的函数:

void addValuesToLegend(Legend L, Series S, bool addYValues)
{
    // create a new row for the legend
    LegendItem newItem = new LegendItem();
    // if the series has a markerstyle we show it:
    newItem.MarkerStyle = S.MarkerStyle ;
    newItem.MarkerColor = S.Color; 
    newItem.MarkerSize *= 2;   // bump up the size
    if (S.MarkerStyle == MarkerStyle.None)
    {
        // no markerstyle so we just show a colored rectangle
        // you could add code to show a line for other chart types..
        newItem.ImageStyle = LegendImageStyle.Rectangle;
        newItem.BorderColor = Color.Transparent;
        newItem.Color = S.Color;
    }
    else newItem.ImageStyle =  LegendImageStyle.Marker;

    // the rowheader shows the marker or the series color
    newItem.Cells.Add(LegendCellType.SeriesSymbol, "", ContentAlignment.MiddleCenter);
    // add series name
    newItem.Cells.Add(LegendCellType.Text, addYValues ? S.Name : "",
                      ContentAlignment.MiddleLeft);
    // combine the 1st two cells:
    newItem.Cells[1].CellSpan = 2;

    // we hide the first cell of the header row
    if (!addYValues)
    {
        newItem.ImageStyle = LegendImageStyle.Line;
        newItem.Color = Color.Transparent;
        newItem.Cells[0].Tag = "*";  // we mark the 1st cell for not painting it
    }
    // now we loop over the points:
    foreach (DataPoint dp in S.Points)
    {
        // we format the y-value
        string t = dp.YValues[0].ToString(S.Tag.ToString());
        // or maybe the x-value. it is a datatime so we need to convert it!
        // note the escaping to work around my european locale!
        if (!addYValues) t = DateTime.FromOADate(dp.XValue).ToString("M\\/d\\/yyyy");
        newItem.Cells.Add(LegendCellType.Text, t, ContentAlignment.MiddleCenter);
    }
    // we can create some white space around the data:
    foreach (var cell in newItem.Cells)  cell.Margins = new Margins(25, 20, 25, 20);
    // finally add the row of cells:
    L.CustomItems.Add(newItem);
}
要在图例表的单元格周围绘制边框,我们需要对
PrePaint
事件进行编码:

private void chart1_PrePaint(object sender, ChartPaintEventArgs e)
{
    LegendCell cell = e.ChartElement as LegendCell;
    if (cell != null && cell.Tag == null) 
    {
        RectangleF r = e.ChartGraphics.GetAbsoluteRectangle(e.Position.ToRectangleF());
        e.ChartGraphics.Graphics.DrawRectangle(Pens.DimGray,Rectangle.Round(r));
        // Let's hide the left border when there is a cell span!
        if (cell.CellSpan != 1) 
                e.ChartGraphics.Graphics.DrawLine(Pens.White, 
                                r.Left, r.Top+1, r.Left, r.Bottom-1);
    }
}

您可以添加更多样式,尽管我不确定您是否能够完美匹配示例。

创建两个具有相同数据的图表,然后将其中一个拖放到另一个图表上?我已更新了答案,以显示如何添加单元格边框。您解决了问题吗?谢谢您的帮助。我没有解决问题,但我能够改变客户的想法。:)使用相同的数据创建两个图表,然后将其中一个拖放到另一个上?我已更新了答案,以显示如何添加单元格边框。您解决了问题吗?谢谢您的帮助。我没有解决问题,但我能够改变客户的想法。:)