Well, it has turned into something more than I expected. The problem arises because MSChart draws a line between every two points as a separate DrawLine call. If all things were drawn with a single DrawLines call, the problem would not exist.
As such, I came up with a way to process the drawing.
Firstly, in PrePaint, I save all the "BorderWidth" before setting them to 0. This means that MSChart is not drawing my lines.
Finally, in PostPaint, I draw the lines using the dash style I want. This gives perfect rendering.
I'm sure there are some edge cases for which my code will not work, but this should give you a good idea on how to do this:
private List< int > mBorderWidths = null; private void LineChartPrePaint( object sender, System.Windows.Forms.DataVisualization.Charting.ChartPaintEventArgs e ) { if ( e.ChartElement.GetType() == typeof( System.Windows.Forms.DataVisualization.Charting.ChartArea ) ) { System.Windows.Forms.DataVisualization.Charting.Chart c = (System.Windows.Forms.DataVisualization.Charting.Chart)e.Chart; System.Windows.Forms.DataVisualization.Charting.ChartArea ca = (System.Windows.Forms.DataVisualization.Charting.ChartArea)e.ChartElement; mBorderWidths = new List<int>(); foreach( System.Windows.Forms.DataVisualization.Charting.Series s in c.Series ) { mBorderWidths.Add( s.BorderWidth ); s.BorderWidth = 0; s.ShadowOffset = 0; } RectangleF rectF = ca.Position.ToRectangleF(); rectF = e.ChartGraphics.GetAbsoluteRectangle( rectF ); e.ChartGraphics.Graphics.FillRectangle( new SolidBrush( ca.BackColor ), rectF ); } if ( e.ChartElement.GetType() == typeof( System.Windows.Forms.DataVisualization.Charting.Chart ) ) { RectangleF rectF = e.Position.ToRectangleF(); rectF = e.ChartGraphics.GetAbsoluteRectangle( rectF ); e.ChartGraphics.Graphics.FillRectangle( new SolidBrush( e.Chart.BackColor ), rectF ); } } System.Drawing.Drawing2D.DashStyle ChartToDrawingDashStyle( System.Windows.Forms.DataVisualization.Charting.ChartDashStyle cds ) { switch( cds ) { case System.Windows.Forms.DataVisualization.Charting.ChartDashStyle.NotSet: case System.Windows.Forms.DataVisualization.Charting.ChartDashStyle.Solid: return System.Drawing.Drawing2D.DashStyle.Solid; case System.Windows.Forms.DataVisualization.Charting.ChartDashStyle.Dash: return System.Drawing.Drawing2D.DashStyle.Dash; case System.Windows.Forms.DataVisualization.Charting.ChartDashStyle.DashDot: return System.Drawing.Drawing2D.DashStyle.DashDot; case System.Windows.Forms.DataVisualization.Charting.ChartDashStyle.DashDotDot: return System.Drawing.Drawing2D.DashStyle.DashDotDot; case System.Windows.Forms.DataVisualization.Charting.ChartDashStyle.Dot: return System.Drawing.Drawing2D.DashStyle.Dot; } return System.Drawing.Drawing2D.DashStyle.Solid; } private void LineChartPostPaint( object sender, System.Windows.Forms.DataVisualization.Charting.ChartPaintEventArgs e ) { if ( e.ChartElement.GetType() == typeof( System.Windows.Forms.DataVisualization.Charting.ChartArea ) ) { System.Windows.Forms.DataVisualization.Charting.Chart c = (System.Windows.Forms.DataVisualization.Charting.Chart)e.Chart; System.Windows.Forms.DataVisualization.Charting.ChartArea ca = (System.Windows.Forms.DataVisualization.Charting.ChartArea)e.ChartElement; RectangleF clipRect = e.ChartGraphics.GetAbsoluteRectangle( e.Position.ToRectangleF() ); RectangleF oldClip = e.ChartGraphics.Graphics.ClipBounds; e.ChartGraphics.Graphics.SetClip( clipRect ); int seriesIdx = 0; foreach( System.Windows.Forms.DataVisualization.Charting.Series s in c.Series ) { PointF ptFLast = new PointF( 0.0f, 0.0f ); List< PointF > points = new List<PointF>(); foreach( System.Windows.Forms.DataVisualization.Charting.DataPoint dp in s.Points ) { double dx = (double)dp.XValue; double dy = (double)dp.YValues[0];
I really hope this saves someone the pain!
source share