private IEnumerable <Shape> _addSerieAsBezier(Point[] points, bool animate = true) { if (points.Length < 2) { return(Enumerable.Empty <Shape>()); } var addedFigures = new List <Shape>(); Point[] cp1, cp2; BezierSpline.GetCurveControlPoints(points, out cp1, out cp2); var lines = new PathSegmentCollection(); var areaLines = new PathSegmentCollection { new LineSegment(points[0], true) }; var l = 0d; for (var i = 0; i < cp1.Length; ++i) { lines.Add(new BezierSegment(cp1[i], cp2[i], points[i + 1], true)); areaLines.Add(new BezierSegment(cp1[i], cp2[i], points[i + 1], true)); //it would be awesome to use a better formula to calculate bezier lenght l += Math.Sqrt( Math.Pow(Math.Abs(cp1[i].X - cp2[i].X), 2) + Math.Pow(Math.Abs(cp1[i].Y - cp2[i].Y), 2)); l += Math.Sqrt( Math.Pow(Math.Abs(cp2[i].X - points[i + 1].X), 2) + Math.Pow(Math.Abs(cp2[i].Y - points[i + 1].Y), 2)); } //aprox factor, it was calculated by aproximation. //the more line is curved, the more it fails. l = l * .65; areaLines.Add(new LineSegment(new Point(points.Max(x => x.X), ToPlotArea(Chart.Min.Y, AxisTags.Y)), true)); var f = new PathFigure(points[0], lines, false); var fa = new PathFigure(new Point(points.Min(x => x.X), ToPlotArea(Chart.Min.Y, AxisTags.Y)), areaLines, false); var g = new PathGeometry(new[] { f }); var ga = new PathGeometry(new[] { fa }); var path = new Path { Stroke = Stroke, StrokeThickness = StrokeThickness, Data = g, StrokeEndLineCap = PenLineCap.Round, StrokeStartLineCap = PenLineCap.Round, StrokeDashOffset = l, StrokeDashArray = new DoubleCollection { l, l }, ClipToBounds = true }; var patha = new Path { StrokeThickness = 0, Data = ga, Fill = Fill, ClipToBounds = true }; Chart.Canvas.Children.Add(path); addedFigures.Add(path); Chart.Canvas.Children.Add(patha); addedFigures.Add(patha); var draw = new DoubleAnimationUsingKeyFrames { BeginTime = TimeSpan.FromSeconds(0), KeyFrames = new DoubleKeyFrameCollection { new SplineDoubleKeyFrame { KeyTime = TimeSpan.FromMilliseconds(1), Value = l }, new SplineDoubleKeyFrame { KeyTime = TimeSpan.FromMilliseconds(750), Value = 0 } } }; Storyboard.SetTarget(draw, path); Storyboard.SetTargetProperty(draw, new PropertyPath(Shape.StrokeDashOffsetProperty)); var sbDraw = new Storyboard(); sbDraw.Children.Add(draw); var animated = false; if (!Chart.DisableAnimation) { if (animate) { sbDraw.Begin(); animated = true; } } if (!animated) { path.StrokeDashOffset = 0; } return(addedFigures); }
private IEnumerable <Shape> _addSerieAsBezier(Point[] points, bool animate = true) { if (points.Length < 2) { return(Enumerable.Empty <Shape>()); } var addedFigures = new List <Shape>(); Point[] cp1, cp2; BezierSpline.GetCurveControlPoints(points, out cp1, out cp2); var lines = new PathSegmentCollection(); var areaLines = new PathSegmentCollection { new LineSegment(points[0], true) }; var l = 0d; for (var i = 0; i < cp1.Length; ++i) { lines.Add(new BezierSegment(cp1[i], cp2[i], points[i + 1], true)); areaLines.Add(new BezierSegment(cp1[i], cp2[i], points[i + 1], true)); l += GetBezierLength(new [] { points[i], cp1[i], cp2[i], points[i + 1] }); } l *= 1.05; l /= StrokeThickness; var lastP = Chart.Invert ? new Point(ToDrawMargin(Chart.Min.X, AxisTags.X), points.Min(x => x.Y)) : new Point(points.Max(x => x.X), ToDrawMargin(Chart.Min.Y, AxisTags.Y)); areaLines.Add(new LineSegment(lastP, true)); var f = new PathFigure(points[0], lines, false); var aOrigin = Chart.Invert ? new Point(ToDrawMargin(Chart.Min.X, AxisTags.X), points.Max(x => x.Y)) : new Point(points.Min(x => x.X), ToDrawMargin(Chart.Min.Y, AxisTags.Y)); var fa = new PathFigure(aOrigin, areaLines, false); var g = new PathGeometry(new[] { f }); var ga = new PathGeometry(new[] { fa }); var path = new Path { Stroke = Stroke, StrokeThickness = StrokeThickness, Data = g, StrokeEndLineCap = PenLineCap.Round, StrokeStartLineCap = PenLineCap.Round, StrokeDashOffset = l, StrokeDashArray = new DoubleCollection { l, l }, ClipToBounds = true }; var patha = new Path { StrokeThickness = 0, Data = ga, Fill = Fill, ClipToBounds = true }; Chart.DrawMargin.Children.Add(path); addedFigures.Add(path); Chart.DrawMargin.Children.Add(patha); addedFigures.Add(patha); var draw = new DoubleAnimationUsingKeyFrames { BeginTime = TimeSpan.FromSeconds(0), KeyFrames = new DoubleKeyFrameCollection { new SplineDoubleKeyFrame { KeyTime = TimeSpan.FromMilliseconds(1), Value = l }, new SplineDoubleKeyFrame { KeyTime = TimeSpan.FromMilliseconds(750), Value = 0 } } }; Storyboard.SetTarget(draw, path); Storyboard.SetTargetProperty(draw, new PropertyPath(Shape.StrokeDashOffsetProperty)); var sbDraw = new Storyboard(); sbDraw.Children.Add(draw); var animated = false; if (!Chart.DisableAnimation) { if (animate) { sbDraw.Begin(); animated = true; } } if (!animated) { path.StrokeDashOffset = 0; } return(addedFigures); }