【问题标题】:Making a pie chart using Core Graphics使用 Core Graphics 制作饼图
【发布时间】:2016-03-02 16:23:06
【问题描述】:

到目前为止,我有一个实心圆圈,仅此而已。我正在尝试制作一个饼图来表示满意和不满意的客户数量并进行展示。我对 CG 非常陌生,我想知道有人可以编写出足够多的代码来给我一个想法或指导我。

我是否应该让底部的圆圈代表满意的客户数量,然后在其顶部添加另一个圆圈以显示不满意的客户?我是否以正确的方式接近它?

到目前为止,这是我的代码。

override func drawRect(rect: CGRect) {

    // Get current context
    let context = UIGraphicsGetCurrentContext()

    // Set color
    CGContextSetStrokeColorWithColor(context,UIColor(red: 0.2, green: 0.4, blue: 1, alpha: 1.0).CGColor)

    let rectangle = CGRectMake((frame.size.width / 3) - 50, frame.size.height / 2 + 40,220,220)
    CGContextAddEllipseInRect(context,rectangle)

    CGContextSetFillColorWithColor(context, UIColor(red: 0.2, green: 0.4, blue: 1, alpha: 1.0).CGColor)
    CGContextFillPath(context)
    CGContextStrokePath(context)

}

编辑

另外,现在我开始看到我可能需要根据不满意的客户总数用弧线覆盖我的圈子。如何根据人数增加或减少覆盖弧的大小?

任何帮助将不胜感激!

【问题讨论】:

  • 可能下面的帖子可以帮到你:pie-chart-plot-in-swift.
  • 我非常仔细地研究了这个答案,他的代码除了一个空圆圈之外什么都没有。不过谢谢。
  • @Ah 我没有研究细节,因此“可能”:) 除非您真的想自己实现它,否则您可以查看(或受到启发)PieChart(...) of @ 987654322@(见this tutorial)或例如Swift-PieChart.
  • 我真的很感激你的努力。我已经广泛研究了实现这一目标的各种库。从我收集到的信息来看,如果我知道自己在做什么,它不应该超过 20 行代码。我只是去尝试和学习。 :)
  • 希望其他人可以帮助您;我自己对 CoreGraphics 不是很精通,所以关于现有库的提示是我能做的最好的:)祝你好运!

标签: ios swift core-graphics


【解决方案1】:

您需要使用 CGContextAddArc() 函数(在 Swift 3 中为 CGContext.addArc())。这将允许您通过为饼图的每个段绘制弧线来为饼图创建多个段。

这样的事情应该可以解决问题:

import UIKit

struct Segment {

    // the color of a given segment
    var color: UIColor

    // the value of a given segment – will be used to automatically calculate a ratio
    var value: CGFloat
}

class PieChartView: UIView {

    /// An array of structs representing the segments of the pie chart
    var segments = [Segment]() {
        didSet {
            setNeedsDisplay() // re-draw view when the values get set
        }
    }

    override init(frame: CGRect) {
        super.init(frame: frame)
        isOpaque = false // when overriding drawRect, you must specify this to maintain transparency.
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }

    override func draw(_ rect: CGRect) {

        // get current context
        let ctx = UIGraphicsGetCurrentContext()

        // radius is the half the frame's width or height (whichever is smallest)
        let radius = min(frame.size.width, frame.size.height) * 0.5

        // center of the view
        let viewCenter = CGPoint(x: bounds.size.width * 0.5, y: bounds.size.height * 0.5)

        // enumerate the total value of the segments by using reduce to sum them
        let valueCount = segments.reduce(0, {$0 + $1.value})

        // the starting angle is -90 degrees (top of the circle, as the context is flipped). By default, 0 is the right hand side of the circle, with the positive angle being in an anti-clockwise direction (same as a unit circle in maths).
        var startAngle = -CGFloat.pi * 0.5

        for segment in segments { // loop through the values array

            // set fill color to the segment color
            ctx?.setFillColor(segment.color.cgColor)

            // update the end angle of the segment
            let endAngle = startAngle + 2 * .pi * (segment.value / valueCount)

            // move to the center of the pie chart
            ctx?.move(to: viewCenter)

            // add arc from the center for each segment (anticlockwise is specified for the arc, but as the view flips the context, it will produce a clockwise arc)
            ctx?.addArc(center: viewCenter, radius: radius, startAngle: startAngle, endAngle: endAngle, clockwise: false)

            // fill segment
            ctx?.fillPath()

            // update starting angle of the next segment to the ending angle of this segment
            startAngle = endAngle
        }
    }
}

您可以将饼图数据输入为Segment 结构的数组,其中每个Segment 代表该段的颜色和值。

该值可以是任何浮点数,并且会自动减少到要在饼图中使用的比率。例如,如果您希望您的饼图表示不满意的客户数量与满意的客户数量,您可以直接将值传入。

使用示例:

let pieChartView = PieChartView()
pieChartView.frame = CGRect(x: 0, y: 0, width: view.frame.size.width, height: 400)
pieChartView.segments = [
    Segment(color: .red, value: 57),
    Segment(color: .blue, value: 30),
    Segment(color: .green, value: 25),
    Segment(color: .yellow, value: 40)
]
view.addSubview(pieChartView)

输出:


完整项目(带有一些额外功能):https://github.com/hamishknight/Pie-Chart-View

【讨论】:

  • 太棒了,我下班回家后会检查一下,看看我是否还有其他问题。非常感谢!
  • @Mihado 乐于提供帮助 :) 使用 UIViews 时,Core Graphics 中的弧线有时会很混乱,因为 y 轴是翻转的,因此指定顺时针弧线会产生逆时针弧线,并且角度反转等。很高兴回答您可能遇到的任何问题。
  • 这是完美的。我不知道该怎么感谢你。只要它允许,我就会奖励你赏金。如果您有兴趣,我很乐意向您展示我正在构建的内容@originaluser2
  • 当然,总是有兴趣看看人们在做什么!不确定您是否感兴趣,但我在PieChartView 类中添加了一些文本功能,因此您可以在每个段上显示文本。如果你有兴趣,它在 github 项目上。由于您没有提出问题,所以我会避免用它来混淆答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-01-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-15
  • 2010-09-23
相关资源
最近更新 更多