Issue with Crosshair in latest Shinobicharts


#1

Hi,

I came accross this issue where once we tap on any series in the graph and scroll it, the crosshair do not move on the series smoothly, but it moves up and then to the next major tick, or down and then to the next major tick. Here is the screen shot. Also when tapping on the series the crossbar is not at that exact point of tap as in previous libraries.

In this picture, the crosshair moves up as int he picture and then to the next major tick on X axis.


#2

Please help !  :confused: :confused: :confused:


#3

Hi sharonnathaniel,

Which version of ShinobiCharts are you using?

What axes are you using for your X and Y axes?

Kind Regards,
Andrew Polkinghorn


#4

Hi Andrew,

We are using the latest 2.5.6 version. interpolation is set to YES. check this

 [chart.crosshair setMode:SChartCrosshairModeFloating];

    [chart.crosshair setInterpolatePoints:YES];
 
 Still same problem .. for x axes age and y axes the amount both int .

#5

Hi sharonnathaniel,

Thank you for raising this issue. I’ve now replicated the issue at this end. I’ll raise a bug in our backlog to investigate and address this.

In the meantime, I’ll investigate the issue and see if I can come up with a workaround for you.

Many thanks,

Dan


#6

Hi sharonnathaniel,

It definitely looks like there are issues with SChartCrosshairModeFloating, although I’m not sure that the issues I’m seeing in my test app are the same as the ones you’re reporting. Do you require floating mode behaviour?

If you put the crosshair into single mode, and set the interpolatePoints property to YES, the crosshair will correctly track the series, and will display the value of the point on the series it is over. For values in between data points, it will display the interpolated value. Does this match your use case?

Many thanks,

Dan


#7

Hi Dan,

in both the modes of crosshair i.e. floating mode and single mode the results are same. I have tried both the modes before posting here. Is there any property in theme I am missing? Here is the code :

+ (ShinobiChart*)lineChartWithFrame:(CGRect)frame {
     BOOL iPad = UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad;
    
    if (iPad) {
        frame.origin.x += 10;
        frame.origin.y += 3.5;
        frame.size.width -= 85;
        frame.size.height -= 7;
         
    } else {
        frame.size.width -= 0;
    }
    
    
    ShinobiChart *chart = [[ShinobiChart alloc] initWithFrame:frame];
     chart.autoresizingMask = ~UIViewAutoresizingNone;
    chart.clipsToBounds = NO;
  
     SChartLightTheme *theme = [SChartLightThemenew];
    
     // configure and sutomize barChart
     theme.chartTitleStyle.position = SChartTitlePositionCenter;
    theme.barLineWidth = [NSNumber numberWithInt:50];
     SChartAxisTitleStyle *titleStyleyAxis = [SChartAxisTitleStylenew];
    titleStyleyAxis.textColor = [UIColor ColorWithHexValue:@"#2e3192"];
    titleStyleyAxis.backgroundColor = [UIColor clearColor];
     titleStyleyAxis.titleOrientation = SChartAxisTitleOrientationVertical;
    theme.yAxisStyle.titleStyle = titleStyleyAxis;
    [theme.chartTitleStyle setFont:[UIFont systemFontOfSize:22.0]];
     [theme.yAxisStyle.majorTickStylesetLabelFont:[UIFontsystemFontOfSize:15]];
    [chart applyTheme:theme];
    
     chart.backgroundColor = [UIColorColorWithHexValue:@"#bed1f1"];
     [chart.crosshairsetMode:SChartCrosshairModeSingleSeries];
     [chart.crosshairsetInterpolatePoints:YES];
    
     //Double tap can either reset zoom or zoom in
     chart.gestureDoubleTapResetsZoom = YES;
    
     //Our xAxis is a category to take the discrete month data
     SChartCategoryAxis *xAxis = [SChartCategoryAxisnew];
     xAxis.tickLabelClippingModeHigh = SChartTickLabelClippingModeTicksAndLabelsPersist; //keep tick marks at the right end
     [xAxis.style.majorTickStylesetLabelColor:[UIColorColorWithHexValue:@"#2e3192"]];
     [xAxis.style.minorTickStylesetLabelColor:[UIColorColorWithHexValue:@"#2e3192"]];
     //Make some space at the axis limits to prevent clipping of the datapoints
    xAxis.rangePaddingHigh = [NSNumber numberWithFloat:0.25f];
    xAxis.rangePaddingLow = [NSNumber numberWithFloat:0.25f];
    
     //allow zooming and panning
     xAxis.enableGesturePanning = NO;
     xAxis.enableGestureZooming = NO;
     xAxis.enableMomentumPanning = NO;
     xAxis.enableMomentumZooming = NO;
    chart.xAxis = xAxis;
    
     //Use a custom range to best display our data
     SChartNumberRange *r = [[SChartNumberRangealloc] initWithMinimum:[NSNumbernumberWithInt:5] andMaximum:[NSNumbernumberWithInt:28]];
     SChartNumberAxis *yAxis = [[SChartNumberAxisalloc] initWithRange:r];
     [yAxis.style.majorTickStylesetLabelColor:[UIColorColorWithHexValue:@"#2e3192"]];
     [yAxis.style.minorTickStylesetLabelColor:[UIColorColorWithHexValue:@"#2e3192"]];
     yAxis.enableGesturePanning = NO;
     yAxis.enableGestureZooming = NO;
     yAxis.enableMomentumPanning = NO;
     yAxis.enableMomentumZooming = NO;
    chart.yAxis = yAxis;
    
    return chart;

}

Thanks and Regards,

Sharon Nathaniel


#8

Hi Dan,

in both the modes of crosshair i.e. floating mode and single mode the results are same. I have tried both the modes before posting here. Is there any property in theme I am missing? Here is the code :

+ (ShinobiChart*)lineChartWithFrame:(CGRect)frame {
     BOOL iPad = UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad;
    
    if (iPad) {
        frame.origin.x += 10;
        frame.origin.y += 3.5;
        frame.size.width -= 85;
        frame.size.height -= 7;
         
    } else {
        frame.size.width -= 0;
    }
    
    
    ShinobiChart *chart = [[ShinobiChart alloc] initWithFrame:frame];
     chart.autoresizingMask = ~UIViewAutoresizingNone;
    chart.clipsToBounds = NO;
  
     SChartLightTheme *theme = [SChartLightThemenew];
    
     // configure and sutomize barChart
     theme.chartTitleStyle.position = SChartTitlePositionCenter;
    theme.barLineWidth = [NSNumber numberWithInt:50];
     SChartAxisTitleStyle *titleStyleyAxis = [SChartAxisTitleStylenew];
    titleStyleyAxis.textColor = [UIColor ColorWithHexValue:@"#2e3192"];
    titleStyleyAxis.backgroundColor = [UIColor clearColor];
     titleStyleyAxis.titleOrientation = SChartAxisTitleOrientationVertical;
    theme.yAxisStyle.titleStyle = titleStyleyAxis;
    [theme.chartTitleStyle setFont:[UIFont systemFontOfSize:22.0]];
     [theme.yAxisStyle.majorTickStylesetLabelFont:[UIFontsystemFontOfSize:15]];
    [chart applyTheme:theme];
    
     chart.backgroundColor = [UIColorColorWithHexValue:@"#bed1f1"];
     [chart.crosshairsetMode:SChartCrosshairModeSingleSeries];
     [chart.crosshairsetInterpolatePoints:YES];
    
     //Double tap can either reset zoom or zoom in
     chart.gestureDoubleTapResetsZoom = YES;
    
     //Our xAxis is a category to take the discrete month data
     SChartCategoryAxis *xAxis = [SChartCategoryAxisnew];
     xAxis.tickLabelClippingModeHigh = SChartTickLabelClippingModeTicksAndLabelsPersist; //keep tick marks at the right end
     [xAxis.style.majorTickStylesetLabelColor:[UIColorColorWithHexValue:@"#2e3192"]];
     [xAxis.style.minorTickStylesetLabelColor:[UIColorColorWithHexValue:@"#2e3192"]];
     //Make some space at the axis limits to prevent clipping of the datapoints
    xAxis.rangePaddingHigh = [NSNumber numberWithFloat:0.25f];
    xAxis.rangePaddingLow = [NSNumber numberWithFloat:0.25f];
    
     //allow zooming and panning
     xAxis.enableGesturePanning = NO;
     xAxis.enableGestureZooming = NO;
     xAxis.enableMomentumPanning = NO;
     xAxis.enableMomentumZooming = NO;
    chart.xAxis = xAxis;
    
     //Use a custom range to best display our data
     SChartNumberRange *r = [[SChartNumberRangealloc] initWithMinimum:[NSNumbernumberWithInt:5] andMaximum:[NSNumbernumberWithInt:28]];
     SChartNumberAxis *yAxis = [[SChartNumberAxisalloc] initWithRange:r];
     [yAxis.style.majorTickStylesetLabelColor:[UIColorColorWithHexValue:@"#2e3192"]];
     [yAxis.style.minorTickStylesetLabelColor:[UIColorColorWithHexValue:@"#2e3192"]];
     yAxis.enableGesturePanning = NO;
     yAxis.enableGestureZooming = NO;
     yAxis.enableMomentumPanning = NO;
     yAxis.enableMomentumZooming = NO;
    chart.yAxis = yAxis;
    
    return chart;

}

Thanks and Regards,

Sharon Nathaniel


#9

Hi Dan,

in both the modes of crosshair i.e. floating mode and single mode the results are same. I have tried both the modes before posting here. Is there any property in theme I am missing? Here is the code :

+ (ShinobiChart*)lineChartWithFrame:(CGRect)frame {
     BOOL iPad = UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad;
    
    if (iPad) {
        frame.origin.x += 10;
        frame.origin.y += 3.5;
        frame.size.width -= 85;
        frame.size.height -= 7;
         
    } else {
        frame.size.width -= 0;
    }
    
    
    ShinobiChart *chart = [[ShinobiChart alloc] initWithFrame:frame];
     chart.autoresizingMask = ~UIViewAutoresizingNone;
    chart.clipsToBounds = NO;
  
     SChartLightTheme *theme = [SChartLightThemenew];
    
     // configure and sutomize barChart
     theme.chartTitleStyle.position = SChartTitlePositionCenter;
    theme.barLineWidth = [NSNumber numberWithInt:50];
     SChartAxisTitleStyle *titleStyleyAxis = [SChartAxisTitleStylenew];
    titleStyleyAxis.textColor = [UIColor ColorWithHexValue:@"#2e3192"];
    titleStyleyAxis.backgroundColor = [UIColor clearColor];
     titleStyleyAxis.titleOrientation = SChartAxisTitleOrientationVertical;
    theme.yAxisStyle.titleStyle = titleStyleyAxis;
    [theme.chartTitleStyle setFont:[UIFont systemFontOfSize:22.0]];
     [theme.yAxisStyle.majorTickStylesetLabelFont:[UIFontsystemFontOfSize:15]];
    [chart applyTheme:theme];
    
     chart.backgroundColor = [UIColorColorWithHexValue:@"#bed1f1"];
     [chart.crosshairsetMode:SChartCrosshairModeSingleSeries];
     [chart.crosshairsetInterpolatePoints:YES];
    
     //Double tap can either reset zoom or zoom in
     chart.gestureDoubleTapResetsZoom = YES;
    
     //Our xAxis is a category to take the discrete month data
     SChartCategoryAxis *xAxis = [SChartCategoryAxisnew];
     xAxis.tickLabelClippingModeHigh = SChartTickLabelClippingModeTicksAndLabelsPersist; //keep tick marks at the right end
     [xAxis.style.majorTickStylesetLabelColor:[UIColorColorWithHexValue:@"#2e3192"]];
     [xAxis.style.minorTickStylesetLabelColor:[UIColorColorWithHexValue:@"#2e3192"]];
     //Make some space at the axis limits to prevent clipping of the datapoints
    xAxis.rangePaddingHigh = [NSNumber numberWithFloat:0.25f];
    xAxis.rangePaddingLow = [NSNumber numberWithFloat:0.25f];
    
     //allow zooming and panning
     xAxis.enableGesturePanning = NO;
     xAxis.enableGestureZooming = NO;
     xAxis.enableMomentumPanning = NO;
     xAxis.enableMomentumZooming = NO;
    chart.xAxis = xAxis;
    
     //Use a custom range to best display our data
     SChartNumberRange *r = [[SChartNumberRangealloc] initWithMinimum:[NSNumbernumberWithInt:5] andMaximum:[NSNumbernumberWithInt:28]];
     SChartNumberAxis *yAxis = [[SChartNumberAxisalloc] initWithRange:r];
     [yAxis.style.majorTickStylesetLabelColor:[UIColorColorWithHexValue:@"#2e3192"]];
     [yAxis.style.minorTickStylesetLabelColor:[UIColorColorWithHexValue:@"#2e3192"]];
     yAxis.enableGesturePanning = NO;
     yAxis.enableGestureZooming = NO;
     yAxis.enableMomentumPanning = NO;
     yAxis.enableMomentumZooming = NO;
    chart.yAxis = yAxis;
    
    return chart;

}

Thanks and Regards,

Sharon Nathaniel


#10

Hello Sharon,

I’ve had a look and I too have managed to replicate the issue. I’ve managed to replicate it in a very stripped down project, using the following key settings:

...
chart.xAxis = [SChartCategoryAxis new];
chart.yAxis = [SChartNumberAxis new];
...
chart.crosshair.interpolatePoints = YES;
..

It seem as though the crosshair is refusing to interpolate across category axes, so it is jumping along the X-axis, whilst smoothly moving up and down the Y-axis. Is this the same behaviour that you are seeing?

I’ll raise this as a bug and we’ll look into getting it fixed - we’ll update this thread with any progress we make. In the meanwhile, have you thought about perhaps using a number axis for your X-axis? If you set the major tick frequency to @1, you should get the same axis effect, and this would work perfectly seeing that your X-axis is actually displaying numbers.

chart.xAxis = [SChartNumberAxis new];
chart.xAxis.majorTickFrequency = @1;

Thanks,
Jan


#11

Hi Jan,

Yes the crosshair is refusing to interpolate, I tried setting majorTickFrequency to @1 but no effect I have tried it for around a week in different graphs in our app still same issue.

Thanks and Regards,

Sharon Nathaniel


#12

Hi Sharon Nathaniel,

With a category axis, I can also replicate the issue you’re seeing. As Jan mentioned, it’s not really possible to interpolate between categories, as they are discrete values. ShinobiCharts should probably handle this configuration better, maybe by disabling crosshair interpolation if one or both of the axes are category axes.

When I change the x axis to be a numeric axis rather than a category axis, I’m afraid I’ve been unable to replicate the issue you’re seeing. I’ve taken the code you posted, and plotted some sample data in a chart. When I enable crosshair interpolation, the crosshair behaves as expected.

If you’d like, I could send you the test project I’ve created, and you could see whether that works for you? If so, it might be worth looking at what is set up differently between the two projects. If you don’t feel that the test project covers the use case you’re after, maybe you could modify it to demonstrate the problem, and then send it back to us? That would allow us to replicate the issue at this end.

Let me know what you think.

Regards,

Dan


#13

Hi Dan,

I would like the test project that you have, it will better help us to understand the difference.

Thanks and Regards,

Sharon Nathaniel


#14

Hi Sharon Nathaniel,

I’ve just sent over the test project. Let me know how things go with that.

Many thanks,

Dan


#15

Hi Dan.

Thanks for the test project, there is no difference in your project and ours, except how we provide the datapoints to x and y axis, something like this:

//
//  Datasource.m
//  LineChart
 
 #import "Datasource.h"
 #import "ShinobiChart+LineChart.h"
 
@implementation Datasource
 
- (int)numberOfSeriesInSChart:(ShinobiChart *)chart {
     return [_productModalDelegatedataKeys].count;
}
 
- (SChartSeries*)sChart:(ShinobiChart *)chart seriesAtIndex:(int)index {
    return [chart lineSeriesForKey:[[_productModalDelegate dataKeys] objectAtIndex:index]];
}
 
- (int)sChart:(ShinobiChart *)chart numberOfDataPointsForSeriesAtIndex:(int)seriesIndex {
     return [_productModalDelegateageArray].count;
}
 
- (id<SChartData>)sChart:(ShinobiChart *)chart dataPointAtIndex:(int)dataIndex forSeriesAtIndex:(int)seriesIndex {
     SChartDataPoint *dp = [SChartDataPointnew];
    
     //Map our data values from the data to our chart
     dp.xValue =  [[_productModalDelegateageArray] objectAtIndex:[_productModalDelegateageArray].count - dataIndex - 1];
    
     dp.yValue =[[[_productModalDelegatedata] objectForKey:dp.xValue] objectForKey:[[_productModalDelegatedataKeys] objectAtIndex:seriesIndex]];
    
    return dp;

}

The data points are plotted just fine. Still the problem arises with the crosshair tracking. 

Thanks and Regards,

Sharon Nathaniel


#16

Hi Sharonnathaniel,

I think it would be best if you sent in a cut down version of your project that replicates this issue to info@shinobicontrols.com referencing this forum thread. We’ll take a look at it first hand and it should be a lot easier to determine what the issue is.

Thanks,

Jan Akerman


#17

Hi Jan,

I will try to do that.

Thanks and Regards,

Sharon Nathaniel


#18

Hi Jan, Dan,

Thanks for everything, I just was missing one line that was always slipping through our eyes:

    SChartCategoryAxis *xAxis = [SChartCategoryAxisnew];

needs to be canged to:

    SChartAxis *xAxis = [SChartNumberAxisnew];

And it started to work just fine.

Thanks Again for the sample project, it helped us out for figure that out.

Thanks and Regards,

Sharon Nathaniel