2016-03-02 15 views
13

Do tej pory mam wypełnione koło i to wszystko. Próbuję zrobić wykres kołowy, który przedstawia liczbę zadowolonych i niezadowolonych klientów i przedstawić go. Jestem niezmiernie nowy w CG i zastanawiałam się, czy ktoś może wykręcić wystarczająco dużo kodu, by dać mi pomysł lub poprowadzić mnie.Tworzenie wykresu kołowego przy użyciu grafiki głównej

Czy mam dolne kółko reprezentujące liczbę zadowolonych klientów, a następnie dodać na nim kolejny krąg, aby pokazać niezadowolonych klientów? Czy podchodzę do niego we właściwy sposób?

Oto mój kod do tej pory.

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

Również teraz zaczynam widzieć, że może muszę pokryć moje koło z łuku w oparciu off ogółu niezadowolonego klienta. Jak mogę zwiększyć lub zmniejszyć rozmiar łuku pokrywającego w zależności od liczby osób?

Każda pomoc zostanie ogromnie doceniona!

+0

Ewentualnie wątku może pomóc: [pie-chart-działka-w-swift] (http://stackoverflow.com/questions/28768550/pie -art-działka-w-swift). – dfri

+0

Zbadałem dokładnie tę odpowiedź, jego kod nie wytwarza niczego więcej niż puste koło. Ale dzięki. – Mihado

+1

@Ah Nie zaglądałem w szczegóły, stąd "prawdopodobnie" :) Jeśli naprawdę nie chcesz tego zaimplementować samodzielnie, możesz przyjrzeć się (lub zainspirować się) 'PieChart (...)' z [iOS- Wykresy] (https://github.com/danielgindi/ios-charts) (zobacz [ten samouczek] (http://www.appcoda.com/ios-charts-api-tutorial/)) lub np. [Swift-PieChart] (https://github.com/zemirco/swift-piechart). – dfri

Odpowiedz

36

Będziesz chciał użyć funkcji CGContextAddArc() (CGContext.addArc() w Swift 3). Umożliwi to utworzenie wielu segmentów wykresu kołowego poprzez narysowanie łuku dla każdego segmentu wykresu kołowego.

Coś jak to powinno załatwić sprawę:

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 
     } 
    } 
} 

można wprowadzać swoje dane wykres kołowy jako tablica Segment elemencie, gdzie każdy Segment oznacza kolor i wartość tego segmentu.

Wartość może być dowolną wartością zmiennoprzecinkową i zostanie automatycznie zmniejszona do wartości, która będzie stosowana na wykresie kołowym. Tak na przykład, jeśli chcesz, aby wykres kołowy do reprezentują liczbę niezadowolonych w porównaniu z liczbą zadowolonych klientów, można po prostu przekazać wartości bezpośrednio w

Przykład użycia.

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) 

wyjście:

enter image description here


Pełny projekt (z pewną dodatkową funkcjonalność): https://github.com/originaluser2/Pie-Chart-View

+0

Niesamowite, sprawdzę to, jak tylko wrócę do domu z pracy i zobaczę, czy mam dodatkowe pytania. Dziękuję bardzo! – Mihado

+0

@Mihado chętnie pomoże :) łuki mogą czasami być dość mylące w Core Graphics podczas pracy z UIViews, ponieważ oś Y jest odwrócona, więc określenie łuku w prawo wytwarza łuk przeciwnie do ruchu wskazówek zegara, a kąty są odwrócone itd. aby odpowiedzieć na wszelkie pytania. – Hamish

+0

To jest PERFEKCYJNE. Nie wiem, jak ci podziękować. Oddam ci nagrodę tak szybko, jak mi pozwoli. Chciałbym pokazać, co buduję, jeśli byłbyś zainteresowany @ originaluser2 – Mihado

Powiązane problemy