Pie chart spoke with value and name


#1

Hi,

I would like to create pie chart with a little bit custom spokes.

What I would like to achieved is to display name od datapoint above spoke and value below spoke. Right now I know how to do it both above with

func sChart(_ chart: ShinobiChart, labelForSliceAt sliceIndex: Int, in series: SChartRadialSeries) -> UILabel?

and set label number of line to 2…

How to put one label below and one above?

Marko


Pie spokes don't overlap
#2

Hi Marko,

If you weren’t using spokes, then the way to do this would be to use the delegate method sChart:alterLabel:forDatapoint:atSliceIndex:inRadialSeries: to reposition the label, but unfortunately there’s currently an issue which means that when displaying spokes, this method is called before the labels are positioned.

We’ll try to get the issue fixed for a future release of shinobicharts but in the meantime you can work around the issue by creating your own additional labels and using KVO, like this:

func sChart(_ chart: ShinobiChart, labelForSliceAt sliceIndex: Int, in series: SChartRadialSeries) -> UILabel {
    let pieSeries = series as! SChartPieSeries
    let dp = self.sChart(chart, dataPointAt: sliceIndex, forSeriesAt: 0)
    let label = UILabel()
    label.text = String(format:"Slice %i", sliceIndex)
    label.sizeToFit()
    label.addObserver(self, forKeyPath: "frame", options: NSKeyValueObservingOptions(rawValue: 0), context: nil)
    label.addObserver(self, forKeyPath: "center", options: NSKeyValueObservingOptions(rawValue: 0), context: nil)
    label.layer.addObserver(self, forKeyPath: "frame", options: NSKeyValueObservingOptions(rawValue: 0), context: nil)
    label.layer.addObserver(self, forKeyPath: "center", options: NSKeyValueObservingOptions(rawValue: 0), context: nil)
    
    sliceLabels[sliceIndex] = label

    let customLabel = UILabel()
    customLabel.text = String(format:"Value: %.0f", dp.sChartYValue() as! Float)
    customLabel.font = pieSeries.style().labelFont
    customLabel.textColor = pieSeries.style().labelFontColor
    customLabel.backgroundColor = pieSeries.style().labelBackgroundColor
    customLabel.sizeToFit()
    chart.canvas.overlay.addSubview(customLabel);
    customLabels[sliceIndex] = customLabel;
    
    return label;
}

override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
    if let changedLabel = object as? UILabel {
        for (index, label) in sliceLabels {
            if let sliceLabel = label as? UILabel, sliceLabel === changedLabel {
                let customLabel = customLabels[index] as! UILabel
                customLabel.center = CGPoint(x: sliceLabel.center.x,
                                             y: sliceLabel.center.y + sliceLabel.frame.size.height);
            }
        }
    }
}

Note that as explained here UIKit is not officially KVO compliant, but most users on that post agree that the code suggested there does work. (You may wish to add more observers than I’ve added here.)

I apologise for the rather long workaround, but I hope it helps you.

Alison


#3

Thank you. Do you know when will new version be released?


#4

Hi Marko,

We’ve added the issue to our backlog but it needs to be prioritised, fixed then put into a release. Unfortunately we don’t have an estimate for the release date yet.

Kind regards,

Alison