Search code examples
iosswiftuiviewuiviewcontrollerios-charts

Bar Chart not scaling to size of BarChartView


I am using the ios-charts library by Daniel Gindi to try and create a bar chart.

I programatically create a BarChartView with a red background, and fill it with hard-coded data. The view is sized correctly, however the bar chart doesn't scale properly and is cut off when it reaches the top of the view.

My view looks like this:

enter image description here

This view controller is instantiated inside a scrollview using the storyboard method instantiateViewControllerWithIdentifier. However when I make this view controller the initial view controller, the chart scales correctly, and looks like this:

enter image description here

Why does my chart scale incorrectly?

I would also like to note that if I set the leftAxis.axisMaxValue property of the incorrectly-scaled graph to something large, like 100, the graph looks like this:

enter image description here

I will also provide the code I used to create the graph, minus the 30+ lines I used to set properties and the data of the graph.

override func viewDidLoad(){
    var chart : UIView?
    let gBFrame = self.graphBackground.frame
    let frame = CGRect(origin: gBFrame.origin, size: CGSize(width: gBFrame.width, height: gBFrame.height-25))
    chart = BarChartView(frame: frame)
    self.view.addSubview(chart!)
    constrainChart()
}

func constrainChart(){

    if type == "Bar Chart"{            
        chart!.translatesAutoresizingMaskIntoConstraints = false
        let leftConstraint = NSLayoutConstraint(item: self.chart!, attribute: NSLayoutAttribute.Left, relatedBy: NSLayoutRelation.Equal, toItem: self.graphBackground, attribute: NSLayoutAttribute.Left, multiplier: 1, constant: 0)
        let rightConstraint = NSLayoutConstraint(item: self.chart!, attribute: NSLayoutAttribute.Right, relatedBy: NSLayoutRelation.Equal, toItem: self.graphBackground, attribute: NSLayoutAttribute.Right, multiplier: 1, constant: 0)
        let topConstraint = NSLayoutConstraint(item: self.chart!, attribute: NSLayoutAttribute.Top, relatedBy: NSLayoutRelation.Equal, toItem: self.graphBackground, attribute: NSLayoutAttribute.Top, multiplier: 1, constant: 0)
        let bottomConstraint = NSLayoutConstraint(item: self.chart!, attribute: NSLayoutAttribute.Bottom, relatedBy: NSLayoutRelation.Equal, toItem: self.graphBackground, attribute: NSLayoutAttribute.Bottom, multiplier: 1, constant: -25)
        self.view.addConstraints([leftConstraint,rightConstraint,topConstraint,bottomConstraint])
    } else if type == "Horizontal Bar Chart"{
    } else if type == "Pie Chart"{
    } else {

    }
    chart?.layoutIfNeeded()
}

I can provide any additional information if it is helpful.

Any ideas on what could be the problem? Or what to try next?

EDIT:

when I instantiate the view controller inside the scrollview, I use NSLayoutConstraints to position it such that its left boundary is 2*self.view.frame.width from the left boundary of the scrollview.

I find that if I set that constraint to 0, such that the view controller with the chart appears in the leftmost frame of the scrollview, the chart appears correctly. However if I change that constraint at all (like by one unit), the chart scales incorrectly again.

Right after I instantiate the view controller using the aforementioned storyboard method, I position it using the method whose code is shown below:

func setUpQuestionFrame(newViewController: UIViewController){

    var frame = newViewController.view.frame
    frame.origin.x = self.view.frame.size.width*2
    newViewController.view.frame = frame

    self.addChildViewController(newViewController)
    self.scrollView.addSubview(newViewController.view)
    newViewController.didMoveToParentViewController(self)

    newViewController.view.translatesAutoresizingMaskIntoConstraints = false

    let widthConstraintVCBAR = NSLayoutConstraint(item: view, attribute: NSLayoutAttribute.Width, relatedBy: NSLayoutRelation.Equal, toItem: newViewController.view, attribute: NSLayoutAttribute.Width, multiplier: 1, constant: 0)
    view.addConstraint(widthConstraintVCBAR)

    let heightConstraintVCBAR = NSLayoutConstraint(item: view, attribute: NSLayoutAttribute.Height, relatedBy: NSLayoutRelation.Equal, toItem: newViewController.view, attribute: NSLayoutAttribute.Height, multiplier: 1, constant: 0)
    view.addConstraint(heightConstraintVCBAR)

    let horizontalConstraintVCBAR = NSLayoutConstraint(item: newViewController.view, attribute: NSLayoutAttribute.Left, relatedBy: NSLayoutRelation.Equal, toItem: scrollView, attribute: NSLayoutAttribute.Right, multiplier: 1, constant: 5)//self.view.frame.width*2)
    view.addConstraint(horizontalConstraintVCBAR)

    let verticalConstraintVCBAR = NSLayoutConstraint(item:  newViewController.view, attribute: NSLayoutAttribute.Top, relatedBy: NSLayoutRelation.Equal, toItem: scrollView, attribute: NSLayoutAttribute.Top, multiplier: 1, constant: 0)
    view.addConstraint(verticalConstraintVCBAR)
}

Solution

  • The issue was solved by adding chart!.notifyDataSetChanged(), which tells the chart to reconfigure once it receives new data.

    It was the same solution that was used in this question.