4

I'm using iOS-Charts library, and I need to subclass HorizontalBarChartRenderer so that I can change implementation of drawDataSet(...). This should be possible as stated before, like in this answer.

So I created my custom renderer, but because of access control and because I'm using Cocoapods I had to override little more than just drawDataSet:

  • fileprivate class Buffer
  • fileprivate var _buffers = Buffer
  • fileprivate func prepareBuffer(dataSet: IBarChartDataSet, index: Int)
  • fileprivate var _barShadowRectBuffer: CGRect = CGRect() open override
  • open override func drawDataSet(context: CGContext, dataSet: IBarChartDataSet, index: Int)

I didn't change anything yet, above methods were just copied from HorizontalBarChartRenderer, and I set renderer like this:

self.horizontalBarView.renderer = HorizontalBarStackRenderer(dataProvider: self.horizontalBarView, animator: self.horizontalBarView.chartAnimator, viewPortHandler: self.horizontalBarView.viewPortHandler).

When I try to run it, I get fatal error: Index out of range at BarCharRenderer's drawValues():

let buffer = _buffers[dataSetIndex]

When I tried to set renderer to standard HorizontalBarChartRenderer the same way:

self.horizontalBarView.renderer = HorizontalBarChartRenderer(dataProvider: self.horizontalBarView, animator: self.horizontalBarView.chartAnimator, viewPortHandler: self.horizontalBarView.viewPortHandler)

everything works fine. Am I missing something?

Community
  • 1
  • 1
Adam Bardon
  • 3,829
  • 7
  • 38
  • 73

2 Answers2

4

How I made it work for bar charts:

Your custom renderer:

class RoundedBarChartRenderer: BarChartRenderer {

    private class Buffer {
       var rects = [CGRect]()
    }

    private var _buffers = [Buffer]()

    private var _barShadowRectBuffer: CGRect = CGRect()

    override func initBuffers() { /* copy everything from original file */ }

    override func drawDataSet(context: CGContext, dataSet: IBarChartDataSet, index: Int)
        { /* Copy everything */ }

    private func prepareBuffer(dataSet: IBarChartDataSet, index: Int)  { /* copy everything */ }

    override func drawValues(context: CGContext) { /* Copy everything */ }
}

Some parts will still not work properly, like accessibility. Comment out those part. Also, don't use any super.METHOD_NAME()

jocken
  • 324
  • 3
  • 10
3

I finally know what was the issue, my subclass didn't override drawValues() method, as it wasn't explicit that it is needed. Moreover, this method is accessing variable shouldDrawValues which is internal and therefor can't be accessed outside the module. I commented out the part where it's used for now, but I'll have to somehow mimic it on my own.

Adam Bardon
  • 3,829
  • 7
  • 38
  • 73