ZedGraph PointPairs только 1 символ

Я надеюсь, что у кого-то может быть ответ на этот

Я добавил несколько значений «PointPair» в график ZedGraph, и все это работает нормально. Однако, когда я показываю символы, он показывает только символ с высоким значением, а не с низким значением.

Кто-нибудь знает, что может быть причиной этого?

EDIT — Образец кода (извините, я должен был включить это вчера)

// GraphPane pane (field)

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

Где upperPoints и LowerPoints имеют тип PointPairList


person Paul    schedule 16.12.2009    source источник
comment
Не могли бы вы опубликовать код, который вы использовали для создания панели, кривой и точки? Я пробовал пару вещей, и я не могу воспроизвести вашу проблему, для меня она всегда ставит символ в каждую точку. Если вы опубликуете часть своего кода, я смогу помочь.   -  person Kyle Gibbons    schedule 16.12.2009
comment
да, код был бы полезен   -  person Gacek    schedule 17.12.2009
comment
Я добавил небольшой фрагмент кода того, как создается строка.   -  person Paul    schedule 17.12.2009


Ответы (1)


Я обнаружил проблему в библиотеке ZedGraph... кто-нибудь, пожалуйста, поправьте меня, если я пропустил что-то, чего не должен был делать.

При использовании FilledLineItem он имеет набор верхних и нижних точек.

Когда вызывается "Draw", он вызывается в классе LineItem, который имеет только набор точек.

Поэтому я добавил в метод Draw:

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

DrawPoints — это метод, который я извлек из метода «Draw» в «Symbol». Он содержит следующее

    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).

Это устранило проблему, и я надеюсь, что это поможет всем, у кого может быть такая же проблема.

person Paul    schedule 17.12.2009
comment
Не могли бы вы рассказать немного подробнее о том, что вы на самом деле сделали, потому что я не слежу за вами. Я добавил вашу строку в метод рисования и получил массу ошибок, вы сделали что-то еще, чего не было в вашем ответе? В решении нет метода DrawPoints, поэтому я не уверен, откуда он взялся. Спасибо. - person Kyle Gibbons; 17.12.2009
comment
Упс, похоже, я извлек DrawPoints как метод, чтобы вызывать его дважды. Я опубликую фактический код в ответе - person Paul; 21.12.2009