private void Canvas_Draw(CanvasControl sender, CanvasDrawEventArgs args) { if (ItemTemplate == null) { return; } if (ItemsSource == null) { return; } var repairedItemsSource = ItemsSource.Cast <ChartDataItem>().Where(item => item.Part > 0.01).ToList(); var newSum = repairedItemsSource.Sum(i => i.Value); foreach (var item in repairedItemsSource) { item.Part = item.Value / newSum; } var d = 0d; foreach (var item in repairedItemsSource) { var chartItem = (DoughnutChartItem)ItemTemplate.LoadContent(); if (chartItem == null) { return; } chartItem.DataContext = item; if (chartItem.Color == default(Color)) { chartItem.Color = DefaultColors.GetRandom(); } var sweepAngle = chartItem.Angle; var startAngle = (float)(d - Math.PI / 2); d += sweepAngle; var center = new Vector2((float)(ActualWidth / 2), (float)(ActualHeight / 2)); var radius = center.X > center.Y ? new Vector2(center.Y) : new Vector2(center.X); var startPoint = center + Vector2.Transform(Vector2.UnitX, Matrix3x2.CreateRotation(startAngle)) * radius; var relativeDistance = Distance / radius.X; var relativeSecondDistance = Distance / (radius.X - Thickness / 2); var repairSweepAngle = sweepAngle > relativeDistance ? sweepAngle - relativeDistance : 0; var repairSecondSweepAngle = sweepAngle > relativeSecondDistance / 2 ? sweepAngle - relativeSecondDistance / 2 : 0; using (var builder = new CanvasPathBuilder(canvas)) { builder.BeginFigure(startPoint); builder.AddArc(center, radius.X, radius.Y, (float)(startAngle + relativeDistance / 2), (float)repairSweepAngle); builder.AddArc(center, radius.X - (float)Thickness / 2, (float)(radius.Y - Thickness / 2), (float)(startAngle + sweepAngle - relativeSecondDistance / 2), -(float)repairSecondSweepAngle); builder.EndFigure(CanvasFigureLoop.Closed); args.DrawingSession.FillGeometry( CanvasGeometry.CreatePath(builder), chartItem.Color); } } }
private void Canvas_Draw(CanvasControl sender, CanvasDrawEventArgs args) { if (ItemTemplate == null) { return; } if (ItemsSource == null) { return; } /* * var items = ItemsSource.Select(o => { * var item = ItemTemplate.LoadContent() as LineChartItem; * item.DataContext = o; * return item; * }).ToList(); */ List <LineChartItem> items = new List <LineChartItem>(); foreach (LineChartItem item in ItemsSource) { items.Add(item); } if (!items.Any()) { return; } var availableWidth = (float)_canvas.ActualWidth; var availableHeight = (float)_canvas.ActualHeight; var fill = Fill ?? new SolidColorBrush(DefaultColors.GetRandom()); var elementWidth = availableWidth / (items.Count - 1); var radius = (float)(Thickness * 2); var min = items.Min(i => i.Value); var max = items.Max(i => i.Value); var diff = max - min; var d = diff * 0.01; #region Add X captions _xCap.Children.Clear(); _xCap.Children.Add(new TextBlock { Text = "Test",//items.First().Key.ToString(), HorizontalAlignment = HorizontalAlignment.Left, VerticalAlignment = VerticalAlignment.Stretch }); _xCap.Children.Add(new TextBlock { Text = "Test", //items.Last().Key.ToString(), HorizontalAlignment = HorizontalAlignment.Right, VerticalAlignment = VerticalAlignment.Stretch }); #endregion #region Add Y captions _yCap.Children.Clear(); if (YAxis == YMode.FromMin) { _yCap.Children.Add(new TextBlock { Text = min.ToString(), HorizontalAlignment = HorizontalAlignment.Stretch, VerticalAlignment = VerticalAlignment.Bottom }); } else { _yCap.Children.Add(new TextBlock { Text = "0", HorizontalAlignment = HorizontalAlignment.Stretch, VerticalAlignment = VerticalAlignment.Bottom }); _yCap.Children.Add(new TextBlock { Text = min.ToString(), HorizontalAlignment = HorizontalAlignment.Stretch, VerticalAlignment = VerticalAlignment.Bottom, Margin = new Thickness(0, 0, 0, -10 + min * availableHeight / max) }); } _yCap.Children.Add(new TextBlock { Text = max.ToString(), HorizontalAlignment = HorizontalAlignment.Stretch, VerticalAlignment = VerticalAlignment.Top, }); #endregion // Draw lines using (var builder = new CanvasPathBuilder(sender)) { for (var i = 0; i < items.Count; i++) { var item = items[i]; var x = i * elementWidth; var y = availableHeight - (YAxis == YMode.FromMin ? (float)((item.Value - min) * availableHeight / diff) : (float)(item.Value * availableHeight / max)); // Fixes for edge points if (max - item.Value < d) { y += radius; } if (item.Value - min < d) { y -= radius; } // Main drawing if (i == 0) { builder.BeginFigure(x, y); } else { builder.AddLine(x, y); } } builder.EndFigure(CanvasFigureLoop.Open); using (var geometry = CanvasGeometry.CreatePath(builder)) args.DrawingSession.DrawGeometry(geometry, fill.Color, (float)Thickness); // Draw axis var color = ForegroundColor; args.DrawingSession.DrawLine(0, 0, 0, availableHeight, Colors.Black, 1); args.DrawingSession.DrawLine(0, availableHeight, availableWidth, availableHeight, Colors.Black, 1); } }
private void Redraw() { if (ItemTemplate == null) { return; } if (ItemsSource == null) { return; } _root.Children.Clear(); //double valueSum = 0; List <DoughnutChartItem> Items = new List <DoughnutChartItem>(); List <DoughnutChartItem> ItemsGood = new List <DoughnutChartItem>(); foreach (ChartPart item in ItemsSource) { Items.Add(new DoughnutChartItem { Value = item.UnrelativeValue, Color = item.SolidColorBrush.Color, }); } double valueSum = Items.Sum(i => i.Value); foreach (DoughnutChartItem chartItem in Items) { if (chartItem.Value / valueSum > 0.01) { ItemsGood.Add(chartItem); } } valueSum = ItemsGood.Sum(i => i.Value); foreach (DoughnutChartItem chartItem in ItemsGood) { if (chartItem.Color == default(Color)) { chartItem.Color = DefaultColors.GetRandom(); } var arc = new Arc { Thickness = Thickness, Distance = Distance }; arc.DataContext = chartItem; chartItem.Value = chartItem.Value / valueSum; // Angle var angleBinding = new Binding { Path = new PropertyPath(nameof(DoughnutChartItem.Angle)) }; arc.SetBinding(Arc.SweepAngleProperty, angleBinding); // Fill var fillBinding = new Binding { Path = new PropertyPath(nameof(DoughnutChartItem.Fill)) }; arc.SetBinding(Arc.FillProperty, fillBinding); _root.Children.Add(arc); } /* * for (var i = 0; i < ItemsSource.Count; i++) { * var c = i; * var chartItem = ItemTemplate.LoadContent() as DoughnutChartItem; * if (chartItem == null) * return; * chartItem.DataContext = ItemsSource[c]; * if (chartItem.Color == default(Color)) * chartItem.Color = DefaultColors.GetRandom(); * var arc = new Arc { * Thickness = Thickness, * Distance = Distance * }; * arc.DataContext = chartItem; * // Angle * var angleBinding = new Binding { * Path = new PropertyPath(nameof(DoughnutChartItem.Angle)) * }; * arc.SetBinding(Arc.SweepAngleProperty, angleBinding); * // Fill * var fillBinding = new Binding { * Path = new PropertyPath(nameof(DoughnutChartItem.Fill)) * }; * arc.SetBinding(Arc.FillProperty, fillBinding); * _root.Children.Add(arc); * } */ UpdateStartAngles(); }
private void Canvas_Draw(CanvasControl sender, CanvasDrawEventArgs args) { if (ItemTemplate == null) { return; } if (ItemsSource == null) { return; } var items = ItemsSource.Cast <LineChartItem>().ToList(); if (!items.Any()) { return; } var availableWidth = (float)_canvas.ActualWidth; var availableHeight = (float)_canvas.ActualHeight; var fill = Fill ?? new SolidColorBrush(DefaultColors.GetRandom()); var elementWidth = (availableWidth - (Thickness * 2)) / (items.Count - 1); var radius = (float)(Thickness * 2); var min = items.Min(i => i.Value); var max = items.Max(i => i.Value); var diff = max - min; var d = diff * 0.01; #region Add X captions _xCap.Children.Clear(); _xCap.Children.Add(new TextBlock { // Text = items.First().Key.ToString(), HorizontalAlignment = HorizontalAlignment.Left, VerticalAlignment = VerticalAlignment.Stretch }); _xCap.Children.Add(new TextBlock { // Text = items.Last().Key.ToString(), HorizontalAlignment = HorizontalAlignment.Right, VerticalAlignment = VerticalAlignment.Stretch }); #endregion /* #region Add Y captions * _yCap.Children.Clear(); * if (YAxis == YMode.FromMin) { * _yCap.Children.Add(new TextBlock { * Text = min.ToString(), * HorizontalAlignment = HorizontalAlignment.Stretch, * VerticalAlignment = VerticalAlignment.Bottom * }); * } * else { * _yCap.Children.Add(new TextBlock { * Text = "0", * HorizontalAlignment = HorizontalAlignment.Stretch, * VerticalAlignment = VerticalAlignment.Bottom * }); * _yCap.Children.Add(new TextBlock { * Text = min.ToString(), * HorizontalAlignment = HorizontalAlignment.Stretch, * VerticalAlignment = VerticalAlignment.Bottom, * Margin = new Thickness(0, 0, 0, -10 + min * availableHeight / max) * }); * } * _yCap.Children.Add(new TextBlock { * Text = max.ToString(), * HorizontalAlignment = HorizontalAlignment.Stretch, * VerticalAlignment = VerticalAlignment.Top, * }); #endregion * */ IList <Vector2> array = new List <Vector2>(); IList <Vector2> controlPoints = new List <Vector2>(); for (var i = 0; i < items.Count; i++) { var item = items[i]; var x = (float)(i * (elementWidth) + Thickness); var y = availableHeight - (YAxis == YMode.FromMin ? (float)((item.Value - min) * availableHeight / diff) : (float)(item.Value * availableHeight / max)); // Fixes for edge points if (max - item.Value < d) { y += radius; } if (item.Value - min < d) { y -= radius; } array.Add(new Vector2(x, y)); } for (int i = 1; i < array.Count - 1; i++) { Vector2[] controlPoint2 = CalculateControlPoints(array[i - 1], array[i], array[i + 1]); controlPoints.Add(controlPoint2[0]); controlPoints.Add(controlPoint2[1]); } // Fill area using (var fillBuilder = new CanvasPathBuilder(sender)) { // Draw lines using (var drawBuilder = new CanvasPathBuilder(sender)) { for (int i = 0; i < array.Count; i++) { if (i == 0) { drawBuilder.BeginFigure(array[i]); fillBuilder.BeginFigure(array[i]); } else if (i == 1 && array.Count == 2) { drawBuilder.AddCubicBezier(array[0], array[1], array[1]); fillBuilder.AddCubicBezier(array[0], array[1], array[1]); } else if (i == 1 && array.Count > 2) { drawBuilder.AddCubicBezier(array[0], controlPoints[0], array[1]); fillBuilder.AddCubicBezier(array[0], controlPoints[0], array[1]); } else if (i < array.Count - 1) { drawBuilder.AddCubicBezier(controlPoints[i * 2 - 3], controlPoints[i * 2 - 2], array[i]); fillBuilder.AddCubicBezier(controlPoints[i * 2 - 3], controlPoints[i * 2 - 2], array[i]); } else if (array.Count > 1) { drawBuilder.AddCubicBezier(controlPoints[i * 2 - 3], array[i], array[i]); fillBuilder.AddCubicBezier(controlPoints[i * 2 - 3], array[i], array[i]); } } drawBuilder.EndFigure(CanvasFigureLoop.Open); using (var geometry = CanvasGeometry.CreatePath(drawBuilder)) { CanvasStrokeStyle strokeStyle = new CanvasStrokeStyle { EndCap = CanvasCapStyle.Round, StartCap = CanvasCapStyle.Round }; Color startColor = fill.Color; Color startColor2 = fill.Color; startColor2.A = 150; CanvasLinearGradientBrush ee = new CanvasLinearGradientBrush(_canvas, startColor, startColor2) { StartPoint = new Vector2(0, 0), EndPoint = new Vector2(0, availableHeight) }; args.DrawingSession.DrawGeometry(geometry, ee, (float)Thickness, strokeStyle); } fillBuilder.AddLine(array.Last().X, availableHeight); fillBuilder.AddLine(array[0].X, availableHeight); fillBuilder.EndFigure(CanvasFigureLoop.Closed); using (var geometry = CanvasGeometry.CreatePath(fillBuilder)) { Color startColor = fill.Color; startColor.A = 50; CanvasLinearGradientBrush ee = new CanvasLinearGradientBrush(_canvas, startColor, Colors.Transparent) { StartPoint = new Vector2(0, 0), EndPoint = new Vector2(0, availableHeight) }; args.DrawingSession.FillGeometry(geometry, ee); } } } args.DrawingSession.DrawLine( 0, availableHeight, availableWidth, availableHeight + 16, Color.FromArgb(35, 255, 255, 255), 0.5f); // Draw axis Color color = ((SolidColorBrush)Foreground).Color; color.A = 40; CanvasStrokeStyle strokeStyle2 = new CanvasStrokeStyle { CustomDashStyle = new float[] { 2, 4 }, }; var part = (availableHeight - 2 * radius) / 3; for (int i = 0; i < 4; i++) { var yPos = radius + i * part; args.DrawingSession.DrawLine(0, yPos, availableWidth, yPos, color, 1, strokeStyle2); } }
private void Canvas_Draw(CanvasControl sender, CanvasDrawEventArgs args) { if (ItemTemplate == null) { return; } if (ItemsSource == null) { return; } var items = ItemsSource.Select(o => { var item = ItemTemplate.LoadContent() as LineChartItem; item.DataContext = o; return(item); }).ToList(); if (!items.Any()) { return; } var availableWidth = (float)_canvas.ActualWidth; var availableHeight = (float)_canvas.ActualHeight - 32; var fill = Fill ?? new SolidColorBrush(DefaultColors.GetRandom()); var elementWidth = (availableWidth - (Thickness * 2)) / (items.Count - 1); var radius = (float)(Thickness * 2); var min = items.Min(i => i.Value); var max = items.Max(i => i.Value); var diff = max - min; var d = diff * 0.01; #region Add X captions _xCap.Children.Clear(); _xCap.Children.Add(new TextBlock { Text = items.First().Key.ToString(), HorizontalAlignment = HorizontalAlignment.Left, VerticalAlignment = VerticalAlignment.Stretch }); _xCap.Children.Add(new TextBlock { Text = items.Last().Key.ToString(), HorizontalAlignment = HorizontalAlignment.Right, VerticalAlignment = VerticalAlignment.Stretch }); #endregion /* #region Add Y captions * _yCap.Children.Clear(); * if (YAxis == YMode.FromMin) { * _yCap.Children.Add(new TextBlock { * Text = min.ToString(), * HorizontalAlignment = HorizontalAlignment.Stretch, * VerticalAlignment = VerticalAlignment.Bottom * }); * } * else { * _yCap.Children.Add(new TextBlock { * Text = "0", * HorizontalAlignment = HorizontalAlignment.Stretch, * VerticalAlignment = VerticalAlignment.Bottom * }); * _yCap.Children.Add(new TextBlock { * Text = min.ToString(), * HorizontalAlignment = HorizontalAlignment.Stretch, * VerticalAlignment = VerticalAlignment.Bottom, * Margin = new Thickness(0, 0, 0, -10 + min * availableHeight / max) * }); * } * _yCap.Children.Add(new TextBlock { * Text = max.ToString(), * HorizontalAlignment = HorizontalAlignment.Stretch, * VerticalAlignment = VerticalAlignment.Top, * }); #endregion * */ IList <Vector2> array = new List <Vector2>(); // IList<Vector2> controlPoints = new List<Vector2>(); // CanvasGeometry path; // Draw lines using (var builder = new CanvasPathBuilder(sender)) { for (var i = 0; i < items.Count; i++) { var item = items[i]; var x = (float)(i * (elementWidth) + Thickness); var y = 16 + availableHeight - (YAxis == YMode.FromMin ? (float)((item.Value - min) * availableHeight / diff) : (float)(item.Value * availableHeight / max)); // Fixes for edge points if (max - item.Value < d) { y += radius; } if (item.Value - min < d) { y -= radius; } if (i == 0) { builder.BeginFigure(x, y); } else { builder.AddLine(x, y); } array.Add(new Vector2(x, y)); } builder.EndFigure(CanvasFigureLoop.Open); args.DrawingSession.DrawLine(0, availableHeight + 16, availableWidth, availableHeight + 16, Color.FromArgb(35, 255, 255, 255), 1); using (var geometry = CanvasGeometry.CreatePath(builder)) { CanvasStrokeStyle strokeStyle = new CanvasStrokeStyle { EndCap = CanvasCapStyle.Round, StartCap = CanvasCapStyle.Round }; Color startColor = Fill.Color; Color startColor2 = Fill.Color; startColor2.A = 150; CanvasLinearGradientBrush ee = new CanvasLinearGradientBrush(_canvas, startColor, startColor2) { StartPoint = new Vector2(0, 0), EndPoint = new Vector2(0, availableHeight) }; args.DrawingSession.DrawGeometry(geometry, ee, (float)Thickness, strokeStyle); } // Draw axis var color = ForegroundColor; // args.DrawingSession.DrawLine(0, 0, 0, availableHeight, Colors.Red, 1); // args.DrawingSession.DrawLine(0, availableHeight + 16, availableWidth, availableHeight + 16, Colors.DarkGray, 1); } using (var builder = new CanvasPathBuilder(sender)) { builder.BeginFigure(array[0].X, availableHeight); foreach (Vector2 item in array) { builder.AddLine(item); } builder.AddLine(array.Last().X, availableHeight); builder.EndFigure(CanvasFigureLoop.Closed); using (var geometry = CanvasGeometry.CreatePath(builder)) { Color startColor = Fill.Color; startColor.A = 50; CanvasLinearGradientBrush ee = new CanvasLinearGradientBrush(_canvas, startColor, Colors.Transparent) { StartPoint = new Vector2(0, 0), EndPoint = new Vector2(0, availableHeight) }; args.DrawingSession.FillGeometry(geometry, ee); } } }