Search code examples
iosswiftcocoapods

danielgindi/Charts how to get xLabel position


I was able to get the position of the x Label from xAxisRenderer. But I failed to import this into my project. I'm trying to get this position and create a custom x-axis. How can I store a value in an external module and use it in an internal module?

 @objc open func drawLabels(context: CGContext, pos: CGFloat, anchor: CGPoint)
{
    guard let transformer = self.transformer else { return }
    
    let paraStyle = ParagraphStyle.default.mutableCopy() as! MutableParagraphStyle
    paraStyle.alignment = .center
    
    let labelAttrs: [NSAttributedString.Key : Any] = [.font: axis.labelFont,
                                                     .foregroundColor: axis.labelTextColor,
                                                     .paragraphStyle: paraStyle]

    let labelRotationAngleRadians = axis.labelRotationAngle.DEG2RAD
    let isCenteringEnabled = axis.isCenterAxisLabelsEnabled
    let valueToPixelMatrix = transformer.valueToPixelMatrix

    var position = CGPoint.zero
    var labelMaxSize = CGSize.zero
    
    if axis.isWordWrapEnabled
    {
        labelMaxSize.width = axis.wordWrapWidthPercent * valueToPixelMatrix.a
    }
    
    let entries = axis.entries
    
    for i in entries.indices
    {
        let px = isCenteringEnabled ? CGFloat(axis.centeredEntries[i]) : CGFloat(entries[i])
        position = CGPoint(x: px, y: 0)
            .applying(valueToPixelMatrix)

        guard viewPortHandler.isInBoundsX(position.x) else { continue }
        
        let label = axis.valueFormatter?.stringForValue(axis.entries[i], axis: axis) ?? ""
        let labelns = label as NSString
        
        if axis.isAvoidFirstLastClippingEnabled
        {
            // avoid clipping of the last
            if i == axis.entryCount - 1 && axis.entryCount > 1
            {
                let width = labelns.boundingRect(with: labelMaxSize, options: .usesLineFragmentOrigin, attributes: labelAttrs, context: nil).size.width
                
                if width > viewPortHandler.offsetRight * 2.0,
                    position.x + width > viewPortHandler.chartWidth
                {
                    position.x -= width / 2.0
                }
            }
            else if i == 0
            { // avoid clipping of the first
                let width = labelns.boundingRect(with: labelMaxSize, options: .usesLineFragmentOrigin, attributes: labelAttrs, context: nil).size.width
                position.x += width / 2.0
            }
        }
        
        print(position.x)
        
        drawLabel(context: context,
                  formattedLabel: label,
                  x: position.x,
                  y: pos,
                  attributes: labelAttrs,
                  constrainedTo: labelMaxSize,
                  anchor: anchor,
                  angleRadians: labelRotationAngleRadians)
    }
}

I tried to get the position value by creating an open class called XAxisPosition, but the value is initialized to 0 in the process of importing it into my project module. I have access to it, but how do I get the values ​​fully into my project?


Solution

  •     public protocol XAxisRendererDelegate
    {
        @objc optional func renderer(_ renderer: XAxisRenderer, 
    labelPostion: CGPoint)
    }
    
     @objc open weak var delegate: XAxisRendererDelegate?
    

    I added this XAxisRenderer.

    and add this in drawLabels.

     let px = isCenteringEnabled ? CGFloat(axis.centeredEntries[i]) : 
     CGFloat(entries[i])
                position = CGPoint(x: px, y: 0)
                    .applying(valueToPixelMatrix)
                delegate?.renderer?(self, labelPostion: position)
    

    and use this

     chartView.xAxisRenderer.delegate = self