我在.NET Windows表单项目中使用DataVisualizations Charting控件。我遇到的问题是,当我打印图表时,图例没有显示系列标记(实际上它显示的类似,但它看起来像是线条上的较暗像素)。当在表单上查看图表时,标记是可见的,尽管它们不是很大,并且似乎与系列的MarkerSize值无关。但是当打印图表时(在纸上或PDF上),标记不在那里。
此图显示了在表单上查看时的图表视图。正如您所看到的那样,图例标记有点可见但仍然没有接近实际系列标记的位置。
此图显示同一图表的PDF版本。如果您用力眯眼,可以在图例线的中心看到较暗的像素。
如何修复图例标记,以便它们在打印时实际显示并使其尺寸更大?
答案 0 :(得分:1)
由于似乎无法控制图例标记,您可能需要创建自定义图例。以下是Form
和PDF
:
我不得不缩小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
颜色所必需的。NamedImage
和Chart.Images
。这是必要的,因为在Chart
中设置任何图像需要一个字符串!LegendCells
。例如see here!ChartType
(Line
)和两个MarkerStyles
编码了图像绘制。 CustomItems
。有关详细信息,请参阅here。Series.MarkerSize
,但通过在循环中设置ir = S.MarkerSize;
等来轻松调整代码!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