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

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

0 голосов
/ 16 декабря 2009

Я надеюсь, что кто-то может иметь ответ на этот вопрос

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

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

РЕДАКТИРОВАТЬ - Пример кода (извините, я должен был надеть это вчера)

// GraphPane pane (field)

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

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

1 Ответ

0 голосов
/ 17 декабря 2009

Я обнаружил проблему в библиотеке 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).

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

...