add an image for each slice in iOS-chart pieChart

I’m using ios-charts. I want to create a pie chart like below image. I have done all the confings, but I have problem with adding the image in the circle beside the values outside the circle.

enter image description here

  • What does it mean : “Property type ”JSQMessagesCollectionView“ is incompatible with type ”UICollectionView“, inherited from ”UICollectionViewLayout"
  • Checking For Internet Connectivity in Objective C
  • KVO broken in iOS 9.3
  • How do I save a UIColor with NSUserDefaults?
  • SKAction playSoundFileNamed stops background music
  • iOS Screenshot part of the screen
  • Can anybody help me how to to add the circles and image inside it ?

    UPDATED:
    note that the pie chart will scroll and those images should scroll with the related slices.

    UPDATED:
    I used @Aditya Garg sample code to draw images beside the position of labels, and my chart is now looks like this :

    enter image description here

    I set the imageViewFrame like this:

    imageView.frame = CGRect(x: xPos-10, y: yPos+10, width: 20, height: 20)
    

    UPDATED:
    Github Pull request for ios-chart repo swift

    Solutions Collect From Internet About “add an image for each slice in iOS-chart pieChart”

    Setting the circle and the image inside is easy. First create a UIImageView, change the corner radius, and put the image inside

    //Assuming you have declared a UIImageView and an image
    imageView.layer.cornerRadius = imageView.frame.size.width/2
    imageView.clipsToBounds = true
    imageView.image = image
    

    You can create as many of these as you need programmatically

    func drawCircle(xPos:CGFloat, yPos:CGFloat, name: String){ 
        let image = UIImage(named: name)
        let imageView = UIImageView(image: image!)
        imageView.frame = CGRect(x: xPos-10, y: yPos+10, width: (image?.size.width)!, height: (image?.size.height)!)
        imageView.layer.cornerRadius = imageView.frame.size.width/2
        imageView.clipsToBounds = true
        imageView.tag = 1000 //this is so we can later remove and redraw the circle in a new position
        pieChart.addSubview(imageView)
    }
    

    The trickier part is drawing these images at the correct place (the circle image is always aligned with the middle of the pie chart section). You have to calculate the angle between these sections manually, and then add in the UImageView we created to this position

    These are the geometric properties that pieChart exposes to us

    let FDEG2RAD = CGFloat(M_PI / 180.0)
    var absoluteAngles : [CGFloat] = pieChart.absoluteAngles
    absoluteAngles.insert(0, at: 0)
    var center = pieChart.centerCircleBox
    center.x = center.x - 15 //correction factor for center, adjust these as you see fit
    center.y = center.y - 11
    let r: CGFloat = pieChart.radius + 30 //distance from center
    

    Where absolute angles is an array of the slice angles. These always get bigger and end at 360 degrees. Note that we manually insert 0 at the beginning so that the code works nicely.

    There is a bug where centerCircleBox does not return the true center. To fix this use this function to draw an image on where the pieChart says its center is and then adjust the correction factor to get it in the true center. (make sure to add a smallish image file to your project, i used a red x mark)

       func drawCenterX(xPos:CGFloat, yPos:CGFloat){
       let xred = "xmarks.png"
       let image = UIImage(named: xred)
       let imageView = UIImageView(image: image!)
       imageView.frame = CGRect(x: xPos, y: yPos, width: (image?.size.width)!, height: (image?.size.height)!)
       pieChart.addSubview(imageView)
    }
    

    For the math, we simply have to keep track of our last absolute angle, our current absolute angle and find the angle in between. Add this onto our last value to find the true angle and then convert to X,Y coordinates. Note that the larger the Y gets, the more down the screen it goes, so we have to subtract not add.

    let x = center.x + (r * sin((absoluteAngles[last] + ((absoluteAngles[current] - absoluteAngles[last] )/2)) * FDEG2RAD))
    let y = center.y - (r * cos((absoluteAngles[last] + ((absoluteAngles[current] - absoluteAngles[last] )/2)) * FDEG2RAD)) 
    

    Now, just iterate through the absoluteAngles array, calculate the position, and place the UIImageView here. See the full code below

    func setLabels(vals : [Int]){
    
        let subViews = self.pieChart.subviews //this removes the previous UIImageViews
        for subview in subViews{
            if subview.tag == 1000 {
                subview.removeFromSuperview()
            }
        }
    
        let FDEG2RAD = CGFloat(M_PI / 180.0)
        var absoluteAngles : [CGFloat] = pieChart.absoluteAngles
        absoluteAngles.insert(0, at: 0)
        var center = pieChart.centerCircleBox
        center.x = center.x - 15 //correction factor for center, adjust these as you see fit
        center.y = center.y - 11
        let r: CGFloat = pieChart.radius + 30 //distance from center
        var current = 1
        var last = 0
    
        for value in vals{
    
    
            let x = center.x + (r * sin((absoluteAngles[last] + ((absoluteAngles[current] - absoluteAngles[last] )/2)) * FDEG2RAD))
            let y = center.y - (r * cos((absoluteAngles[last] + ((absoluteAngles[current] - absoluteAngles[last] )/2)) * FDEG2RAD)) 
    
            last = current
            current = current + 1
    
            UIView.animate(withDuration: 1.0, delay: 0, options: .curveEaseOut, animations: { //Adds a nice animation that brings the circle in from off screen
                //Implement your own logic for how you want to pass in the name of the section to the function we defined above.
                self.drawCircle(xPos: x, yPos: y, name: name)
                }, completion: nil)
        }
        drawCenterX(xPos: center.x, yPos: center.y)//visually locate center
    }
    

    Let me know if you have any questions!