ZedGraph PointPairs只有1个符号

时间:2009-12-16 15:53:07

标签: zedgraph

我希望有人可以得到这个答案

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

有谁知道造成这种情况的原因是什么?

编辑 - 代码示例(抱歉,我应该在昨天提出这个问题)

// GraphPane pane (field)

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

其中upperPoints和lowerPoints的类型为PointPairList

1 个答案:

答案 0 :(得分:0)

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

使用FilledLineItem时,它有一组高点和低点。

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

所以我添加了Draw方法:

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

DrawPoints是我从“符号”中的“绘图”方法中提取出来的方法。它包含以下

    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之前)。

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