Building your own chart in iOS — Part 1: Bar chart (Revised)
In this article, I will share with you the way I build my own bar chart without using any third-party library.
I use Swift 5.0 and XCode 10.1 for the sample project and the source code is provided at the end of this post.
Of course, there are a number of good chart libraries for iOS out there. You may consider using one of them before building one for your own if they match your need. However, do it yourself is relatively straightforward and will definitely helps you learn more. It also has some other advantages:
- Flexible design: You can make it look like whatever you want it to be. A third-party library may not have a chart that look like the design that your company provided you.
- No code redundancy: Because you just build what you need.
Objective
I will walk you through how to build the bar chart below, of course, with the animation. Since I received quite a number of emails asking me how to animate the bar chart, so, I decided to make it animatable.

In this article, I will only discuss about the key ideas and not too much about the source code since you can easily download and view it.
What you need to know
Here are the ingredients that I use to build the chart above:
- UIScrollView: to enable left and right scrolling
- UIBezierPath: to create paths for shapes
- CALayer: to build rectangular bars
- CAShapeLayer: to build shapes like the bars in “Chart 1: Beautiful bar chart”. This is a very cool class that help you to build all sorts of 2D shapes. It also has extra functionalities such as fill and stroke color, line caps, patterns and more.
- CATextLayer: to display text
Let’s begin
You can download the source code here: https://github.com/nhatminh12369/BarChart and run it first to see how it works.
I will show you how to build a bar chart with rectangular bars like the one below first. After that, we will change rectangular bars to curve bars. Let’s call the chart below BasicBarChart.

BasicBarChart
Class diagram

The class diagram looks quite boring but it is quite simple. Understanding the BasicBarChart will help you get a basic idea of all the elements needed to create a chart.
BasicBarChart class
BasicBarChart, a subclass of UIView, responsible for showing all layers (CALayer) to construct a bar chart. It contains a scrollView in order to allow the the chart’s content scrolls horizontally and the scrollView contains a CALayer instance called mainLayer. mainLayer contains all other layers created by the chart and the size of mainLayer is equal to the contentSize of the scrollView. The image below represent how the chart being shown:

I use UIScrollView to support scrolling. However, CAScrollLayer can also be used instead, but, using UIScrollView is much more easier and it already supports a very nice bouncing effect when you reach to edge of the content.
BasicBarChartPresenter class
The idea of having a presenter is to move all the works that are not related to UIKit out of BasicBarChart. So, BasicBarChartPresenter calculates the positions and frames of the chart elements and give them to BasicBarChart to show.
BasicBarEntry struct
Contains the positions and frames of all elements of a single bar.

Showing a basic bar entry
So, a basic bar entry consists of only 3 layers: a rectangle layer, which is the main bar; a text layer below the main bar (to show title); and a text layer above the main bar (to show value).
addRectangleLayer and addTextLayer are from CALayerExtension.swift. All the low-level works related to CALayer are here. I will discuss about it later.
Now, you already have a basic understanding of how to build the Basic Bar Chart. Let’s move on to create the Beautiful Bar Chart.
Beautiful Bar Chart
Create a curved line segment
A curved line path can be created with UIBezierPath using 2 control points:

A bar in Beautiful Bar Chart consists of multiple curved line segments like this. So, I defined it as follow (in CustomSegments.swift):
For the curve on the image above, startPoint is A, toPoint is B, endPoint is at the same position as controlPoint1 (only for the image above). You can imagine that startPoint, toPoint and endPoint are 3 vertices of a triangle in which AB is a curved line segment.
A CurvedSegment instance can be converted in to a path using a convenience init method in UIBezierPathExtension.swift. That curved line segment will be shown as a triangle with one curved side.
Let’s look at CALayerExtension first and then, we will see how a curved line segment get displayed.
CALayerExtension.swift
There are a number of methods in this extension. These methods make my code look cleaner. Here are some layer classes that I used:
- CALayer: You often see a CALayer instance in an UIView instance, it manages visual content of an UIView. Properties and methods of a CALayer are quite similar to that of an UIView. In my bar chart, I use it to create rectangular bars.
- CAShapeLayer: A subclass of CALayer. It allows to show a shape of any given path. In my bar chart, I create curved line segments using UIBezierPath and create shapes using CAShapeLayer and add them to the mainLayer.
- CATextLayer: A subclass of CALayer. It is used to show text. It has properties and methods quite similar to UILabel.
Here is an example of how to use CAShapeLayer:
In the addCurvedLayer method, I just need to create a CAShapeLayer instance, set a curved path to it and set the fillColor, strokeColor. Then, I will have half of my curved-bar:

You can easily see now that a curved-bar is created by 2 shaped. The one above is the left half of it, the right half is similar. When those 2 shapes are put together, they will form a curved-bar.
BeautifulBarEntry struct
This struct responsible for calculating all curved line segments (CurvedSegment instances) a curved bar can have.
The main bar is created by 2 curved line segments. The small bubble above each bar (to show value) consists of 4 curved line segments. When we have them generated, the job of showing them is very straightforward and quite similar to how we show the Basic Bar Chart.
Animating the bar chart
You can do animation with CALayer and CALayer’s subclasses. In order to know which property of CALayer is animatable, you can check Apple Documentation
CALayer does not have an animate method like UIView. Instead, we animate a CALayer using CABasicAnimation or CAKeyFrameAnimation.
CABasicAnimation is good enough for my bar chart. Here is my animate method in CALayerExtension.swift:
A CABasicAnimation instance need to be created with a keyPath, which is the name of the property in CALayer that we want to animate. Then, we give it the fromValue and toValue. The timing function that I use here is the default one that UIView uses.
So, nothing fancy here, it’s just a very simple and short animate(..) method. The key here is to have the right fromValue and toValue for it to animate.
Animate CAShapeLayer
Notice that the path property in CAShapeLayer is animatable, so, we have:
- keyPath: “path”
- fromValue: The previous curved path from the previous bar
- toValue: The current curved path
To be more specific, let’s look at the showEntry method in BeautifulBarChart.swift:
In showEntry method, when calling the addCurvedLayer, I supply it with the newSegment of the current chart and the respective oldSegment from the previous chart. newSegment and oldSegment will be used to construct the toValue and fromValue curved paths respectively for our animate(..) method.
Animate CALayer’s frame
The frame property in CALayer is not animatable. So, in order to animate it’s frame, we need to animate 2 properties: “position” and “bounds”
By default, position is at the center of the CALayer, bounds is the origin and size of the layer in its own coordinate space.
We can get the old frame of a bar’s element from the previous chart and use it to generate the fromValue. And then, we can animate it.
Remark:
- If you want to add touch interaction into the chart, you can add a gesture recognizer to the scrollView so that you can get the location of the touch event. CALayer and CALayer’s subclasses don’t support handling touch events.
Github project
https://github.com/nhatminh12369/BarChart
Thank you for reading
This is my first article on Medium, I hope it will be useful for you. Please let me know your thoughts and opinions :). If you enjoyed it, feel free to hit the clap button below 👏 to help others find it!
