private void VisualizeGraph(RainData rainData, bool animated = true) { List<int> pointValues; if (rainData == null || rainData.Points == null) pointValues = new List<int>(); else pointValues = rainData.Points.Take(25).Select(p => p.AdjustedValue).ToList(); while (pointValues.Count < 25) pointValues.Add(pointValues.LastOrDefault()); var path = GraphView.Data as PathGeometry; var graphSize = new Size(GraphContainer.ActualWidth, GraphContainer.ActualHeight); var step = graphSize.Width / Model.Entries; Func<int, double> xForIndex = idx => idx == 0 ? -2 : idx * step; var x = 0; var max = (graphSize.Height / 12.0 * 11.0) - 10; var allZeros = pointValues.Take(Model.Entries + 1).All(p => p == 0); var points = pointValues.Select(v => { var y = allZeros ? max - 20 : Math.Max(1, max - (v * max / 100)); var p = new Point(xForIndex(x), y); x++; return p; }).ToList(); points.Add(new Point(graphSize.Width + 2, points.Last().Y)); points.Add(new Point(graphSize.Width + 2, graphSize.Height + 2)); PathFigure figure; var startPoint = new Point(-2.0, graphSize.Height + 2); if (path == null) { path = new PathGeometry(); figure = new PathFigure() { StartPoint = startPoint, IsClosed = true }; path.Figures.Add(figure); foreach (var p in points) { figure.Segments.Add(new LineSegment() { Point = p }); } GraphView.Data = path; } var entriesAnimated = graphEntries != Model.Entries && graphEntries > 0 && Model.Entries > 0; if (entriesAnimated) UpdateEntriesImage(); var ms300 = TimeSpan.FromMilliseconds(entriesAnimated ? 450 / Math.Abs(Model.Entries - graphEntries) : animated ? 300 : 0); graphEntries = Model.Entries; var storyboard = new Storyboard() { Duration = ms300 }; figure = path.Figures[0]; var anim = new PointAnimation() { Duration = ms300, To = startPoint, FillBehavior = FillBehavior.HoldEnd, EnableDependentAnimation = true }; Storyboard.SetTarget(anim, figure); Storyboard.SetTargetProperty(anim, "StartPoint"); storyboard.Children.Add(anim); for (var i = 0; i < points.Count; ++i) { anim = new PointAnimation() { Duration = ms300, To = points[i], FillBehavior = FillBehavior.HoldEnd, EnableDependentAnimation = true }; Storyboard.SetTarget(anim, figure.Segments[i]); Storyboard.SetTargetProperty(anim, "Point"); storyboard.Children.Add(anim); } var strokeAnim = new ColorAnimation() { Duration = ms300, FillBehavior = FillBehavior.HoldEnd, To = allZeros ? Colors.Transparent : graphStrokeColor, EnableDependentAnimation = true }; Storyboard.SetTarget(strokeAnim, GraphView.Stroke); Storyboard.SetTargetProperty(strokeAnim, "Color"); storyboard.Children.Add(strokeAnim); var fillTopAnim = new ColorAnimation() { Duration = ms300, FillBehavior = FillBehavior.HoldEnd, To = allZeros ? Colors.Black : graphFillFrom, EnableDependentAnimation = true }; Storyboard.SetTarget(fillTopAnim, ((LinearGradientBrush)GraphView.Fill).GradientStops[0]); Storyboard.SetTargetProperty(fillTopAnim, "Color"); storyboard.Children.Add(fillTopAnim); storyboard.Begin(() => GraphView.Data = path); }
private async void VisualizeRain(RainData rainData) { if (Model.RainWasUpdated) Animatable.Mode = AnimatableMode.Forced; Model.RainWasUpdated = false; string chanceText; Color chanceColor; string mmImage; string mmText; var chance = rainData != null ? rainData.ChanceForEntries(Model.Entries) : -1; if (chance >= 0) { chanceText = string.Format("{0}%", chance); chanceColor = Colors.White; } else { chanceText = "?"; chanceColor = Colors.DarkGray; } var intensity = 0; var mm = 0.0; if (rainData != null) { mm = rainData.PrecipitationForEntries(Model.Entries); intensity = rainData.IntensityForEntries(Model.Entries); } if (intensity > 0 || mm > 0) { mm = Math.Max(mm, 0.001); intensity = ((int)Math.Max(1, Math.Min(1 + intensity / 25.0, 4))); var format = mm < 0.01 ? "{0:0.000}" : "{0:0.00}"; mmText = Math.Floor(mm) == mm ? string.Format("{0}", (int)mm) : string.Format(format, mm); mmImage = intensity.ToString(CultureInfo.InvariantCulture); } else { mmText = "0"; mmImage = "0"; } mmText = mmText + "\nmm"; string night; if (intensity == 0 && Model.Location != null) { var solarinfo = SolarInfo.ForDate(Model.Location.Latitude, Model.Location.Longitude, DateTime.Now); var sunrisen = solarinfo.Sunrise < DateTime.UtcNow && DateTime.UtcNow < solarinfo.Sunset; night = !sunrisen ? "n" : "d"; } else { night = ""; } mmImage = string.Format("ms-appx:/Assets/intensity{0}{1}.png", mmImage, night); // we have to jump through silly hoops to have the text change if (Animatable.Mode == AnimatableMode.Forced) { Animatable.Mode = AnimatableMode.Disabled; if (Chance == chanceText) Chance = null; if (Precipitation == mmText) Precipitation = null; Animatable.Mode = AnimatableMode.Forced; } Chance = chanceText; Precipitation = mmText; IntensityImage = new BitmapImage(new Uri(mmImage)); await Task.Delay(500); Animatable.Mode = AnimatableMode.Enabled; }