2012-08-28 72 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); 
     } 
    } 

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