Search code examples
iosswiftios-charts

HorizontalBarChart Value Highlighting


I am currently using Charts cocoapod and I can't figure out how to implement the following functionality: when selecting a DataEntry from HorizontalBarChartDatSet I want to highlight it by just changing the borderColor of the bar. Is this possible with the current version of the pod and if not, can you please at least give me some information regarding where to look at in order to override this functionality?

At the moment I am able to highlight the DataEntry like this:

dataSet.highlightColor = UIColor.lightGray
dataSet.highlightAlpha = 1

However, I want to only make a border around the selected DataEntry not change its color.

I have already overriden the library for few specific functionalities but cannot seem to be able to figure this one out.

Thank you in advance!


Solution

  • As I know, the current version of the Chart library has no properties for highlight border around a selected bar. But you could inherit your own class from BarChartRenderer class, override function drawHighlighted(context: indices:) and use an instance of your new renderer class as custom renderer for your chart.

    Custom renderer class:

    class MyBarChartRenderer: BarChartRenderer {
    
        // New properties for the border
        var highlightBorderColor: UIColor = .red
        var highlightBorderWidth: CGFloat = 2
    
        open override func drawHighlighted(context: CGContext, indices: [Highlight])
        {
            guard
                let dataProvider = dataProvider,
                let barData = dataProvider.barData
                else { return }
    
            context.saveGState()
    
            var barRect = CGRect()
    
            for high in indices
            {
                guard
                    let set = barData.getDataSetByIndex(high.dataSetIndex) as? IBarChartDataSet,
                    set.isHighlightEnabled
                    else { continue }
    
                if let e = set.entryForXValue(high.x, closestToY: high.y) as? BarChartDataEntry
                {
                    let trans = dataProvider.getTransformer(forAxis: set.axisDependency)
    
                    // Setting color and width for the border
                    context.setStrokeColor(highlightBorderColor.cgColor)
                    context.setLineWidth(highlightBorderWidth)
    
                    let isStack = high.stackIndex >= 0 && e.isStacked
    
                    let y1: Double
                    let y2: Double
    
                    if isStack
                    {
                        if dataProvider.isHighlightFullBarEnabled
                        {
                            y1 = e.positiveSum
                            y2 = -e.negativeSum
                        }
                        else
                        {
                            let range = e.ranges?[high.stackIndex]
    
                            y1 = range?.from ?? 0.0
                            y2 = range?.to ?? 0.0
                        }
                    }
                    else
                    {
                        y1 = e.y
                        y2 = 0.0
                    }
    
                    prepareBarHighlight(x: e.x, y1: y1, y2: y2, barWidthHalf: barData.barWidth / 2.0, trans: trans, rect: &barRect)
                    // Drawing the border
                    context.stroke(barRect)
                }
            }
    
            context.restoreGState()
        }
    }
    

    Using of new renderer:

    myBarChartView.renderer = MyBarChartRenderer(
        dataProvider: self.barChartView, 
        animator: self.barChartView.chartAnimator, 
        viewPortHandler: self.barChartView.viewPortHandler)
    

    And result:

    enter image description here