【问题标题】:MSChart line graph with dashed style and large amount of data points带有虚线样式和大量数据点的 MSChart 折线图
【发布时间】:2012-08-23 02:57:54
【问题描述】:

我正在尝试使用 C# 中的 MSChart 以虚线样式呈现折线图。我设置样式没有问题,但我有大量数据。这会导致虚线渲染出错,因为它似乎在绘制每个线段时重新启动了“破折号”序列。因此,我得到一条看起来与实线相同的线。如果我放大以使我的数据点密度降低,则虚线样式变得可见。

这对我没有好处,因为我真的需要它来保持任何缩放级别的冲刺。有没有人知道这怎么可能?对我来说它搞砸了这样的渲染似乎很奇怪......

有什么想法吗?

【问题讨论】:

    标签: c# mschart linestyle


    【解决方案1】:

    嗯,这比我预期的要麻烦得多。问题的出现是因为 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 );
            }
        }
    

    我真的希望这能减轻一些人的痛苦!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-02-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-09-14
      • 1970-01-01
      • 2016-02-16
      相关资源
      最近更新 更多