Search code examples
ios-charts

How can I add the arrow of the maximum and minimum value in iOS-charts?


I want to show the arrow of the maximum and minimum value just like the picture below.

Does anyone have ideas about how to achieve it using iOS-Charts? Thanks a lot.

Chart description


Solution

  • You need to write your own custom renderer for CandleStickChartView. Fortunately, in your case you need overwrite only one method.

    So, inherit class from CandleStickChartRenderer and override method drawValues(context: CGContext). You can just copy/paste most of the code from parent's method and make only necessary changes.

    class MyCandleStickChartRenderer: CandleStickChartRenderer {
    
        internal var _xBounds = XBounds()
    
        var minValue: Double
        var maxValue: Double
    
        init (view: CandleStickChartView, minValue: Double, maxValue: Double) {
            self.minValue = minValue
            self.maxValue = maxValue
    
            super.init(dataProvider: view, animator: view.chartAnimator, viewPortHandler: view.viewPortHandler)
        }
    
        override func drawValues(context: CGContext)
        {
            // ... I remove some code that was not changed ...
    
                for j in stride(from: _xBounds.min, through: _xBounds.range + _xBounds.min, by: 1)
                {
                    guard let e = dataSet.entryForIndex(j) as? CandleChartDataEntry else { break }
    
                    // need to show only min and max values
                    guard e.high == maxValue || e.low == minValue else { continue }
    
                    pt.x = CGFloat(e.x)
                    if e.high == maxValue {
                        pt.y = CGFloat(e.high * phaseY)
                    } else if e.low == minValue {
                        pt.y = CGFloat(e.low * phaseY)
                    }
                    pt = pt.applying(valueToPixelMatrix)
    
                    // ... I remove some code that was not changed ...   
    
                    if dataSet.isDrawValuesEnabled
                    {
                        var textValue: String?
                        var align: NSTextAlignment = .center
    
                        // customize position for min/max value 
                        if e.high == maxValue {
                            pt.y -= yOffset
                            textValue = "←  " + String(maxValue)
                            align = .left
                        } else if e.low == minValue {
                            pt.y += yOffset / 5
                            textValue = String(minValue) + "  →"
                            align = .right
                        }
    
                        if let textValue = textValue {
                            ChartUtils.drawText(
                                context: context,
                                text: textValue,
                                point: CGPoint(
                                    x: pt.x,
                                    y: pt.y ),
                                align: align,
                                attributes: [NSAttributedStringKey.font: valueFont, NSAttributedStringKey.foregroundColor: dataSet.valueTextColorAt(j)])
                        }
                    }
                }
            }
        }
    }
    

    Also you need to create instance of your renderer and set it as property in your chart view.

    myCandleStickChartView.renderer = MyCandleStickChartRenderer(view: candleStickChartView, minValue: 400, maxValue: 1450)
    

    And in the end ...

    enter image description here