Quick Start Guide – Objective-C

Introduction

This is a brief introduction to using the ShinobiCharts component. This quick start guide will walk you through a series of simple steps introducing the key features of the charting library which includes supplying data to the chart via the datasource, simple styling and configuration of the labels, title and axes.

At the end of this guide you will have created the following chart:

What we're aiming for

Your Download

The ‘ShinobiCharts’ folder contains:

  • A copy of the framework.
  • A copy of the documentation for the framework.
  • A set of samples to demonstrate getting started with ShinobiCharts.
  • A README file with setup steps.
  • A change log stating the changes made in each release.
  • A copy of the ShinobiControls Licence.
  • A text file containing the version number of the framework.

Draw a Simple Chart

Start-up Xcode and create a new project via File / New / Single View Application.

Within your newly created project add a reference to the ShinobiCharts framework by dragging the framework from the Finder into the project.

ShinobiCharts makes use of a few other frameworks, so add the following as well:

  • libc++.tbd

If you’re using a trial framework, ensure you check “Keychain Sharing” under your app’s Capabilities tab, in the project settings.

The first step is to create an instance of the chart and add it to the view. Open up the ViewController.m file and add the following import statement

#import <ShinobiCharts/ShinobiCharts.h>

Within the same file add the following to the viewDidLoad method:

self.view.backgroundColor = [UIColor whiteColor];

CGFloat margin = [UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPhone ? 10.0 : 50.0;
ShinobiChart *chart = [[ShinobiChart alloc] initWithFrame:CGRectInset(self.view.bounds, margin, margin)];
chart.title = @"Trigonometric Functions";

This instantiates the chart object, and sets its title. Note that the margin around that chart depends on the device form factor. For the iPad a larger margin is used. The ShinobiChart object is a UIView subclass, so respects resizing masks and auto-layout. Further down the same method add the following:

chart.autoresizingMask = ~UIViewAutoresizingNone;

This ensures that the chart frame is adjusted when the device orientation changes.

If you have downloaded a trial version of the ShinobiCharts you will have been issued with a trial license key. Add the key that you were supplied with at the location indicated below.

chart.licenseKey = @""; // TODO: add your trial licence key here!

The next step is to add the axes to the chart. In this example both the X and Y axes are linear, although the chart also supports date-time and category axes. Further down the same method add the following:

// add a pair of axes
SChartNumberAxis *xAxis = [SChartNumberAxis new];
chart.xAxis = xAxis;

SChartNumberAxis *yAxis = [SChartNumberAxis new];
chart.yAxis = yAxis;

Now that the chart is configured, the final step is to add it to the view. Add the following to the end of the method:

[self.view addSubview:chart];

Before you can see the chart in action, you need to supply some data, which brings us onto the next step …

Adding a Datasource

In order to render your data within the chart you need to supply a ‘datasource’, this is a class that adopts the SChartDatasource protocol methods.

If you have worked with UITableView the idea of a datasource should be familiar to you. The shinobichart shares the same concepts both of a datasource, for supplying data, and a delegate, for reacting to user interactions.

Within ViewController.m adopt the datasource protocol via the class extension, that Xcode generated for you, as follows:

@interface ViewController () <SChartDatasource>

The SChartDatasource protocol has four required methods. We’ll take a look at each of them in turn.

The first method numberOfSeriesInSChart: is used to inform the chart how many series you wish to render. Add the following implementation, with a hard-coded value of two:

- (NSInteger)numberOfSeriesInSChart:(ShinobiChart *)chart {
    return 2;
}

The next method, sChart:seriesAtIndex: is used to supply each series to the chart. The series objects describe the visual appearance of each series, but not their actual data values. Add the following to the view controller in order to return two different line series:

-(SChartSeries *)sChart:(ShinobiChart *)chart seriesAtIndex:(NSInteger)index {
    SChartLineSeries *lineSeries = [SChartLineSeries new];

    // the first series is a cosine curve, the second is a sine curve
    if (index == 0) {
        lineSeries.title = @"y = cos(x)";
    } else {
        lineSeries.title = @"y = sin(x)";
    }

    return lineSeries;
}

The next method, sChart:numberOfDataPointsForSeriesAtIndex:, is used to specify the number of data points within a specific series. Add the following implementation below:

- (NSInteger)sChart:(ShinobiChart *)chart numberOfDataPointsForSeriesAtIndex:(NSInteger)seriesIndex {
    return 100;
}

In this example, both series have 100 points, but they do not have to have the same number.

The last method required by the protocol is sChart:dataPointAtIndex:forSeriesAtIndex:, which the chart uses to request the value of each individual datapoint for each series. The returned datapoint must adopt the SChartDataprotocol, which specifies xValue and yValue properties. The charting framework supplies a concrete implementation of this protocol, SChartDataPoint, however, you have the option of implementing this protocol with your own data-objects in order to avoid the need to maintain two copies of your data.

Add the following implementation:

- (idSChartData)sChart:(ShinobiChart *)chart dataPointAtIndex:(NSInteger)dataIndex forSeriesAtIndex:(NSInteger)seriesIndex {
    SChartDataPoint *datapoint = [SChartDataPoint new];

    // both functions share the same x-values
    double xValue = dataIndex / 10.0;
    datapoint.xValue = @(xValue);

    // compute the y-value for each series
    if (seriesIndex == 0) {
        datapoint.yValue = @(cos(xValue));
    } else {
        datapoint.yValue = @(sin(xValue));
    }

    return datapoint;
}

Now that the datasource is implemented, you can add the following to viewDidLoad:

chart.datasource = self;

At this point if you build and run, you should see a couple of series:

Basic chart

With the current implementation each individual datapoint is requested via the datasource. If you have a lot of data, and it is already present in memory, you can optionally make use of the sChart:dataPointsForSeriesAtIndex: protocol method. Your implementation of this method should return all the points for a given series, and this method will be used instead of sChart:dataPointAtIndex:forSeriesAtIndex:.

Adding Labels and Basic Styling

The chart in its current state is a little plain! This section will build on the simple chart that you have created and add a bit more style.

Firstly, the axes could do with having some labels. Also, the Y axis could do with a bit of padding around the top and bottom values to make it easier to see the top and bottom of the curves.

Open up ViewController.m and edit the axis creation code as follows:

SChartNumberAxis *xAxis = [SChartNumberAxis new];
xAxis.title = @"X Value";
chart.xAxis = xAxis;

SChartNumberAxis *yAxis = [SChartNumberAxis new];
yAxis.title = @"Y Value";
yAxis.rangePaddingLow = @(0.1);
yAxis.rangePaddingHigh = @(0.1);
chart.yAxis = yAxis;

It would be nice to see the legend on the iPad, where there is much more screen space to play with. Add the following to the viewDidLoad method:

chart.legend.hidden = [UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPhone;

One of the most powerful features of the Shinobi charts is their gesture-based interactions. Enable pan and zoom on each axis by adding the following code:

// enable gestures
yAxis.enableGesturePanning = YES;
yAxis.enableGestureZooming = YES;
xAxis.enableGesturePanning = YES;
xAxis.enableGestureZooming = YES;

These properties allow the user to pan the chart with a single-finger pan gesture, and zoom using two-finger pinch.

Finally, enable area fill by adding the following just after each series is created within sChart:seriesAtIndex::

lineSeries.style.showFill = YES;

To color the fill area and make it transparent to allow the user to see both series, add this just below lineSeries.title = @"y = cos(x)";:

lineSeries.style.areaColor = [[UIColor blueColor] colorWithAlphaComponent:0.5];
lineSeries.style.areaColorLowGradient = [[UIColor blueColor] colorWithAlphaComponent:0.8];

And this just below lineSeries.title = @"y = sin(x)":

lineSeries.style.areaColor = [[UIColor greenColor] colorWithAlphaComponent:0.5];
lineSeries.style.areaColorLowGradient = [[UIColor greenColor] colorWithAlphaComponent:0.8];

Each series has a style object associated with it, where the style type depends on the series type. A line series has a style object of type SChartLineSeriesStyle. These objects have a a number of properties which you can adjust including line color, thickness and the colors used for gradient fill.

To see the effect of the few simple changes you have just made, build and run:

What we're aiming for

Now that you have created a simple chart, why not have a go at creating a column, or pie chart?