Creating Spider Pie Chart library

Finally after more than 2 months since my planning I was finally able to finish the Spider pie chart library implementation. Here is the documentation below.

Spider Pie Chart library allows you to create a chart in 2-D space. You can plot 2 units at once. One unit in radial direction and other in angular one. This could be confusing initially, but can be clear as we go through more examples.

You can download and view library demo directly from GitHub at https://github.com/jayesh15111988/JKSpiderChartLibrary. If you want to integrate it into your project, please add following line to your podfile and run pod install.


pod 'JKSpiderChartLibrary', :git => 'https://github.com/jayesh15111988/JKSpiderChartLibrary.git'

If you are integrating this library into swift project, please be sure to include following line at the top of podfile.

use_frameworks!

To begin with, here are some of the screenshots of the spider charts generated by this library,

Third party dependencies

Library uses one third party dependency which is BlocksKit. This is useful to intercept touch event on the UIView subclass.

Usage:

Library takes following mandatory options through the initializer.

  • firstOptions ([string]) - List of options with string datatype to plot values in radial direction. Library then draws pie shapes with the values from firstOptions array mapped to appropriate radius values

  • secondOptions ([string]) - List of options with string datatype to plot values in the form of arc. Each arc represents values in percentage mapped to appropriate angle which is fraction of 360. Make sure values you pass are represented in the form of percentages. Meaning when you sum all values from secondOptions, it should equal to 100

  • labelTitles ([string]) - List of labels to be used for individual section. For example, section might represent individual student, department or any entity which is under evaluation.

Please make all these arrays are equal in size. Otherwise application will crash with assertion failure.

Library also takes following optional parameter,

  • animated - Indicates if pie chart will be drawn with animation. Default value is false, meaning animation won't be applied. Default animation duration is 1.0 second which is not configurable.

Protocol

Library provides following options protocol for getting callback as well as configuring appearance based on the user preferences

@objc public protocol SpiderChartProtocol: class {
    optional func mapLegendSelectedAt(index: Int)
    optional func legendLabelsFont() -> UIFont
    optional func graphLabelsFont() -> UIFont
    optional func graphPadding() -> CGFloat
}

Their description is as follows,

optional func mapLegendSelectedAt(index: Int) - If client adheres to protocol and implements this method, it sends callback when user selects one the legend items at the bottom bar in the graph.
Note: Index starts from 0

optional func legendLabelsFont() -> UIFont - If implemented, it overrides the default font used for a legend labels. Default values is system font with 13 font size

optional func graphLabelsFont() -> UIFont - If implemented, it overrides the fonts used to annotate the pie chart. Default values is system font with 10 font size

optional func graphPadding() -> CGFloat - If implemented, overrides the default padding for pie chart. Padding is important to add annotations to the chart. Default values is 44 pixels. Can be configured as per necessity.

Note

Please note that library uses CALayer and since autolayout is not supported on the CALayers, chart library does not get exact view frame until autolayout is completely drawn on the viewport. To make up with that, you can initialize pie chart anywhere in the class as follows,

let spider = SpiderChart(firstOptions: ["200", "100", "148", "107", "133"], secondOptions: ["20", "10", "40", "15","15"], labelTitles: ["l1", "l2", "l3", "l4", "15"])
spider?.translatesAutoresizingMaskIntoConstraints = false
spider?.chartDelegate = self
self.view.addSubview(spider!)

And then in your viewController, override the method viewDidLayoutSubviews, call the superclass variant and then call the method drawSpiderChart on SpiderChart instance as follows,

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()
    spider?.drawSpiderChart()
}

Please note that I am assuming client will be making use of autolayout. I haven't really tried using it with non-autolayout code, but I strongly recommend you to use autolayout for best results possible.