/// <inheritdoc/> /// see https://github.com/oxyplot/oxyplot/blob/develop/Source/OxyPlot/Series/ScatterSeries%7BT%7D.cs#L322-L460 public override void Render(IRenderContext rc) { var actualPoints = ActualPointsList; if (actualPoints == null || actualPoints.Count == 0) { return; } var clippingRect = GetClippingRect(); var n = actualPoints.Count; var allPoints = new List <ScreenPoint>(n); var allMarkerSizes = new List <double>(n); var groupPoints = new Dictionary <int, IList <ScreenPoint> >(); var groupSizes = new Dictionary <int, IList <double> >(); // Transform all points to screen coordinates for (var i = 0; i < n; i++) { var dp = new DataPoint(actualPoints[i].X, actualPoints[i].Y); // Skip invalid points if (!IsValidPoint(dp)) { continue; } var size = double.NaN; var value = double.NaN; var scatterPoint = actualPoints[i]; if (scatterPoint != null) { size = scatterPoint.Size; value = scatterPoint.Value; } if (double.IsNaN(size)) { size = MarkerSize; } // Transform from data to screen coordinates var screenPoint = this.Transform(dp.X, dp.Y); if (ColorAxis != null) { if (double.IsNaN(value)) { continue; } var group = ColorAxis.GetPaletteIndex(value); if (!groupPoints.ContainsKey(group)) { groupPoints.Add(group, new List <ScreenPoint>()); groupSizes.Add(group, new List <double>()); } groupPoints[group].Add(screenPoint); groupSizes[group].Add(size); } else { allPoints.Add(screenPoint); allMarkerSizes.Add(size); } } // Offset of the bins var binOffset = this.Transform(MinX, MaxY); if (ColorAxis != null) { // Draw the grouped (by color defined in ColorAxis) markers var markerIsStrokedOnly = MarkerType == MarkerType.Plus || MarkerType == MarkerType.Star || MarkerType == MarkerType.Cross; foreach (var(key, value) in groupPoints) { var color = ColorAxis.GetColor(key); rc.DrawMarkers( value, MarkerType, MarkerOutline, groupSizes[key], OxyColor.FromAColor(Opacity, MarkerFill.GetActualColor(color)), markerIsStrokedOnly ? color : MarkerStroke, MarkerStrokeThickness, EdgeRenderingMode, BinSize, binOffset); } } rc.DrawMarkers( allPoints, MarkerType, MarkerOutline, allMarkerSizes, OxyColor.FromAColor(Opacity, ActualMarkerFillColor), MarkerStroke, MarkerStrokeThickness, EdgeRenderingMode, BinSize, binOffset); if (LabelFormatString != null) { RenderPointLabels(rc, clippingRect); } }