2012-08-28 75 views
4

我想使用MSChart从C#虚线样式渲染线条图线。我没有设置风格的问题,但我有大量的数据。这会导致虚线渲染出错,因为它似乎在绘制每条线段时重新开始“虚线”序列。因此,我得到一条与实线完全相同的线。如果我放大,使我的数据点密度减少,然后虚线样式变得可见。MSChart线条图与虚线样式和大量的数据点

这对我并不好,因为我真的需要它来保持在任何缩放级别的潇洒。有没有人有任何想法如何这可能是可能的?这似乎很奇怪,它渲染像这样呈现给我......

有什么想法?

回答

6

好吧,这变成了比我期待的更多的一种淡出。出现这个问题的原因是MSChart在每个2点之间绘制一条独立的DrawLine调用。如果整个事情是用一个DrawLines调用绘制的,那么问题就不存在。

因此,我想出了一个方法来处理它。

首先在PrePaint中,我将所有的“BorderWidth”设置为0之前存储。这意味着MSChart不会绘制我的线条。

最后在PostPaint中,我使用我想要的短划线样式绘制线条。这给完美的渲染。

我敢肯定有一些边缘的情况下为其我的代码将无法正常工作,但是这应该给你如何做一个好主意:

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]; 

        // Log the value if its axis is logarithmic. 
        if (ca.AxisX.IsLogarithmic) 
        { 
         dx = Math.Log10(dx); 
        } 
        if (ca.AxisY.IsLogarithmic) 
        { 
         dy = Math.Log10(dy); 
        } 

        dx = e.ChartGraphics.GetPositionFromAxis(ca.Name, System.Windows.Forms.DataVisualization.Charting.AxisName.X, dx); 
        dy = e.ChartGraphics.GetPositionFromAxis(ca.Name, System.Windows.Forms.DataVisualization.Charting.AxisName.Y, dy); 

        PointF ptFThis   = e.ChartGraphics.GetAbsolutePoint(new PointF((float)dx, (float)dy)); 
        points.Add(ptFThis); 
       } 


       if (points.Count > 0) 
       { 
        Pen pen = new Pen(Color.FromArgb(255, s.Color)); 
        pen.Width  = mBorderWidths[seriesIdx]; 
        pen.DashStyle = ChartToDrawingDashStyle(s.BorderDashStyle); 
        //pen.DashStyle = System.Drawing.Drawing2D.DashStyle.Custom; 
        //pen.DashPattern = new float[]{ 4.0f, 4.0f, 1.0f, 3.0f, 2.0f, 3.0f }; 
        pen.DashCap  = System.Drawing.Drawing2D.DashCap.Round; 

        e.ChartGraphics.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality; 
        e.ChartGraphics.Graphics.DrawLines(pen, points.ToArray()); 

       } 
       s.BorderWidth = mBorderWidths[seriesIdx]; 
      } 

      e.ChartGraphics.Graphics.SetClip(oldClip); 
     } 
    } 

我真的希望有人可以节省一些痛苦!