Skip to content

Instantly share code, notes, and snippets.

@MacKaSL
Created October 29, 2018 11:30
Show Gist options
  • Save MacKaSL/99908b6937e9a57e3be39403f29b931d to your computer and use it in GitHub Desktop.
Save MacKaSL/99908b6937e9a57e3be39403f29b931d to your computer and use it in GitHub Desktop.
//
// MultiColoredPie.swift
//
// Created by Himal Madhushan
//
import UIKit
import CoreGraphics
class MultiColoredPie: UIView {
private var commonPath: UIBezierPath {
get {
let x = self.frame.width/2
let y = self.frame.height/2
let center = CGPoint(x: x, y: y)
let path = UIBezierPath(arcCenter: center, radius: CGFloat(x - lineWidth/2), startAngle: -90.degreesToRadians, endAngle: 270.degreesToRadians, clockwise: true)
path.close()
return path
}
}
private lazy var shapeLayer: CAShapeLayer = {
var layer = CAShapeLayer()
layer.fillColor = nil
layer.strokeColor = UIColor.pieChartNonFillPath.cgColor
layer.lineCap = CAShapeLayerLineCap.square
// layer.path = commonPath.cgPath
return layer
}()
@IBInspectable var lineWidth: CGFloat = 40
var data: [MultiPieData]?
private lazy var pathLayers: [PieLayer] = {
guard let data = self.data else { return [] }
var previousPercentage: CGFloat = 0
let sorted = data.sorted(by: { (data1, data2) -> Bool in
return data1.percentage < data2.percentage
})
var layers: [PieLayer] = []
for (index, item) in sorted.enumerated() {
previousPercentage += item.percentage
let layer = PieLayer()
layer.index = index
layer.lineCap = CAShapeLayerLineCap.square
layer.fillColor = nil
layer.strokeColor = item.color.cgColor
layer.strokeEnd = previousPercentage //item.percentage
layer.percentage = previousPercentage //item.percentage
layers.append(layer)
}
return layers
}()
// private lazy var pathLayers: [PieLayer] = []
override init(frame: CGRect) {
super.init(frame: frame)
}
required public init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
override func layoutSubviews() {
super.layoutSubviews()
self.addShapes()
}
func addShapes() {
shapeLayer.path = commonPath.cgPath
shapeLayer.lineWidth = lineWidth
self.layer.addSublayer(shapeLayer)
for layer in pathLayers.reversed() {
print("\(layer.index) - \(layer.percentage)")
layer.lineWidth = lineWidth
layer.path = commonPath.cgPath
self.layer.addSublayer(layer)
}
}
func getPath() -> UIBezierPath {
var path = UIBezierPath()
path = UIBezierPath(ovalIn: CGRect(x: lineWidth/2, y: lineWidth/2, width: self.frame.width-lineWidth, height: self.frame.height-lineWidth))
path.close()
return path
}
}
class MultiPieData {
var color: UIColor = .navigationBarColor
var percentage: CGFloat = 0.0
var label: String = ""
init(label: String, percentage: CGFloat, color: UIColor) {
self.color = color
self.label = label
self.percentage = percentage
}
}
class PieLayer: CAShapeLayer {
var index: Int = 0
var percentage: CGFloat = 0.0
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment