/// <summary> /// Returns the index of a scatter point that is nearest to the location <c>hitpoint</c> /// </summary> /// <param name="layer">The layer in which this plot item is drawn into.</param> /// <param name="hitpoint">The point where the mouse is pressed.</param> /// <returns>The information about the point that is nearest to the location, or null if it can not be determined.</returns> public XYScatterPointInformation GetNearestPlotPoint(IPlotArea layer, PointF hitpoint) { Processed2DPlotData pdata; if (null != (pdata = _cachedPlotDataUsedForPainting)) { PlotRangeList rangeList = pdata.RangeList; PointF[] ptArray = pdata.PlotPointsInAbsoluteLayerCoordinates; double mindistance = double.MaxValue; int minindex = -1; for (int i = 1; i < ptArray.Length; i++) { double distance = Drawing2DRelated.SquareDistanceLineToPoint(ptArray[i - 1], ptArray[i], hitpoint); if (distance < mindistance) { mindistance = distance; minindex = Drawing2DRelated.Distance(ptArray[i - 1], hitpoint) < Drawing2DRelated.Distance(ptArray[i], hitpoint) ? i - 1 : i; } } // ok, minindex is the point we are looking for // so we have a look in the rangeList, what row it belongs to int rowindex = rangeList.GetRowIndexForPlotIndex(minindex); return(new XYScatterPointInformation(ptArray[minindex], rowindex, minindex)); } return(null); }
/// <summary> /// Test wether the mouse hits a plot item. /// </summary> /// <param name="layer">The layer in which this plot item is drawn into.</param> /// <param name="hitpoint">The point where the mouse is pressed.</param> /// <returns>Null if no hit, or a <see cref="IHitTestObject" /> if there was a hit.</returns> public override IHitTestObject HitTest(IPlotArea layer, PointF hitpoint) { Processed2DPlotData pdata = _cachedPlotDataUsedForPainting; if (null == pdata) { return(null); } PlotRangeList rangeList = pdata.RangeList; PointF[] ptArray = pdata.PlotPointsInAbsoluteLayerCoordinates; if (ptArray.Length < 2048) { GraphicsPath gp = new GraphicsPath(); gp.AddLines(ptArray); if (gp.IsOutlineVisible(hitpoint.X, hitpoint.Y, new Pen(Color.Black, 5))) { gp.Widen(new Pen(Color.Black, 5)); return(new HitTestObject(gp, this)); } } else // we have too much points for the graphics path, so make a hit test first { int hitindex = -1; for (int i = 1; i < ptArray.Length; i++) { if (Drawing2DRelated.IsPointIntoDistance(ptArray[i - 1], ptArray[i], hitpoint, 5)) { hitindex = i; break; } } if (hitindex < 0) { return(null); } GraphicsPath gp = new GraphicsPath(); int start = Math.Max(0, hitindex - 1); gp.AddLine(ptArray[start], ptArray[start + 1]); gp.AddLine(ptArray[start + 1], ptArray[start + 2]); gp.Widen(new Pen(Color.Black, 5)); return(new HitTestObject(gp, this)); } return(null); }