Samy Gray
Samy Gray

Reputation: 43

SkiaSharp Arcs in Xamarin.Forms , differentiate Colors for Arcs

Am new to SkiaSharp in Xamarin.Forms, Am trying to create arcs which should end up forming of pie chart. Currently am unable to get different colors for the objects in my observable collection. the output ends up with last object's (ie: tiger = SKColors.Blue) color property in all the arcs.

i really need output similar to figure 1, where as ends with with figure 2.

Any information related would be really helpful to me. Thanks

 public partial class MyCustomCanvasView : ContentPage
    {
        public MyCustomCanvasView()
        {
            InitializeComponent();
        }

        public SKPaint _arcPaint;
        public float _temp;
        public float _total;
        public float _percentage;
        public float _arcAnglePoint;
        public SKColor _Color;

        private ObservableCollection<Profile> _profileDetails;
        public ObservableCollection<Profile> ProfileDetails
        {
            get { return _profileDetails; }
            set
            {
                _profileDetails = value;
                OnPropertyChanged(nameof(ProfileDetails));
            }
        }

        private float _sweepAngle=0;
        public float SweepAngle
        {
            get { return _sweepAngle; }
            set
            {
                _sweepAngle = value;
                OnPropertyChanged(nameof(SweepAngle));
            }
        }

        private float _startAngle = 0;
        public float StartAngle
        {
            get { return _startAngle; }
            set
            {
                _startAngle = value;
                OnPropertyChanged(nameof(SweepAngle));
            }
        }

        void OnCanvasViewPaintSurface(System.Object sender, SkiaSharp.Views.Forms.SKPaintSurfaceEventArgs args)
        {
            

            SKImageInfo info = args.Info;
            SKSurface surface = args.Surface;
            SKCanvas canvas = surface.Canvas;
            canvas.Clear();

            SKPaint FilledCircle = new SKPaint
            {
                Style = SKPaintStyle.Fill,
                Color = Color.LightGray.ToSKColor(),
            };

            SKPaint arcPaint = new SKPaint
            {
                Style = SKPaintStyle.Stroke,
                StrokeWidth = 200,
                Color = SKColors.Green //_Color
            };
            _arcPaint = arcPaint;

            SKPoint center = new SKPoint(info.Width / 2, info.Height / 2);
            SKRect _rect = new SKRect(center.X - 150, center.Y - 150, center.X + 150, center.Y + 150);

            using (SKPath path = new SKPath())
            using (SKPaint fillPaint = new SKPaint())
            using (SKPaint outlinePaint = new SKPaint())
            {
                
                ProfileDetails = new ObservableCollection<Profile>()
                {
                    new Profile{Id = 0,Name = "Dog", sKColors = SKColors.Red , Values = 541 },
                    new Profile{Id = 1,Name = "Cat",sKColors = SKColors.Pink ,Values = 2587 },
                    new Profile{Id = 2,Name = "Horse",sKColors = SKColors.Green, Values = 365 },
                    new Profile{Id = 3,Name = "Tiger",sKColors = SKColors.Blue, Values = 257 }
                };

                foreach (var item in ProfileDetails)
                {
                    _total = _total + item.Values;
                }

                foreach (var item in ProfileDetails)
                {
                    PercentageCalculator(item.Values);
                    ArcPercentCalculator(_percentage);

                    SweepAngle = (float)_arcAnglePoint;
                    SweepAngle = (float)Math.Round(SweepAngle, 2);

                    if (item.Id == 0)
                    {
                        StartAngle = (float)0;
                        _temp = SweepAngle;
                    }
                    else
                    {
                        StartAngle = (float)_temp - 1;
                        var x = SweepAngle;
                        _temp = _temp + x;
                    }

                    path.AddArc(_rect, StartAngle, SweepAngle);
                    canvas.DrawPath(path, _arcPaint);

                }

            }

            canvas.DrawCircle(center, 80, FilledCircle);
        }

        private void ArcPercentCalculator(float _percentage)
        {
          var _sweepAngle =  (_percentage / 100) *  360;
            _arcAnglePoint = _sweepAngle;
            _arcAnglePoint = _arcAnglePoint * -1;
        }

        private void PercentageCalculator(float values)
        {
           var percent =  (values / _total) * 100;
            _percentage = percent;

        }
    }

    public class Profile
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public float Values { get; set; }
        public SKColor sKColors { get; set; }
    }

enter image description here

Upvotes: 1

Views: 494

Answers (1)

Samy Gray
Samy Gray

Reputation: 43

i moved my observable collection out of the foreach loop and moved the SKPaint and its object inside of the foreach loop so it would create object and its properties for creating new arcs everytime. I am trying to get its outline and naming labels and will update the code soon

public partial class MyCustomCanvasView : ContentPage
{
    public MyCustomCanvasView()
    {
        InitializeComponent();
    }

    public SKPaint _arcPaint;
    public float _temp;
    public float _total;
    public float _percentage;
    public float _arcAnglePoint;
    public SKColor _Color;

    private ObservableCollection<Profile> _profileDetails;
    public ObservableCollection<Profile> ProfileDetails
    {
        get { return _profileDetails; }
        set
        {
            _profileDetails = value;
            OnPropertyChanged(nameof(ProfileDetails));
        }
    }

    private float _sweepAngle = 0;
    public float SweepAngle
    {
        get { return _sweepAngle; }
        set
        {
            _sweepAngle = value;
            OnPropertyChanged(nameof(SweepAngle));
        }
    }

    private float _startAngle = 0;
    public float StartAngle
    {
        get { return _startAngle; }
        set
        {
            _startAngle = value;
            OnPropertyChanged(nameof(SweepAngle));
        }
    }

    void OnCanvasViewPaintSurface(System.Object sender, SkiaSharp.Views.Forms.SKPaintSurfaceEventArgs args)
    {

        SKImageInfo info = args.Info;
        SKSurface surface = args.Surface;
        SKCanvas canvas = surface.Canvas;
        canvas.Clear();

        SKPaint FilledCircle = new SKPaint
        {
            Style = SKPaintStyle.Fill,
            Color = Color.LightGray.ToSKColor(),
        };

        SKPaint arcPaint = new SKPaint
        {
            Style = SKPaintStyle.Stroke,
            StrokeWidth = 200,
            Color = SKColors.Green //_Color
        };
        _arcPaint = arcPaint;

        SKPoint center = new SKPoint(info.Width / 2, info.Height / 2);
        SKRect _rect = new SKRect(center.X - 150, center.Y - 150, center.X + 150, center.Y + 150);

        ProfileDetails = new ObservableCollection<Profile>()
            {
                new Profile{Id = 0,Name = "Dog", sKColors = SKColors.Red , Values = 541 },
                new Profile{Id = 1,Name = "Cat",sKColors = SKColors.Pink ,Values = 2587 },
                new Profile{Id = 2,Name = "Horse",sKColors = SKColors.Green, Values = 365 },
                new Profile{Id = 3,Name = "Tiger",sKColors = SKColors.Blue, Values = 257 }
            };

        foreach (var item in ProfileDetails)
        {
            _total = _total + item.Values;
        }


        foreach (var item in ProfileDetails)
        {
            PercentageCalculator(item.Values);
            ArcPercentCalculator(_percentage);

            SweepAngle = (float)_arcAnglePoint;
            SweepAngle = (float)Math.Round(SweepAngle, 2);

            if (item.Id == 0)
            {
                StartAngle = (float)0;
                _temp = SweepAngle;
            }
            else
            {
                StartAngle = (float)_temp - 1;
                var x = SweepAngle;
                _temp = _temp + x;
            }

            using (SKPath path = new SKPath())
            using (SKPaint fillPaint = new SKPaint())
            using (SKPaint outlinePaint = new SKPaint())
            {
                fillPaint.Style = SKPaintStyle.Stroke;
                fillPaint.StrokeWidth = 150;
                fillPaint.Color = item.sKColors; //_Color

                path.AddArc(_rect, StartAngle, SweepAngle);
                canvas.DrawPath(path, fillPaint);
            }
        }
       // canvas.DrawCircle(center, 80, FilledCircle);
    }

    private void ArcPercentCalculator(float _percentage)
    {
        var _sweepAngle = (_percentage / 100) * 360;
        _arcAnglePoint = _sweepAngle;
        _arcAnglePoint = _arcAnglePoint * -1;
    }

    private void PercentageCalculator(float values)
    {
        var percent = (values / _total) * 100;
        _percentage = percent;

    }
}

public class Profile
{
    public int Id { get; set; }
    public string Name { get; set; }
    public float Values { get; set; }
    public SKColor sKColors { get; set; }
}

enter image description here

Upvotes: 1

Related Questions