Customize x-axis using Shinobi for iOS


#1

All , I am a complete novice to Shinobi hence starting out with the basics. The amount of documentation is quite overwhelming so I honestly don’t know from where to start 

I am looking into a simple graph where the x-axis needs to display the time in hours with an hour spacing in between ( 1- 24 on the x-axis). If I fit all of this into a single screen then the data looks very untidy . I am looking at any sample code /API/ Pointers that would tell me how using Shinobi APIs I could customize my x-axis such that say only 1- 12 is displayed on the current app screen and then when the user perfomrs a pan / slide gesture  the remianing x-axis screen is displayed 


#2

I  tried using the xAxis.majorTickFrequency to increase the frequency but everything is still shown in the same page. I need help on how to space out the x-axis beyond the current page


#3

Hi Sim777,

Your majorTickFrequency dictates how often your tick marks should be displayed in terms of data increments. To control the zoom level you’ll want to modify each of your axes’ ranges:

  • If you set a range with a smaller span on your axis, it will have the effect of zooming in as a smaller range is displayed over the same physical axis space.
  • If you set a range with a larger span on your axis, it will have the effect of zooming out as a larger range is displayed over the same physical axis space.

Here’s a link to our SChartAxis documentation which contains information about all of our range setting properties. If you want to programatically set the range of your chart at any time then you’ll want to use the method setRangeWithMinimum:andMaximum:withAnimation: on your axes.

Since you’re interested in setting the range of your axes upon start up, you’re actually interested in setting the default range. You can do this via the initWithRange: method. I’m not sure what kind of axis you’re using but if you were using a number axis it’d look something like this.

SChartNumberRange *range = [[SChartNumberRange alloc] initWithMinimum:@0 andMaximum:@12];

SChartNumberAxis *xAxis = [[SChartNumberAxis alloc] initWithRange:range];

self.chart.xAxis = xAxis;

Thanks,
Jan


#4

Thank you for your response. I am using the initWithMinimum and Maximum APIs to set the range for the x-axis.
So when I do this , based on your sample code below I will see the x axis having values from 0 to 12. The problem is I see 0 to 12 in the current app screen . 
Now my requirement is to NOT show the entire range of 0 to 12 on the current x-axis on the app screen . instead I should be showing 0 to 6 in the current screen and then when the user does a slide / pan gesture movement the user should be able to see the remaining 6 to 12 ticks on the x-axis
I  am looking to implement only a simple pan gesture / slide swipe on the x-axis . I am not considering implementing zoom in zoom out yet.


#5

Hi Sim,

To do this you can set the “enableGesturePanning” property on your X-axis to YES and set your initial range from 0 to 6.

You can now pan across your X-axis keeping a range span of 6.

Let me know if you have any questions.

Kind regards,
Andrew Polkinghorn


#6

This is what I have tried but its still not working . Please let me know if I have missed out on anything . My intention is to have the total range from 1 to 12 , and a single screen from 0 to 6 and then 6 to 12.

 SChartNumberRange *range=[[SChartNumberRangealloc]initWithMinimum:[NSNumbernumberWithInt:0 andMaximum:[NSNumbernumberWithInt:6]]; //Initial screen for 0 to 6

SChartNumberAxis *xAxis = [[SChartNumberAxisalloc]initWithRange:range];

 [xAxis setRangeWithMinimum:[NSNumber numberWithInt:0] andMaximum:[NSNumber numberWithInt:12] withAnimation:true usingBounceLimits:true]; //Setting the total gesture from 0 to 12.
 xAxis.style.titleStyle.position = SChartTitlePositionTopOrRight;
 xAxis.title = @"Hours";
 xAxis.style.majorTickStyle.showTicks=YES;
  xAxis.enableGesturePanning = YES; //Sim added for Cesar
  xAxis.style.majorGridLineStyle.showMajorGridLines = NO; //Sim added for Cesar
  xAxis.style.gridStripeStyle.showGridStripes = NO; //Sim added for Cesar
  _shinobiChart.xAxis = xAxis;

 


#7

Hi sim777,

I think your problem may be with the following lines:

SChartNumberRange *range=[[SChartNumberRangealloc]initWithMinimum:[NSNumbernumberWithInt:0 andMaximum:[NSNumbernumberWithInt:6]]; //Initial screen for 0 to 6

SChartNumberAxis *xAxis = [[SChartNumberAxisalloc] initWithRange:range];

[xAxis setRangeWithMinimum:[NSNumber numberWithInt:0] andMaximum:[NSNumber numberWithInt:12]withAnimation:true usingBounceLimits:true]; //Setting the total gesture from 0 to 12.

You are creating an axis with the range 0 - 6 (which is what you want) and then immediately setting its range to 0 - 12 (which is what you don’t want). Your comment next to the code where you set the range to 0 - 12 says something about a gesture, so I’m not sure this is doing what you would like it to do. Just try removing the last line I have referenced above and your chart should render with a range of 0 - 6.

I hope that helps!  :grin:


#8

Thank you for your post

So my requirement is as follows :

1)My total range for the x-axis is from 0 to 12

2)I want this range of 0 to 12 to be distributed into 2 parts (0 to 6 and 7 to 12)

3)The 0 to 6 should be displayed on the x-axis in the first screen when the app is present 

4)Then when the user does a slide  / pan gesture on the x-axis it should show the next screen i.e 7 to 12 

To achieve the above I did as per earlier guideline

a)Set the enable pan gesture to true i.e  xAxis.enableGesturePanning = true

b)Set the total range of the x-axis from 0 to 12 --Did that using setRangeWithMinimum and Maximum

c)Set the initial range that will show on the screen as 0 to 6 – using the range and initWithRange function

 

However this doesnt work . Only my initial screen range from 0 to 6 is shown and no pan or slide gesture works 

Please let me know how to get the above requirement working. Also note at this point I am looking at simple pan gesture / slide gesture (no zoom in and zoom out is needed 


#9

Hi sim777,

Zooming and panning are done in exactly the same way in ShinobiCharts (by setting the min and max of the range, but where the difference between min and max does not change when panning). This is why we sometimes use the terms ‘zooming’ and ‘panning’ interchangeably. But rest assured that we understand you are not looking to implement zooming in this case.

Your recent post makes it sound like you would like to achieve panning via paging (a swipe should shift the range of the x-axis by some set amount, rather than letting the user pan continuously over the whole range). I would like to be clear, before proceeding any further with your use case, that panning in the way you have described (paging) isn’t supported out of the box with ShinobiCharts. To see the type of panning that is supported I would suggest taking a look at our MultipleAxes sample (multiple axes aren’t necessary, this just happens to be a sample setup with a pannable range). 

This doesn’t mean that paging the x-axis is impossible, it would just require a lot more work to achieve (i.e. your own gesture recogniser which handles manually changing the range by a set amount on a swipe).

Before we make any further suggestions would you please let us know are you trying to achieve paging, or are you trying to achieve continuous panning similar to the MultipleAxes sample?

Thanks

Ryan 


#10

Hi,

I would like to restart this conversation again . My requirement is to achieve continuos panning by the user .

Basically the X-axis of my graph is a day with spacing of 15 min (Starting 12 am and ending 11:59 pm ). Each plot on the x-axis will be spaced at 15 minutes.

Now since this is too much to be accomodated into a single screen (basically 96 data points since i am considering every 15 minutes of data) , I would like to use the continuos panning to achieve this. 

Can you please help me out on this ? How and where can i start this implementation .My current code for the daily x-axis is as follows :

  1. The graph is drawn over a scroll view 

  2. X axis : 

SChartDateRange *range = [[SChartDateRangealloc] initWithDateMinimum:prev andDateMaximum:next]; //prev and next indicate previous and next days date

SChartDateTimeAxis *xAxis = [[SChartDateTimeAxisalloc] initWithRange:range];

    NSDateFormatter *dayFormatter = [[NSDateFormatteralloc] init];

    [dayFormatter setDateFormat:@“hh a”];

    SChartTickLabelFormatter *formatter = [SChartTickLabelFormatterdateFormatter];

    [formatter setFormatter:dayFormatter];

    xAxis.labelFormatter = formatter;

    xAxis.rangePaddingLow = [SChartDateFrequencydateFrequencyWithHour:1];

    xAxis.rangePaddingHigh = [SChartDateFrequencydateFrequencyWithHour:1]; xAxis.majorTickFrequency = [[SChartDateFrequencyalloc] initWithHour:2];

    xAxis.style.majorTickStyle.showTicks=YES;

    _shinobiChart.xAxis = xAxis;

This shows the x-axis within a single app screen with each tick at a spacing of 2 hrs to accomodate the entire x-axis into a signle screen. Now I want to change this to have each tick at a spacing of 15 minutes and the user can do continuos panning to go through the entire range of the x-axis


#11

You’ll need to set the range of your axis as follows (assuming dateFromString is a method that parses a string and returns an NSDate object)

SChartDateRange* dateRange = [[SChartDateRange alloc] initWithDateMinimum:[self dateFromString:@"10-03-13 00:00:00"] andDateMaximum:[self dateFromString:@"10-03-13 12:00:00"]];

SChartDateTimeAxis *xAxis = [[SChartDateTimeAxis alloc] initWithRange:dateRange];

Assuming your datapoints are 15 minutes intervals on 13-03-2015, then this would show all the datapoints between midnight and 12 o’clock in the afternoon. With the remainder ‘off screen’ that will be shown if the chart is panned.

You’ll need to adjust your tick frequency to:

xAxis.majorTickFrequency = [SChartDateFrequency dateFrequencyWithMinute:15];

I’m afraid I don’t quite understand what you mean by ‘continuously panning’, but as long you have enableGesturePanning enabled on your axis then the user should be able to pan along the axis. If you mean animating the pan programmatically, then please see - (BOOL)setRangeWithMinimum:(id)minimum andMaximum:(id)maximum withAnimation:(BOOL)animation which may be waht you’re looking for.

Kind regards,

Sam


#12

Here is the latest update based on the code and feedback . I have also uploaded the graph obtained  using the source code below. X-axis without panning

   //Getting the previous date :

    NSCalendar *calendar = [NSCalendarcurrentCalendar];

    NSDateComponents *components = [calendar components:NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit

                                               fromDate:trial];

    NSDate *start = [calendar dateFromComponents:components];

    NSTimeInterval reducesecondsInHours = -1 * 60 * 60;

    NSTimeInterval  increasesecondsInHours = 1 * 60 * 60;

    NSDate *prev = [start dateByAddingTimeInterval:reducesecondsInHours]; //This gives 11 pm of the previous day I.e March 9th 11:00 pm

    //Getting the next date :

    calendar = [NSCalendarcurrentCalendar];

    components = [NSDateComponentsnew];

    components.day = 1;

    NSDate *enddate = [calendar dateByAddingComponents:components

                                             toDate:start

                                            options:0];

    enddate = [enddate dateByAddingTimeInterval:-1];

    NSDate *next =  [enddate dateByAddingTimeInterval:increasesecondsInHours]; //This gives the 12 am of the next day I.e March 11th 12:00 am

    //Plotting the axis now

    SChartDateRange *range = [[SChartDateRangealloc] initWithDateMinimum:prev andDateMaximum:next]; //Prev and next are NSDate that show (

    SChartDateTimeAxis *xAxis = [[SChartDateTimeAxisalloc] initWithRange:range];

    NSDateFormatter *dayFormatter = [[NSDateFormatteralloc] init];

    [dayFormatter setDateFormat:@“hh a”];

    SChartTickLabelFormatter *formatter = [SChartTickLabelFormatterdateFormatter];

    [formatter setFormatter:dayFormatter];

    xAxis.labelFormatter = formatter;

    xAxis.rangePaddingLow = [SChartDateFrequencydateFrequencyWithHour:1];

    xAxis.rangePaddingHigh = [SChartDateFrequencydateFrequencyWithHour:1];

    xAxis.style.majorGridLineStyle.showMajorGridLines = NO;

    xAxis.style.gridStripeStyle.showGridStripes = NO; 

    xAxis.style.titleStyle.position = SChartTitlePositionTopOrRight;

    xAxis.majorTickFrequency = [[SChartDateFrequencyalloc] initWithMinute:15];

    xAxis.style.majorTickStyle.showTicks=YES;

    xAxis.enableGesturePanning = YES;

    xAxis.enableMomentumPanning = YES;

    _shinobiChart.xAxis = xAxis;

    

    [_shinobiChartreloadData];

    [_shinobiChartredrawChart];


#13

Hi sim777,

Unfortunatley I am unable to see the image you have included in your post. Does the code you have posted above work, or are you still having problems?

Thanks

Ryan