Use UICollectionView to implement highly customisable Bar Chart

When working on the new product Fruitful, I found that a Bar Chart framework with clear API and easily yet highly customisable is so difficult to find(OK, free is  required).

What a bar chart(all charts indeed) is? It's a layout of a data structure,  bars lay on lines. The lines are used to represent values ranges, and the bars showing items value ranges. Bar grows on same direction. A very logical layout.

I think a good chart should just tell us the layout and let us modify the views ourself. Wait, it just sounds like, it just sounds like... Yup a collection view. Let's recap what a collection view is. Nah, you know what a collection view is - a collection of view which can be define in rules.

Using collection view to implement a bar chart would be very good idea. Actually, we don't have to implement a whole new collection view, just make a chart layout is good enough. Also, we can use interface builder to design our bars visually and enjoy auto layout, how good is it? (I've also used section to define stacked bars.)

How to do?

Subclass the CollectionViewLayout, override all needed methods:

layoutAttributesForElementsInRect(_:CGRect) , calculate what items should be shown in current context. We should provide items' attributes , supplementary views' attributes here. For example, here is how I doing that:

(I used the new stride(::) function here, it's just a convenience generator help me to reduce code here, you can use "for loop" or "generator" instead)

layoutAttributesForItemAtIndexPath(_:NSIndexPath). Here is the real trick. How a item in a collection view layout is defined here, for a bar chart layout, doesn't like the flow layout, all items occupy a single row/col no matter it's width/height. You should calculate the item's frame to represent the datas (values) you want to show.

layoutAttributesForSupplementaryViewOfKind(:String,:NSIndexPath). We should implement it also because it let us to put extra infos for the bars and chart easily.

And now you can customise all bars as a UICollectionViewCell and row/col as a supplementary view like using UICollectionView.

After we've finish the previous tasks, we can now try out our ChartLayout.