internal ChartDataContext GetDataContext(Point physicalOrigin, ChartPointDistanceCalculationMode pointDistanceMode) { // The tool tip location has to be translated because the data points are laid out in a larger layout slot if there is a zoom factor. // Also, the absolute value of the pan offset is used in the transformation because the pan offset is applied as a negative value to // the visualization of the plot area in order to simulate pan behavior. RadRect plotAreaClip = this.PlotAreaClip; physicalOrigin.X += Math.Abs(plotAreaClip.Width * this.scrollOffsetCache.X); physicalOrigin.Y += Math.Abs(plotAreaClip.Height * this.scrollOffsetCache.Y); if (this.lastDataContext != null && this.lastDataContext.TouchLocation == physicalOrigin) { return(this.lastDataContext); } this.lastDataContext = this.GetDataContextCore(physicalOrigin, pointDistanceMode); return(this.lastDataContext); }
internal override double GetDistanceToPoint(DataPoint dataPoint, Point tapLocation, ChartPointDistanceCalculationMode pointDistanceMode) { var pieDataPoint = dataPoint as PieDataPoint; if (pieDataPoint != null && pointDistanceMode == ChartPointDistanceCalculationMode.TwoDimensional) { // TODO: Consider whether we will need linear distance. return(pieDataPoint.GetPolarDistance(tapLocation)); } return(base.GetDistanceToPoint(dataPoint, tapLocation, pointDistanceMode)); }
internal virtual double GetDistanceToPoint(DataPoint dataPoint, Point tapLocation, ChartPointDistanceCalculationMode pointDistanceMode) { var dataPointLocation = dataPoint.Center(); if (pointDistanceMode == ChartPointDistanceCalculationMode.TwoDimensional) { ////TODO: Math.Sqrt could lead to potential performance issues with lost of points/series. return(RadMath.GetPointDistance(dataPointLocation.X, tapLocation.X, dataPointLocation.Y, tapLocation.Y)); } else { AxisPlotDirection plotDirection = this.Model.GetTypedValue <AxisPlotDirection>(AxisModel.PlotDirectionPropertyKey, AxisPlotDirection.Vertical); if (plotDirection == AxisPlotDirection.Vertical) { return(Math.Abs(tapLocation.X - dataPointLocation.X)); } else { return(Math.Abs(tapLocation.Y - dataPointLocation.Y)); } } }
/// <summary> /// Gets <see cref="ChartDataContext"/> associated with a gives physical location. /// </summary> /// <param name="tapLocation">The relative physical position of the requested data context.</param> /// <param name="pointDistanceMode">The point distance calculation mode to be used in finding closest point.</param> /// <returns>Returns <see cref="ChartDataContext"/> object holding information for the requested physical location.</returns> protected virtual ChartDataContext GetDataContextCore(Point tapLocation, ChartPointDistanceCalculationMode pointDistanceMode) { List <DataPointInfo> closestPoints = new List <DataPointInfo>(); double totalMinDistance = double.PositiveInfinity; DataPointInfo closestPoint = null; foreach (ChartSeriesModel series in this.chartArea.Series) { if (!series.Presenter.IsVisible) { continue; } DataPointInfo currentClosestDataPoint = null; double minDistance = double.PositiveInfinity; ChartSeries visualSeries = series.presenter as ChartSeries; foreach (DataPoint dataPoint in series.DataPointsInternal) { if (dataPoint.isEmpty) { continue; } double distance; if (dataPoint.ContainsPosition(tapLocation.X, tapLocation.Y)) { distance = 0; } else { distance = visualSeries.GetDistanceToPoint(dataPoint, tapLocation, pointDistanceMode); } if (distance < minDistance) { minDistance = distance; if (currentClosestDataPoint == null) { currentClosestDataPoint = new DataPointInfo(); } currentClosestDataPoint.DataPoint = dataPoint; currentClosestDataPoint.SeriesModel = series; } if (distance < totalMinDistance) { totalMinDistance = distance; closestPoint = currentClosestDataPoint; if (distance == 0) { closestPoint.ContainsTouchLocation = true; } } } if (currentClosestDataPoint != null) { closestPoints.Add(currentClosestDataPoint); } } return(new ChartDataContext(closestPoints, closestPoint) { TouchLocation = tapLocation }); }