Allow PieChartView to hide value line for tiny sli

2020-05-06 10:47发布

问题:

I'm building a pie chart by chart iOS framework. I'm able to hide the value and label when the the slice is tiny but I can't hide the value line for tiny slice.

If I add this code on setDataCount()

set.valueLineWidth = 0.0

It will hide all the value line. How to hide it by the size of slice?

@IBOutlet weak var myChart: PieChartView!

var valueColors = [UIColor]()
var dataEntries = [PieChartDataEntry]()
var record = [Record]()
var category = [String]()
var categoryTotal : [Double] = []
var categoryArray : [String] = []

func setDataCount() {
    var totalValue = 0.0
    for a in categoryTotal {
        totalValue += a
    }
    UserDefaults.standard.set(totalValue, forKey: "totalValue")
    valueAndColor()

    let set = PieChartDataSet(values: dataEntries, label: nil)

    set.colors = valueColors
    set.valueLinePart1OffsetPercentage = 0.8
    set.valueLinePart1Length = 0.2
    set.valueLinePart2Length = 0.4
    set.xValuePosition = .outsideSlice
    set.yValuePosition = .outsideSlice
    set.selectionShift = 0.0

    let data = PieChartData(dataSet: set)
    let Formatter:ChartFormatter = ChartFormatter()
    data.setValueFormatter(Formatter)
    data.setValueFont(.systemFont(ofSize: 11, weight: .light))
    data.setValueTextColor(.black)

    myChart.data = data
    myChart.highlightValues(nil)
}

func valueAndColor(){
    for i in 0..<categoryArray.count{
        let dataEntry = PieChartDataEntry(value: categoryTotal[i], label: categoryArray[i % categoryArray.count])
        dataEntries.append(dataEntry)

        //I'm using this code to hide the label
        let value = categoryTotal[i]
        let total = UserDefaults.standard.double(forKey: "totalValue")
        var valueToUse = value/total * 100
        valueToUse = Double(round(10*valueToUse)/10)
        let minNumber = 10.0

        if(valueToUse < minNumber) {
            dataEntries[i].label = ""
        }else{
            dataEntries[i].label = categoryArray[i % categoryArray.count]
        }
        if categoryArray[i] == "吃喝" {
            valueColors.append(UIColor.yellow)
        }...
 }

I'm using this code to hide the value %

public class ChartFormatter: NSObject, IValueFormatter{

    public func stringForValue(_ value: Double, entry: ChartDataEntry, dataSetIndex: Int, viewPortHandler: ViewPortHandler?) -> String {
        let total = UserDefaults.standard.double(forKey: "totalValue")
        var valueToUse = value/total * 100
        valueToUse = Double(round(10*valueToUse)/10)
        let minNumber = 10.0

        if(valueToUse < minNumber) {
            return ""
        }
        else {
            let pFormatter = NumberFormatter()
            pFormatter.numberStyle = .percent
            pFormatter.maximumFractionDigits = 1
            pFormatter.multiplier = 1
            pFormatter.percentSymbol = " %"
            let hideValue = pFormatter.string(from: NSNumber(value: value))

            return String(hideValue ?? "0")
        }
    }
}

回答1:

Inside the file PieChartRenderer change from this:

 if dataSet.valueLineColor != nil        
 {
    context.setStrokeColor(dataSet.valueLineColor!.cgColor)
    context.setLineWidth(dataSet.valueLineWidth)

    context.move(to: CGPoint(x: pt0.x, y: pt0.y))
    context.addLine(to: CGPoint(x: pt1.x, y: pt1.y))
    context.addLine(to: CGPoint(x: pt2.x, y: pt2.y))

    context.drawPath(using: CGPathDrawingMode.stroke)

 }

to this:

 if dataSet.valueLineColor != nil
 {

     if(valueText == "") {
         context.setStrokeColor(UIColor.clear.cgColor)
     }
     else {
         context.setStrokeColor(dataSet.valueLineColor!.cgColor)
     }

     context.setLineWidth(dataSet.valueLineWidth)

     context.move(to: CGPoint(x: pt0.x, y: pt0.y))
     context.addLine(to: CGPoint(x: pt1.x, y: pt1.y))
     context.addLine(to: CGPoint(x: pt2.x, y: pt2.y))

     context.drawPath(using: CGPathDrawingMode.stroke)
 }

The change basically checks if the valueText is the empty string, and if so it changes the linecolor to a clear color.