private VisualPoint GetShapes(ChartPoint point, PathFigure pathFigure) { VisualPoint trackable; if (IsPrimitive) { if (Tracker.Primitives.TryGetValue(point.Key, out trackable)) { trackable.IsNew = false; return(trackable); } } else { if (Tracker.Instances.TryGetValue(point.Instance, out trackable)) { trackable.IsNew = false; return(trackable); } } Ellipse e = null; Rectangle hs = null; TextBlock tb = null; if (RequeriesDataPoint) { e = new Ellipse { Width = PointRadius * 2, Height = PointRadius * 2, Stroke = new SolidColorBrush { Color = Chart.PointHoverColor }, StrokeThickness = 1 }; BindingOperations.SetBinding(e, Shape.FillProperty, new Binding { Path = new PropertyPath(StrokeProperty), Source = this }); BindingOperations.SetBinding(e, VisibilityProperty, new Binding { Path = new PropertyPath(VisibilityProperty), Source = this }); } if (Chart.Hoverable) { hs = new Rectangle { Fill = Brushes.Transparent, StrokeThickness = 0 }; BindingOperations.SetBinding(hs, VisibilityProperty, new Binding { Path = new PropertyPath(VisibilityProperty), Source = this }); } if (DataLabels) { tb = BindATextBlock(0); } trackable = new LineVisualPoint(pathFigure) { IsNew = true, HoverShape = hs, Shape = e, TextBlock = tb, Segment = new BezierSegment() }; if (IsPrimitive) { Tracker.Primitives[point.Key] = trackable; } else { Tracker.Instances[point.Instance] = trackable; } return(trackable); //Todo: If Hoverable property changes this could throw a null exception, //When Hoverable property changes, we need to load the shapes again. //or delete then if false, to improve performance. //map.ChartPoint.X = point.X; ToDo This might break something!!! //map.ChartPoint.Y = point.Y; //return new VisualHelper //{ // PointShape = map.Shape, // HoverShape = map.HoverShape, // IsNew = false //}; }
public override void Plot(bool animate = true) { IsPrimitive = Values.Count >= 1 && Values[0].GetType().IsPrimitive; _animSpeed = AnimationsSpeed ?? Chart.AnimationsSpeed; var hoverShapeMinSize = PointRadius < 5 ? 5 : PointRadius; var f = (Chart.Invert ? CurrentXAxis : CurrentYAxis).GetFormatter(); var s = 0; var so = 0; var isUp = Chart is IUnitaryPoints; foreach (var segment in Values.Points.AsSegments().Where(segment => segment.Count != 0)) { LineAndAreaShape area; Point ofPt; var isNew = GetArea(s, isUp, out area, out ofPt); var p0 = ToDrawMargin(segment[0], ScalesXAt, ScalesYAt).AsPoint(); area.Figure.StartPoint = isNew ? (Chart.Invert ? new Point(ToPlotArea(CurrentXAxis.MinLimit, AxisTags.X, ScalesXAt), p0.X) : new Point(p0.X, ToPlotArea(CurrentYAxis.MinLimit, AxisTags.Y, ScalesYAt))) : p0; if (!Chart.DisableAnimations) { area.Figure.BeginAnimation(PathFigure.StartPointProperty, new PointAnimation(area.Figure.StartPoint, segment.Count > 0 ? p0 : new Point(), _animSpeed)); } LineVisualPoint previous = null; var firstIteration = true; var first = new Point(); var last = new Point(); for (var i = 0; i < segment.Count; i++) { var point = segment[i]; point.Location = ToDrawMargin(point, ScalesXAt, ScalesYAt).AsPoint(); if (isUp) { point.Location = new Point(point.Location.X + ofPt.X, point.Location.Y + ofPt.Y); } if (firstIteration) { firstIteration = false; first = point.Location; } var visualPoint = GetShapes(segment[i], area.Figure) as LineVisualPoint; if (visualPoint == null) { continue; } visualPoint.ChartPoint = point; visualPoint.Series = this; PlaceShapes(visualPoint, point, hoverShapeMinSize, f); visualPoint.Data = i == segment.Count - 1 ? new BezierData(previous != null ? previous.Data.Point3 : area.Figure.StartPoint) : CalculateBezier(i, segment); visualPoint.Previous = previous != null && previous.IsNew ? previous.Previous : previous; visualPoint.Animate(i + so, Chart, so, _animSpeed); previous = visualPoint; last = point.Location; } area.DrawLimits(first, last, new Point(ToDrawMargin(CurrentXAxis.MinLimit, AxisTags.X, ScalesXAt), ToDrawMargin(CurrentYAxis.MinLimit, AxisTags.Y, ScalesYAt)), Chart); #if DEBUG Trace.WriteLine("Segments count: " + area.Figure.Segments.Count); #endif s++; so += segment.Count; } }
private void PlaceShapes(LineVisualPoint lineVisualPoint, ChartPoint chartPoint, double radius, Func <double, string> f) { if (lineVisualPoint.HoverShape != null) { lineVisualPoint.HoverShape.Width = radius * 2; lineVisualPoint.HoverShape.Height = radius * 2; Canvas.SetLeft(lineVisualPoint.HoverShape, chartPoint.Location.X - lineVisualPoint.HoverShape.Width * .5); Canvas.SetTop(lineVisualPoint.HoverShape, chartPoint.Location.Y - lineVisualPoint.HoverShape.Height * .5); if (lineVisualPoint.IsNew) { Chart.DrawMargin.Children.Add(lineVisualPoint.HoverShape); Panel.SetZIndex(lineVisualPoint.HoverShape, int.MaxValue); lineVisualPoint.HoverShape.MouseDown += Chart.DataMouseDown; lineVisualPoint.HoverShape.MouseEnter += Chart.DataMouseEnter; lineVisualPoint.HoverShape.MouseLeave += Chart.DataMouseLeave; } } if (lineVisualPoint.Shape != null) { if (lineVisualPoint.IsNew) { Panel.SetZIndex(lineVisualPoint.Shape, int.MaxValue - 2); if (Chart.Invert) { Canvas.SetLeft(lineVisualPoint.Shape, 0d); Canvas.SetTop(lineVisualPoint.Shape, chartPoint.Location.Y - lineVisualPoint.Shape.Height * .5); } else { Canvas.SetLeft(lineVisualPoint.Shape, chartPoint.Location.X - lineVisualPoint.Shape.Width * .5); Canvas.SetTop(lineVisualPoint.Shape, Chart.DrawMargin.Height); } Chart.DrawMargin.Children.Add(lineVisualPoint.Shape); } if (Chart.DisableAnimations) { Canvas.SetTop(lineVisualPoint.Shape, chartPoint.Location.Y - lineVisualPoint.Shape.Height * .5); Canvas.SetLeft(lineVisualPoint.Shape, chartPoint.Location.X - lineVisualPoint.Shape.Width * .5); } else { lineVisualPoint.Shape.BeginAnimation(Canvas.LeftProperty, new DoubleAnimation(chartPoint.Location.X - lineVisualPoint.Shape.Width * .5, _animSpeed)); lineVisualPoint.Shape.BeginAnimation(Canvas.TopProperty, new DoubleAnimation(chartPoint.Location.Y - lineVisualPoint.Shape.Height * .5, _animSpeed)); } } if (lineVisualPoint.TextBlock != null) { var te = f(Chart.Invert ? chartPoint.X : chartPoint.Y); lineVisualPoint.TextBlock.Text = te; lineVisualPoint.TextBlock.UpdateLayout(); lineVisualPoint.TextBlock.Measure(new Size(double.MaxValue, double.MaxValue)); var ft = lineVisualPoint.TextBlock.DesiredSize; var length = chartPoint.Location.X - ft.Width * .5; length = length < 0 ? 0 : (length + ft.Width > Chart.DrawMargin.Width ? Chart.DrawMargin.Width - ft.Width : length); var tp = chartPoint.Location.Y - ft.Height - 5; tp = tp < 0 ? 0 : tp; if (lineVisualPoint.IsNew) { Chart.DrawMargin.Children.Add(lineVisualPoint.TextBlock); Panel.SetZIndex(lineVisualPoint.TextBlock, int.MaxValue - 2); if (Chart.Invert) { Canvas.SetLeft(lineVisualPoint.TextBlock, 0d); Canvas.SetTop(lineVisualPoint.TextBlock, tp); } else { Canvas.SetLeft(lineVisualPoint.TextBlock, length); Canvas.SetTop(lineVisualPoint.TextBlock, Chart.DrawMargin.Height); } } if (Chart.DisableAnimations) { Canvas.SetTop(lineVisualPoint.TextBlock, tp); Canvas.SetLeft(lineVisualPoint.TextBlock, length); } else { lineVisualPoint.TextBlock.BeginAnimation(Canvas.TopProperty, new DoubleAnimation(tp, _animSpeed)); lineVisualPoint.TextBlock.BeginAnimation(Canvas.LeftProperty, new DoubleAnimation(length, _animSpeed)); } } }