.NET图表图例标记大小

时间:2015-12-28 02:59:26

标签: c# .net vb.net windows charts

我在.NET Windows表单项目中使用DataVisualizations Charting控件。我遇到的问题是,当我打印图表时,图例没有显示系列标记(实际上它显示的类似,但它看起来像是线条上的较暗像素)。当在表单上查看图表时,标记是可见的,尽管它们不是很大,并且似乎与系列的MarkerSize值无关。但是当打印图表时(在纸上或PDF上),标记不在那里。

此图显示了在表单上查看时的图表视图。正如您所看到的那样,图例标记有点可见但仍然没有接近实际系列标记的位置。

Viewing chart on form

此图显示同一图表的PDF版本。如果您用力眯眼,可以在图例线的中心看到较暗的像素。

PDF printed chart

如何修复图例标记,以便它们在打印时实际显示并使其尺寸更大?

2 个答案:

答案 0 :(得分:1)

由于似乎无法控制图例标记,您可能需要创建自定义图例。以下是FormPDF

中的示例

enter image description here enter image description here

我不得不缩小PDF,因此看起来更薄/更轻。

这是一个返回CustomLegend

的函数
Legend CustomCloneLegend(Chart chart, Legend oLeg)
{
    Legend newL = new Legend();
    newL.Position = oLeg.Position;  // copy a few settings:
    newL.Docking = oLeg.Docking;
    newL.Alignment = oLeg.Alignment;
    // a few numbers for the drawing to play with; you may want to use floats..
    int iw = 32; int iw2 = iw / 2;    int ih = 18; int ih2 = ih / 2;
    int ir = 12;  int ir2 = ir / 2;   int lw = 3;
    // we want to access the series' colors!
    chart.ApplyPaletteColors();
    foreach (Series S in chart.Series)
    {
        // the drawing code is only for linechart and markerstyles circle or square:
        Bitmap bmp = new Bitmap(iw, ih);
        using (Graphics G = Graphics.FromImage(bmp))
        using (Pen pen = new Pen(S.Color, lw))
        using (SolidBrush brush = new SolidBrush(S.Color))
        {
            G.DrawLine(pen, 0, ih2, iw, ih2);
            if (S.MarkerStyle == MarkerStyle.Circle)
                G.FillEllipse(brush, iw2 - ir2, ih2 - ir2, ir, ir);
            else if (S.MarkerStyle == MarkerStyle.Square)
                G.FillRectangle(brush, iw2 - ir2, ih2 - ir2, ir, ir);
        }
        // add a new NamesImage
        NamedImage ni = new NamedImage(S.Name, bmp);
        chart.Images.Add(ni);
        // create and add the custom legend item
        LegendItem lit = new LegendItem( S.Name, Color.Red, S.Name);
        newL.CustomItems.Add(lit);
    }
    oLeg.Enabled = false;
    return newL;
}

以下是我的称呼方式:

Legend LC = CustomCloneLegend(chart3, L);
chart1.Legends.Add(LC);

一些注意事项:

  • 代码使用chart.ApplyPaletteColors()。这是访问Series颜色所必需的。
  • 它还使用了很少知道的类NamedImageChart.Images。这是必要的,因为在Chart中设置任何图像需要一个字符串!
  • 如果您想放大图片,可能需要使用LegendCells。例如see here
  • 我仅为一个ChartTypeLine)和两个MarkerStyles编码了图像绘制。
  • 有很多方法可以自定义CustomItems。有关详细信息,请参阅here
  • 我确实使用了Series.MarkerSize,但通过在循环中设置ir = S.MarkerSize;等来轻松调整代码!
  • 您可能需要将原始图例中的其他设置复制到自定义图例,而不是我所做的3。我刚刚注意到你设置了Font ..

答案 1 :(得分:0)

这是 TaW 解决方案的 VB 翻译。我添加了绘制三角形标记的代码,并注释掉了通过每个标记绘制一条线的代码,以便我更容易看到标记形状。因此,您必须在调用此函数之前为每个系列设置 MarkerStyle,否则取消注释该行。

我的图表有一些额外的系列,可以在数据点周围绘制椭圆。我不想在图例中显示那些,所以我只显示具有命名 LegendText 的系列的图例条目。这些行在下面被注释掉,但如果您想要相同的行为,您可以取消注释它们。

Public Function CustomCloneLegend(chart As Chart, oLeg As Legend) As Legend

    Dim newL As Legend = New Legend With {
        .Position = oLeg.Position,
        .Docking = oLeg.Docking,
        .Alignment = oLeg.Alignment,
        .Font = oLeg.Font
        }
    ' a few numbers for the drawing to play with'
    Dim iw As Integer = 16        
    Dim iw2 As Integer = iw / 2
    Dim ih As Integer = 16
    Dim ih2 As Integer = ih / 2
    Dim ir As Integer = 6
    Dim ir2 As Integer = ir / 2
    Dim lw As Integer = 3
    Dim lit As LegendItem
    ' point array for drawing triangles, can expand to other shapes'
    Dim pts(2) As Point

    ' we want to access the series colors!'
    chart.ApplyPaletteColors()
    For Each S As Series In chart.Series
        ir = S.MarkerSize
        ' the drawing code Is only for linechart And markerstyles circle, square, triangle'
        Dim bmp As Bitmap = New Bitmap(iw, ih)
        Using G As Graphics = Graphics.FromImage(bmp)
            Using pen As Pen = New Pen(S.Color, lw)
                Using Brush As SolidBrush = New SolidBrush(S.Color)
                    ' Commented out the next line: Makes it hard to see the marker 'shapes
                    'G.DrawLine(pen, 0, ih2, iw, ih2) '
                    Select Case S.MarkerStyle
                        Case MarkerStyle.Circle
                            G.FillEllipse(Brush, iw2 - ir2, ih2 - ir2, ir, ir)
                        Case MarkerStyle.Square
                            G.FillRectangle(Brush, iw2 - ir2, ih2 - ir2, ir, ir)
                        Case MarkerStyle.Triangle
                            pts(0) = New Point(iw2, ih2)
                            pts(1) = New Point(1, ih)
                            pts(2) = New Point(iw - 1, ih)
                            G.FillPolygon(Brush, pts)
                    End Select
                    ' add a New NamesImage '
                    Dim ni As NamedImage = New NamedImage(S.Name, bmp) 
                    chart.Images.Add(ni) 
                    ' create And add the custom legend item '

                    'Uncomment the If block to hide legend labels for series with no LegendText '
                    'If S.LegendText <> "" Then '
                    lit = New LegendItem(S.Name, Color.Red, S.Name) With {
                        .MarkerStyle = MarkerStyle.None,
                        .ImageStyle = LegendImageStyle.Marker
                    }
                    newL.CustomItems.Add(lit)
                    'End If '

                End Using
            End Using
        End Using
    Next
    oLeg.Enabled = False
    Return newL
End Function