iOS: Simple Bar Chart with UISatckViews

 

A lot of times we start to search third party libraries to include a simple chart in our iOS app instead to develop our own code to solve the problem.

Maybe the third party library configuration works in that case but sometimes because of design decisions you have to make modifications of third party library and apply some workaround to adjust to your iOS app. In that times you think, what takes more time? and what is the more maintainable option?.

That happened to me in a project and I started to research about the difficulty to develop my own solution. And voila using UIStackView objects I developed my solution in a short time.

What is a UIStackView?

It’s an optimized interface to show a collection view disposed  in a column or in a row. For our case the easy way to understand is that each bar chart is an UIView object. If we can add one collection of these objects to an UIStackView disposed in a row with equivalent spacing we have a simple bar chart.

 

Example: Running App

 

For this example we will develop a bar char to show the running time in the last six months. This bar chart can be uses in the stats section of training app. The bar chart will be like the image, with a bottom index and value indicator in each bar.

Really this bar chart is formed by two UIStackView objects as containers where we applied some configurations. In our case that configurations will be very similar. The stack 1, we called GraphStackView, will contain the chart bar and the stack 2, we called IndexStackView, will contain the index UILabels.

The GraphStackView has the peculiarity that each element will be an vertical UIStackView that contain an UIView and an UILabel to indicate the time.

Both, GraphStackView and IndexStackView will be define in the Interface Builder and the UIStackView objects contained inside of the GraphStackView will be develop programatically.

We start with Interface Builder

In a Storyboard view we create two horizontal UIStackView objects.

The IndexGraphView is a horizontal UIStackView with a separation between the elementos of 20px and a equality distribution, that means that every elements inside the IndexGraphView will have the same width.

 

The GraphStackView has the same properties that the IndexStackView but with more heigth.

Data type.

In order to show the time used monthly we use a simple structure: TimeGraphData

struct TimeGraphData {
    var order: Int
    var amount: String
    var month: String
    var percentage: Double
    
    init (order: Int, amount: String, month: String, percentage: Double) {
        self.order = order
        self.amount = amount
        self.month = month
        self.percentage = percentage
    }
}

 

Each TimeGraphData element render a bar item of the bar chart. In the final example we will loop the TimeGraphData collection and we will create the related UIStackView objects and it’s elements.

IndexStackView

The IndexStackView will represent the months list set in the bottom. Inside of this stack we will add each of UILabels with the month name.

This is the code to make each UILabel element of the IndexStackView. Each UILabel will set a height inside the IndexStackView with the “heightAnchor” property.

 

private func addIndexElement (timeGraphData: TimeGraphData) {
        let monthLabelHeight: CGFloat = 13.0
        
        let monthLabel = UILabel()
        monthLabel.text = timeGraphData.month
        monthLabel.font = UIFont.systemFont(ofSize: monthLabelHeight)
        monthLabel.textAlignment = .center
       
        monthLabel.heightAnchor.constraint(equalToConstant: monthLabelHeight).isActive = true
        
        indexStackView.addArrangedSubview(monthLabel)
        indexStackView.translatesAutoresizingMaskIntoConstraints = false;
}

GraphStackView

Create the content of this stack will be more complex. The GraphStackView contain each vertical UIStackView developed programatically that will be formed by an UIView and an UILabel.

 

This is the code to add each item:

private func addGraphElement (timeGraphData: TimeGraphData) {

        let amountLabelFontSize: CGFloat = 9.0
        let amountLabelPadding: CGFloat = 15.0
        let height = heightPixelsDependOfPercentage(percentage: timeGraphData.percentage)
        let totalHeight = height + amountLabelPadding
        
        let verticalStackView: UIStackView = UIStackView()
        verticalStackView.axis = .vertical
        verticalStackView.alignment = .fill
        verticalStackView.distribution = .fill
        verticalStackView.spacing = 8.0
        
        let amountLabel = UILabel()
        amountLabel.text = timeGraphData.amount
        amountLabel.font = UIFont.systemFont(ofSize: amountLabelFontSize)
        amountLabel.textAlignment = .center
        amountLabel.textColor = UIColor.darkText
        amountLabel.adjustsFontSizeToFitWidth = true
        amountLabel.heightAnchor.constraint(equalToConstant: amountLabelFontSize).isActive = true
        
        let view = UIView()
        view.backgroundColor = graphColor
        view.heightAnchor.constraint(equalToConstant: height).isActive = true
        
        verticalStackView.addArrangedSubview(amountLabel)
        verticalStackView.addArrangedSubview(view)
        
        verticalStackView.heightAnchor.constraint(equalToConstant: totalHeight).isActive = true
        verticalStackView.translatesAutoresizingMaskIntoConstraints = false;
        
        graphStackView.addArrangedSubview(verticalStackView)
        graphStackView.translatesAutoresizingMaskIntoConstraints = false;
}

The method “heighPixelDependOfPercentage” return the height of the vertical stack in pixels.

 

We create the “verticalStackView” with vertical orientation, and fill distribution with a space of 8 px between elementos.

In the same way that the previews stack both, UILabel and UIView set the height inside the stack using the “heightAnchor” property.

 

Download de complete project

In this article I have showed the key parts of the code to make a simple bar chart with UIStackView but here it’s available the complete project.

Conclusion

With this code in a simple way we can integrate a bar chart in our app without use a third party library. If we dedicate some time we can improve this example in order to add more elements, clickable bars, scrolling bars, etc.

And you, Do you often prefer use a third party library  or develop your own controls?

 

Related articles:

Bridging Swift – Objective-C

iOS code signing

Petrol App – Integration with CARTO in a Mobile App

iOS Touch ID

 

Leave a Comment

By completing the form you agree to the Privacy Policy