Swift : Custom Label on yAxis Bar Chart


#1

I need to know can Shinobi do this. I implement simple vertical stack bar like below :

I want change the label on yAxis (“Data 1”) with an image. Any suggest and answer will help for me. Thanks in Advance


#2

Hi MrX,

It should be possible to do this as follows:

  • Set the width of the y-axis to be wide enough for your images
  • Implement the sChart(_ chart: ShinobiChart, alter tickMark: SChartTickMark, beforeAddingTo axis: SChartAxis) method to do the following:
  • Get the current center of the tickMark.tickLabel
  • Set tickMark.tickLabel.text to be empty
  • Check whether the tickMark.tickLabel has any existing UIImageView subviews and remove them if so. (This is because the chart reuses its tickmark objects when panning/zooming.)
  • Add the UIImageView to tickMark.tickLabel and resize the label to fit.
  • Reposition the label to it is vertically centered on the bar (based on the previous center).

I hope that helps.

Alison


#3

Hi aclarke,
Thank you for your suggestion but I have a question. How to check tickMark.tickLabel have exiting UIImage ? I try your suggestion but the image doesnt show in yAxis.
Thanks


#4

Hi MrX,

I realised in my previous answer I’d mentioned UIImage instead of UIImageView - I’ve now corrected that.

To check whether there’s already a UIImageView on the label you just need to iterate through tickMark.tickLabel.subviews and call removeFromSuperview on any UIImageView instances that you’d previously added.

If it’s still not working, first check that you’ve set the chart’s delegate property and that the alter tickMark method is being called. If it still doesn’t work, could you post your code here?

Kind regards,

Alison


#5

Hi aclarke,

Here my code :

func sChart(_ chart: ShinobiChart, alter tickMark: SChartTickMark, beforeAddingTo axis: SChartAxis) {
    let centerOfTick = tickMark.tickLabel?.center

    if axis == chart.yAxis {
        let image = UIImage(named: "Done.png")
        let imageView: UIImageView = UIImageView(image: image)
        
        if tickMark.tickLabel?.subviews != nil {
            imageView.removeFromSuperview()
        }
        
        tickMark.tickLabel?.text = ""
        
        imageView.frame = CGRect(x: 0, y: 0, width: 30, height: 30)
        
        tickMark.tickLabel?.sizeToFit()
        tickMark.tickLabel?.addSubview(imageView)

    }
}

Do I do a mistake? Thank you,


#6

Hi MrX,

First of all, you need to call removeFromSuperview on the current subviews of the tick label, rather than on the new imageView (which doesn’t yet have a superview), e.g.:

for view in (tickMark.tickLabel?.subviews)! {
    view.removeFromSuperview()
}

Then at the end of your code sample, you need to add the imageView subview before calling sizeToFit, otherwise the label will be too small to fit your image.

You’re also not re-centering the tickLabel at the end, e.g.

tickMark.tickLabel?.center = centerOfTick!

Kind regards,

Alison


#7

This nice and useful info for me. Thanks a lot