Как найти подходящую позицию для моих ярлыков на круговой диаграмме? - PullRequest
0 голосов
/ 17 ноября 2018

Я не пользуюсь никакими библиотеками, так что это не дубликат this .

Я рисую круговые секции так:

var sections: [PieChartSection] = [] {
    didSet {
        setNeedsDisplay()
    }
}

override func draw(_ rect: CGRect) {
    let sumOfSections = sections.map { $0.value }.reduce(0, +)
    var pathStart = CGFloat.pi
    let smallerDimension = min(height, width)
    for section in sections {
        // draw section
        let percentage = section.value / sumOfSections
        let pathEnd = pathStart + CGFloat.pi * percentage.f * 2
        let path = UIBezierPath(arcCenter: CGPoint(x: bounds.midX, y: bounds.midY),
                                radius: smallerDimension / 4, startAngle: pathStart, endAngle: pathEnd, clockwise: true)

        //draw labels
        // this is my attempt at calculating the position of the labels
        let midAngle = (pathStart + pathEnd) / 2
        let textX = bounds.midX + smallerDimension * 3 / 8 * cos(midAngle)
        let textY = bounds.midY + smallerDimension * 3 / 8 * sin(midAngle)

        // creating the text to be shown, don't this is relevant
        let attributedString = NSMutableAttributedString(string: section.name, attributes: [
            .foregroundColor: UIColor.black.withAlphaComponent(0.15),
            .font: UIFont.systemFont(ofSize: 9)
            ])
        let formatter = NumberFormatter()
        formatter.maximumFractionDigits = 0
        let percentageString = "\n" + formatter.string(from: (percentage * 100) as NSNumber)! + "%"
        attributedString.append(NSAttributedString(string: percentageString, attributes: [
            .foregroundColor: UIColor.black.withAlphaComponent(0.5),
            .font: UIFont.systemFont(ofSize: 12)
            ]))
        attributedString.draw(at: CGPoint(x: textX, y: textY))

        // stroke path
        path.lineWidth = 6
        section.color.setStroke()
        path.stroke()
        pathStart = pathEnd
    }
}

ИPieChartSection - это простая структура:

struct PieChartSection {
    let value: Double
    let color: UIColor
    let name: String
}

Пирог выглядит хорошо, но метки иногда находятся далеко от пирога, а иногда очень близко к нему:

enter image description here

Я думаю, проблема в том, что NSAttriutedString.draw всегда рисует текст из верхнего левого угла, а это означает, что верхние левые углы текста находятся на одинаковом расстоянии.в круговую диаграмму, тогда как мне нужно нарисовать текст так, чтобы их ближайшие точки к круговой диаграмме находились на одинаковом расстоянии от круговой диаграммы.

Как я могу нарисовать такой текст?

Я не использую какао-стручок, потому что мне очень трудно сделать диаграмму так, как я хочу, используя высокоуровневый API.Здесь просто слишком много сложностей.Я хочу, чтобы нижний уровень контроля над тем, как нарисована моя круговая диаграмма.

1 Ответ

0 голосов
/ 17 ноября 2018

Мне кажется, проблема в том, что NSAttriutedString.draw всегда рисует текст из верхнего левого угла

Конечно, метод draw поместит начало строки прямо в точку, которую вы передаете. В этом случае решение простое - найдите size строки и сделайте правильный источник.

let size = attributedString.size()
let origin = CGPoint(x: textX - size.width / 2, y: textY - size.height / 2)
attributedString.draw(at: origin)

Результат:

enter image description here

...