/// <summary> /// Fills a SKPoint array of data points absolute pixel positions. /// </summary> /// <param name="graph">Graphics object.</param> /// <param name="area">Chart area.</param> /// <param name="series">Point series.</param> /// <returns>Array of data points position.</returns> override protected SKPoint[] GetPointsPosition(ChartGraphics graph, ChartArea area, Series series) { SKPoint[] pointPos = new SKPoint[series.Points.Count + 1]; int index = 0; foreach (DataPoint point in series.Points) { // Change Y value if line is out of plot area double yValue = GetYValue(Common, area, series, point, index, 0); // Recalculates y position double yPosition = area.AxisY.GetPosition(yValue); // Recalculates x position double xPosition = area.circularCenter.X; // Add point position into array pointPos[index] = graph.GetAbsolutePoint(new SKPoint((float)xPosition, (float)yPosition)); // Rotate position float sectorAngle = area.CircularPositionToAngle(point.XValue); SKMatrix matrix = SkiaSharpExtensions.CreateRotationDegrees(sectorAngle, graph.GetAbsolutePoint(area.circularCenter)); SKPoint[] rotatedPoint = new SKPoint[] { pointPos[index] }; matrix.TransformPoints(rotatedPoint); pointPos[index] = rotatedPoint[0]; index++; } // Add last center point pointPos[index] = graph.GetAbsolutePoint(area.circularCenter); return(pointPos); }
/// <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); } }