Exemple #1
0
        /// <summary>
        /// Draws a line connecting two SKPoint structures.
        /// </summary>
        /// <param name="series">Chart series.</param>
        /// <param name="point">Series last data point in the group.</param>
        /// <param name="pointMin">Series minimum Y value data point in the group.</param>
        /// <param name="pointMax">Series maximum Y value data point in the group.</param>
        /// <param name="pointIndex">Point index.</param>
        /// <param name="pen">Pen object that determines the color, width, and style of the line.</param>
        /// <param name="firstPointX">First point X coordinate.</param>
        /// <param name="firstPointY">First point Y coordinate</param>
        /// <param name="secondPointX">Second point X coordinate.</param>
        /// <param name="secondPointY">Second point Y coordinate</param>
        public virtual void DrawLine(
            Series series,
            DataPoint point,
            DataPoint pointMin,
            DataPoint pointMax,
            int pointIndex,
            SKPaint pen,
            float firstPointX,
            float firstPointY,
            float secondPointX,
            float secondPointY
            )
        {
            // Transform 3D coordinates
            if (chartArea3DEnabled)
            {
                Point3D[] points = new Point3D[2];

                // All coordinates has to be transformed in relative coordinate system
                // NOTE: Fixes issue #5496
                SKPoint firstPoint  = Graph.GetRelativePoint(new SKPoint(firstPointX, firstPointY));
                SKPoint secondPoint = Graph.GetRelativePoint(new SKPoint(secondPointX, secondPointY));

                points[0] = new Point3D(firstPoint.X, firstPoint.Y, seriesZCoordinate);
                points[1] = new Point3D(secondPoint.X, secondPoint.Y, seriesZCoordinate);
                matrix3D.TransformPoints(points);

                // All coordinates has to be transformed back to pixels
                // NOTE: Fixes issue #5496
                points[0].SKPoint = Graph.GetAbsolutePoint(points[0].SKPoint);
                points[1].SKPoint = Graph.GetAbsolutePoint(points[1].SKPoint);

                firstPointX  = points[0].X;
                firstPointY  = points[0].Y;
                secondPointX = points[1].X;
                secondPointY = points[1].Y;
            }

            // Draw line
            Graph.DrawLine(pen, firstPointX, firstPointY, secondPointX, secondPointY);

            // Process selection regions
            if (Common.ProcessModeRegions)
            {
                // Create grapics path object for the line
                using SKPath path = new();
                float width = pen.StrokeWidth + 2;

                if (Math.Abs(firstPointX - secondPointX) > Math.Abs(firstPointY - secondPointY))
                {
                    path.AddLine(firstPointX, firstPointY - width, secondPointX, secondPointY - width);
                    path.AddLine(secondPointX, secondPointY + width, firstPointX, firstPointY + width);
                    path.Close();
                }
                else
                {
                    path.AddLine(firstPointX - width, firstPointY, secondPointX - width, secondPointY);
                    path.AddLine(secondPointX + width, secondPointY, firstPointX + width, firstPointY);
                    path.Close();
                }

                // Calculate bounding rectangle
                SKRect pathBounds = path.GetBounds();

                // If one side of the bounding rectangle is less than 2 pixels
                // use rectangle region shape to optimize used coordinates space
                if (pathBounds.Width <= 2.0 || pathBounds.Height <= 2.0)
                {
                    // Add hot region path as rectangle
                    pathBounds.Inflate(pen.StrokeWidth, pen.StrokeWidth);
                    Common.HotRegionsList.AddHotRegion(
                        Graph.GetRelativeRectangle(pathBounds),
                        point,
                        point.series.Name,
                        pointIndex);
                }
                else
                {
                    // Add hot region path as polygon
                    Common.HotRegionsList.AddHotRegion(
                        path,
                        false,
                        point,
                        point.series.Name,
                        pointIndex);
                }
            }
        }
        /// <summary>
        /// Draws a marker that represents a data point in FastPoint series.
        /// </summary>
        /// <param name="graph">Chart graphics used to draw the marker.</param>
        /// <param name="point">Series data point drawn.</param>
        /// <param name="pointIndex">Data point index in the series.</param>
        /// <param name="location">Marker location in pixels.</param>
        /// <param name="markerStyle">Marker style.</param>
        /// <param name="markerSize">Marker size in pixels.</param>
        /// <param name="brush">Brush used to fill marker shape.</param>
        /// <param name="borderPen">Marker border pen.</param>
        virtual protected void DrawMarker(
            ChartGraphics graph,
            DataPoint point,
            int pointIndex,
            SKPoint location,
            MarkerStyle markerStyle,
            int markerSize,
            SKPaint brush,
            SKPaint borderPen)
        {
            // Transform 3D coordinates
            if (chartArea3DEnabled)
            {
                Point3D[] points = new Point3D[1];
                location  = graph.GetRelativePoint(location);
                points[0] = new Point3D(location.X, location.Y, seriesZCoordinate);
                matrix3D.TransformPoints(points);
                location.X = points[0].X;
                location.Y = points[0].Y;
                location   = graph.GetAbsolutePoint(location);
            }

            // Create marker bounding rectangle in pixels
            SKRect markerBounds = new(
                location.X - markerSize / 2f, location.Y - markerSize / 2f, markerSize, markerSize);

            // Draw Marker
            switch (markerStyle)
            {
            case (MarkerStyle.Star4):
            case (MarkerStyle.Star5):
            case (MarkerStyle.Star6):
            case (MarkerStyle.Star10):
            {
                // Set number of corners
                int cornerNumber = 4;
                if (markerStyle == MarkerStyle.Star5)
                {
                    cornerNumber = 5;
                }
                else if (markerStyle == MarkerStyle.Star6)
                {
                    cornerNumber = 6;
                }
                else if (markerStyle == MarkerStyle.Star10)
                {
                    cornerNumber = 10;
                }

                // Get star polygon
                SKPoint[] points = ChartGraphics.CreateStarPolygon(markerBounds, cornerNumber);

                // Fill shape
                graph.FillPolygon(brush, points);

                // Draw border
                if (borderPen != null)
                {
                    graph.DrawPolygon(borderPen, points);
                }
                break;
            }

            case (MarkerStyle.Circle):
            {
                graph.FillEllipse(brush, markerBounds);

                // Draw border
                if (borderPen != null)
                {
                    graph.DrawEllipse(borderPen, markerBounds);
                }

                break;
            }

            case (MarkerStyle.Square):
            {
                graph.FillRectangle(brush, markerBounds);

                // Draw border
                if (borderPen != null)
                {
                    graph.DrawRectangle(
                        borderPen,
                        (int)Math.Round(markerBounds.Left, 0),
                        (int)Math.Round(markerBounds.Top, 0),
                        (int)Math.Round(markerBounds.Width, 0),
                        (int)Math.Round(markerBounds.Height, 0));
                }

                break;
            }

            case (MarkerStyle.Cross):
            {
                // Calculate cross line width and size
                float crossLineWidth = (float)Math.Ceiling(markerSize / 4F);
                float crossSize      = markerSize;      // * (float)Math.Sin(45f/180f*Math.PI)

                // Calculate cross coordinates
                SKPoint[] points = new SKPoint[12];
                points[0].X = location.X - crossSize / 2F;
                points[0].Y = location.Y + crossLineWidth / 2F;
                points[1].X = location.X - crossSize / 2F;
                points[1].Y = location.Y - crossLineWidth / 2F;

                points[2].X = location.X - crossLineWidth / 2F;
                points[2].Y = location.Y - crossLineWidth / 2F;
                points[3].X = location.X - crossLineWidth / 2F;
                points[3].Y = location.Y - crossSize / 2F;
                points[4].X = location.X + crossLineWidth / 2F;
                points[4].Y = location.Y - crossSize / 2F;

                points[5].X = location.X + crossLineWidth / 2F;
                points[5].Y = location.Y - crossLineWidth / 2F;
                points[6].X = location.X + crossSize / 2F;
                points[6].Y = location.Y - crossLineWidth / 2F;
                points[7].X = location.X + crossSize / 2F;
                points[7].Y = location.Y + crossLineWidth / 2F;

                points[8].X  = location.X + crossLineWidth / 2F;
                points[8].Y  = location.Y + crossLineWidth / 2F;
                points[9].X  = location.X + crossLineWidth / 2F;
                points[9].Y  = location.Y + crossSize / 2F;
                points[10].X = location.X - crossLineWidth / 2F;
                points[10].Y = location.Y + crossSize / 2F;
                points[11].X = location.X - crossLineWidth / 2F;
                points[11].Y = location.Y + crossLineWidth / 2F;

                // Rotate cross coordinates 45 degrees
                SKMatrix rotationMatrix = SKMatrix.CreateRotationDegrees(45, location.X, location.Y);
                rotationMatrix.TransformPoints(points);

                // Fill shape
                graph.FillPolygon(brush, points);

                // Draw border
                if (borderPen != null)
                {
                    graph.DrawPolygon(borderPen, points);
                }
                break;
            }

            case (MarkerStyle.Diamond):
            {
                SKPoint[] points = new SKPoint[4];
                points[0].X = markerBounds.Left;
                points[0].Y = markerBounds.Top + markerBounds.Height / 2F;
                points[1].X = markerBounds.Left + markerBounds.Width / 2F;
                points[1].Y = markerBounds.Top;
                points[2].X = markerBounds.Right;
                points[2].Y = markerBounds.Top + markerBounds.Height / 2F;
                points[3].X = markerBounds.Left + markerBounds.Width / 2F;
                points[3].Y = markerBounds.Bottom;

                graph.FillPolygon(brush, points);

                // Draw border
                if (borderPen != null)
                {
                    graph.DrawPolygon(borderPen, points);
                }
                break;
            }

            case (MarkerStyle.Triangle):
            {
                SKPoint[] points = new SKPoint[3];
                points[0].X = markerBounds.Left;
                points[0].Y = markerBounds.Bottom;
                points[1].X = markerBounds.Top + markerBounds.Width / 2F;
                points[1].Y = markerBounds.Top;
                points[2].X = markerBounds.Right;
                points[2].Y = markerBounds.Bottom;

                graph.FillPolygon(brush, points);

                // Draw border
                if (borderPen != null)
                {
                    graph.DrawPolygon(borderPen, points);
                }
                break;
            }

            default:
            {
                throw (new InvalidOperationException(SR.ExceptionFastPointMarkerStyleUnknown));
            }
            }

            // Process selection regions
            if (Common.ProcessModeRegions)
            {
                Common.HotRegionsList.AddHotRegion(
                    graph.GetRelativeRectangle(markerBounds),
                    point,
                    point.series.Name,
                    pointIndex);
            }
        }