ZedGraph PointPairs 仅 1 个符号

发布于 2024-08-15 01:01:46 字数 457 浏览 4 评论 0原文

我希望有人能找到这个问题的答案,

我已经在 ZedGraph 图中添加了一些“PointPair”值,这一切都工作正常。但是,当我显示符号时,它只显示高值上的符号,而不显示低值。

有谁知道这可能是什么原因造成的?

编辑 - 代码示例(抱歉,我应该把它放在昨天)

// GraphPane pane (field)

FilledLineItem filledLineItem = new FilledLineItem("myline", upperPoints, lowerPoints, Color.DodgerBlue, ZedGraph.SymbolType.Square)
pane.CurveList.Add(filledLineItem);

其中 upperPoints 和 lowerPoints 的类型为 PointPairList

I'm hoping someone may have the answer to this one

I've added some "PointPair" values to a ZedGraph graph, and this all works fine. However, when I show Symbols, it only shows the symbol on the high value, not the low value.

Does anyone know what could be causing this?

EDIT - Code Sample (sorry, I should've put this on yesterday)

// GraphPane pane (field)

FilledLineItem filledLineItem = new FilledLineItem("myline", upperPoints, lowerPoints, Color.DodgerBlue, ZedGraph.SymbolType.Square)
pane.CurveList.Add(filledLineItem);

Where upperPoints and lowerPoints are of type PointPairList

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

伤感在游骋 2024-08-22 01:01:46

我在 ZedGraph 库中发现了这个问题...如果我错过了一些我不应该拥有的东西,请纠正我。

当使用 FilledLineItem 时,它有一组上限点和下限点。

当调用“Draw”时,它是在 LineItem 类上调用的 - 该类只有一组点。

所以我在Draw方法中添加了:

DrawPoints(pane, maxX, maxY, curve, curve.LowerPoints, g, source, scaleFactor, minX, minY, isPixelDrawn)

DrawPoints是我从“Symbol”中的“Draw”方法中提取出来的方法。它包含以下内容

    private void DrawPoints(GraphPane pane, int maxX, int maxY, LineItem curve, IPointList points, Graphics g, Symbol source, float scaleFactor, int minX, int minY, bool[,] isPixelDrawn)
    {
        double curX;
        double curY;
        int tmpX;
        int tmpY;
        double lowVal;
        if ( points != null && ( _border.IsVisible || _fill.IsVisible ) )
        {
            SmoothingMode sModeSave = g.SmoothingMode;
            if ( _isAntiAlias )
                g.SmoothingMode = SmoothingMode.HighQuality;

            // For the sake of speed, go ahead and create a solid brush and a pen
            // If it's a gradient fill, it will be created on the fly for each symbol
            //SolidBrush    brush = new SolidBrush( this.fill.Color );

            using ( Pen pen = source._border.GetPen( pane, scaleFactor ) )
            using ( GraphicsPath path = MakePath( g, scaleFactor ) )
            {
                RectangleF rect = path.GetBounds();

                using ( Brush brush = source.Fill.MakeBrush( rect ) )
                {
                    ValueHandler valueHandler = new ValueHandler( pane, false );
                    Scale xScale = curve.GetXAxis( pane ).Scale;
                    Scale yScale = curve.GetYAxis( pane ).Scale;

                    bool xIsLog = xScale.IsLog;
                    bool yIsLog = yScale.IsLog;
                    bool xIsOrdinal = xScale.IsAnyOrdinal;

                    double xMin = xScale.Min;
                    double xMax = xScale.Max;

                    // Loop over each defined point                         
                    for ( int i = 0; i < points.Count; i++ )
                    {
                        // Check that this symbol should be shown, if not, then continue to the next symbol
                        if(!points[i].ShowSymbol)
                        {
                            continue;
                        }

                        // Get the user scale values for the current point
                        // use the valueHandler only for stacked types
                        if ( pane.LineType == LineType.Stack )
                        {
                            valueHandler.GetValues( curve, i, out curX, out lowVal, out curY );
                        }
                            // otherwise, just access the values directly.  Avoiding the valueHandler for
                            // non-stacked types is an optimization to minimize overhead in case there are
                            // a large number of points.
                        else
                        {
                            curX = points[i].X;
                            if ( curve is StickItem )
                                curY = points[i].Z;
                            else
                                curY = points[i].Y;
                        }

                        // Any value set to double max is invalid and should be skipped
                        // This is used for calculated values that are out of range, divide
                        //   by zero, etc.
                        // Also, any value <= zero on a log scale is invalid

                        if ( curX != PointPair.Missing &&
                             curY != PointPair.Missing &&
                             !System.Double.IsNaN( curX ) &&
                             !System.Double.IsNaN( curY ) &&
                             !System.Double.IsInfinity( curX ) &&
                             !System.Double.IsInfinity( curY ) &&
                             ( curX > 0 || !xIsLog ) &&
                             ( !yIsLog || curY > 0.0 ) &&
                             ( xIsOrdinal || ( curX >= xMin && curX <= xMax ) ) )
                        {
                            // Transform the user scale values to pixel locations
                            tmpX = (int) xScale.Transform( curve.IsOverrideOrdinal, i, curX );
                            tmpY = (int) yScale.Transform( curve.IsOverrideOrdinal, i, curY );

                            // Maintain an array of "used" pixel locations to avoid duplicate drawing operations
                            if ( tmpX >= minX && tmpX <= maxX && tmpY >= minY && tmpY <= maxY ) // guard against the zoom-in case
                            {
                                if ( isPixelDrawn[tmpX, tmpY] )
                                    continue;
                                isPixelDrawn[tmpX, tmpY] = true;
                            }

                            // If the fill type for this symbol is a Gradient by value type,
                            // the make a brush corresponding to the appropriate current value
                            if ( _fill.IsGradientValueType || _border._gradientFill.IsGradientValueType )
                            {
                                using ( Brush tBrush = _fill.MakeBrush( rect, points[i] ) )
                                using ( Pen tPen = _border.GetPen( pane, scaleFactor, points[i] ) )
                                    this.DrawSymbol( g, tmpX, tmpY, path, tPen, tBrush );
                            }
                            else
                            {
                                // Otherwise, the brush is already defined
                                // Draw the symbol at the specified pixel location
                                this.DrawSymbol( g, tmpX, tmpY, path, pen, brush );
                            }
                        }
                    }
                }
            }

            g.SmoothingMode = sModeSave;
        }
    }

所以我的“Draw”方法现在看起来像这样:

    public void Draw( Graphics g, GraphPane pane, LineItem curve, float scaleFactor,
        bool isSelected )
    {
        Symbol source = this;
        if ( isSelected )
            source = Selection.Symbol;

        int tmpX, tmpY;

        int minX = (int)pane.Chart.Rect.Left;
        int maxX = (int)pane.Chart.Rect.Right;
        int minY = (int)pane.Chart.Rect.Top;
        int maxY = (int)pane.Chart.Rect.Bottom;

        // (Dale-a-b) we'll set an element to true when it has been drawn   
        bool[,] isPixelDrawn = new bool[maxX + 1, maxY + 1];

        double curX, curY, lowVal;
        DrawPoints(pane, maxX, maxY, curve, curve.Points, g, source, scaleFactor, minX, minY, isPixelDrawn);

        // Need to check if this is a "Filled" line item, if it is, it may have lower points, in which case the lower points need to be output as well
        FilledLineItem filledLineItem = curve as FilledLineItem;
        if (filledLineItem != null)
        {
            DrawPoints(pane, maxX, maxY, curve, filledLineItem.LowerPoints, g, source, scaleFactor, minX, minY, isPixelDrawn);
        }
    }

...在将曲线转换为 FilledLineItem 之后(但不是在检查它实际上是 FilledLineItem 之前)。

这已经解决了这个问题,我希望它可以帮助其他可能遇到同样问题的人。

I have discovered the problem in the ZedGraph library...someone please correct me if I've missed something I shouldn't have

When using a FilledLineItem, this has a set of upper points and lower points.

When "Draw" is called, it is called on the LineItem class - which only has a set of points.

So I have added to the Draw method:

DrawPoints(pane, maxX, maxY, curve, curve.LowerPoints, g, source, scaleFactor, minX, minY, isPixelDrawn)

DrawPoints is a method that I extracted out of the "Draw" method in "Symbol". It contains the following

    private void DrawPoints(GraphPane pane, int maxX, int maxY, LineItem curve, IPointList points, Graphics g, Symbol source, float scaleFactor, int minX, int minY, bool[,] isPixelDrawn)
    {
        double curX;
        double curY;
        int tmpX;
        int tmpY;
        double lowVal;
        if ( points != null && ( _border.IsVisible || _fill.IsVisible ) )
        {
            SmoothingMode sModeSave = g.SmoothingMode;
            if ( _isAntiAlias )
                g.SmoothingMode = SmoothingMode.HighQuality;

            // For the sake of speed, go ahead and create a solid brush and a pen
            // If it's a gradient fill, it will be created on the fly for each symbol
            //SolidBrush    brush = new SolidBrush( this.fill.Color );

            using ( Pen pen = source._border.GetPen( pane, scaleFactor ) )
            using ( GraphicsPath path = MakePath( g, scaleFactor ) )
            {
                RectangleF rect = path.GetBounds();

                using ( Brush brush = source.Fill.MakeBrush( rect ) )
                {
                    ValueHandler valueHandler = new ValueHandler( pane, false );
                    Scale xScale = curve.GetXAxis( pane ).Scale;
                    Scale yScale = curve.GetYAxis( pane ).Scale;

                    bool xIsLog = xScale.IsLog;
                    bool yIsLog = yScale.IsLog;
                    bool xIsOrdinal = xScale.IsAnyOrdinal;

                    double xMin = xScale.Min;
                    double xMax = xScale.Max;

                    // Loop over each defined point                         
                    for ( int i = 0; i < points.Count; i++ )
                    {
                        // Check that this symbol should be shown, if not, then continue to the next symbol
                        if(!points[i].ShowSymbol)
                        {
                            continue;
                        }

                        // Get the user scale values for the current point
                        // use the valueHandler only for stacked types
                        if ( pane.LineType == LineType.Stack )
                        {
                            valueHandler.GetValues( curve, i, out curX, out lowVal, out curY );
                        }
                            // otherwise, just access the values directly.  Avoiding the valueHandler for
                            // non-stacked types is an optimization to minimize overhead in case there are
                            // a large number of points.
                        else
                        {
                            curX = points[i].X;
                            if ( curve is StickItem )
                                curY = points[i].Z;
                            else
                                curY = points[i].Y;
                        }

                        // Any value set to double max is invalid and should be skipped
                        // This is used for calculated values that are out of range, divide
                        //   by zero, etc.
                        // Also, any value <= zero on a log scale is invalid

                        if ( curX != PointPair.Missing &&
                             curY != PointPair.Missing &&
                             !System.Double.IsNaN( curX ) &&
                             !System.Double.IsNaN( curY ) &&
                             !System.Double.IsInfinity( curX ) &&
                             !System.Double.IsInfinity( curY ) &&
                             ( curX > 0 || !xIsLog ) &&
                             ( !yIsLog || curY > 0.0 ) &&
                             ( xIsOrdinal || ( curX >= xMin && curX <= xMax ) ) )
                        {
                            // Transform the user scale values to pixel locations
                            tmpX = (int) xScale.Transform( curve.IsOverrideOrdinal, i, curX );
                            tmpY = (int) yScale.Transform( curve.IsOverrideOrdinal, i, curY );

                            // Maintain an array of "used" pixel locations to avoid duplicate drawing operations
                            if ( tmpX >= minX && tmpX <= maxX && tmpY >= minY && tmpY <= maxY ) // guard against the zoom-in case
                            {
                                if ( isPixelDrawn[tmpX, tmpY] )
                                    continue;
                                isPixelDrawn[tmpX, tmpY] = true;
                            }

                            // If the fill type for this symbol is a Gradient by value type,
                            // the make a brush corresponding to the appropriate current value
                            if ( _fill.IsGradientValueType || _border._gradientFill.IsGradientValueType )
                            {
                                using ( Brush tBrush = _fill.MakeBrush( rect, points[i] ) )
                                using ( Pen tPen = _border.GetPen( pane, scaleFactor, points[i] ) )
                                    this.DrawSymbol( g, tmpX, tmpY, path, tPen, tBrush );
                            }
                            else
                            {
                                // Otherwise, the brush is already defined
                                // Draw the symbol at the specified pixel location
                                this.DrawSymbol( g, tmpX, tmpY, path, pen, brush );
                            }
                        }
                    }
                }
            }

            g.SmoothingMode = sModeSave;
        }
    }

So my "Draw" method now looks like this:

    public void Draw( Graphics g, GraphPane pane, LineItem curve, float scaleFactor,
        bool isSelected )
    {
        Symbol source = this;
        if ( isSelected )
            source = Selection.Symbol;

        int tmpX, tmpY;

        int minX = (int)pane.Chart.Rect.Left;
        int maxX = (int)pane.Chart.Rect.Right;
        int minY = (int)pane.Chart.Rect.Top;
        int maxY = (int)pane.Chart.Rect.Bottom;

        // (Dale-a-b) we'll set an element to true when it has been drawn   
        bool[,] isPixelDrawn = new bool[maxX + 1, maxY + 1];

        double curX, curY, lowVal;
        DrawPoints(pane, maxX, maxY, curve, curve.Points, g, source, scaleFactor, minX, minY, isPixelDrawn);

        // Need to check if this is a "Filled" line item, if it is, it may have lower points, in which case the lower points need to be output as well
        FilledLineItem filledLineItem = curve as FilledLineItem;
        if (filledLineItem != null)
        {
            DrawPoints(pane, maxX, maxY, curve, filledLineItem.LowerPoints, g, source, scaleFactor, minX, minY, isPixelDrawn);
        }
    }

...after casting the curve to a FilledLineItem (but not before checking that it is actually a FilledLineItem).

This has fixed the problem, and I hope it helps anyone else who may have the same problem.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文