gpt4 book ai didi

c# - 具有虚线样式和大量数据点的 MSChart 折线图

转载 作者:行者123 更新时间:2023-12-01 19:24:04 24 4
gpt4 key购买 nike

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

这对我来说没有好处,因为我确实需要它来保持任何缩放级别的冲线。有谁知道这如何可能吗?对我来说,它把这样的渲染弄乱了,这似乎很奇怪......

有什么想法吗?

最佳答案

嗯,这比我预想的要麻烦一些。出现问题的原因是 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 );
}
}

我真心希望这可以减轻某人的痛苦!

关于c# - 具有虚线样式和大量数据点的 MSChart 折线图,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12162013/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com