Как отобразить значения за пределами p ie на графике ap ie в SwiftUI? - PullRequest
0 голосов
/ 20 января 2020

введите описание изображения здесь

Я совершенно новичок в программировании для устройств Apple и начал изучать SwiftUI. Может кто-нибудь, пожалуйста, помогите мне с отображением значения p ie за пределами p ie. Как вы можете видеть на первом изображении, все 3 значения накладываются друг на друга, но я хочу что-то вроде второго изображения.

Точное место, где я накладываю текст, отмечено комментарием, как показано ниже:

.overlay(
   Text(String(value)) // ****** This is the place where value is overlayed
)

А весь код ниже:



import SwiftUI



public struct PieChartCell : View {
    @State private var show:Bool = false
    var rect: CGRect
    var radius: CGFloat {
        return min(rect.width, rect.height)/2
    }
    var value: Double
    var startDeg: Double
    var endDeg: Double
    var path: Path {
        var path = Path()
        path.addArc(center:rect.mid , radius:self.radius, startAngle: Angle(degrees: self.startDeg), endAngle: Angle(degrees: self.endDeg), clockwise: false)
        path.addLine(to: rect.mid)
        path.closeSubpath()
        return path
    }
    var index: Int
    var foregroundColor:Color
    public var body: some View {

        path
            .fill()
            .foregroundColor(self.foregroundColor)
            .overlay(
                Text(String(value)) // ****** This is the place where value is overlayed
            )
            .scaleEffect(self.show ? 1 : 0)
            .animation(Animation.spring().delay(Double(self.index) * 0.04))
            .onAppear(){
                self.show = true
        }

    }
}

extension CGRect {
    var mid: CGPoint {
        return CGPoint(x:self.midX, y: self.midY)
    }
}


struct PieSlice: Identifiable {
    var id = UUID()
    var startDeg: Double
    var endDeg: Double
    var value: Double
    var foregroundColor: Color
}

public struct Pie : View {
    var data: [QuestionType: Double]
    var slices: [PieSlice] {
        var tempSlices:[PieSlice] = []
        var lastEndDeg:Double = 0
        let maxValue = data.values.reduce(0, +)
        for slice in data.keys {
            let normalized:Double = Double(data[slice]!)/Double(maxValue)
            let startDeg = lastEndDeg
            let endDeg = lastEndDeg + (normalized * 360)
            lastEndDeg = endDeg
            tempSlices.append(PieSlice(startDeg: startDeg, endDeg: endDeg, value: data[slice]!, foregroundColor: slice.getColor()))
        }
        return tempSlices
    }


    public var body: some View {
        GeometryReader { geometry in
            ZStack{
                ForEach(0..<self.slices.count){ i in
                    PieChartCell(
                        rect: geometry.frame(in: .local),
                        value: self.slices[i].value,
                        startDeg: self.slices[i].startDeg,
                        endDeg: self.slices[i].endDeg,
                        index: i,
                        foregroundColor: self.slices[i].foregroundColor)
                }
            }
        }
    }
}

public struct PieChart : View {
    public var data: [QuestionType: Double]
    public var title: String
    public var legend: String
    public var style: ChartStyle
    public var formSize:CGSize
    public var dropShadow: Bool

    public init(data: [QuestionType: Double], title: String, legend: String, style: ChartStyle = Styles.pieChartStyleOne, form: CGSize? = ChartForm.medium, dropShadow: Bool? = true ){
        self.data = data
        self.title = title
        self.legend = legend
        self.style = style
        self.formSize = form!
        self.dropShadow = dropShadow!
    }

    public var body: some View {
        ZStack{
            Rectangle()
                .fill(self.style.backgroundColor)
                .cornerRadius(20)
                .shadow(color: Color.gray, radius: self.dropShadow ? 12 : 0)
            VStack(alignment: .leading){
                HStack{
                    Text(self.title)
                        .font(.headline)
                        .foregroundColor(self.style.textColor)
                    Spacer()
                    Image(systemName: "chart.pie.fill")
                        .imageScale(.large)
                        .foregroundColor(self.style.legendTextColor)
                }.padding()
                Pie(data: data)
                LegendView()


            }
        }.frame(width: self.formSize.width, height: self.formSize.height)
    }
}


struct Legend: Hashable {
    let color: Color
    let label: String
}



struct LegendView: View {
    private let legends: [Legend] = [
        Legend(color: Color.green, label: "Correct"),
        Legend(color: Color.red, label: "Incorrect"),
        Legend(color: Color.blue, label: "Unattempted")

    ]

    var body: some View {
        HStack(alignment: .center) {
            ForEach(legends, id: \.self) { legend in
                HStack(alignment: .center) {
                    Circle()
                        .fill(legend.color)
                        .frame(width: 16, height: 16)

                    Text(legend.label)
                        .font(.subheadline)
                        .lineLimit(nil)
                }
            }
        }
    }
}

#if DEBUG
struct PieChart_Previews : PreviewProvider {
    static var previews: some View {
        PieChart(data:[
            QuestionType.Correct: 10,
            QuestionType.Incorrect: 25,
            QuestionType.Unattempted: 15
        ], title: "Title", legend: "Legend")
    }
}
#endif

А вот ContentView

import SwiftUI

struct ContentView: View {
    @State var tabIndex:Int = 0
    var body: some View {
        TabView(selection: $tabIndex) {

            PieCharts().tabItem { Group{
                Image(systemName: "chart.pie")
                Text("Pie charts")
                }}.tag(2)

        }
    }
}


struct PieCharts:View {
    var body: some View {
        VStack{
            PieChart(data: [
                QuestionType.Correct: 10,
                QuestionType.Incorrect: 5,
                QuestionType.Unattempted: 25
            ], title: "Title", legend: "legend")
        }
    }
}

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...