2016-03-02 2 views
13

Пока у меня есть заполненный круг, и это все. Я пытаюсь составить круговую диаграмму, которая представляет количество удовлетворенных и неудовлетворенных клиентов и представляет ее. Я чрезвычайно новичок в CG, и мне было интересно, кто-то может прокрутить достаточно кода, чтобы дать мне идею или направить меня.Создание круговой диаграммы с использованием Core Graphics

Должен ли я иметь нижний круг, представляющий количество довольных клиентов, а затем добавить еще один круг поверх него, чтобы показать неудовлетворенных клиентов? Я подхожу к нему правильно?

Вот мой код.

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) 

} 

EDIT

Кроме того, теперь я начинаю видеть, что я, возможно, потребуется, чтобы покрыть мой круг с дугой Основе от общего числа недовольных клиентов. Как увеличить или уменьшить размер дуги покрытия на основе количества людей?

Любая помощь была бы чрезвычайно оценена!

+0

Возможно, следующая нить может помочь вам: [пирог-чарт-сюжет-в-стрижа] (http://stackoverflow.com/questions/28768550/pie -chart-сюжет-в-Свифт). – dfri

+0

Я исследовал этот ответ довольно близко, его код не производит ничего больше, чем пустой круг. Но спасибо. – Mihado

+1

@ Я не рассматривал специфику, следовательно, «возможно» :) Если вы действительно не хотите ее реализовать самостоятельно, вы можете посмотреть (или вдохновиться) 'PieChart (...)' из [iOS- Графики] (https://github.com/danielgindi/ios-charts) (см. [Этот учебник] (http://www.appcoda.com/ios-charts-api-tutorial/)) или, например, [Свифта-PieChart] (https://github.com/zemirco/swift-piechart). – dfri

ответ

36

Вы должны использовать функцию CGContextAddArc() (CGContext.addArc() в Swift 3). Это позволит вам создавать несколько сегментов для вашей круговой диаграммы, рисуя дугу для каждого сегмента вашей круговой диаграммы.

Что-то вроде этого следует сделать трюк:

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) 

Выход:

enter image description here


Полный проект (с некоторыми дополнительными функциональными возможностями): https://github.com/originaluser2/Pie-Chart-View

+0

Удивительно, я проверю это, как только вернусь домой с работы и посмотрю, есть ли у меня дополнительные вопросы. Спасибо большое! – Mihado

+0

@ Михадо рад помочь :) Арки иногда могут быть довольно запутанными в Core Graphics при работе с UIViews, так как ось y перевернута, поэтому указание дуги по часовой стрелке создает против часовой стрелки дугу, а углы меняются на противоположные и т. Д. Happy чтобы ответить на любые ваши вопросы. – Hamish

+0

Это СОВЕРШЕННО. Я не знаю, как поблагодарить вас. Я награду тебя щедростью, как только это позволит мне. Я хотел бы показать вам, что я создаю, если вам будет интересно @ originaluser2 – Mihado