예제 #1
0
        /// <summary>
        /// Gets called whenever figures get added/removed from the figure collection.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void OnFigureListEntriesChanged(object sender, NotifyCollectionChangedEventArgs e)
        {
            switch (e.Action)
            {
            case NotifyCollectionChangedAction.Add:
                foreach (var o in e.NewItems)
                {
                    FigureAccess access = new FigureAccess(o, OnFigureValueChanged, easeInValue: true);
                    FigureAccesses.Add(access);
                    var entryAnimation = new Animation((v) => { access.Entrance = (float)v; Redraw(); }, 0, 1, Easing.CubicInOut);
                    entryAnimation.Commit(this, access.EntranceHandle, _animationFramerate, 500u);
                }
                break;

            case NotifyCollectionChangedAction.Move:
                break;

            case NotifyCollectionChangedAction.Remove:
                foreach (var o in e.OldItems)
                {
                    var access = FigureAccesses[o];
                    if (access == null)
                    {
                        continue;
                    }
                    if (this.AnimationIsRunning(access.EntranceHandle))
                    {
                        this.AbortAnimation(access.EntranceHandle);
                    }
                    access.Unsubscribe();
                    var leaveAnimation = new Animation((v) => { access.Entrance = (float)v; Redraw(); }, access.Entrance, 0, Easing.CubicInOut);
                    leaveAnimation.Commit(this, access.EntranceHandle, _animationFramerate, 500u, finished: (v, c) => { FigureAccesses.Remove(o); Redraw(force: true); });
                }
                break;

            case NotifyCollectionChangedAction.Replace:
                break;

            case NotifyCollectionChangedAction.Reset:
                break;

            default:
                break;
            }
        }
예제 #2
0
        protected override void DrawSpecific(SKCanvas canvas, int width, int height)
        {
            float widthCut       = 0f;
            float startPositionX = 0f;
            float rotationPivotX = 0f;
            float rotationPivotY = 0f;

            switch (DescribtionPosition)
            {
            case DescribtionArea.Default:
                widthCut       = width - 2 * Padding;
                rotationPivotX = width / 2;
                rotationPivotY = height / 2;
                break;

            case DescribtionArea.LeftAndRight:
                widthCut       = width - 2 * Padding - 2 * DescribtionSpace;
                startPositionX = DescribtionSpace;
                rotationPivotX = width / 2;
                rotationPivotY = height / 2;
                break;

            case DescribtionArea.Left:
                widthCut       = width - 2 * Padding - DescribtionSpace;
                startPositionX = DescribtionSpace;
                rotationPivotX = (widthCut / 2) + startPositionX;
                rotationPivotY = height / 2;
                break;

            case DescribtionArea.Right:
                widthCut       = width - 2 * Padding - DescribtionSpace;
                rotationPivotX = widthCut / 2;
                rotationPivotY = height / 2;
                break;
            }

            if (Rotation != 0)
            {
                canvas.RotateDegrees(Rotation, rotationPivotX, rotationPivotY);
            }


            //the sum of all values, adjusted by their animation
            float maxValue = 0;

            if (FigureAccesses == null || FigureAccesses.Count == 0)
            {
                return;
            }

            maxValue = FigureAccesses.Max(fig => fig.AnimatedValue);

            //The starting position as portion of the full circle angle, going from 0 to 1
            //Gets adjusted after every figure by the portion of the radius that figure demands
            float position = 0;
            float barWidth = widthCut / FigureAccesses.Count;
            float barHeight;

            foreach (FigureAccess figure in FigureAccesses)
            {
                if (BarOrientation == BarOrientation.Up || BarOrientation == BarOrientation.Down)
                {
                    barHeight = (height - 2 * Padding) * (figure.AnimatedValue / maxValue);
                }
                else
                {
                    barHeight = (widthCut) * (figure.AnimatedValue / maxValue);
                    barWidth  = (height - 2 * Padding) / FigureAccesses.Count;
                }

                using (var paint = new SKPaint()
                {
                    Color = figure.Color,
                    IsAntialias = IsAntiAliased,
                    Style = SKPaintStyle.Fill
                })
                {
                    switch (BarOrientation)
                    {
                    case BarOrientation.Up:
                        canvas.DrawRect(
                            x: startPositionX + Padding + BarPadding + position * barWidth,
                            y: height - Padding - barHeight,
                            w: barWidth - 2 * BarPadding,
                            h: barHeight,
                            paint: paint);
                        break;

                    case BarOrientation.Down:
                        canvas.DrawRect(
                            x: startPositionX + Padding + BarPadding + position * barWidth,
                            y: Padding,
                            w: barWidth - 2 * BarPadding,
                            h: barHeight,
                            paint: paint);
                        break;

                    case BarOrientation.Left:
                        canvas.DrawRect(
                            x: widthCut - Padding - barHeight,
                            y: Padding + position * barWidth,
                            w: barHeight,
                            h: barWidth - 2 * BarPadding,
                            paint: paint);
                        break;

                    case BarOrientation.Right:
                        canvas.DrawRect(
                            x: startPositionX + Padding,
                            y: Padding + position * barWidth,
                            w: barHeight,
                            h: barWidth - 2 * BarPadding,
                            paint: paint);
                        break;

                    default:
                        break;
                    }
                }
                //Increase the position for the next figure
                position += 1;
            }
        }
예제 #3
0
        protected override void DrawSpecific(SKCanvas canvas, int width, int height)
        {
            using (new SKAutoCanvasRestore(canvas))
            {
                float radius = 0f;

                switch (DescribtionPosition)
                {
                case DescribtionArea.Default:
                    radius = Math.Min((width / 2f) - Padding, (height / 2f) - Padding);
                    canvas.Translate(width / 2, height / 2);
                    break;

                case DescribtionArea.LeftAndRight:
                    radius = Math.Min((width / 2f) - Padding - DescribtionSpace, (height / 2f) - Padding);
                    canvas.Translate(width / 2, height / 2);
                    break;

                case DescribtionArea.Left:
                    radius = Math.Min((width / 2f) - Padding - DescribtionSpace / 2f, (height / 2f) - Padding);
                    canvas.Translate(DescribtionSpace / 2f + (width / 2f), height / 2f);
                    break;

                case DescribtionArea.Right:
                    radius = Math.Min((width / 2f) - Padding - DescribtionSpace / 2f, (height / 2f) - Padding);
                    canvas.Translate(-DescribtionSpace / 2f + (width / 2f), height / 2f);
                    break;
                }

                if (Rotation != 0)
                {
                    canvas.RotateDegrees(Rotation);
                }

                //Create the inner and outer clip.
                //If its a polygon
                if (IsPolygon)
                {
                    canvas.ClipPath(CircleMath.GetPolygonPath(InnerCirclePropoertionAnimated * radius, InnerCorners), SKClipOperation.Difference, antialias: IsAntiAliased);
                    canvas.ClipPath(CircleMath.GetPolygonPath(radius, OuterCorners), SKClipOperation.Intersect, antialias: IsAntiAliased);
                }
                //If its a circle
                else
                {
                    canvas.ClipPath(CircleMath.GetCirclePath(InnerCirclePropoertionAnimated * radius), SKClipOperation.Difference, antialias: IsAntiAliased);
                    canvas.ClipPath(CircleMath.GetCirclePath(radius), SKClipOperation.Intersect, antialias: IsAntiAliased);
                }

                //If there are no Figures, draw a placeholder and return
                if (FigureAccesses == null || FigureAccesses.Count == 0)
                {
                    using (var paint = new SKPaint()
                    {
                        Color = PlaceHolderColor,
                        IsAntialias = IsAntiAliased,
                        Style = SKPaintStyle.Fill
                    }) canvas.DrawPath(CircleMath.GetPiePath(radius, 0, CircleRadius), paint);
                    return;
                }


                //Draw the Pie pieces for every figure

                //the sum of all values, adjusted by their animation
                float valueSum = FigureAccesses.Sum(x => x.AnimatedValue);
                //if the sum is 0, then the valuesum is set to 1 because the circle needs a valuesum > 0
                if (valueSum == 0)
                {
                    valueSum = Math.Max(valueSum, 1);
                }

                //The starting position as portion of the full circle angle, going from 0 to 1
                //Gets adjusted after every figure by the portion of the radius that figure demands
                float position = 0;

                foreach (FigureAccess figure in FigureAccesses)
                {
                    //Create The pie shaped path
                    float  circlePortion = figure.AnimatedValue / valueSum;
                    SKPath path          = CircleMath.GetPiePath
                                           (
                        radius: radius,
                        fromRad: position * CircleRadius,
                        toRad: (position + circlePortion) * CircleRadius
                                           );

                    //Draw the clipped pie shape
                    using (var paint = new SKPaint()
                    {
                        Color = figure.Color,
                        IsAntialias = IsAntiAliased,
                        Style = SKPaintStyle.Fill
                    }) canvas.DrawPath(path, paint);

                    //Increase the position for the next figure
                    position += circlePortion;
                }
            }
        }
예제 #4
0
        /// <summary>
        /// Draw the describtions. So far, this is chart unspecific.
        /// </summary>
        protected void DrawValueLabels(SKCanvas canvas, int width, int height)
        {
            if (FigureAccesses == null || FigureAccesses.Count == 0)
            {
                return;
            }

            using (var describtionPaint = new SKPaint()
            {
                TextSize = 20f,
                IsAntialias = IsAntiAliased,
                Color = SKColors.Black,
                IsStroke = false
            })
            {
                //Calculating the maximum line height, that is then used for every line.
                float maxDescribtionHeight = 0f;
                foreach (FigureAccess fig in FigureAccesses)
                {
                    if (!string.IsNullOrWhiteSpace(fig.Describtion))
                    {
                        var describtionBounds = new SKRect();
                        describtionPaint.MeasureText(fig.Describtion, ref describtionBounds);
                        maxDescribtionHeight = Math.Max(maxDescribtionHeight, describtionBounds.Height);
                    }
                }

                DrawDescribtionBackGround(canvas, width, height, maxDescribtionHeight, FigureAccesses.Count);



                for (int i = 0; i < this.FigureAccesses.Count(); i++)
                {
                    FigureAccess figure = FigureAccesses.ElementAt(i);
                    if (!string.IsNullOrEmpty(figure.Describtion))
                    {
                        var    describtionBounds = new SKRect();
                        string text = figure.Describtion;
                        describtionPaint.MeasureText(text, ref describtionBounds);
                        maxDescribtionHeight = Math.Max(maxDescribtionHeight, describtionBounds.Height);


                        float xOffset       = 0;
                        float yOffset       = 0;
                        float xStep         = 0;
                        float yStep         = 0;
                        int   adjustedIndex = i;

                        switch (DescribtionPosition)
                        {
                        case DescribtionArea.Default:
                        case DescribtionArea.LeftAndRight:
                            bool halfDone = i < (this.FigureAccesses.Count() + 1) / 2;
                            adjustedIndex = halfDone ? i : i - this.FigureAccesses.Count() % 2 - this.FigureAccesses.Count() / 2;
                            xOffset       = halfDone ? width - Padding - DescribtionSpace + DescribtionPadding : +Padding + DescribtionPadding;
                            yOffset       = halfDone ? Padding + DescribtionPadding : +Padding + DescribtionPadding + ((height - 2 * Padding) - Math.Min((this.FigureAccesses.Count() / 2) * maxDescribtionHeight * DescribtionSpacing + DescribtionPadding, height - 2 * Padding));
                            xStep         = 0;
                            yStep         = maxDescribtionHeight * DescribtionSpacing;
                            break;

                        case DescribtionArea.Right:
                            xOffset = width - Padding - DescribtionSpace + DescribtionPadding;
                            yOffset = Padding + DescribtionPadding;
                            xStep   = 0;
                            yStep   = maxDescribtionHeight * DescribtionSpacing;
                            break;

                        case DescribtionArea.Left:
                            xOffset = +Padding + DescribtionPadding;
                            yOffset = +Padding + DescribtionPadding;
                            xStep   = 0;
                            yStep   = maxDescribtionHeight * DescribtionSpacing;
                            break;

                        case DescribtionArea.Top:
                            break;

                        case DescribtionArea.Bottom:
                            break;

                        default:
                            break;
                        }

                        SKRect colorRect = SKRect.Create(
                            x: xOffset + xStep * adjustedIndex,
                            y: yOffset + yStep * adjustedIndex,
                            width: maxDescribtionHeight,
                            height: maxDescribtionHeight
                            );

                        using (var paint = new SKPaint()
                        {
                            IsAntialias = IsAntiAliased,
                            Color = figure.Color,
                            Style = SKPaintStyle.Fill
                        }) canvas.DrawRect(colorRect, paint);

                        canvas.DrawText(text,
                                        x: colorRect.Right + 3f,
                                        y: colorRect.Bottom,
                                        paint: describtionPaint);

                        float  valToShow = AnimateVisibleValues ? figure.AnimatedValue : figure.Value;
                        string valText   = Math.Round(valToShow, FractionalDigits).ToString("n" + FractionalDigits);

                        canvas.DrawText(
                            text: valText,
                            x: colorRect.Right + describtionBounds.Width + 9f,
                            y: colorRect.Bottom,
                            paint: describtionPaint);
                    }
                }
            }
        }