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);
        }
示例#4
0
        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));
        }
示例#5
0
        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);
        }
示例#6
0
        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++;
            }
        }
示例#8
0
 /// <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;
 }
示例#10
0
        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);
        }