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);
                }
            }
        }
Exemple #2
0
        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();
        }
Exemple #4
0
        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);
            }
        }
Exemple #5
0
        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);
                }
            }
        }