private void BuildIndividualTrackInfos(ChartDataContext context) { int index = 0; List <DataPointInfo> infos = new List <DataPointInfo>(context.DataPoints); infos.Sort(new DataPointInfoYComparer()); foreach (DataPointInfo info in infos) { ContentPresenter presenter; if (this.individualTrackInfos.Count > index) { presenter = this.individualTrackInfos[index]; presenter.Visibility = Visibility.Visible; } else { presenter = new ContentPresenter(); this.individualTrackInfos.Add(presenter); this.chart.adornerLayer.Children.Add(presenter); } presenter.Content = info; presenter.ContentTemplate = GetTrackInfoTemplate(info.Series); index++; } while (index < this.individualTrackInfos.Count) { this.individualTrackInfos[index].Visibility = Visibility.Collapsed; index++; } }
private void UpdateTrackInfo(ChartDataContext context) { if (!this.showInfo) { return; } // arrange the track content if (this.lineControl.Line.Points.Count == 0) { Debug.Assert(false, "Must have line points initialized."); return; } TrackBallInfoEventArgs args = new TrackBallInfoEventArgs(context); if (this.TrackInfoUpdated != null) { this.TrackInfoUpdated(this, args); } if (this.infoMode == TrackInfoMode.Multiple) { this.trackInfoControl.Update(args); } else { this.BuildIndividualTrackInfos(context); } }
private void UpdateVisuals() { ChartDataContext context = this.GetDataContext(this.position, true); if (context.ClosestDataPoint != null) { var point = context.ClosestDataPoint.DataPoint as CategoricalDataPoint; if (point != null) { List <DataPointInfo> points = null; if (point.Category == null) { points = context.DataPoints.Where(c => c.DataPoint is CategoricalDataPoint && ((CategoricalDataPoint)c.DataPoint).Category == null).ToList(); } else { // select points only with the same category. TODO: Refactor this. points = context.DataPoints.Where(c => c.DataPoint is CategoricalDataPoint && point.Category.Equals(((CategoricalDataPoint)c.DataPoint).Category) ).ToList(); } context = new ChartDataContext(points, context.ClosestDataPoint); } } this.UpdateLine(context); this.UpdateIntersectionPoints(context); this.UpdateTrackInfo(context); }
private object GetTooltipContext(Point location) { ChartDataContext defaultContext = this.GetDataContext(location, true); this.closestDataPointInfo = defaultContext.ClosestDataPoint; if (this.closestDataPointInfo != null && this.closestDataPointInfo.DataPoint.Presenter != null) { var template = GetContentTemplate(this.closestDataPointInfo.DataPoint.Presenter as ChartSeries); if (template != null) { this.toolTipContent.ContentTemplate = template; } if (template == null) { template = GetContentTemplate(this); this.toolTipContent.ContentTemplate = template; } if (template == null) { this.toolTipContent.ClearValue(ContentControl.ContentTemplateProperty); } } return(this.OnContextNeeded(defaultContext)); }
private object OnContextNeeded(ChartDataContext defaultContext) { EventHandler <TooltipContextNeededEventArgs> handler = this.ContextNeeded; if (handler == null) { return(defaultContext.ClosestDataPoint); } TooltipContextNeededEventArgs args = new TooltipContextNeededEventArgs(defaultContext); handler(this, args); return(args.Context != null ? args.Context : defaultContext.ClosestDataPoint); }
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); }
private void UpdateIntersectionPoints(ChartDataContext context) { if (!this.showIntersectionPoints) { return; } int index = 0; Point plotOrigin = this.chart.PlotOrigin; foreach (ContentPresenter presenter in this.intersectionPoints) { presenter.Visibility = Visibility.Collapsed; } foreach (DataPointInfo info in context.DataPoints) { DataTemplate template = GetIntersectionTemplate(info.Series); if (template == null) { continue; } ContentPresenter presenter = this.GetIntersectionPointPresenter(index); presenter.Visibility = Visibility.Visible; presenter.Content = info; presenter.ContentTemplate = template; presenter.Measure(RadChartBase.InfinitySize); Point center = info.DataPoint.Center(); Size desiredSize = presenter.DesiredSize; Canvas.SetLeft(presenter, center.X - Math.Abs(plotOrigin.X) - (desiredSize.Width / 2)); Canvas.SetTop(presenter, center.Y - Math.Abs(plotOrigin.Y) - (desiredSize.Height / 2)); index++; } }
/// <summary> /// Initializes a new instance of the <see cref="TrackBallInfoEventArgs"/> class. /// </summary> /// <param name="context">The context.</param> public TrackBallInfoEventArgs(ChartDataContext context) { this.context = context; }
/// <summary> /// Initializes a new instance of the TooltipContextNeededEventArgs class. /// </summary> /// <param name="defaultContext">The default context which will be used if no new context is provided.</param> public TooltipContextNeededEventArgs(ChartDataContext defaultContext) { this.DefaultContext = defaultContext; }
private void UpdateLine(ChartDataContext context) { this.lineControl.Line.Points.Clear(); Point plotOrigin = this.chart.PlotOrigin; if (this.snapMode == TrackBallSnapMode.AllClosePoints) { Point[] points = new Point[context.DataPoints.Count]; int index = 0; foreach (DataPointInfo info in context.DataPoints) { Point center = info.DataPoint.Center(); center.X += plotOrigin.X; center.Y += plotOrigin.Y; points[index++] = center; } Array.Sort(points, new PointYComparer()); foreach (Point point in points) { this.lineControl.Line.Points.Add(point); } } else if (this.snapMode == TrackBallSnapMode.ClosestPoint && context.ClosestDataPoint != null) { Point center = context.ClosestDataPoint.DataPoint.Center(); center.X += plotOrigin.X; center.Y += plotOrigin.Y; // Temporary fix for NAN values. Remove when the chart starts to support null values. if (double.IsNaN(center.X)) { center.X = 0; } if (double.IsNaN(center.Y)) { center.Y = this.chart.chartArea.plotArea.layoutSlot.Bottom; } this.lineControl.Line.Points.Add(center); } RadRect plotArea = this.chart.chartArea.plotArea.layoutSlot; Point topPoint; Point bottomPoint; if (this.lineControl.Line.Points.Count > 0) { topPoint = new Point(this.lineControl.Line.Points[0].X, plotArea.Y); bottomPoint = new Point(this.lineControl.Line.Points[this.lineControl.Line.Points.Count - 1].X, plotArea.Bottom); } else { topPoint = new Point(this.position.X, plotArea.Y); bottomPoint = new Point(this.position.X, plotArea.Bottom); } this.lineControl.Line.Points.Insert(0, topPoint); this.lineControl.Line.Points.Insert(this.lineControl.Line.Points.Count, bottomPoint); }