具有3D效果的iOS雷达图

问题描述 投票:0回答:1

我想在我的应用中复制此图。

我尝试在线搜索,但只找到豆荚,特别是Charts.

我试图自定义它,但是我无法通过为每个“三角形”分配不同的阴影来赋予它3d效果。

如何复制它?Uibezierpath还是其他?this

ios swift core-graphics uibezierpath ios-charts
1个回答
1
投票

玩得开心。

class GraphView: UIView {

let cirleSegnaposto:CGFloat = 20.0
let labelSize:Double = 50
let spacingGraphLabel:Double = 0
let widthOfZero:Double = 30

let labels = ["Label 1", "Label 2", "Label 3", "Label 4", "Label 5"]
let firstColors:[UIColor] = [.darkGray, .black, .darkGray, .lightGray, .white]
let secondColors:[UIColor] = [.orange, .brown, .orange, .yellow, .red]

var values: [Int]? = nil
var secondValues: [Int]? = nil

override func draw(_ rect: CGRect) {
    for i in 0 ..< 4 {
        let cirleLayer = CAShapeLayer()

        let delta = Double(15 * i) + labelSize
        let path = UIBezierPath(ovalIn: CGRect(x: delta,
                                               y: delta,
                                               width: Double(rect.width) - delta * 2,
                                               height: Double(rect.width) - delta * 2))

        cirleLayer.path = path.cgPath
        cirleLayer.lineWidth = 1
        cirleLayer.strokeColor = UIColor.lightGray.cgColor
        cirleLayer.fillColor = UIColor.clear.cgColor

        self.layer.addSublayer(cirleLayer)
    }

    let radius:Double = Double(rect.width/2) - (labelSize - spacingGraphLabel)
    let labelRadius:Double = Double(rect.width/2) + (spacingGraphLabel)

    let origin = CGPoint(x: rect.width/2, y: rect.height/2)

    for i in 0..<5 {
        let cirleLayer = CAShapeLayer()

        let angle:Double = Double(i)/5.0 * (2 * .pi)

        let centerX = Double(origin.x) + radius * cos(angle)
        let centerY = Double(origin.y) - radius * sin(angle)

        let path = UIBezierPath(ovalIn: CGRect(x: CGFloat(centerX) - cirleSegnaposto/2,
                                               y: CGFloat(centerY) - cirleSegnaposto/2,
                                               width: cirleSegnaposto,
                                               height: cirleSegnaposto))

        cirleLayer.path = path.cgPath
        cirleLayer.fillColor = UIColor.lightGray.cgColor
        cirleLayer.lineWidth = 0.5
        cirleLayer.strokeColor = UIColor.black.cgColor

        self.layer.addSublayer(cirleLayer)

        let label = UILabel(frame: .zero)
        label.font = UIFont.systemFont(ofSize: 12)
        label.text = labels[i]
        label.frame.size = CGSize(width: labelSize, height: labelSize/2)

        let labelCenterX = Double(origin.x) + labelRadius * cos(angle)
        let labelCenterY = Double(origin.y) - labelRadius * sin(angle)

        label.center = CGPoint(x: labelCenterX, y: labelCenterY)
        label.transform = label.transform.rotated(by: .pi/2)

        self.addSubview(label)
    }

    if let values = secondValues {
        drawGraph(values: values, center: origin, maxValue: radius, colors: secondColors.map({$0.cgColor}))
    }

    if let values = values {
        drawGraph(values: values, center: origin, maxValue: radius, colors: firstColors.map({$0.cgColor}))
    }
}

func drawGraph(values: [Int], center: CGPoint, maxValue: Double, colors: [CGColor]) {
    var points = [CGPoint]()
    for i in 0 ..< values.count {
        let radius = Double(values[i])/10.0 * (maxValue - widthOfZero) + widthOfZero

        let angle:Double = Double(i)/5.0 * (2 * .pi)

        let x = Double(center.x) + radius * cos(angle)
        let y = Double(center.y) - radius * sin(angle)

        let point = CGPoint(x: x, y: y)
        points.append(point)
    }

    for (i, point) in points.enumerated() {
        let secondPoint = point == points.last ? points[0] : points[i+1]

        let path = UIBezierPath()
        path.move(to: center)
        path.addLine(to: point)
        path.addLine(to: secondPoint)
        path.close()

        let layer = CAShapeLayer()
        layer.path = path.cgPath
        layer.fillColor = colors[i]
        layer.lineWidth = 1
        layer.lineJoin = .round
        layer.strokeColor = UIColor.black.cgColor

        self.layer.addSublayer(layer)
    }
}

}
© www.soinside.com 2019 - 2024. All rights reserved.